Commit Graph

426 Commits

Author SHA1 Message Date
Greg Eremeev dcc9e6772a
Add requirements.txt and requirements-dev.txt (#172) 2021-01-06 01:56:00 +01:00
Jakub Stasiak 94e5b175d7 Correct two typos 2020-12-09 19:49:37 +01:00
Jakub Stasiak 4e3a28911c
Verify that noninjectable/inject ordering doesn't matter (#166)
Closes GH-141.
2020-12-06 13:59:41 +01:00
Jakub Stasiak 1d3d5e1003 Change some comments to variable annotations for clarity
Since we only support Python 3.6+ now we can do this.
2020-12-03 22:09:36 +01:00
Jakub Stasiak 7abb04e90b Drop Python 3.5 support, it's EOL now 2020-12-03 19:10:54 +01:00
Jakub Stasiak 098f46def2 Test with Python 3.9, it's been released two months ago 2020-12-03 19:04:10 +01:00
Jakub Stasiak e05eb082c6 Remove some no longer used Python 2-specific code 2020-12-03 19:02:06 +01:00
Jakub Stasiak a189dfcb9d Gitignore some Python artifacts 2020-12-03 19:02:06 +01:00
Joshua Adelman 0edfc5524d
include license file in source distribution (#160) 2020-10-14 20:49:20 +02:00
Jakub Stasiak 6e7941d6d0 Release version 0.18.4 2020-09-22 20:45:13 +02:00
Jakub Stasiak 6b2d563acf Actually interpret all NoInjects when multiple are present
Fixes GH-154.
2020-09-22 20:43:01 +02:00
Jakub Stasiak d4251f3962 Reformat using the latest black 2020-09-22 20:21:02 +02:00
Jakub Stasiak e912acfdd3
Add a note regarding client code knowing about Injector 2020-09-22 20:15:40 +02:00
Jakub Stasiak e686f36d88 Update terminology in the documentation 2020-05-23 12:10:12 +02:00
Jakub Stasiak 072e868bd2 Don't require typing_extensions on Python 3.9 unnecessarily 2020-05-23 12:05:15 +02:00
Jakub Stasiak 211994f48e Fix some links to avoid redirections 2020-02-05 11:19:43 +01:00
Jakub Stasiak 2293a8905d Release version 0.18.3 2020-02-03 15:35:27 +01:00
Jakub Stasiak a639cd5afb
Fix Python 3.5.3 compatibility (#136)
Fixes GH-135.
2020-02-03 15:34:02 +01:00
Sanjay Siddhanti 4137c35b7e Fix typos in README (#134) 2020-01-24 00:20:53 +01:00
Jakub Stasiak e6d55adf6f Document some of the Binder.bind() behavior 2020-01-21 19:00:14 +01:00
Jakub Stasiak fbbdbb1c61 Document injecting into CallableProvider callables 2020-01-21 18:59:38 +01:00
Jakub Stasiak d52147256b Release version 0.18.2 2019-12-14 19:28:55 +01:00
Jakub Stasiak 94f5460b02 Exclude few lines from missing coverage
They will never be executed so they artificially lower the coverage
total.
2019-12-14 19:18:07 +01:00
Jakub Stasiak 484b6881c5 Remove the standalone pytest script
I don't believe it's necessary to have this anymore.
2019-12-14 19:11:09 +01:00
Jakub Stasiak d31b83ffcc Support forward references in provider method return types
Closes GH-130.
2019-12-14 19:02:32 +01:00
Jakub Stasiak bcae038b45 Add a forgotten assertion
Closes GH-131.
2019-12-14 18:23:10 +01:00
Jakub Stasiak dd5f407a94 Explicitly type UnsatisfiedRequirement parameters
This also fixes an AttributeError issue described in [1].

[1] https://github.com/alecthomas/injector/issues/129#issuecomment-563886013
2019-12-12 02:57:58 +01:00
Jakub Stasiak 45700b139d Disallow untyped functions
The whole codebase is typed now, this will help keeping it this way to
make development nicer.
2019-12-12 02:44:33 +01:00
Jakub Stasiak 9dfabf12f6 Provide all remaining type hints
This includes workarounds for the cases where existing static analysis
tooling can't know about some things.
2019-12-12 02:44:33 +01:00
Jakub Stasiak f529eec73d Release version 0.18.1 2019-12-10 02:25:28 +01:00
Jakub Stasiak dc84575580 Update the mypy/Annotated version note (0.750 got released recently) 2019-12-10 02:11:44 +01:00
Jakub Stasiak ae39af0ad8 Simplify pytest configuration
It seems to be doing fine on its own.

As a bonus this restores running doctests from the injector source code
which I broke when I made it a package (code in injector/__init__.py)
instead of a simple module. *But* we need to start skipping running
doctests for get_bindings on Python versions that don't support
Annotated (or don't support it well enough).
2019-12-10 02:00:19 +01:00
Jakub Stasiak b399dcf908 Fix a BoundKey UnknownProvider regression
The example of an error this regression caused:

    1302 A BoundKey provides a key to a type with pre-injected arguments.
    1303
    1304     >>> class A:
    1305     ...   def __init__(self, a, b):
    1306     ...     self.a = a
    1307     ...     self.b = b
    1308     >>> InjectedA = BoundKey(A, a=InstanceProvider(1), b=InstanceProvider(2))
    1309     >>> injector = Injector()
    1310     >>> a = injector.get(InjectedA)
    UNEXPECTED EXCEPTION: UnknownProvider("couldn't determine provider for InstanceProvider(1) to None")
    Traceback (most recent call last):
      File "/Users/user/projects/injector/injector/__init__.py", line 583, in get_binding
        return self._get_binding(interface, only_this_binder=is_scope)
      File "/Users/user/projects/injector/injector/__init__.py", line 578, in _get_binding
        raise KeyError
    KeyError

    During handling of the above exception, another exception occurred:

    Traceback (most recent call last):
      File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/doctest.py", line 1329, in __run
        compileflags, 1), test.globs)
      File "<doctest injector.BoundKey[3]>", line 1, in <module>
      File "/Users/user/projects/injector/injector/__init__.py", line 864, in get
        result = scope_instance.get(interface, binding.provider).get(self)
      File "/Users/user/projects/injector/injector/__init__.py", line 289, in get
        return injector.call_with_injection(self._callable)
      File "/Users/user/projects/injector/injector/__init__.py", line 918, in call_with_injection
        owner_key=self_.__class__ if self_ is not None else callable.__module__,
      File "/Users/user/projects/injector/injector/__init__.py", line 80, in wrapper
        return function(*args, **kwargs)
      File "/Users/user/projects/injector/injector/__init__.py", line 959, in args_to_inject
        instance = self.get(interface)
      File "/Users/user/projects/injector/injector/__init__.py", line 853, in get
        binding, binder = self.binder.get_binding(interface)
      File "/Users/user/projects/injector/injector/__init__.py", line 592, in get_binding
        binding = self.create_binding(interface)
      File "/Users/user/projects/injector/injector/__init__.py", line 511, in create_binding
        provider = self.provider_for(interface, to)
      File "/Users/user/projects/injector/injector/__init__.py", line 569, in provider_for
        raise UnknownProvider('couldn\'t determine provider for %r to %r' % (interface, to))

    injector.UnknownProvider: couldn't determine provider for InstanceProvider(1) to None

It's been reported in GH-125. We haven't seen this because until
recently doctests weren't running.

Closes GH-125.
2019-12-10 01:50:11 +01:00
Jakub Stasiak 79e787887c Stop executing two code samples in inject's docstring as tests
They're actually meant to be just for human use here. Executing them
will fail as the Dependency is not defined.
2019-12-10 01:24:33 +01:00
Jakub Stasiak 531d5272b1 Fix get_bindings' doctest
Since I introduced the function in eb5344cd8a
the doctest inside had invalid outputs. It hasn't been caught as due to
an unrelated bug we haven't been actually executing doctests (I'm
working on fixing it).
2019-12-10 01:24:33 +01:00
Jakub Stasiak d8bc01e2d8 Fix InstanceProvider doctest
I broke it in 00cbfde845 – this actually
means to be a regular binding.
2019-12-10 01:24:33 +01:00
Jakub Stasiak 789c93bd09 Rationalize CallableProvider doctest
Firstly, integers can be cached and reused by the implementation so the
result of one injector.get(key) call may return the same int as the
other.

Secondly, NewType was unnecessarily introduced here so let's replace the
NewType+int tandem with a single class.
2019-12-10 01:24:33 +01:00
Jakub Stasiak cf7b0757dc Fix UnsatisfiedRequirement rendering
The issue helpfully described and solution suggested by eugenhu.
UnsatisfiedRequirement's __str__ depends on there being two arguments
(the first one optionally None).

Closes GH-129.
2019-12-09 23:56:33 +01:00
Jakub Stasiak 23cd45935b Fix new issues discovered by latest mypy (0.750)
The errors in question:

    % mypy injector
    injector/__init__.py:34: error: Incompatible types in assignment (expression has type "None", variable has type "_SpecialForm")
    injector/__init__.py:37: error: All conditional function variants must have identical signatures
    injector/__init__.py:1067: error: Argument 1 to "pop" of "MutableMapping" has incompatible type "Optional[str]"; expected "str"
    injector/__init__.py:1068: error: Argument 1 to "pop" of "MutableMapping" has incompatible type "Optional[str]"; expected "str"

Coincidentally this commit fixes an issue [1] discovered by eugenhu.
Although the solution to the issue is different than eugenhu suggests
the analysis of the underlying cause is helpful and appreciated.

[1] "Cannot inject dependency which is a subclass of a subscripted type", GH-128

Closes GH-128
2019-12-09 23:42:29 +01:00
Jakub Stasiak a461f722ad Test with stable Python 3.8 as it's available now 2019-11-21 01:02:38 +01:00
Jakub Stasiak ddc73e1aa9 Massage Inject and NoInject documentation a little 2019-11-21 01:01:43 +01:00
Jakub Stasiak a02cd797c0 Stop allowing Python 3.8 failures in CI
That shouldn't fail really.
2019-10-17 00:12:31 +02:00
Jakub Stasiak 05dd5b88b0 Fix a typo (there was a dash instead of a hyphen) 2019-10-16 23:50:28 +02:00
Jakub Stasiak 8c5b97352a Prepare release 0.18.0 2019-10-16 23:50:28 +02:00
Jakub Stasiak 3f76909bb5 Polish the documentation a bit, it got stale 2019-10-16 23:50:28 +02:00
Jakub Stasiak 63e6015d02 Fix a docstring typo 2019-10-16 23:05:48 +02:00
Jakub Stasiak d50e581734 Experiment with PEP 593-based way to declare what's (non)injectable
There's an implementation of PEP 593 draft in typing_extensions and mypy
supports it already.

See also:

* typing module discussion (pre-PEP): https://github.com/python/typing/issues/600
* python-ideas discussion (pre-PEP): https://mail.python.org/pipermail/python-ideas/2019-January/054908.html
* The actual PEP: https://www.python.org/dev/peps/pep-0593/
* typing-sig PEP discussion (ongoing): https://mail.python.org/archives/list/typing-sig@python.org/thread/CZ7N3M3PGKHUY63RWWSPTICVOAVYI73D/
2019-10-16 18:23:43 +02:00
Jakub Stasiak eb5344cd8a Document get_bindings
Might want to look into making pytest handle Sphinx-formatted doctests
to reduce the code repetition here.
2019-10-15 21:55:23 +02:00
Jakub Stasiak 9590ebda5b Extract _get_callable_bindings into a top-level function
It's gonna be exposed as part of the public API.
2019-10-15 21:28:21 +02:00
Jakub Stasiak c5c3978f43 Make _get_callable_bindings to handle noninjectable parameters
This is needed to extract the function to be a top-level one so that it
can be exposes as public API.
2019-10-15 21:10:42 +02:00