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

defer type annotation analysis #234

Open
RonnyPfannschmidt opened this issue Aug 30, 2024 · 5 comments
Open

defer type annotation analysis #234

RonnyPfannschmidt opened this issue Aug 30, 2024 · 5 comments
Labels
enhancement New feature or request

Comments

@RonnyPfannschmidt
Copy link

im currently migrating a codebase with quite some import cycles to dishka to resolve this,

unfortunately i frequently see errors like

  File "$MYLIB/base/_dependency_inject.py", line 118, in ApplicationProvider
    @provide
     ^^^^^^^
  File "$SITE/dishka/dependency_source/make_factory.py", line 548, in provide
    return _provide(
           ^^^^^^^^^
  File "$SITE/dishka/dependency_source/make_factory.py", line 475, in _provide
    factory = make_factory(
              ^^^^^^^^^^^^^
  File "$SITE/dishka/dependency_source/make_factory.py", line 433, in make_factory
    return _make_factory_by_function(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "$SITE/dishka/dependency_source/make_factory.py", line 272, in _make_factory_by_function
    hints = get_type_hints(source, include_extras=True)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/typing.py", line 2414, in get_type_hints
    hints[name] = _eval_type(value, globalns, localns)
                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/typing.py", line 395, in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib64/python3.11/typing.py", line 905, in _evaluate
    eval(self.__forward_code__, globalns, localns),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<string>", line 1, in <module>
AttributeError: partially initialized module '$MYLIB.base.application' has no attribute 'Application' (most likely due to a circular import)
@RonnyPfannschmidt
Copy link
Author

note this is not a pressing issue, i found a way to resolve this by moving a provider class to a especially ugly place and lazy importing it when making the root container

@Tishka17
Copy link
Member

You can try registering classes in provider instance instead of class-based approach with decorators

@RonnyPfannschmidt
Copy link
Author

the providers are actual type-annotated functions, so i'd like to avoid pulling things apart even more
if there was way to wait with the type annotation parsing until its instantiation time for the provider, then it would work in the initial case (im using deferred type annotations as the import is not yet available, the decorator going after them at definition time is kind of beating that

@Tishka17
Copy link
Member

Tishka17 commented Sep 3, 2024

I mean instead of this:

class MyProvider(Provider):
   @provide
   def create_x(self, dep: Y) -> X: ...  # immediate resolving

You can do this:

def create_x(dep: "Y") -> "X": ... 
..

from x import X
from y import Y
provider = Provider()
provider.provide(create_x)

But from my side it looks like a problem with your code structure. Try splitting providers into more parts. Just in case something is missed: your providers do not need to know about each other and who produces what, they are wired only inside container.

@RonnyPfannschmidt
Copy link
Author

If evaluating the type annotations was deferred until wireing time I wouldn't see any issues

I'm in the process of resolving historical grown recursive dependencies,

I'm happy to provide an implementation that retains eagerness but makes wire time available but import time unavailable types a warning instead of a error as it's not always easy to quick detangle

@Tishka17 Tishka17 added the enhancement New feature or request label Sep 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants