From bbbed8972a7cf2ab5e5905d6748bd9865667b5b6 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Mon, 8 Mar 2021 16:32:34 -0500 Subject: [PATCH] Wiring import fixes numpy scipy (#422) * Add signature guards * Fix flake8 errors and update changelog * Fix slow numpy/scipy installs on pypy3 --- docs/main/changelog.rst | 6 ++++++ requirements-dev.txt | 2 ++ src/dependency_injector/wiring.py | 21 +++++++++++++++++++-- tests/unit/samples/wiringsamples/module.py | 14 ++++++++++++++ tox.ini | 13 +++++++++++++ 5 files changed, 54 insertions(+), 2 deletions(-) diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index f583f705..8694f644 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -7,6 +7,12 @@ that were made in every particular version. From version 0.7.6 *Dependency Injector* framework strictly follows `Semantic versioning`_ +Development version +------------------- +- Fix wiring to not crash on missing signatures. + See issue: `#420 `_. + Thanks to `@Balthus1989 `_ for reporting the issue. + 4.29.1 ------ - Fix recursive copying issue in ``Delegate`` provider. diff --git a/requirements-dev.txt b/requirements-dev.txt index 062b9272..3c5353db 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,5 +10,7 @@ pyyaml httpx fastapi pydantic +numpy +scipy -r requirements-ext.txt diff --git a/src/dependency_injector/wiring.py b/src/dependency_injector/wiring.py index 222e0d63..a818fb75 100644 --- a/src/dependency_injector/wiring.py +++ b/src/dependency_injector/wiring.py @@ -298,6 +298,8 @@ class InspectFilter: return True elif self._is_starlette_request_cls(instance): return True + elif self._is_builtin(instance): + return True else: return False @@ -309,6 +311,9 @@ class InspectFilter: and isinstance(instance, type) \ and issubclass(instance, starlette.requests.Request) + def _is_builtin(self, instance: object) -> bool: + return inspect.isbuiltin(instance) + def wire( # noqa: C901 container: Container, @@ -476,7 +481,7 @@ def _unpatch_attribute(patched: PatchedAttribute) -> None: setattr(patched.member, patched.name, patched.marker) -def _fetch_reference_injections( +def _fetch_reference_injections( # noqa: C901 fn: Callable[..., Any], ) -> Tuple[Dict[str, Any], Dict[str, Any]]: # Hotfix, see: @@ -488,7 +493,15 @@ def _fetch_reference_injections( )): fn = fn.__init__ - signature = inspect.signature(fn) + try: + signature = inspect.signature(fn) + except ValueError as exception: + if 'no signature found' in str(exception): + return {}, {} + elif 'not supported by signature' in str(exception): + return {}, {} + else: + raise exception injections = {} closing = {} @@ -874,9 +887,13 @@ class AutoLoader: super().exec_module(module) loader.wire_module(module) + class ExtensionFileLoader(importlib.machinery.ExtensionFileLoader): + ... + loader_details = [ (SourcelessFileLoader, importlib.machinery.BYTECODE_SUFFIXES), (SourceFileLoader, importlib.machinery.SOURCE_SUFFIXES), + (ExtensionFileLoader, importlib.machinery.EXTENSION_SUFFIXES), ] self._path_hook = importlib.machinery.FileFinder.path_hook(*loader_details) diff --git a/tests/unit/samples/wiringsamples/module.py b/tests/unit/samples/wiringsamples/module.py index 333de332..eabfb525 100644 --- a/tests/unit/samples/wiringsamples/module.py +++ b/tests/unit/samples/wiringsamples/module.py @@ -1,6 +1,7 @@ """Test module for wiring.""" from decimal import Decimal +import sys from typing import Callable from dependency_injector import providers @@ -128,3 +129,16 @@ def test_class_decorator(service: Service = Provide[Container.service]): def test_container(container: Container = Provide[Container]): return container.service() + + +# Import tests + +if 'pypy' not in sys.version.lower(): + import numpy # noqa + from numpy import * # noqa + + import scipy # noqa + from scipy import * # noqa + + import builtins # noqa + from builtins import * # noqa diff --git a/tox.ini b/tox.ini index b35ebac7..595cd458 100644 --- a/tox.ini +++ b/tox.ini @@ -8,6 +8,8 @@ deps= typing_extensions httpx fastapi + numpy + scipy extras= yaml pydantic @@ -62,6 +64,17 @@ extras= commands= python -m unittest discover -s tests/unit -p test_*_py2_py3.py +[testenv:pypy3] +deps= + httpx + fastapi +extras= + yaml + flask +commands= + python -m unittest discover -s tests/unit -p test_*_py2_py3.py + + [testenv:pylint] deps= pylint