Comments (3)
i am try to work on this and will post my progress here.
from dishka.
Problem Description:
We have a generator function that provides a dependency at the beginning of the request lifecycle and finalizes it at the end of the request lifecycle.
Inside the request lifecycle e.g:
with container() as request_container:
...
An exception may occur, the dependency is finalized anyway, but we also want to give it information about the exception that occurred by sending its object to the generator using the .send()
and .asend()
methods for asynchronous generators.
The code
provider = Provider()
class Person:
def __init__(self, name: str, age: int):
self.name = name
self.age = age
def __str__(self) -> str:
return f"I'm {self.name}, my age is: {self.age}"
def get_person() -> Iterator[Person]:
print("dependency initialization")
x = yield Person("alex", 18)
if isinstance(x, Exception):
print("Some exception occurred:", x)
print("dependency finalization")
provider.provide(get_person, scope=Scope.REQUEST)
container = make_container(provider)
with container() as request_container:
person = request_container.get(Person)
print("Hello!", person)
raise ValueError("Some error in request scope!")
Expected output
dependency initialization
Hello! Im alex, my age is: 18
Some exception occurred: Some error in request scope!
dependency finalization
<Traceback here>
Current output
dependency initialization
Hello! Im alex, my age is: 18
dependency finalization
<Traceback here>
Correct me if I'm wrong.
from dishka.
Implementation of this functionality
Where do we need to make changes?
In the case of REQUEST
scope, the finalization of generators is handled by the Container.close
method, which in this case is called by the __exit__
method of the ContextWrapper
class.
Accordingly, we need to change __exit__
and .close()
in the synchronous and asynchronous versions of Container
respectively.
What can we use to implement this functionality?
We can easily see if an exception has occurred in the context manager block, because __exit__
takes information about the exception that occurred
def __exit__(self, exc_type, exc_val, exc_tb):
Where exc_val
is the instance of the exception class that occurred, and I guess that's what we need to pass to the generator function.
The finalization of the generators is handled by the .close()
method of the container, it is called by __exit__()
of the ContextWrapper
, here is how the finalization itself happens:
def close(self) -> None:
errors = []
for exit_generator in self._exits[:::-1]:
try:
if exit_generator.type is FactoryType.GENERATOR:
next(exit_generator.callable)
We could add an Optional
parameter to the .close()
method that defaults to None
, the signature would look like this, and it wouldn't break backwards compatibility:
def close(self, exception: Optional[Exception] = None) -> None:
Next, we just check for the argument in the loop and call .send()
if exit_generator.type is FactoryType.GENERATOR:
if not exception:
next(exit_generator.callable)
else:
exit_generator.callable.send(exception)
The same is for the asynchronous version of Container, respectively.
Conclusion
If you have no objections, I'll start to get down to implementation.
from dishka.
Related Issues (20)
- Resolve by parent class HOT 1
- Provide list of depedencies HOT 1
- Можно обернуть в Optional
- Skippable scopes HOT 1
- Interface segregation syntaxes support HOT 1
- Pytest integration
- Incorrect ressolve for AnyOf HOT 1
- Show an error if `@decorate` is applied to context var
- Singleton invalidation HOT 3
- Recursion in provide with source=random
- Graph validation fails with depends on Generic[T]
- SqlAlchemy AsyncSession resolve failed HOT 1
- SQLAlchemy Async error HOT 4
- Container override HOT 1
- Add metadata of user-defined code to exceptions HOT 2
- Performance benchmark
- Pass to annotation `Provider` instead of `FromComponent("component name")` HOT 2
- mypy [type-abstract] error
- DB connection always created with pooling with Dishka HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from dishka.