engin 0.0.6__tar.gz → 0.0.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {engin-0.0.6 → engin-0.0.7}/CHANGELOG.md +7 -0
- {engin-0.0.6 → engin-0.0.7}/PKG-INFO +1 -1
- engin-0.0.7/docs/concepts/engin.md +11 -0
- engin-0.0.7/docs/concepts/invocations.md +132 -0
- engin-0.0.7/docs/concepts/providers.md +176 -0
- {engin-0.0.6 → engin-0.0.7}/pyproject.toml +1 -1
- {engin-0.0.6 → engin-0.0.7}/src/engin/_dependency.py +1 -1
- {engin-0.0.6 → engin-0.0.7}/src/engin/_engin.py +1 -2
- engin-0.0.7/tests/conftest.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/tests/test_assembler.py +18 -0
- {engin-0.0.6 → engin-0.0.7}/tests/test_dependencies.py +14 -2
- {engin-0.0.6 → engin-0.0.7}/uv.lock +88 -88
- engin-0.0.6/docs/concepts/providers.md +0 -2
- {engin-0.0.6 → engin-0.0.7}/.github/workflows/check.yaml +0 -0
- {engin-0.0.6 → engin-0.0.7}/.github/workflows/publish.yaml +0 -0
- {engin-0.0.6 → engin-0.0.7}/.gitignore +0 -0
- {engin-0.0.6 → engin-0.0.7}/.readthedocs.yaml +0 -0
- {engin-0.0.6 → engin-0.0.7}/LICENSE +0 -0
- {engin-0.0.6 → engin-0.0.7}/README.md +0 -0
- /engin-0.0.6/examples/__init__.py → /engin-0.0.7/docs/concepts/lifecycle.md +0 -0
- {engin-0.0.6 → engin-0.0.7}/docs/engin.md +0 -0
- {engin-0.0.6 → engin-0.0.7}/docs/guides/dependency_injection.md +0 -0
- {engin-0.0.6 → engin-0.0.7}/docs/index.md +0 -0
- {engin-0.0.6 → engin-0.0.7}/docs/js/readthedocs.js +0 -0
- {engin-0.0.6 → engin-0.0.7}/docs/overrides/main.html +0 -0
- {engin-0.0.6/examples/asgi → engin-0.0.7/examples}/__init__.py +0 -0
- {engin-0.0.6/examples/asgi/common → engin-0.0.7/examples/asgi}/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/app.py +0 -0
- {engin-0.0.6/examples/asgi/common/db → engin-0.0.7/examples/asgi/common}/__init__.py +0 -0
- {engin-0.0.6/examples/asgi/common/db/adapaters → engin-0.0.7/examples/asgi/common/db}/__init__.py +0 -0
- {engin-0.0.6/examples/asgi/common/starlette → engin-0.0.7/examples/asgi/common/db/adapaters}/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/common/db/adapaters/memory.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/common/db/block.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/common/db/ports.py +0 -0
- {engin-0.0.6/examples/asgi/features → engin-0.0.7/examples/asgi/common/starlette}/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/common/starlette/endpoint.py +0 -0
- {engin-0.0.6/examples/asgi/features/cats → engin-0.0.7/examples/asgi/features}/__init__.py +0 -0
- {engin-0.0.6/examples/asgi/features/cats/api → engin-0.0.7/examples/asgi/features/cats}/__init__.py +0 -0
- {engin-0.0.6/examples/fastapi → engin-0.0.7/examples/asgi/features/cats/api}/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/features/cats/api/get.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/features/cats/api/post.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/features/cats/block.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/features/cats/domain.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/asgi/main.py +0 -0
- {engin-0.0.6/examples/fastapi/routes → engin-0.0.7/examples/fastapi}/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/fastapi/app.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/fastapi/main.py +0 -0
- {engin-0.0.6/examples/fastapi/routes/cats → engin-0.0.7/examples/fastapi/routes}/__init__.py +0 -0
- {engin-0.0.6/examples/fastapi/routes/cats/adapters → engin-0.0.7/examples/fastapi/routes/cats}/__init__.py +0 -0
- {engin-0.0.6/examples/simple → engin-0.0.7/examples/fastapi/routes/cats/adapters}/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/fastapi/routes/cats/adapters/repository.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/fastapi/routes/cats/api.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/fastapi/routes/cats/block.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/fastapi/routes/cats/domain.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/fastapi/routes/cats/ports.py +0 -0
- {engin-0.0.6/src/engin/ext → engin-0.0.7/examples/simple}/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/examples/simple/main.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/mkdocs.yaml +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/_assembler.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/_block.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/_exceptions.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/_lifecycle.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/_type_utils.py +0 -0
- {engin-0.0.6/tests → engin-0.0.7/src/engin/ext}/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/ext/asgi.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/ext/fastapi.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/src/engin/py.typed +0 -0
- {engin-0.0.6/tests/acceptance → engin-0.0.7/tests}/__init__.py +0 -0
- /engin-0.0.6/tests/conftest.py → /engin-0.0.7/tests/acceptance/__init__.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/tests/acceptance/test_error_in_shutdown.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/tests/acceptance/test_error_in_start_up.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/tests/deps.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/tests/test_engin.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/tests/test_modules.py +0 -0
- {engin-0.0.6 → engin-0.0.7}/tests/test_utils.py +0 -0
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
7
7
|
|
8
|
+
## [0.0.7] - 2025-02-20
|
9
|
+
|
10
|
+
### Changed
|
11
|
+
|
12
|
+
- TypeId retains Annotations allowing them to be used to discriminate otherwise identical
|
13
|
+
types.
|
14
|
+
|
8
15
|
|
9
16
|
## [0.0.6] - 2025-02-19
|
10
17
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# The Engin
|
2
|
+
|
3
|
+
The Engin is a self-contained modular application.
|
4
|
+
|
5
|
+
When ran the Engin takes care of the complete application lifecycle:
|
6
|
+
1. The Engin assembles all Invocations. Only Providers that are required to satisfy
|
7
|
+
the Invocations parameters are assembled.
|
8
|
+
2. All Invocations are run sequentially in the order they were passed in to the Engin.
|
9
|
+
3. Any Lifecycle Startup defined by Provider that were assembled is ran.
|
10
|
+
4. The Engin waits for a stop signal, i.e. SIGINT or SIGTERM.
|
11
|
+
5. Any Lifecyce Shutdown task is ran, in the reverse order to the Startup order.
|
@@ -0,0 +1,132 @@
|
|
1
|
+
# Invocations
|
2
|
+
|
3
|
+
Invocations define the behaviour of your application, therefore without any Invocations
|
4
|
+
your application will not do anything.
|
5
|
+
|
6
|
+
Like providers invocations are functions that take one or more dependencies as parameters,
|
7
|
+
and they should always return None as the return value will not used by the Engin.
|
8
|
+
|
9
|
+
As part of the Engin's startup, all declared invocations will be called sequentially in
|
10
|
+
the order they were registered.
|
11
|
+
|
12
|
+
Invocations can be used to define behaviour in two ways.
|
13
|
+
|
14
|
+
**Implicit: Provider Lifecycle**
|
15
|
+
|
16
|
+
Invocations are always called therefore their dependencies are always assembled. This
|
17
|
+
means that any providers with lifecycles will register their lifecycles with the
|
18
|
+
application if directly or indirectly used by an invocation.
|
19
|
+
|
20
|
+
To illustrate this, imagine we have a provider for an imaginary `Worker` type that is our
|
21
|
+
applications primary functionality. Our factory might look like the below (omitting
|
22
|
+
imports for brevity):
|
23
|
+
|
24
|
+
```python
|
25
|
+
def worker_factory(lifecycle: Lifecycle) -> Worker:
|
26
|
+
worker = Worker()
|
27
|
+
|
28
|
+
@asynccontextmanager
|
29
|
+
async def worker_lifecycle() -> Iterable[None]:
|
30
|
+
worker.start()
|
31
|
+
yield
|
32
|
+
worker.shutdown()
|
33
|
+
|
34
|
+
lifecycle.append(worker_lifecycle)
|
35
|
+
|
36
|
+
return worker
|
37
|
+
```
|
38
|
+
|
39
|
+
We can register it with the Engin as a provider.
|
40
|
+
|
41
|
+
```python
|
42
|
+
engin = Engin(Provide(worker_factory))
|
43
|
+
```
|
44
|
+
|
45
|
+
However, when we run the `engin` nothing happens. It will not start the `Worker` as it is
|
46
|
+
not required by any invocations. Let us fix that by adding the invocation.
|
47
|
+
|
48
|
+
```python
|
49
|
+
def use_worker(worker: Worker) -> None:
|
50
|
+
return None
|
51
|
+
|
52
|
+
|
53
|
+
engin = Engin(Provide(worker_factory), Invoke(use_worker))
|
54
|
+
```
|
55
|
+
|
56
|
+
Now when we run the `engin` a `Worker` is constructed and it starts up. This invocation
|
57
|
+
has no behaviour of its own, hence we can call it implicit, but by registering it with the
|
58
|
+
Engin it declares the behaviour we want our modular application to have at runtime.
|
59
|
+
|
60
|
+
This pattern of empty invocations as declaration of intended behaviour is very common, so
|
61
|
+
the framework has a marker class called `Entrypoint` as a shorthand for the above.
|
62
|
+
|
63
|
+
```python
|
64
|
+
engin = Engin(Provide(worker_factory), Entrypoint(Worker))
|
65
|
+
```
|
66
|
+
|
67
|
+
This `engin` has the same behaviour as the one declared above. Entrypoints can be
|
68
|
+
considered idiomatic as they have more explicit semantics.
|
69
|
+
|
70
|
+
**Explicit: Invoked Behaviour**
|
71
|
+
|
72
|
+
Sometimes you want to have logic that runs before the lifecycle startup occurs and after
|
73
|
+
the dependency graph is built, some examples might be:
|
74
|
+
- Pining a server to check its healthy.
|
75
|
+
- Running database migrations.
|
76
|
+
- Configuring a logger.
|
77
|
+
|
78
|
+
In these cases you would simply write an invocation that does these things, for example:
|
79
|
+
|
80
|
+
```python
|
81
|
+
def run_database_migrations(conn: SQLConnection) -> None:
|
82
|
+
print("running database migrations")
|
83
|
+
required_migrations = get_migrations(conn)
|
84
|
+
for migration in required_migrations:
|
85
|
+
print(f"migrating database to version {migration.version}")
|
86
|
+
migration.execute(conn)
|
87
|
+
|
88
|
+
engin = Engin(Provide(sql_connection_factory), Invoke(run_database_migrations), ...)
|
89
|
+
```
|
90
|
+
|
91
|
+
|
92
|
+
## Defining an invocation
|
93
|
+
|
94
|
+
Any function can be turned into an invocation by using the marker class: `Invoke`.
|
95
|
+
|
96
|
+
```python
|
97
|
+
import asyncio
|
98
|
+
from engin import Engin, Invoke
|
99
|
+
|
100
|
+
# define a function with some behaviour
|
101
|
+
def print_hello_world() -> None:
|
102
|
+
print("hello world!")
|
103
|
+
|
104
|
+
# register it as a invocation with the Engin
|
105
|
+
engin = Engin(Invoke(print_hello_world))
|
106
|
+
|
107
|
+
# run your application
|
108
|
+
asyncio.run(engin.run()) # hello world!
|
109
|
+
```
|
110
|
+
|
111
|
+
|
112
|
+
## Invocations can use provided types
|
113
|
+
|
114
|
+
Invocations can use any types as long as they have the matching providers.
|
115
|
+
|
116
|
+
```python
|
117
|
+
import asyncio
|
118
|
+
from engin import Engin, Invoke
|
119
|
+
|
120
|
+
# define a constructor
|
121
|
+
def name_factory() -> str:
|
122
|
+
return "Dmitrii"
|
123
|
+
|
124
|
+
def print_hello(name: str) -> None:
|
125
|
+
print(f"hello {name}!")
|
126
|
+
|
127
|
+
# register it as a invocation with the Engin
|
128
|
+
engin = Engin(Provide(name_factory()), Invoke(hello_world))
|
129
|
+
|
130
|
+
# run your application
|
131
|
+
asyncio.run(engin.run()) # hello Dmitrii!
|
132
|
+
```
|
@@ -0,0 +1,176 @@
|
|
1
|
+
# Providers
|
2
|
+
|
3
|
+
Providers are the factories of your application, they are reponsible for the construction
|
4
|
+
of the objects that your application needs.
|
5
|
+
|
6
|
+
Remember, the Engin only calls the providers that are necessary to run your application.
|
7
|
+
More specifically: when starting up the Engin will call all providers necessary to run its
|
8
|
+
invocations, and the Assembler (the component responsible for constructing types) will
|
9
|
+
call any providers that these providers require and so on.
|
10
|
+
|
11
|
+
|
12
|
+
## Defining a provider
|
13
|
+
|
14
|
+
Any function that returns an object can be turned into a provider by using the marker
|
15
|
+
class: `Provide`.
|
16
|
+
|
17
|
+
```python
|
18
|
+
from engin import Engin, Provide
|
19
|
+
|
20
|
+
# define our constructor
|
21
|
+
def string_factory() -> str:
|
22
|
+
return "hello"
|
23
|
+
|
24
|
+
# register it as a provider with the Engin
|
25
|
+
engin = Engin(Provide(string_factory))
|
26
|
+
|
27
|
+
# construct the string
|
28
|
+
a_string = await engin.assembler.get(str)
|
29
|
+
|
30
|
+
print(a_string) # hello
|
31
|
+
```
|
32
|
+
|
33
|
+
Providers can be asynchronous as well, this factory function would work exactly the same
|
34
|
+
in the above example.
|
35
|
+
|
36
|
+
```python
|
37
|
+
async def string_factory() -> str:
|
38
|
+
return "hello"
|
39
|
+
```
|
40
|
+
|
41
|
+
## Providers can use other providers
|
42
|
+
|
43
|
+
Providers that construct more interesting objects generally require their own parameters.
|
44
|
+
|
45
|
+
```python
|
46
|
+
from engin import Engin, Provide
|
47
|
+
|
48
|
+
class Greeter:
|
49
|
+
def __init__(self, greeting: str) -> None:
|
50
|
+
self._greeting = greeting
|
51
|
+
|
52
|
+
def greet(self, name: str) -> None:
|
53
|
+
print(f"{self._greeting}, {name}!")
|
54
|
+
|
55
|
+
# define our constructors
|
56
|
+
def string_factory() -> str:
|
57
|
+
return "hello"
|
58
|
+
|
59
|
+
def greeter_factory(greeting: str) -> Greeter:
|
60
|
+
return Greeter(greeting=greeting)
|
61
|
+
|
62
|
+
# register them as providers with the Engin
|
63
|
+
engin = Engin(Provide(string_factory), Provide(greeter_factory))
|
64
|
+
|
65
|
+
# construct the Greeter
|
66
|
+
greeter = await engin.assembler.get(Greeter)
|
67
|
+
|
68
|
+
greeter.greet("Bob") # hello, Bob!
|
69
|
+
```
|
70
|
+
|
71
|
+
|
72
|
+
## Providers are only called when required
|
73
|
+
|
74
|
+
The Assembler will only call a provider when the type is requested, directly or indirectly
|
75
|
+
when constructing an object. This means that your application will do the minimum work
|
76
|
+
required on startup.
|
77
|
+
|
78
|
+
```python
|
79
|
+
from engin import Engin, Provide
|
80
|
+
|
81
|
+
|
82
|
+
# define our constructors
|
83
|
+
def string_factory() -> str:
|
84
|
+
return "hello"
|
85
|
+
|
86
|
+
def evil_factory() -> int:
|
87
|
+
raise RuntimeError("I have ruined your plans")
|
88
|
+
|
89
|
+
# register them as providers with the Engin
|
90
|
+
engin = Engin(Provide(string_factory), Provide(evil_factory))
|
91
|
+
|
92
|
+
# this will not raise an error
|
93
|
+
await engin.assembler.get(str)
|
94
|
+
|
95
|
+
# this will raise an error
|
96
|
+
await engin.assembler.get(int)
|
97
|
+
```
|
98
|
+
|
99
|
+
|
100
|
+
## Multiproviders
|
101
|
+
|
102
|
+
Sometimes it is useful for many providers to construct a single collection of objects,
|
103
|
+
these are called multiproviders. For example in a web application, many
|
104
|
+
distinct providers could register one or more routes, and the root of the application
|
105
|
+
would handle registering them.
|
106
|
+
|
107
|
+
To turn a factory into a multiprovider, simply return a list:
|
108
|
+
|
109
|
+
```python
|
110
|
+
from engin import Engin, Provide
|
111
|
+
|
112
|
+
# define our constructors
|
113
|
+
def animal_names_factory() -> list[str]:
|
114
|
+
return ["cat", "dog"]
|
115
|
+
|
116
|
+
def other_animal_names_factory() -> list[str]:
|
117
|
+
return ["horse", "cow"]
|
118
|
+
|
119
|
+
# register them as providers with the Engin
|
120
|
+
engin = Engin(Provide(animal_names_factory), Provide(other_animal_names_factory))
|
121
|
+
|
122
|
+
# construct the list of strings
|
123
|
+
animal_names = await engin.assembler.get(list[str])
|
124
|
+
|
125
|
+
print(animal_names) # ["cat", "dog", "horse", "cow"]
|
126
|
+
```
|
127
|
+
|
128
|
+
|
129
|
+
## Discriminating providers of the same type
|
130
|
+
|
131
|
+
Providers of the same type can be discriminated using annotations.
|
132
|
+
|
133
|
+
```python
|
134
|
+
from engin import Engin, Provide
|
135
|
+
from typing import Annotated
|
136
|
+
|
137
|
+
# define our constructors
|
138
|
+
def greeting_factory() -> Annotated[str, "greeting"]:
|
139
|
+
return "hello"
|
140
|
+
|
141
|
+
def name_factory() -> Annotated[str, "name"]:
|
142
|
+
return "Jelena"
|
143
|
+
|
144
|
+
# register them as providers with the Engin
|
145
|
+
engin = Engin(Provide(greeting_factory), Provide(name_factory))
|
146
|
+
|
147
|
+
# this will return "hello"
|
148
|
+
await engin.assembler.get(Annotated[str, "greeting"])
|
149
|
+
|
150
|
+
# this will return "Jelena"
|
151
|
+
await engin.assembler.get(Annotated[str, "name"])
|
152
|
+
|
153
|
+
# N.B. this will raise an error!
|
154
|
+
await engin.assembler.get(str)
|
155
|
+
```
|
156
|
+
|
157
|
+
|
158
|
+
## Supply can be used for static objects
|
159
|
+
|
160
|
+
The `Supply` marker class can be used as a shorthand when provided static objects. The
|
161
|
+
provided type is automatically inferred.
|
162
|
+
|
163
|
+
For example the first example on this page could be rewritten as:
|
164
|
+
|
165
|
+
|
166
|
+
```python
|
167
|
+
from engin import Engin, Supply
|
168
|
+
|
169
|
+
# Supply the Engin with a str value
|
170
|
+
engin = Engin(Supply("hello"))
|
171
|
+
|
172
|
+
# construct the string
|
173
|
+
a_string = await engin.assembler.get(str)
|
174
|
+
|
175
|
+
print(a_string) # hello
|
176
|
+
```
|
@@ -136,7 +136,7 @@ class Provide(Dependency[Any, T]):
|
|
136
136
|
return_type = self._func # __init__ returns self
|
137
137
|
else:
|
138
138
|
try:
|
139
|
-
return_type = get_type_hints(self._func)["return"]
|
139
|
+
return_type = get_type_hints(self._func, include_extras=True)["return"]
|
140
140
|
except KeyError as err:
|
141
141
|
raise RuntimeError(
|
142
142
|
f"Dependency '{self.name}' requires a return typehint"
|
@@ -35,8 +35,7 @@ class Engin:
|
|
35
35
|
Supply) and at least one invocation (Invoke or Entrypoint).
|
36
36
|
|
37
37
|
When instantiated the Engin can be run. This is typically done via the `run` method,
|
38
|
-
but
|
39
|
-
methods.
|
38
|
+
but for advanced usecases it can be easier to use the `start` and `stop` methods.
|
40
39
|
|
41
40
|
When ran the Engin takes care of the complete application lifecycle:
|
42
41
|
1. The Engin assembles all Invocations. Only Providers that are required to satisfy
|
File without changes
|
@@ -1,3 +1,5 @@
|
|
1
|
+
from typing import Annotated
|
2
|
+
|
1
3
|
import pytest
|
2
4
|
|
3
5
|
from engin import Assembler, Invoke, Provide
|
@@ -65,3 +67,19 @@ async def test_assembler_with_unknown_type_raises_assembly_error():
|
|
65
67
|
|
66
68
|
with pytest.raises(ProviderError):
|
67
69
|
await assembler.get(str)
|
70
|
+
|
71
|
+
|
72
|
+
async def test_annotations():
|
73
|
+
def make_str_1() -> Annotated[str, "1"]:
|
74
|
+
return "bar"
|
75
|
+
|
76
|
+
def make_str_2() -> Annotated[str, "2"]:
|
77
|
+
return "foo"
|
78
|
+
|
79
|
+
assembler = Assembler([Provide(make_str_1), Provide(make_str_2)])
|
80
|
+
|
81
|
+
with pytest.raises(LookupError):
|
82
|
+
await assembler.get(str)
|
83
|
+
|
84
|
+
assert await assembler.get(Annotated[str, "1"]) == "bar"
|
85
|
+
assert await assembler.get(Annotated[str, "2"]) == "foo"
|
@@ -1,9 +1,11 @@
|
|
1
|
+
from typing import Annotated
|
2
|
+
|
1
3
|
from engin import Provide
|
2
4
|
from engin._dependency import Supply
|
3
5
|
from tests.deps import make_aliased_int
|
4
6
|
|
5
7
|
|
6
|
-
def
|
8
|
+
def test_provide_discriminates_singular():
|
7
9
|
def i_provide() -> int:
|
8
10
|
return 3
|
9
11
|
|
@@ -13,7 +15,7 @@ def test_provide_discriminates_singluar():
|
|
13
15
|
assert not provider.return_type_id.multi
|
14
16
|
|
15
17
|
|
16
|
-
def
|
18
|
+
def test_provide_discriminates_multi():
|
17
19
|
def i_provide_multi() -> list[int]:
|
18
20
|
return [3]
|
19
21
|
|
@@ -45,3 +47,13 @@ def test_provide_with_alias():
|
|
45
47
|
provider = Provide(make_aliased_int)
|
46
48
|
|
47
49
|
assert provider.return_type_id.type
|
50
|
+
|
51
|
+
|
52
|
+
def test_provide_with_annotation():
|
53
|
+
def make_str_1() -> Annotated[str, "1"]:
|
54
|
+
return "bar"
|
55
|
+
|
56
|
+
provider = Provide(make_str_1)
|
57
|
+
|
58
|
+
assert provider.return_type_id.type
|
59
|
+
assert str(provider.return_type_id) == "Annotated[str, 1]"
|
@@ -27,20 +27,20 @@ wheels = [
|
|
27
27
|
|
28
28
|
[[package]]
|
29
29
|
name = "babel"
|
30
|
-
version = "2.
|
30
|
+
version = "2.17.0"
|
31
31
|
source = { registry = "https://pypi.org/simple" }
|
32
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
32
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852 }
|
33
33
|
wheels = [
|
34
|
-
{ url = "https://files.pythonhosted.org/packages/
|
34
|
+
{ url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537 },
|
35
35
|
]
|
36
36
|
|
37
37
|
[[package]]
|
38
38
|
name = "certifi"
|
39
|
-
version = "
|
39
|
+
version = "2025.1.31"
|
40
40
|
source = { registry = "https://pypi.org/simple" }
|
41
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
41
|
+
sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 }
|
42
42
|
wheels = [
|
43
|
-
{ url = "https://files.pythonhosted.org/packages/
|
43
|
+
{ url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 },
|
44
44
|
]
|
45
45
|
|
46
46
|
[[package]]
|
@@ -127,7 +127,7 @@ wheels = [
|
|
127
127
|
|
128
128
|
[[package]]
|
129
129
|
name = "engin"
|
130
|
-
version = "0.0.
|
130
|
+
version = "0.0.6"
|
131
131
|
source = { editable = "." }
|
132
132
|
|
133
133
|
[package.dev-dependencies]
|
@@ -181,16 +181,16 @@ wheels = [
|
|
181
181
|
|
182
182
|
[[package]]
|
183
183
|
name = "fastapi"
|
184
|
-
version = "0.115.
|
184
|
+
version = "0.115.8"
|
185
185
|
source = { registry = "https://pypi.org/simple" }
|
186
186
|
dependencies = [
|
187
187
|
{ name = "pydantic" },
|
188
188
|
{ name = "starlette" },
|
189
189
|
{ name = "typing-extensions" },
|
190
190
|
]
|
191
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
191
|
+
sdist = { url = "https://files.pythonhosted.org/packages/a2/b2/5a5dc4affdb6661dea100324e19a7721d5dc524b464fe8e366c093fd7d87/fastapi-0.115.8.tar.gz", hash = "sha256:0ce9111231720190473e222cdf0f07f7206ad7e53ea02beb1d2dc36e2f0741e9", size = 295403 }
|
192
192
|
wheels = [
|
193
|
-
{ url = "https://files.pythonhosted.org/packages/
|
193
|
+
{ url = "https://files.pythonhosted.org/packages/8f/7d/2d6ce181d7a5f51dedb8c06206cbf0ec026a99bf145edd309f9e17c3282f/fastapi-0.115.8-py3-none-any.whl", hash = "sha256:753a96dd7e036b34eeef8babdfcfe3f28ff79648f86551eb36bfc1b0bf4a8cbf", size = 94814 },
|
194
194
|
]
|
195
195
|
|
196
196
|
[[package]]
|
@@ -207,14 +207,14 @@ wheels = [
|
|
207
207
|
|
208
208
|
[[package]]
|
209
209
|
name = "griffe"
|
210
|
-
version = "1.5.
|
210
|
+
version = "1.5.7"
|
211
211
|
source = { registry = "https://pypi.org/simple" }
|
212
212
|
dependencies = [
|
213
213
|
{ name = "colorama" },
|
214
214
|
]
|
215
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
215
|
+
sdist = { url = "https://files.pythonhosted.org/packages/59/80/13b6456bfbf8bc854875e58d3a3bad297ee19ebdd693ce62a10fab007e7a/griffe-1.5.7.tar.gz", hash = "sha256:465238c86deaf1137761f700fb343edd8ffc846d72f6de43c3c345ccdfbebe92", size = 391503 }
|
216
216
|
wheels = [
|
217
|
-
{ url = "https://files.pythonhosted.org/packages/
|
217
|
+
{ url = "https://files.pythonhosted.org/packages/76/67/b43330ed76f96be098c165338d47ccb952964ed77ba1d075247fbdf05c04/griffe-1.5.7-py3-none-any.whl", hash = "sha256:4af8ec834b64de954d447c7b6672426bb145e71605c74a4e22d510cc79fe7d8b", size = 128294 },
|
218
218
|
]
|
219
219
|
|
220
220
|
[[package]]
|
@@ -386,16 +386,16 @@ wheels = [
|
|
386
386
|
|
387
387
|
[[package]]
|
388
388
|
name = "mkdocs-autorefs"
|
389
|
-
version = "1.3.
|
389
|
+
version = "1.3.1"
|
390
390
|
source = { registry = "https://pypi.org/simple" }
|
391
391
|
dependencies = [
|
392
392
|
{ name = "markdown" },
|
393
393
|
{ name = "markupsafe" },
|
394
394
|
{ name = "mkdocs" },
|
395
395
|
]
|
396
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
396
|
+
sdist = { url = "https://files.pythonhosted.org/packages/52/f4/77e3cf5e7ba54dca168bc718688127844721982ae88b08684669c5b5752d/mkdocs_autorefs-1.3.1.tar.gz", hash = "sha256:a6d30cbcccae336d622a66c2418a3c92a8196b69782774529ad441abb23c0902", size = 2056416 }
|
397
397
|
wheels = [
|
398
|
-
{ url = "https://files.pythonhosted.org/packages/
|
398
|
+
{ url = "https://files.pythonhosted.org/packages/db/19/f20edc082c1de2987dbaf30fcc514ed7a908d465a15aba7cba595c3b245a/mkdocs_autorefs-1.3.1-py3-none-any.whl", hash = "sha256:18c504ae4d3ee7f344369bb26cb31d4105569ee252aab7d75ec2734c2c8b0474", size = 2837887 },
|
399
399
|
]
|
400
400
|
|
401
401
|
[[package]]
|
@@ -414,7 +414,7 @@ wheels = [
|
|
414
414
|
|
415
415
|
[[package]]
|
416
416
|
name = "mkdocs-material"
|
417
|
-
version = "9.
|
417
|
+
version = "9.6.4"
|
418
418
|
source = { registry = "https://pypi.org/simple" }
|
419
419
|
dependencies = [
|
420
420
|
{ name = "babel" },
|
@@ -429,9 +429,9 @@ dependencies = [
|
|
429
429
|
{ name = "regex" },
|
430
430
|
{ name = "requests" },
|
431
431
|
]
|
432
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
432
|
+
sdist = { url = "https://files.pythonhosted.org/packages/9b/80/4efbd3df76c6c1ec27130b43662612f9033adc5a4166f1df2acb8dd6fb1b/mkdocs_material-9.6.4.tar.gz", hash = "sha256:4d1d35e1c1d3e15294cb7fa5d02e0abaee70d408f75027dc7be6e30fb32e6867", size = 3942628 }
|
433
433
|
wheels = [
|
434
|
-
{ url = "https://files.pythonhosted.org/packages/
|
434
|
+
{ url = "https://files.pythonhosted.org/packages/5b/a5/f3c0e86c1d28fe04f1b724700ff3dd8b3647c89df03a8e10c4bc6b4db1b8/mkdocs_material-9.6.4-py3-none-any.whl", hash = "sha256:414e8376551def6d644b8e6f77226022868532a792eb2c9accf52199009f568f", size = 8688727 },
|
435
435
|
]
|
436
436
|
|
437
437
|
[[package]]
|
@@ -445,21 +445,20 @@ wheels = [
|
|
445
445
|
|
446
446
|
[[package]]
|
447
447
|
name = "mkdocstrings"
|
448
|
-
version = "0.
|
448
|
+
version = "0.28.1"
|
449
449
|
source = { registry = "https://pypi.org/simple" }
|
450
450
|
dependencies = [
|
451
|
-
{ name = "click" },
|
452
451
|
{ name = "jinja2" },
|
453
452
|
{ name = "markdown" },
|
454
453
|
{ name = "markupsafe" },
|
455
454
|
{ name = "mkdocs" },
|
456
455
|
{ name = "mkdocs-autorefs" },
|
457
|
-
{ name = "
|
456
|
+
{ name = "mkdocs-get-deps" },
|
458
457
|
{ name = "pymdown-extensions" },
|
459
458
|
]
|
460
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
459
|
+
sdist = { url = "https://files.pythonhosted.org/packages/82/6a/3980e05d7522423dc4ca547771d16d399fc3f4266df652f624f4f4dd7890/mkdocstrings-0.28.1.tar.gz", hash = "sha256:fb64576906771b7701e8e962fd90073650ff689e95eb86e86751a66d65ab4489", size = 4551690 }
|
461
460
|
wheels = [
|
462
|
-
{ url = "https://files.pythonhosted.org/packages/
|
461
|
+
{ url = "https://files.pythonhosted.org/packages/6f/5d/8580b426396d8cbbe98df364ef891487c4942e36356d56bb5a6dd91f51a9/mkdocstrings-0.28.1-py3-none-any.whl", hash = "sha256:a5878ae5cd1e26f491ff084c1f9ab995687d52d39a5c558e9b7023d0e4e0b740", size = 6426938 },
|
463
462
|
]
|
464
463
|
|
465
464
|
[package.optional-dependencies]
|
@@ -469,54 +468,55 @@ python = [
|
|
469
468
|
|
470
469
|
[[package]]
|
471
470
|
name = "mkdocstrings-python"
|
472
|
-
version = "1.
|
471
|
+
version = "1.15.0"
|
473
472
|
source = { registry = "https://pypi.org/simple" }
|
474
473
|
dependencies = [
|
475
474
|
{ name = "griffe" },
|
476
475
|
{ name = "mkdocs-autorefs" },
|
477
476
|
{ name = "mkdocstrings" },
|
477
|
+
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
|
478
478
|
]
|
479
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
479
|
+
sdist = { url = "https://files.pythonhosted.org/packages/28/5e/ea531f1798d6b614f87b7a1191f8bfda864767adecef3c75ec87f30e0a3d/mkdocstrings_python-1.15.0.tar.gz", hash = "sha256:2bfecbbe1252c67281408a6567d59545f4979931110f01ab625aa8c227c06edc", size = 422613 }
|
480
480
|
wheels = [
|
481
|
-
{ url = "https://files.pythonhosted.org/packages/
|
481
|
+
{ url = "https://files.pythonhosted.org/packages/6f/d7/1d35cce198f76e8ae4010a71ff5acabe8b75aeb35f8c3d920e175a6476ca/mkdocstrings_python-1.15.0-py3-none-any.whl", hash = "sha256:77aced1bb28840d7d3510f77353319eeb450961880d87f9c53fdab331ba0120d", size = 449068 },
|
482
482
|
]
|
483
483
|
|
484
484
|
[[package]]
|
485
485
|
name = "mypy"
|
486
|
-
version = "1.
|
486
|
+
version = "1.15.0"
|
487
487
|
source = { registry = "https://pypi.org/simple" }
|
488
488
|
dependencies = [
|
489
489
|
{ name = "mypy-extensions" },
|
490
490
|
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
491
491
|
{ name = "typing-extensions" },
|
492
492
|
]
|
493
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
493
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ce/43/d5e49a86afa64bd3839ea0d5b9c7103487007d728e1293f52525d6d5486a/mypy-1.15.0.tar.gz", hash = "sha256:404534629d51d3efea5c800ee7c42b72a6554d6c400e6a79eafe15d11341fd43", size = 3239717 }
|
494
494
|
wheels = [
|
495
|
-
{ url = "https://files.pythonhosted.org/packages/
|
496
|
-
{ url = "https://files.pythonhosted.org/packages/
|
497
|
-
{ url = "https://files.pythonhosted.org/packages/
|
498
|
-
{ url = "https://files.pythonhosted.org/packages/
|
499
|
-
{ url = "https://files.pythonhosted.org/packages/
|
500
|
-
{ url = "https://files.pythonhosted.org/packages/
|
501
|
-
{ url = "https://files.pythonhosted.org/packages/
|
502
|
-
{ url = "https://files.pythonhosted.org/packages/
|
503
|
-
{ url = "https://files.pythonhosted.org/packages/
|
504
|
-
{ url = "https://files.pythonhosted.org/packages/
|
505
|
-
{ url = "https://files.pythonhosted.org/packages/
|
506
|
-
{ url = "https://files.pythonhosted.org/packages/
|
507
|
-
{ url = "https://files.pythonhosted.org/packages/
|
508
|
-
{ url = "https://files.pythonhosted.org/packages/
|
509
|
-
{ url = "https://files.pythonhosted.org/packages/
|
510
|
-
{ url = "https://files.pythonhosted.org/packages/
|
511
|
-
{ url = "https://files.pythonhosted.org/packages/
|
512
|
-
{ url = "https://files.pythonhosted.org/packages/
|
513
|
-
{ url = "https://files.pythonhosted.org/packages/
|
514
|
-
{ url = "https://files.pythonhosted.org/packages/
|
515
|
-
{ url = "https://files.pythonhosted.org/packages/
|
516
|
-
{ url = "https://files.pythonhosted.org/packages/
|
517
|
-
{ url = "https://files.pythonhosted.org/packages/
|
518
|
-
{ url = "https://files.pythonhosted.org/packages/
|
519
|
-
{ url = "https://files.pythonhosted.org/packages/
|
495
|
+
{ url = "https://files.pythonhosted.org/packages/68/f8/65a7ce8d0e09b6329ad0c8d40330d100ea343bd4dd04c4f8ae26462d0a17/mypy-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:979e4e1a006511dacf628e36fadfecbcc0160a8af6ca7dad2f5025529e082c13", size = 10738433 },
|
496
|
+
{ url = "https://files.pythonhosted.org/packages/b4/95/9c0ecb8eacfe048583706249439ff52105b3f552ea9c4024166c03224270/mypy-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4bb0e1bd29f7d34efcccd71cf733580191e9a264a2202b0239da95984c5b559", size = 9861472 },
|
497
|
+
{ url = "https://files.pythonhosted.org/packages/84/09/9ec95e982e282e20c0d5407bc65031dfd0f0f8ecc66b69538296e06fcbee/mypy-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:be68172e9fd9ad8fb876c6389f16d1c1b5f100ffa779f77b1fb2176fcc9ab95b", size = 11611424 },
|
498
|
+
{ url = "https://files.pythonhosted.org/packages/78/13/f7d14e55865036a1e6a0a69580c240f43bc1f37407fe9235c0d4ef25ffb0/mypy-1.15.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c7be1e46525adfa0d97681432ee9fcd61a3964c2446795714699a998d193f1a3", size = 12365450 },
|
499
|
+
{ url = "https://files.pythonhosted.org/packages/48/e1/301a73852d40c241e915ac6d7bcd7fedd47d519246db2d7b86b9d7e7a0cb/mypy-1.15.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2e2c2e6d3593f6451b18588848e66260ff62ccca522dd231cd4dd59b0160668b", size = 12551765 },
|
500
|
+
{ url = "https://files.pythonhosted.org/packages/77/ba/c37bc323ae5fe7f3f15a28e06ab012cd0b7552886118943e90b15af31195/mypy-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:6983aae8b2f653e098edb77f893f7b6aca69f6cffb19b2cc7443f23cce5f4828", size = 9274701 },
|
501
|
+
{ url = "https://files.pythonhosted.org/packages/03/bc/f6339726c627bd7ca1ce0fa56c9ae2d0144604a319e0e339bdadafbbb599/mypy-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2922d42e16d6de288022e5ca321cd0618b238cfc5570e0263e5ba0a77dbef56f", size = 10662338 },
|
502
|
+
{ url = "https://files.pythonhosted.org/packages/e2/90/8dcf506ca1a09b0d17555cc00cd69aee402c203911410136cd716559efe7/mypy-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2ee2d57e01a7c35de00f4634ba1bbf015185b219e4dc5909e281016df43f5ee5", size = 9787540 },
|
503
|
+
{ url = "https://files.pythonhosted.org/packages/05/05/a10f9479681e5da09ef2f9426f650d7b550d4bafbef683b69aad1ba87457/mypy-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:973500e0774b85d9689715feeffcc980193086551110fd678ebe1f4342fb7c5e", size = 11538051 },
|
504
|
+
{ url = "https://files.pythonhosted.org/packages/e9/9a/1f7d18b30edd57441a6411fcbc0c6869448d1a4bacbaee60656ac0fc29c8/mypy-1.15.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a95fb17c13e29d2d5195869262f8125dfdb5c134dc8d9a9d0aecf7525b10c2c", size = 12286751 },
|
505
|
+
{ url = "https://files.pythonhosted.org/packages/72/af/19ff499b6f1dafcaf56f9881f7a965ac2f474f69f6f618b5175b044299f5/mypy-1.15.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1905f494bfd7d85a23a88c5d97840888a7bd516545fc5aaedff0267e0bb54e2f", size = 12421783 },
|
506
|
+
{ url = "https://files.pythonhosted.org/packages/96/39/11b57431a1f686c1aed54bf794870efe0f6aeca11aca281a0bd87a5ad42c/mypy-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:c9817fa23833ff189db061e6d2eff49b2f3b6ed9856b4a0a73046e41932d744f", size = 9265618 },
|
507
|
+
{ url = "https://files.pythonhosted.org/packages/98/3a/03c74331c5eb8bd025734e04c9840532226775c47a2c39b56a0c8d4f128d/mypy-1.15.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:aea39e0583d05124836ea645f412e88a5c7d0fd77a6d694b60d9b6b2d9f184fd", size = 10793981 },
|
508
|
+
{ url = "https://files.pythonhosted.org/packages/f0/1a/41759b18f2cfd568848a37c89030aeb03534411eef981df621d8fad08a1d/mypy-1.15.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2f2147ab812b75e5b5499b01ade1f4a81489a147c01585cda36019102538615f", size = 9749175 },
|
509
|
+
{ url = "https://files.pythonhosted.org/packages/12/7e/873481abf1ef112c582db832740f4c11b2bfa510e829d6da29b0ab8c3f9c/mypy-1.15.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ce436f4c6d218a070048ed6a44c0bbb10cd2cc5e272b29e7845f6a2f57ee4464", size = 11455675 },
|
510
|
+
{ url = "https://files.pythonhosted.org/packages/b3/d0/92ae4cde706923a2d3f2d6c39629134063ff64b9dedca9c1388363da072d/mypy-1.15.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8023ff13985661b50a5928fc7a5ca15f3d1affb41e5f0a9952cb68ef090b31ee", size = 12410020 },
|
511
|
+
{ url = "https://files.pythonhosted.org/packages/46/8b/df49974b337cce35f828ba6fda228152d6db45fed4c86ba56ffe442434fd/mypy-1.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1124a18bc11a6a62887e3e137f37f53fbae476dc36c185d549d4f837a2a6a14e", size = 12498582 },
|
512
|
+
{ url = "https://files.pythonhosted.org/packages/13/50/da5203fcf6c53044a0b699939f31075c45ae8a4cadf538a9069b165c1050/mypy-1.15.0-cp312-cp312-win_amd64.whl", hash = "sha256:171a9ca9a40cd1843abeca0e405bc1940cd9b305eaeea2dda769ba096932bb22", size = 9366614 },
|
513
|
+
{ url = "https://files.pythonhosted.org/packages/6a/9b/fd2e05d6ffff24d912f150b87db9e364fa8282045c875654ce7e32fffa66/mypy-1.15.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:93faf3fdb04768d44bf28693293f3904bbb555d076b781ad2530214ee53e3445", size = 10788592 },
|
514
|
+
{ url = "https://files.pythonhosted.org/packages/74/37/b246d711c28a03ead1fd906bbc7106659aed7c089d55fe40dd58db812628/mypy-1.15.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:811aeccadfb730024c5d3e326b2fbe9249bb7413553f15499a4050f7c30e801d", size = 9753611 },
|
515
|
+
{ url = "https://files.pythonhosted.org/packages/a6/ac/395808a92e10cfdac8003c3de9a2ab6dc7cde6c0d2a4df3df1b815ffd067/mypy-1.15.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:98b7b9b9aedb65fe628c62a6dc57f6d5088ef2dfca37903a7d9ee374d03acca5", size = 11438443 },
|
516
|
+
{ url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541 },
|
517
|
+
{ url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348 },
|
518
|
+
{ url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648 },
|
519
|
+
{ url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777 },
|
520
520
|
]
|
521
521
|
|
522
522
|
[[package]]
|
@@ -584,30 +584,30 @@ wheels = [
|
|
584
584
|
|
585
585
|
[[package]]
|
586
586
|
name = "poethepoet"
|
587
|
-
version = "0.32.
|
587
|
+
version = "0.32.2"
|
588
588
|
source = { registry = "https://pypi.org/simple" }
|
589
589
|
dependencies = [
|
590
590
|
{ name = "pastel" },
|
591
591
|
{ name = "pyyaml" },
|
592
592
|
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
593
593
|
]
|
594
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
594
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ee/c6/4bc7e21166726fc96f82f58b31fd032fdf8864d3aa17e2622578cb96c24d/poethepoet-0.32.2.tar.gz", hash = "sha256:1d68871dac1b191e27bd68fea57d0e01e9afbba3fcd01dbe6f6bc3fcb071fe4c", size = 61381 }
|
595
595
|
wheels = [
|
596
|
-
{ url = "https://files.pythonhosted.org/packages/
|
596
|
+
{ url = "https://files.pythonhosted.org/packages/b1/1f/4e7a9b6b33a085172a826d1f9d0a19a2e77982298acea13d40442f14ef28/poethepoet-0.32.2-py3-none-any.whl", hash = "sha256:97e165de8e00b07d33fd8d72896fad8b20ccafcd327b1118bb6a3da26af38d33", size = 81726 },
|
597
597
|
]
|
598
598
|
|
599
599
|
[[package]]
|
600
600
|
name = "pydantic"
|
601
|
-
version = "2.10.
|
601
|
+
version = "2.10.6"
|
602
602
|
source = { registry = "https://pypi.org/simple" }
|
603
603
|
dependencies = [
|
604
604
|
{ name = "annotated-types" },
|
605
605
|
{ name = "pydantic-core" },
|
606
606
|
{ name = "typing-extensions" },
|
607
607
|
]
|
608
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
608
|
+
sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 }
|
609
609
|
wheels = [
|
610
|
-
{ url = "https://files.pythonhosted.org/packages/
|
610
|
+
{ url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 },
|
611
611
|
]
|
612
612
|
|
613
613
|
[[package]]
|
@@ -709,15 +709,15 @@ wheels = [
|
|
709
709
|
|
710
710
|
[[package]]
|
711
711
|
name = "pymdown-extensions"
|
712
|
-
version = "10.14.
|
712
|
+
version = "10.14.3"
|
713
713
|
source = { registry = "https://pypi.org/simple" }
|
714
714
|
dependencies = [
|
715
715
|
{ name = "markdown" },
|
716
716
|
{ name = "pyyaml" },
|
717
717
|
]
|
718
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
718
|
+
sdist = { url = "https://files.pythonhosted.org/packages/7c/44/e6de2fdc880ad0ec7547ca2e087212be815efbc9a425a8d5ba9ede602cbb/pymdown_extensions-10.14.3.tar.gz", hash = "sha256:41e576ce3f5d650be59e900e4ceff231e0aed2a88cf30acaee41e02f063a061b", size = 846846 }
|
719
719
|
wheels = [
|
720
|
-
{ url = "https://files.pythonhosted.org/packages/
|
720
|
+
{ url = "https://files.pythonhosted.org/packages/eb/f5/b9e2a42aa8f9e34d52d66de87941ecd236570c7ed2e87775ed23bbe4e224/pymdown_extensions-10.14.3-py3-none-any.whl", hash = "sha256:05e0bee73d64b9c71a4ae17c72abc2f700e8bc8403755a00580b49a4e9f189e9", size = 264467 },
|
721
721
|
]
|
722
722
|
|
723
723
|
[[package]]
|
@@ -739,14 +739,14 @@ wheels = [
|
|
739
739
|
|
740
740
|
[[package]]
|
741
741
|
name = "pytest-asyncio"
|
742
|
-
version = "0.25.
|
742
|
+
version = "0.25.3"
|
743
743
|
source = { registry = "https://pypi.org/simple" }
|
744
744
|
dependencies = [
|
745
745
|
{ name = "pytest" },
|
746
746
|
]
|
747
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
747
|
+
sdist = { url = "https://files.pythonhosted.org/packages/f2/a8/ecbc8ede70921dd2f544ab1cadd3ff3bf842af27f87bbdea774c7baa1d38/pytest_asyncio-0.25.3.tar.gz", hash = "sha256:fc1da2cf9f125ada7e710b4ddad05518d4cee187ae9412e9ac9271003497f07a", size = 54239 }
|
748
748
|
wheels = [
|
749
|
-
{ url = "https://files.pythonhosted.org/packages/
|
749
|
+
{ url = "https://files.pythonhosted.org/packages/67/17/3493c5624e48fd97156ebaec380dcaafee9506d7e2c46218ceebbb57d7de/pytest_asyncio-0.25.3-py3-none-any.whl", hash = "sha256:9e89518e0f9bd08928f97a3482fdc4e244df17529460bc038291ccaf8f85c7c3", size = 19467 },
|
750
750
|
]
|
751
751
|
|
752
752
|
[[package]]
|
@@ -912,27 +912,27 @@ wheels = [
|
|
912
912
|
|
913
913
|
[[package]]
|
914
914
|
name = "ruff"
|
915
|
-
version = "0.9.
|
915
|
+
version = "0.9.6"
|
916
916
|
source = { registry = "https://pypi.org/simple" }
|
917
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
917
|
+
sdist = { url = "https://files.pythonhosted.org/packages/2a/e1/e265aba384343dd8ddd3083f5e33536cd17e1566c41453a5517b5dd443be/ruff-0.9.6.tar.gz", hash = "sha256:81761592f72b620ec8fa1068a6fd00e98a5ebee342a3642efd84454f3031dca9", size = 3639454 }
|
918
918
|
wheels = [
|
919
|
-
{ url = "https://files.pythonhosted.org/packages/
|
920
|
-
{ url = "https://files.pythonhosted.org/packages/
|
921
|
-
{ url = "https://files.pythonhosted.org/packages/
|
922
|
-
{ url = "https://files.pythonhosted.org/packages/
|
923
|
-
{ url = "https://files.pythonhosted.org/packages/
|
924
|
-
{ url = "https://files.pythonhosted.org/packages/
|
925
|
-
{ url = "https://files.pythonhosted.org/packages/
|
926
|
-
{ url = "https://files.pythonhosted.org/packages/
|
927
|
-
{ url = "https://files.pythonhosted.org/packages/
|
928
|
-
{ url = "https://files.pythonhosted.org/packages/
|
929
|
-
{ url = "https://files.pythonhosted.org/packages/
|
930
|
-
{ url = "https://files.pythonhosted.org/packages/
|
931
|
-
{ url = "https://files.pythonhosted.org/packages/
|
932
|
-
{ url = "https://files.pythonhosted.org/packages/
|
933
|
-
{ url = "https://files.pythonhosted.org/packages/
|
934
|
-
{ url = "https://files.pythonhosted.org/packages/
|
935
|
-
{ url = "https://files.pythonhosted.org/packages/
|
919
|
+
{ url = "https://files.pythonhosted.org/packages/76/e3/3d2c022e687e18cf5d93d6bfa2722d46afc64eaa438c7fbbdd603b3597be/ruff-0.9.6-py3-none-linux_armv6l.whl", hash = "sha256:2f218f356dd2d995839f1941322ff021c72a492c470f0b26a34f844c29cdf5ba", size = 11714128 },
|
920
|
+
{ url = "https://files.pythonhosted.org/packages/e1/22/aff073b70f95c052e5c58153cba735748c9e70107a77d03420d7850710a0/ruff-0.9.6-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b908ff4df65dad7b251c9968a2e4560836d8f5487c2f0cc238321ed951ea0504", size = 11682539 },
|
921
|
+
{ url = "https://files.pythonhosted.org/packages/75/a7/f5b7390afd98a7918582a3d256cd3e78ba0a26165a467c1820084587cbf9/ruff-0.9.6-py3-none-macosx_11_0_arm64.whl", hash = "sha256:b109c0ad2ececf42e75fa99dc4043ff72a357436bb171900714a9ea581ddef83", size = 11132512 },
|
922
|
+
{ url = "https://files.pythonhosted.org/packages/a6/e3/45de13ef65047fea2e33f7e573d848206e15c715e5cd56095589a7733d04/ruff-0.9.6-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1de4367cca3dac99bcbd15c161404e849bb0bfd543664db39232648dc00112dc", size = 11929275 },
|
923
|
+
{ url = "https://files.pythonhosted.org/packages/7d/f2/23d04cd6c43b2e641ab961ade8d0b5edb212ecebd112506188c91f2a6e6c/ruff-0.9.6-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac3ee4d7c2c92ddfdaedf0bf31b2b176fa7aa8950efc454628d477394d35638b", size = 11466502 },
|
924
|
+
{ url = "https://files.pythonhosted.org/packages/b5/6f/3a8cf166f2d7f1627dd2201e6cbc4cb81f8b7d58099348f0c1ff7b733792/ruff-0.9.6-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5dc1edd1775270e6aa2386119aea692039781429f0be1e0949ea5884e011aa8e", size = 12676364 },
|
925
|
+
{ url = "https://files.pythonhosted.org/packages/f5/c4/db52e2189983c70114ff2b7e3997e48c8318af44fe83e1ce9517570a50c6/ruff-0.9.6-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4a091729086dffa4bd070aa5dab7e39cc6b9d62eb2bef8f3d91172d30d599666", size = 13335518 },
|
926
|
+
{ url = "https://files.pythonhosted.org/packages/66/44/545f8a4d136830f08f4d24324e7db957c5374bf3a3f7a6c0bc7be4623a37/ruff-0.9.6-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d1bbc6808bf7b15796cef0815e1dfb796fbd383e7dbd4334709642649625e7c5", size = 12823287 },
|
927
|
+
{ url = "https://files.pythonhosted.org/packages/c5/26/8208ef9ee7431032c143649a9967c3ae1aae4257d95e6f8519f07309aa66/ruff-0.9.6-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:589d1d9f25b5754ff230dce914a174a7c951a85a4e9270613a2b74231fdac2f5", size = 14592374 },
|
928
|
+
{ url = "https://files.pythonhosted.org/packages/31/70/e917781e55ff39c5b5208bda384fd397ffd76605e68544d71a7e40944945/ruff-0.9.6-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc61dd5131742e21103fbbdcad683a8813be0e3c204472d520d9a5021ca8b217", size = 12500173 },
|
929
|
+
{ url = "https://files.pythonhosted.org/packages/84/f5/e4ddee07660f5a9622a9c2b639afd8f3104988dc4f6ba0b73ffacffa9a8c/ruff-0.9.6-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:5e2d9126161d0357e5c8f30b0bd6168d2c3872372f14481136d13de9937f79b6", size = 11906555 },
|
930
|
+
{ url = "https://files.pythonhosted.org/packages/f1/2b/6ff2fe383667075eef8656b9892e73dd9b119b5e3add51298628b87f6429/ruff-0.9.6-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:68660eab1a8e65babb5229a1f97b46e3120923757a68b5413d8561f8a85d4897", size = 11538958 },
|
931
|
+
{ url = "https://files.pythonhosted.org/packages/3c/db/98e59e90de45d1eb46649151c10a062d5707b5b7f76f64eb1e29edf6ebb1/ruff-0.9.6-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c4cae6c4cc7b9b4017c71114115db0445b00a16de3bcde0946273e8392856f08", size = 12117247 },
|
932
|
+
{ url = "https://files.pythonhosted.org/packages/ec/bc/54e38f6d219013a9204a5a2015c09e7a8c36cedcd50a4b01ac69a550b9d9/ruff-0.9.6-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:19f505b643228b417c1111a2a536424ddde0db4ef9023b9e04a46ed8a1cb4656", size = 12554647 },
|
933
|
+
{ url = "https://files.pythonhosted.org/packages/a5/7d/7b461ab0e2404293c0627125bb70ac642c2e8d55bf590f6fce85f508f1b2/ruff-0.9.6-py3-none-win32.whl", hash = "sha256:194d8402bceef1b31164909540a597e0d913c0e4952015a5b40e28c146121b5d", size = 9949214 },
|
934
|
+
{ url = "https://files.pythonhosted.org/packages/ee/30/c3cee10f915ed75a5c29c1e57311282d1a15855551a64795c1b2bbe5cf37/ruff-0.9.6-py3-none-win_amd64.whl", hash = "sha256:03482d5c09d90d4ee3f40d97578423698ad895c87314c4de39ed2af945633caa", size = 10999914 },
|
935
|
+
{ url = "https://files.pythonhosted.org/packages/e8/a8/d71f44b93e3aa86ae232af1f2126ca7b95c0f515ec135462b3e1f351441c/ruff-0.9.6-py3-none-win_arm64.whl", hash = "sha256:0e2bb706a2be7ddfea4a4af918562fdc1bcb16df255e5fa595bbd800ce322a5a", size = 10177499 },
|
936
936
|
]
|
937
937
|
|
938
938
|
[[package]]
|
@@ -955,14 +955,14 @@ wheels = [
|
|
955
955
|
|
956
956
|
[[package]]
|
957
957
|
name = "starlette"
|
958
|
-
version = "0.
|
958
|
+
version = "0.45.3"
|
959
959
|
source = { registry = "https://pypi.org/simple" }
|
960
960
|
dependencies = [
|
961
961
|
{ name = "anyio" },
|
962
962
|
]
|
963
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
963
|
+
sdist = { url = "https://files.pythonhosted.org/packages/ff/fb/2984a686808b89a6781526129a4b51266f678b2d2b97ab2d325e56116df8/starlette-0.45.3.tar.gz", hash = "sha256:2cbcba2a75806f8a41c722141486f37c28e30a0921c5f6fe4346cb0dcee1302f", size = 2574076 }
|
964
964
|
wheels = [
|
965
|
-
{ url = "https://files.pythonhosted.org/packages/
|
965
|
+
{ url = "https://files.pythonhosted.org/packages/d9/61/f2b52e107b1fc8944b33ef56bf6ac4ebbe16d91b94d2b87ce013bf63fb84/starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d", size = 71507 },
|
966
966
|
]
|
967
967
|
|
968
968
|
[[package]]
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{engin-0.0.6/examples/asgi/common/db/adapaters → engin-0.0.7/examples/asgi/common/db}/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{engin-0.0.6/examples/asgi/features → engin-0.0.7/examples/asgi/common/starlette}/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
{engin-0.0.6/examples/asgi/features/cats/api → engin-0.0.7/examples/asgi/features/cats}/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{engin-0.0.6/examples/fastapi/routes/cats → engin-0.0.7/examples/fastapi/routes}/__init__.py
RENAMED
File without changes
|
File without changes
|
{engin-0.0.6/examples/simple → engin-0.0.7/examples/fastapi/routes/cats/adapters}/__init__.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|