-
-
Notifications
You must be signed in to change notification settings - Fork 753
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
asgiref
backward compatibility
#1305
Comments
If it were me, I'd vendorize the typings again and check the The reason why is Perhaps future While I see the ecosystem around it stabilizing over time, I am happy to open a PR to re-vendorize typings in and with multi-version |
asgiref
dependency? (>=3.4.0
prevents a workaround of common channels
bug)asgiref
backward compatibility
I'm willing to approve a PR with the vendor, and tests running against |
@Kludex I will prepare one ASAP |
Cool. Thanks 👍 |
Follow up in #1312
That hypothesis isn't working out. I don't see a way to mypy or type annotations can branch based on asgiref version. |
This is me buzzing by with the observation that just mellowing out and rolling with |
opened at #1373 |
@tomchristie Would you want to move this to discussion per #1374 until there's a consensus? Or fine keeping it as issue for now? |
I'm not sure @tony - that's a good question. I'd certainly suggest closing #1373 off, yes. Since this issue is open, and since it's clear that it's behaviourally breaking something for you let's keep it open and get it resolved. Your option (2.) seems like it might be a good approach to start with. |
I will keep this issue open for now
Can you clarify what's meant by closing it off? #1305 (comment) discussed using |
Yes. I think we should close #1373. (Without merging.)
I think there's a discussion worth having there, but not we should definitely do this.
Agreed. The lowest-possible change footprint PR is probably a good approach. If (2) would resolve the issue for you then I'd suggest we'd want to go with that. We could later consider either vendoring |
This commit will enable mypy strict mode, and update code accordingly. Type annotations are not used at runtime. The standard library `typing` module includes a `TYPE_CHECKING` constant that is `False` at runtime, but `True` when conducting static type checking prior to runtime. Type imports will be included under `if TYPE_CHECKING:` conditions. These conditions will be ignored when calculating test coverage. https://docs.python.org/3/library/typing.html The Python standard library `logging.config` module uses type stubs. The typeshed types for the `logging.config` module are used solely for type-checking usage of the `logging.config` module itself. They cannot be imported and used to type annotate other modules. For this reason, dict config types will be vendored into a module in the inboard package. https://github.com/python/typeshed/blob/main/stdlib/logging/config.pyi The ASGI application in `inboard.app.main_base` will be updated to ASGI3 and type-annotated with `asgiref.typing`. Note that, while Uvicorn uses `asgiref.typing`, Starlette does not. The type signature expected by the Starlette/FastAPI `TestClient` therefore does not match `asgiref.typing.ASGIApplication`. A mypy `type: ignore[arg-type]` comment will be used to resolve this difference. https://asgi.readthedocs.io/en/stable/specs/main.html Also note that, while the `asgiref` package was a runtime dependency of Uvicorn 0.17.6, it was later removed from Uvicorn's runtime dependencies in 0.18.0 (encode/uvicorn#1305, encode/uvicorn#1532). However, `asgiref` is still used to type-annotate Uvicorn, so any downstream projects like inboard that type-check Uvicorn objects must also install `asgiref`. Therefore, `asgiref` will be added to inboard's development dependencies to ensure that type checking continues to work as expected. A Uvicorn options type will be added to a new inboard types module. The Uvicorn options type will be a `TypedDict` with fields corresponding to arguments to `uvicorn.run`. This type can be used to check arguments passed to `uvicorn.run`, which is how `inboard.start` runs Uvicorn. Uvicorn 0.17.6 is not fully type-annotated, and Uvicorn does not ship with a `py.typed` marker file until 0.19.0. It would be convenient to generate types dynamically with something like `getattr(uvicorn.run, "__annotations__")` (Python 3.9 or earlier) or `inspect.get_annotations(uvicorn.run)` (Python 3.10 or later). https://docs.python.org/3/howto/annotations.html It could look something like this: ```py UvicornOptions = TypedDict( # type: ignore[misc] "UvicornOptions", inspect.get_annotations(uvicorn.run), total=False, ) ``` Note the `type: ignore[misc]` comment. Mypy raises a `misc` error: `TypedDict() expects a dictionary literal as the second argument`. Unfortunately, `TypedDict` types are not intended to be generated dynamically, because they exist for the benefit of static type checking (python/mypy#3932, python/mypy#4128, python/mypy#13940). Furthermore, prior to Uvicorn 0.18.0, `uvicorn.run()` didn't enumerate keyword arguments, but instead accepted `kwargs` and passed them to `uvicorn.Config.__init__()` (encode/uvicorn#1423). The annotations from `uvicorn.Config.__init__()` would need to be used instead. Even after Uvicorn 0.18.0, the signatures of the two functions are not exactly the same (encode/uvicorn#1545), so it helps to have a static type defined. There will be some other differences from `uvicorn.run()`: - The `app` argument to `uvicorn.run()` accepts an un-parametrized `Callable` because Uvicorn tests use callables (encode/uvicorn#1067). It is not necessary for other packages to accept `Callable`, and it would need to be parametrized to pass mypy strict mode anyway. For these reasons, `Callable` will not be accepted in this type. - The `log_config` argument will use the new inboard dict config type instead of `dict[str, Any]` for stricter type checking.
Checklist
master
.Describe the bug
Hi, thank you for the project, this is a shot in the dark since it's not a
channels
bug!#1100 pinned the
asgiref
dependency to>=3.4.0
for mypy purposes. It may be worth loosening it if it's onlymypy
as the restriction requires the user to useasgiref
3.4.0
, which triggers a well-known but unsolved channels (a different package)Alternatives to pulling in
asgiref
for typings:Dropping the
asgiref
dependency and copyingasgiref.typings
to_types
_types
can have compat-like functionality depending on theasgiref
version installed so things so uvicorn can be independent of django and channels.Loosening the constraint
Would mypy work if
try
/catch
withImportError
was used? Would be willing to consider it as a compatibility workaround until ASGIRef 3.4.1 + Channels 3.0.3 causes non-deterministic 500 errors serving static files django/channels#1722 is resolved?A word of note:
This is for posterity, of course it's never needed for an independent project such as
uvicorn
to change it's pinning due to another package's issues, but noteworthy sincechannels
is often used alongsideuvicorn
by users.The reasons why I post this here is channel's bug at django/channels#1722 is prominent, its easiest apparent workaround is to decrease
asgiref
's version below<3.4.0
, and the only reason I can see3.4.0
was pinned in #1100 ismypy
and there may be a way to satisfy mypy and relax the constraint.I think it's up to the maintainer and I wanted to document the issue.
Steps to reproduce the bug
I believe this happens on sites where static files are served via the asgi server. This happens when there's a heavy load (such as selenium tests).
Expected behavior
Static files via dev servers should serve without raising deadlock errors
Actual behavior
No response
Debugging material
Assuming uvicode
0.16.0
, it requires we useasgiref
3.4.0
+Environment
OS: Ubuntu latest via docker
uvicorn: 0.16.0
channels: 2.4.0
asgiref: 3.4.0 (breakage) 3.3.4 (works)
python 3.10
Additional context
No response
The text was updated successfully, but these errors were encountered: