From c51eb5205349cd44430167fd990cd2cc8e539b03 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Mon, 7 Dec 2020 20:02:36 -0500 Subject: [PATCH] Fix init async resources in container on Python 2 --- src/dependency_injector/containers.c | 448 ++++++++++++------ src/dependency_injector/containers.pxd | 3 + src/dependency_injector/containers.pyx | 11 +- .../test_dynamic_async_resources_py36.py | 4 +- 4 files changed, 320 insertions(+), 146 deletions(-) diff --git a/src/dependency_injector/containers.c b/src/dependency_injector/containers.c index e2f37743..3af16f74 100644 --- a/src/dependency_injector/containers.c +++ b/src/dependency_injector/containers.c @@ -2520,6 +2520,14 @@ static void __Pyx_WriteUnraisable(const char *name, int clineno, int lineno, const char *filename, int full_traceback, int nogil); +/* 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 + /* py_dict_items.proto */ static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); @@ -2629,14 +2637,6 @@ static PyObject* __Pyx_patch_inspect(PyObject* module); /* PatchAsyncIO.proto */ static PyObject* __Pyx_patch_asyncio(PyObject* module); -/* 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 - /* ImportFrom.proto */ static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); @@ -2886,6 +2886,7 @@ static PyTypeObject *__pyx_ptype_19dependency_injector_10containers___pyx_scope_ static PyTypeObject *__pyx_ptype_19dependency_injector_10containers___pyx_scope_struct_5_copy = 0; static int __pyx_f_19dependency_injector_10containers_is_container(PyObject *, int __pyx_skip_dispatch); /*proto*/ static PyObject *__pyx_f_19dependency_injector_10containers__check_provider_type(PyObject *, PyObject *, int __pyx_skip_dispatch); /*proto*/ +static int __pyx_f_19dependency_injector_10containers__isawaitable(PyObject *, int __pyx_skip_dispatch); /*proto*/ #define __Pyx_MODULE_NAME "dependency_injector.containers" extern int __pyx_module_is_main_dependency_injector__containers; int __pyx_module_is_main_dependency_injector__containers = 0; @@ -3213,6 +3214,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_4copy__decorator(Py static PyObject *__pyx_pf_19dependency_injector_10containers_6copy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_container); /* proto */ static PyObject *__pyx_pf_19dependency_injector_10containers_8is_container(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_instance); /* proto */ static PyObject *__pyx_pf_19dependency_injector_10containers_10_check_provider_type(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_container, PyObject *__pyx_v_provider); /* proto */ +static PyObject *__pyx_pf_19dependency_injector_10containers_12_isawaitable(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_instance); /* proto */ static PyObject *__pyx_tp_new_19dependency_injector_10containers___pyx_scope_struct____new__(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_19dependency_injector_10containers___pyx_scope_struct_1_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ static PyObject *__pyx_tp_new_19dependency_injector_10containers___pyx_scope_struct_2_genexpr(PyTypeObject *t, PyObject *a, PyObject *k); /*proto*/ @@ -6448,7 +6450,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_ * * resource = provider.init() # <<<<<<<<<<<<<< * - * if inspect.isawaitable(resource): + * if _isawaitable(resource): */ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_provider, __pyx_n_s_init_2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 230, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); @@ -6473,37 +6475,16 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_ /* "dependency_injector/containers.pyx":232 * resource = provider.init() * - * if inspect.isawaitable(resource): # <<<<<<<<<<<<<< + * if _isawaitable(resource): # <<<<<<<<<<<<<< * futures.append(resource) * */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_inspect); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 232, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_isawaitable); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 232, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_8))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_8); - if (likely(__pyx_t_2)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8); - __Pyx_INCREF(__pyx_t_2); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_8, function); - } - } - __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_8, __pyx_t_2, __pyx_v_resource) : __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_resource); - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 232, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 232, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (__pyx_f_19dependency_injector_10containers__isawaitable(__pyx_v_resource, 0) != 0); if (__pyx_t_7) { /* "dependency_injector/containers.pyx":233 * - * if inspect.isawaitable(resource): + * if _isawaitable(resource): * futures.append(resource) # <<<<<<<<<<<<<< * * if futures: @@ -6513,7 +6494,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_ /* "dependency_injector/containers.pyx":232 * resource = provider.init() * - * if inspect.isawaitable(resource): # <<<<<<<<<<<<<< + * if _isawaitable(resource): # <<<<<<<<<<<<<< * futures.append(resource) * */ @@ -6555,12 +6536,12 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = PySequence_Tuple(__pyx_v_futures); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 236, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 236, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 236, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_8; - __pyx_t_8 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; goto __pyx_L0; /* "dependency_injector/containers.pyx":235 @@ -6758,7 +6739,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_ * * shutdown = provider.shutdown() # <<<<<<<<<<<<<< * - * if inspect.isawaitable(shutdown): + * if _isawaitable(shutdown): */ __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_provider, __pyx_n_s_shutdown); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 245, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); @@ -6783,37 +6764,16 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_ /* "dependency_injector/containers.pyx":247 * shutdown = provider.shutdown() * - * if inspect.isawaitable(shutdown): # <<<<<<<<<<<<<< + * if _isawaitable(shutdown): # <<<<<<<<<<<<<< * futures.append(shutdown) * */ - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_inspect); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 247, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_isawaitable); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 247, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); - __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - __pyx_t_2 = NULL; - if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_8))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_8); - if (likely(__pyx_t_2)) { - PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_8); - __Pyx_INCREF(__pyx_t_2); - __Pyx_INCREF(function); - __Pyx_DECREF_SET(__pyx_t_8, function); - } - } - __pyx_t_1 = (__pyx_t_2) ? __Pyx_PyObject_Call2Args(__pyx_t_8, __pyx_t_2, __pyx_v_shutdown) : __Pyx_PyObject_CallOneArg(__pyx_t_8, __pyx_v_shutdown); - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 247, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_1); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 247, __pyx_L1_error) - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (__pyx_f_19dependency_injector_10containers__isawaitable(__pyx_v_shutdown, 0) != 0); if (__pyx_t_7) { /* "dependency_injector/containers.pyx":248 * - * if inspect.isawaitable(shutdown): + * if _isawaitable(shutdown): * futures.append(shutdown) # <<<<<<<<<<<<<< * * if futures: @@ -6823,7 +6783,7 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_ /* "dependency_injector/containers.pyx":247 * shutdown = provider.shutdown() * - * if inspect.isawaitable(shutdown): # <<<<<<<<<<<<<< + * if _isawaitable(shutdown): # <<<<<<<<<<<<<< * futures.append(shutdown) * */ @@ -6865,12 +6825,12 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_16DynamicContainer_ __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __pyx_t_3 = PySequence_Tuple(__pyx_v_futures); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 251, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __pyx_t_8 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 251, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_8); + __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_t_3, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 251, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_r = __pyx_t_8; - __pyx_t_8 = 0; + __pyx_r = __pyx_t_2; + __pyx_t_2 = 0; goto __pyx_L0; /* "dependency_injector/containers.pyx":250 @@ -11114,6 +11074,7 @@ static PyObject *__pyx_f_19dependency_injector_10containers__check_provider_type * if not isinstance(provider, container.provider_type): * raise Error('{0} can contain only {1} ' # <<<<<<<<<<<<<< * 'instances'.format(container, container.provider_type)) + * */ __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_Error); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 517, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); @@ -11122,6 +11083,8 @@ static PyObject *__pyx_f_19dependency_injector_10containers__check_provider_type * if not isinstance(provider, container.provider_type): * raise Error('{0} can contain only {1} ' * 'instances'.format(container, container.provider_type)) # <<<<<<<<<<<<<< + * + * */ __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_kp_s_0_can_contain_only_1_instances, __pyx_n_s_format); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 518, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); @@ -11320,6 +11283,205 @@ static PyObject *__pyx_pf_19dependency_injector_10containers_10_check_provider_t return __pyx_r; } +/* "dependency_injector/containers.pyx":521 + * + * + * cpdef bint _isawaitable(object instance): # <<<<<<<<<<<<<< + * try: + * return inspect.isawaitable(instance) + */ + +static PyObject *__pyx_pw_19dependency_injector_10containers_13_isawaitable(PyObject *__pyx_self, PyObject *__pyx_v_instance); /*proto*/ +static int __pyx_f_19dependency_injector_10containers__isawaitable(PyObject *__pyx_v_instance, CYTHON_UNUSED int __pyx_skip_dispatch) { + int __pyx_r; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + PyObject *__pyx_t_6 = NULL; + int __pyx_t_7; + int __pyx_t_8; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_isawaitable", 0); + + /* "dependency_injector/containers.pyx":522 + * + * cpdef bint _isawaitable(object instance): + * try: # <<<<<<<<<<<<<< + * return inspect.isawaitable(instance) + * except AttributeError: + */ + { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + __Pyx_ExceptionSave(&__pyx_t_1, &__pyx_t_2, &__pyx_t_3); + __Pyx_XGOTREF(__pyx_t_1); + __Pyx_XGOTREF(__pyx_t_2); + __Pyx_XGOTREF(__pyx_t_3); + /*try:*/ { + + /* "dependency_injector/containers.pyx":523 + * cpdef bint _isawaitable(object instance): + * try: + * return inspect.isawaitable(instance) # <<<<<<<<<<<<<< + * except AttributeError: + * return False + */ + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_n_s_inspect); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 523, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_5, __pyx_n_s_isawaitable); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 523, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __pyx_t_5 = NULL; + if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_6))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_6); + if (likely(__pyx_t_5)) { + PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_6); + __Pyx_INCREF(__pyx_t_5); + __Pyx_INCREF(function); + __Pyx_DECREF_SET(__pyx_t_6, function); + } + } + __pyx_t_4 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_6, __pyx_t_5, __pyx_v_instance) : __Pyx_PyObject_CallOneArg(__pyx_t_6, __pyx_v_instance); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 523, __pyx_L3_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_7 = __Pyx_PyObject_IsTrue(__pyx_t_4); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 523, __pyx_L3_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __pyx_r = __pyx_t_7; + goto __pyx_L7_try_return; + + /* "dependency_injector/containers.pyx":522 + * + * cpdef bint _isawaitable(object instance): + * try: # <<<<<<<<<<<<<< + * return inspect.isawaitable(instance) + * except AttributeError: + */ + } + __pyx_L3_error:; + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + + /* "dependency_injector/containers.pyx":524 + * try: + * return inspect.isawaitable(instance) + * except AttributeError: # <<<<<<<<<<<<<< + * return False + */ + __pyx_t_8 = __Pyx_PyErr_ExceptionMatches(__pyx_builtin_AttributeError); + if (__pyx_t_8) { + __Pyx_AddTraceback("dependency_injector.containers._isawaitable", __pyx_clineno, __pyx_lineno, __pyx_filename); + if (__Pyx_GetException(&__pyx_t_4, &__pyx_t_6, &__pyx_t_5) < 0) __PYX_ERR(0, 524, __pyx_L5_except_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_GOTREF(__pyx_t_6); + __Pyx_GOTREF(__pyx_t_5); + + /* "dependency_injector/containers.pyx":525 + * return inspect.isawaitable(instance) + * except AttributeError: + * return False # <<<<<<<<<<<<<< + */ + __pyx_r = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + goto __pyx_L6_except_return; + } + goto __pyx_L5_except_error; + __pyx_L5_except_error:; + + /* "dependency_injector/containers.pyx":522 + * + * cpdef bint _isawaitable(object instance): + * try: # <<<<<<<<<<<<<< + * return inspect.isawaitable(instance) + * except AttributeError: + */ + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L1_error; + __pyx_L7_try_return:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L0; + __pyx_L6_except_return:; + __Pyx_XGIVEREF(__pyx_t_1); + __Pyx_XGIVEREF(__pyx_t_2); + __Pyx_XGIVEREF(__pyx_t_3); + __Pyx_ExceptionReset(__pyx_t_1, __pyx_t_2, __pyx_t_3); + goto __pyx_L0; + } + + /* "dependency_injector/containers.pyx":521 + * + * + * cpdef bint _isawaitable(object instance): # <<<<<<<<<<<<<< + * try: + * return inspect.isawaitable(instance) + */ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_6); + __Pyx_WriteUnraisable("dependency_injector.containers._isawaitable", __pyx_clineno, __pyx_lineno, __pyx_filename, 1, 0); + __pyx_r = 0; + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* Python wrapper */ +static PyObject *__pyx_pw_19dependency_injector_10containers_13_isawaitable(PyObject *__pyx_self, PyObject *__pyx_v_instance); /*proto*/ +static PyObject *__pyx_pw_19dependency_injector_10containers_13_isawaitable(PyObject *__pyx_self, PyObject *__pyx_v_instance) { + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("_isawaitable (wrapper)", 0); + __pyx_r = __pyx_pf_19dependency_injector_10containers_12_isawaitable(__pyx_self, ((PyObject *)__pyx_v_instance)); + + /* function exit code */ + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_19dependency_injector_10containers_12_isawaitable(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_instance) { + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("_isawaitable", 0); + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __Pyx_PyBool_FromLong(__pyx_f_19dependency_injector_10containers__isawaitable(__pyx_v_instance, 0)); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 521, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_AddTraceback("dependency_injector.containers._isawaitable", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + /* "providers.pxd":298 * * # Inline helper functions @@ -13504,6 +13666,7 @@ static PyTypeObject __pyx_type_19dependency_injector_10containers___pyx_scope_st static PyMethodDef __pyx_methods[] = { {"is_container", (PyCFunction)__pyx_pw_19dependency_injector_10containers_9is_container, METH_O, __pyx_doc_19dependency_injector_10containers_8is_container}, {"_check_provider_type", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_19dependency_injector_10containers_11_check_provider_type, METH_VARARGS|METH_KEYWORDS, 0}, + {"_isawaitable", (PyCFunction)__pyx_pw_19dependency_injector_10containers_13_isawaitable, METH_O, 0}, {0, 0, 0, 0} }; @@ -14145,6 +14308,7 @@ static int __Pyx_modinit_function_export_code(void) { /*--- Function export code ---*/ if (__Pyx_ExportFunction("is_container", (void (*)(void))__pyx_f_19dependency_injector_10containers_is_container, "int (PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error) if (__Pyx_ExportFunction("_check_provider_type", (void (*)(void))__pyx_f_19dependency_injector_10containers__check_provider_type, "PyObject *(PyObject *, PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_ExportFunction("_isawaitable", (void (*)(void))__pyx_f_19dependency_injector_10containers__isawaitable, "int (PyObject *, int __pyx_skip_dispatch)") < 0) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_RefNannyFinishContext(); return 0; __pyx_L1_error:; @@ -17199,6 +17363,80 @@ static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, #endif } +/* 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; +} + /* UnpackUnboundCMethod */ static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { PyObject *method; @@ -17733,80 +17971,6 @@ ignore: return module; } -/* 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; -} - /* ImportFrom */ static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); diff --git a/src/dependency_injector/containers.pxd b/src/dependency_injector/containers.pxd index 4c818153..604d74ce 100644 --- a/src/dependency_injector/containers.pxd +++ b/src/dependency_injector/containers.pxd @@ -11,3 +11,6 @@ cpdef bint is_container(object instance) cpdef object _check_provider_type(object container, object provider) + + +cpdef bint _isawaitable(object instance) diff --git a/src/dependency_injector/containers.pyx b/src/dependency_injector/containers.pyx index 4feccabe..2f8639d4 100644 --- a/src/dependency_injector/containers.pyx +++ b/src/dependency_injector/containers.pyx @@ -229,7 +229,7 @@ class DynamicContainer(object): resource = provider.init() - if inspect.isawaitable(resource): + if _isawaitable(resource): futures.append(resource) if futures: @@ -244,7 +244,7 @@ class DynamicContainer(object): shutdown = provider.shutdown() - if inspect.isawaitable(shutdown): + if _isawaitable(shutdown): futures.append(shutdown) if futures: @@ -516,3 +516,10 @@ cpdef object _check_provider_type(object container, object provider): if not isinstance(provider, container.provider_type): raise Error('{0} can contain only {1} ' 'instances'.format(container, container.provider_type)) + + +cpdef bint _isawaitable(object instance): + try: + return inspect.isawaitable(instance) + except AttributeError: + return False \ No newline at end of file diff --git a/tests/unit/containers/test_dynamic_async_resources_py36.py b/tests/unit/containers/test_dynamic_async_resources_py36.py index d81fef21..f11d0cd8 100644 --- a/tests/unit/containers/test_dynamic_async_resources_py36.py +++ b/tests/unit/containers/test_dynamic_async_resources_py36.py @@ -1,4 +1,4 @@ -"""Dependency injector dynamic container unit tests.""" +"""Dependency injector dynamic container unit tests for async resources.""" import unittest2 as unittest @@ -21,7 +21,7 @@ from dependency_injector import ( ) -class AsyncResourcesInitializationTest(AsyncTestCase): +class AsyncResourcesTest(AsyncTestCase): @unittest.skipIf(sys.version_info[:2] <= (3, 5), 'Async test') def test_async_init_resources(self):