From 13aa5fa53d3bba7bb81581a0eef03c50bdb7630e Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Thu, 18 Feb 2021 08:25:22 -0500 Subject: [PATCH] Refactor @containers.copy() decorator --- docs/main/changelog.rst | 1 + src/dependency_injector/containers.c | 195 ++++++++++++++----------- src/dependency_injector/containers.pyx | 4 +- 3 files changed, 110 insertions(+), 90 deletions(-) diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 670a032c..0999b589 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -9,6 +9,7 @@ follows `Semantic versioning`_ Development version ------------------- +- Refactor ``@containers.copy()`` decorator. - Refactor async mode support in containers module. 4.23.5 diff --git a/src/dependency_injector/containers.c b/src/dependency_injector/containers.c index 369c4a20..83eeec89 100644 --- a/src/dependency_injector/containers.c +++ b/src/dependency_injector/containers.c @@ -2759,6 +2759,14 @@ static CYTHON_INLINE PyObject *__Pyx_PyObject_GetItem(PyObject *obj, PyObject* k /* HasAttr.proto */ static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); +/* GetException.proto */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); +#endif + /* GetAttr3.proto */ static CYTHON_INLINE PyObject *__Pyx_GetAttr3(PyObject *, PyObject *, PyObject *); @@ -2831,14 +2839,6 @@ static CYTHON_INLINE int __Pyx_PyList_Extend(PyObject* L, PyObject* v) { /* RaiseNoneIterError.proto */ static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); -/* GetException.proto */ -#if CYTHON_FAST_THREAD_STATE -#define __Pyx_GetException(type, value, tb) __Pyx__GetException(__pyx_tstate, type, value, tb) -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); -#endif - /* TypeImport.proto */ #ifndef __PYX_HAVE_RT_ImportType_proto #define __PYX_HAVE_RT_ImportType_proto @@ -14912,7 +14912,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_4copy__get_provider * try: * source_provider = source_providers[name] # <<<<<<<<<<<<<< * except KeyError: - * ... + * continue */ __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_source_providers, __pyx_v_name); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 677, __pyx_L7_error) __Pyx_GOTREF(__pyx_t_1); @@ -14929,7 +14929,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_4copy__get_provider } /* "dependency_injector/containers.pyx":681 - * ... + * continue * else: * memo[id(source_provider)] = provider # <<<<<<<<<<<<<< * @@ -15014,13 +15014,30 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_4copy__get_provider * try: * source_provider = source_providers[name] * except KeyError: # <<<<<<<<<<<<<< - * ... + * continue * else: */ __pyx_t_15 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_KeyError); if (__pyx_t_15) { - __Pyx_ErrRestore(0,0,0); - goto __pyx_L8_exception_handled; + __Pyx_AddTraceback("dependency_injector.containers.copy._get_providers_memo", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_3, &__pyx_t_6, &__pyx_t_1) < 0) __PYX_ERR(0, 678, __pyx_L9_except_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_1); + + /* "dependency_injector/containers.pyx":679 + * source_provider = source_providers[name] + * except KeyError: + * continue # <<<<<<<<<<<<<< + * else: + * memo[id(source_provider)] = provider + */ + goto __pyx_L19_except_continue; + __pyx_L19_except_continue:; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + goto __pyx_L13_try_continue; } goto __pyx_L9_except_error; __pyx_L9_except_error:; @@ -15037,11 +15054,12 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_4copy__get_provider __Pyx_XGIVEREF(__pyx_t_11); __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11); goto __pyx_L1_error; - __pyx_L8_exception_handled:; + __pyx_L13_try_continue:; __Pyx_XGIVEREF(__pyx_t_9); __Pyx_XGIVEREF(__pyx_t_10); __Pyx_XGIVEREF(__pyx_t_11); __Pyx_ExceptionReset(__pyx_t_9, __pyx_t_10, __pyx_t_11); + goto __pyx_L3_continue; __pyx_L14_try_end:; } @@ -15052,6 +15070,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_4copy__get_provider * try: * source_provider = source_providers[name] */ + __pyx_L3_continue:; } __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; @@ -27999,6 +28018,80 @@ static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { } } +/* GetException */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) +#else +static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) +#endif +{ + PyObject *local_type, *local_value, *local_tb; +#if CYTHON_FAST_THREAD_STATE + PyObject *tmp_type, *tmp_value, *tmp_tb; + local_type = tstate->curexc_type; + local_value = tstate->curexc_value; + local_tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#else + PyErr_Fetch(&local_type, &local_value, &local_tb); +#endif + PyErr_NormalizeException(&local_type, &local_value, &local_tb); +#if CYTHON_FAST_THREAD_STATE + if (unlikely(tstate->curexc_type)) +#else + if (unlikely(PyErr_Occurred())) +#endif + goto bad; + #if PY_MAJOR_VERSION >= 3 + if (local_tb) { + if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) + goto bad; + } + #endif + Py_XINCREF(local_tb); + Py_XINCREF(local_type); + Py_XINCREF(local_value); + *type = local_type; + *value = local_value; + *tb = local_tb; +#if CYTHON_FAST_THREAD_STATE + #if CYTHON_USE_EXC_INFO_STACK + { + _PyErr_StackItem *exc_info = tstate->exc_info; + tmp_type = exc_info->exc_type; + tmp_value = exc_info->exc_value; + tmp_tb = exc_info->exc_traceback; + exc_info->exc_type = local_type; + exc_info->exc_value = local_value; + exc_info->exc_traceback = local_tb; + } + #else + tmp_type = tstate->exc_type; + tmp_value = tstate->exc_value; + tmp_tb = tstate->exc_traceback; + tstate->exc_type = local_type; + tstate->exc_value = local_value; + tstate->exc_traceback = local_tb; + #endif + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#else + PyErr_SetExcInfo(local_type, local_value, local_tb); +#endif + return 0; +bad: + *type = 0; + *value = 0; + *tb = 0; + Py_XDECREF(local_type); + Py_XDECREF(local_value); + Py_XDECREF(local_tb); + return -1; +} + /* GetAttr3 */ static PyObject *__Pyx_GetAttr3Default(PyObject *d) { __Pyx_PyThreadState_declare @@ -28236,80 +28329,6 @@ static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); } -/* GetException */ -#if CYTHON_FAST_THREAD_STATE -static int __Pyx__GetException(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) -#else -static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) -#endif -{ - PyObject *local_type, *local_value, *local_tb; -#if CYTHON_FAST_THREAD_STATE - PyObject *tmp_type, *tmp_value, *tmp_tb; - local_type = tstate->curexc_type; - local_value = tstate->curexc_value; - local_tb = tstate->curexc_traceback; - tstate->curexc_type = 0; - tstate->curexc_value = 0; - tstate->curexc_traceback = 0; -#else - PyErr_Fetch(&local_type, &local_value, &local_tb); -#endif - PyErr_NormalizeException(&local_type, &local_value, &local_tb); -#if CYTHON_FAST_THREAD_STATE - if (unlikely(tstate->curexc_type)) -#else - if (unlikely(PyErr_Occurred())) -#endif - goto bad; - #if PY_MAJOR_VERSION >= 3 - if (local_tb) { - if (unlikely(PyException_SetTraceback(local_value, local_tb) < 0)) - goto bad; - } - #endif - Py_XINCREF(local_tb); - Py_XINCREF(local_type); - Py_XINCREF(local_value); - *type = local_type; - *value = local_value; - *tb = local_tb; -#if CYTHON_FAST_THREAD_STATE - #if CYTHON_USE_EXC_INFO_STACK - { - _PyErr_StackItem *exc_info = tstate->exc_info; - tmp_type = exc_info->exc_type; - tmp_value = exc_info->exc_value; - tmp_tb = exc_info->exc_traceback; - exc_info->exc_type = local_type; - exc_info->exc_value = local_value; - exc_info->exc_traceback = local_tb; - } - #else - tmp_type = tstate->exc_type; - tmp_value = tstate->exc_value; - tmp_tb = tstate->exc_traceback; - tstate->exc_type = local_type; - tstate->exc_value = local_value; - tstate->exc_traceback = local_tb; - #endif - Py_XDECREF(tmp_type); - Py_XDECREF(tmp_value); - Py_XDECREF(tmp_tb); -#else - PyErr_SetExcInfo(local_type, local_value, local_tb); -#endif - return 0; -bad: - *type = 0; - *value = 0; - *tb = 0; - Py_XDECREF(local_type); - Py_XDECREF(local_value); - Py_XDECREF(local_tb); - return -1; -} - /* TypeImport */ #ifndef __PYX_HAVE_RT_ImportType #define __PYX_HAVE_RT_ImportType diff --git a/src/dependency_injector/containers.pyx b/src/dependency_injector/containers.pyx index 21223d0d..e449a472 100644 --- a/src/dependency_injector/containers.pyx +++ b/src/dependency_injector/containers.pyx @@ -659,7 +659,7 @@ def override(object container): def copy(object container): """:py:class:`DeclarativeContainer` copying decorator. - This decorator copy all providers from provided container to decorated one. + This decorator copies all providers from provided container to decorated one. If one of the decorated container providers matches to source container providers by name, it would be replaced by reference. @@ -676,7 +676,7 @@ def copy(object container): try: source_provider = source_providers[name] except KeyError: - ... + continue else: memo[id(source_provider)] = provider