Skip to content
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

Add custom typing to config and ctx #2785

Merged
merged 14 commits into from
Jul 12, 2023
Merged

Add custom typing to config and ctx #2785

merged 14 commits into from
Jul 12, 2023

Conversation

ahopkins
Copy link
Member

@ahopkins ahopkins commented Jul 11, 2023

One thing I have always found slightly annoying is that the reliance upon app.ctx and app.config lead to only partially typed objects. This PR attempts to resolve that by adding some generics into sanic.Sanic and sanic.Request:

app: Sanic[CustomConfig, CustomCtx]

This can also be achieved by implication just through instantiation:

from sanic import Sanic
app = Sanic("test")
reveal_type(app)  # N: Revealed type is "sanic.app.Sanic[sanic.config.Config, types.SimpleNamespace]"
from sanic import Sanic
from sanic.config import Config

class CustomConfig(Config):
    pass

app = Sanic("test", config=CustomConfig())
reveal_type(app)  # N: Revealed type is "sanic.app.Sanic[main.CustomConfig, types.SimpleNamespace]"
from sanic import Sanic

class Foo:
    pass

app = Sanic("test", ctx=Foo())
reveal_type(app)  # N: Revealed type is "sanic.app.Sanic[sanic.config.Config, main.Foo]"
from sanic import Sanic
from sanic.config import Config

class CustomConfig(Config):
    pass

class Foo:
    pass

app = Sanic("test", config=CustomConfig(), ctx=Foo())
reveal_type(app)  # N: Revealed type is "sanic.app.Sanic[main.CustomConfig, main.Foo]"

The goal of this PR is a nicer dev experience to be able to fully type out the ctx and config objects.

Given a simple handler with no custom typing:

@app.get("/")
async def handler(request: Request):
    reveal_type(request.app)

image

Or, a fully custom typed:

image

A side benefit is that sanic.Request.ctx is now a lazy object and will not be instantiated until used. This is accomplished by introducing a new staticmethod on the Request object. It can be used to instantiate a custom ctx object as shown in the above screenshot. This is the only functional change in this PR: moving self.ctx = SimpleNamespace() into the lazy make_context pattern.

TODO:

  • Add generics also to Request.ctx
  • Add generics also to Request so that it can pass the ref in a handler for example

@ahopkins ahopkins changed the title Add Sanic app instance typing Add custom typing to config and ctx Jul 11, 2023
@ahopkins ahopkins marked this pull request as ready for review July 11, 2023 12:43
@ahopkins ahopkins requested review from a team as code owners July 11, 2023 12:43
@ahopkins ahopkins marked this pull request as draft July 11, 2023 16:44
@ahopkins ahopkins marked this pull request as ready for review July 12, 2023 09:56
@codecov
Copy link

codecov bot commented Jul 12, 2023

Codecov Report

Patch coverage: 89.473% and project coverage change: -0.081 ⚠️

Comparison is base (929d270) 88.887% compared to head (044675d) 88.806%.

Additional details and impacted files
@@              Coverage Diff              @@
##              main     #2785       +/-   ##
=============================================
- Coverage   88.887%   88.806%   -0.081%     
=============================================
  Files           92        92               
  Lines         7001      7031       +30     
  Branches      1194      1195        +1     
=============================================
+ Hits          6223      6244       +21     
- Misses         531       538        +7     
- Partials       247       249        +2     
Impacted Files Coverage Δ
sanic/blueprints.py 91.743% <ø> (ø)
sanic/errorpages.py 98.780% <ø> (ø)
sanic/headers.py 96.059% <ø> (ø)
sanic/router.py 96.000% <ø> (ø)
sanic/server/websockets/frame.py 92.523% <ø> (ø)
sanic/app.py 89.072% <76.470%> (-1.097%) ⬇️
sanic/__init__.py 100.000% <100.000%> (ø)
sanic/exceptions.py 97.247% <100.000%> (ø)
sanic/request/types.py 94.915% <100.000%> (+0.163%) ⬆️
sanic/server/websockets/impl.py 37.674% <100.000%> (+0.232%) ⬆️

... and 1 file with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

sanic/server/websockets/frame.py Show resolved Hide resolved
sanic/server/websockets/impl.py Show resolved Hide resolved
tests/typing/test_typing.py Show resolved Hide resolved
@ahopkins ahopkins merged commit dc3c4d1 into main Jul 12, 2023
@ahopkins ahopkins deleted the typed-app branch July 12, 2023 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants