python-injector / python-injector/injector

Evaluation of forward references using if TYPE_CHECKING?

Open
#145 15 comments 3 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
1.5k
Forks
94
PR merge metrics
No merged PRs in 30d

Description

Hey there, giving injector a go with a project and seeing a bit of an issue when trying to inject types which are defined as a forward reference using the if TYPE_CHECKING block, supported by MyPy help prevent circular dependency issues based on the need to import stuff just for typing.

I suspect it might not be possible and injector will require those modules to be imported at runtime, but usage of this functionality would be incredibly handy if it is possible as otherwise I find that MyPy without using TYPE_CHECKING imports tends to make more complicated OO code a mess of circular references caused by the need for importing types for type checking (or in this case, injector if I can't use the if TYPE_CHECKING work around)

I was wondering if some kind of approach of Injector importing all of the modules defined in any binding within a TYPE_CHECKING blocks so it has a reference to them that it can later use when trying to evaluate forward references?

Suspect this might cause some issues with circular references in injector itself, so perhaps it's not possible, or another approach could be taken?

Current error when I try this is:

def _infer_injected_bindings(callable: Callable, only_explicit_bindings: bool) -> Dict[str, type]:
        spec = inspect.getfullargspec(callable)
        try:
            bindings = get_type_hints(callable, include_extras=True)
        except NameError as e:
>           raise _BindingNotYetAvailable(e)
E           injector._BindingNotYetAvailable: name 'InjectMe' is not defined```

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with _infer_injected_bindings and the get_type_hints call in injector, then trace how _BindingNotYetAvailable handles unresolved names. Determine whether annotations referring to types imported only under TYPE_CHECKING can be resolved without introducing circular imports; done means the issue's example no longer raises the reported NameError, with coverage for the supported behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.