From 38ca1cdeede88c9a994105bcf3df7883467032b1 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Fri, 28 Jan 2022 23:12:08 -0500 Subject: [PATCH] Fix #550 --- docs/main/changelog.rst | 4 +++ src/dependency_injector/providers.c | 25 ++++++++++--------- src/dependency_injector/providers.pyx | 2 +- .../unit/providers/test_dependency_py2_py3.py | 16 ++++++++++++ 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index a74c670c..8e1f7509 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -21,6 +21,10 @@ Development version ``FactoryAggregate.factories`` attribute. - Add ``.set_providers()`` method to the ``FactoryAggregate`` provider. It is an alias for ``FactoryAggregate.set_factories()`` method. +- Fix ``Dependency`` provider to don't raise "Dependency is not defined" error when the ``default`` + is a falsy value of proper type. + See issue `#550 `_. Thanks to + `@approxit `_ for reporting the issue. - Refactor ``FactoryAggregate`` provider internals. - Update logo on Github and in docs to support dark themes and remove some imperfections. diff --git a/src/dependency_injector/providers.c b/src/dependency_injector/providers.c index 22a7bda3..1bba8f71 100644 --- a/src/dependency_injector/providers.c +++ b/src/dependency_injector/providers.c @@ -19881,7 +19881,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_7default * * def set_default(self, default): # <<<<<<<<<<<<<< * """Set type.""" - * if default and not isinstance(default, Provider): + * if default is not None and not isinstance(default, Provider): */ /* Python wrapper */ @@ -19914,25 +19914,26 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_14set_de /* "dependency_injector/providers.pyx":882 * def set_default(self, default): * """Set type.""" - * if default and not isinstance(default, Provider): # <<<<<<<<<<<<<< + * if default is not None and not isinstance(default, Provider): # <<<<<<<<<<<<<< * default = Object(default) * self.__default = default */ - __pyx_t_2 = __Pyx_PyObject_IsTrue(__pyx_v_default); if (unlikely(__pyx_t_2 < 0)) __PYX_ERR(1, 882, __pyx_L1_error) - if (__pyx_t_2) { + __pyx_t_2 = (__pyx_v_default != Py_None); + __pyx_t_3 = (__pyx_t_2 != 0); + if (__pyx_t_3) { } else { - __pyx_t_1 = __pyx_t_2; + __pyx_t_1 = __pyx_t_3; goto __pyx_L4_bool_binop_done; } - __pyx_t_2 = __Pyx_TypeCheck(__pyx_v_default, __pyx_ptype_19dependency_injector_9providers_Provider); - __pyx_t_3 = ((!(__pyx_t_2 != 0)) != 0); - __pyx_t_1 = __pyx_t_3; + __pyx_t_3 = __Pyx_TypeCheck(__pyx_v_default, __pyx_ptype_19dependency_injector_9providers_Provider); + __pyx_t_2 = ((!(__pyx_t_3 != 0)) != 0); + __pyx_t_1 = __pyx_t_2; __pyx_L4_bool_binop_done:; if (__pyx_t_1) { /* "dependency_injector/providers.pyx":883 * """Set type.""" - * if default and not isinstance(default, Provider): + * if default is not None and not isinstance(default, Provider): * default = Object(default) # <<<<<<<<<<<<<< * self.__default = default * return self @@ -19945,14 +19946,14 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_14set_de /* "dependency_injector/providers.pyx":882 * def set_default(self, default): * """Set type.""" - * if default and not isinstance(default, Provider): # <<<<<<<<<<<<<< + * if default is not None and not isinstance(default, Provider): # <<<<<<<<<<<<<< * default = Object(default) * self.__default = default */ } /* "dependency_injector/providers.pyx":884 - * if default and not isinstance(default, Provider): + * if default is not None and not isinstance(default, Provider): * default = Object(default) * self.__default = default # <<<<<<<<<<<<<< * return self @@ -19981,7 +19982,7 @@ static PyObject *__pyx_pf_19dependency_injector_9providers_10Dependency_14set_de * * def set_default(self, default): # <<<<<<<<<<<<<< * """Set type.""" - * if default and not isinstance(default, Provider): + * if default is not None and not isinstance(default, Provider): */ /* function exit code */ diff --git a/src/dependency_injector/providers.pyx b/src/dependency_injector/providers.pyx index 0b43feb3..cfcefd43 100644 --- a/src/dependency_injector/providers.pyx +++ b/src/dependency_injector/providers.pyx @@ -879,7 +879,7 @@ cdef class Dependency(Provider): def set_default(self, default): """Set type.""" - if default and not isinstance(default, Provider): + if default is not None and not isinstance(default, Provider): default = Object(default) self.__default = default return self diff --git a/tests/unit/providers/test_dependency_py2_py3.py b/tests/unit/providers/test_dependency_py2_py3.py index c4c2cea1..b21e1c8b 100644 --- a/tests/unit/providers/test_dependency_py2_py3.py +++ b/tests/unit/providers/test_dependency_py2_py3.py @@ -77,6 +77,22 @@ def test_default_attribute_provider(): assert provider.default is default +def test_default_with_empty_dict(): + # See: https://github.com/ets-labs/python-dependency-injector/issues/550 + default = {} + provider = providers.Dependency(instance_of=dict, default=default) + assert provider() == default + assert provider.default() == default + + +def test_default_with_empty_string(): + # See: https://github.com/ets-labs/python-dependency-injector/issues/550 + default = "" + provider = providers.Dependency(instance_of=str, default=default) + assert provider() == default + assert provider.default() == default + + def test_is_defined(provider): assert provider.is_defined is False