From 18a0b62a977d715814d4343668b8c38cd5bbebe5 Mon Sep 17 00:00:00 2001 From: Manish Kumar Date: Wed, 5 Aug 2026 18:22:53 -0500 Subject: [PATCH] Add RBAC fixtures and tests: permission- and org-tenancy-aware Policy Engine Previously had no concept of the JWT permissions claim or org_id at all -- authorization was pure role-name/action-string matching (RBAC), with ABAC and RULES layered after it. The Gateway already forwarded permissions on every /policy/evaluate call; nothing here ever read it. Adds two new, additive gates between RBAC and ABAC: - PERMISSION (app/core/permissions.py): checks req.permissions against an action/resource -> required-permission map (workflow.execute, dataset.read, workflow.manage), using the same permission-registry strings omnibioai-auth already reserves. Opt-in: a no-op when permissions=[] entirely, so today's real traffic (no role is granted these permissions yet) sees zero behavior change -- verified by the full pre-existing test suite passing unmodified. - TENANCY (app/core/tenancy.py): requires org_id == context.resource_org_id when both are supplied. Same opt-in shape. Narrows one legacy RBAC rule: dataset.read no longer requires the data_scientist role (write/delete actions still do) -- read access is now governed by the PERMISSION gate instead, which is what makes a genuine read-only "Viewer" tier possible; previously there was no way to grant read without also granting write/delete. Adds test_role_hierarchy_fixtures.py, mapping PR12's conceptual Platform Owner/Org Admin/Scientist/Viewer hierarchy onto the real role/permission vocabulary (no new roles or DB changes -- see that file's docstring for the full reasoning), with allow/deny cases for each tier. Adds permissions.py/tenancy.py to the Cython IP-protection build (setup.py) for consistency with the rest of app/core, and rebuilds the .c/.so artifacts for engine.py/rbac.py/cache.py/permissions.py/tenancy.py this change touches -- this repo's Dockerfile ships committed binaries directly rather than recompiling at image-build time. Co-Authored-By: Claude Sonnet 5 --- app/core/engine.c | 1078 +- .../engine.cpython-313-aarch64-linux-gnu.so | Bin 80712 -> 80832 bytes app/core/engine.py | 24 +- app/core/permissions.c | 9297 +++++++++++++++++ ...rmissions.cpython-313-aarch64-linux-gnu.so | Bin 0 -> 80872 bytes app/core/permissions.py | 73 + app/core/rbac.c | 181 +- .../rbac.cpython-313-aarch64-linux-gnu.so | Bin 79104 -> 79200 bytes app/core/rbac.py | 14 +- app/core/tenancy.c | 8284 +++++++++++++++ .../tenancy.cpython-313-aarch64-linux-gnu.so | Bin 0 -> 79344 bytes app/core/tenancy.py | 33 + app/models/request.py | 2 + app/services/cache.c | 766 +- .../cache.cpython-313-aarch64-linux-gnu.so | Bin 81784 -> 81888 bytes app/services/cache.py | 18 +- .../engine.cpython-313-aarch64-linux-gnu.so | Bin 80712 -> 80832 bytes ...rmissions.cpython-313-aarch64-linux-gnu.so | Bin 0 -> 80872 bytes .../rbac.cpython-313-aarch64-linux-gnu.so | Bin 79104 -> 79200 bytes .../tenancy.cpython-313-aarch64-linux-gnu.so | Bin 0 -> 79344 bytes .../cache.cpython-313-aarch64-linux-gnu.so | Bin 81784 -> 81888 bytes .../app/core/engine.o | Bin 77736 -> 85592 bytes .../app/core/permissions.o | Bin 0 -> 70360 bytes .../app/core/rbac.o | Bin 48040 -> 48856 bytes .../app/core/tenancy.o | Bin 0 -> 51496 bytes .../app/services/cache.o | Bin 82600 -> 86616 bytes setup.py | 2 + tests/test_engine_permission_tenancy.py | 153 + tests/test_permissions.py | 80 + tests/test_role_hierarchy_fixtures.py | 134 + tests/test_tenancy.py | 32 + 31 files changed, 19441 insertions(+), 730 deletions(-) create mode 100644 app/core/permissions.c create mode 100755 app/core/permissions.cpython-313-aarch64-linux-gnu.so create mode 100644 app/core/permissions.py create mode 100644 app/core/tenancy.c create mode 100755 app/core/tenancy.cpython-313-aarch64-linux-gnu.so create mode 100644 app/core/tenancy.py create mode 100755 build/lib.linux-aarch64-cpython-313/app/core/permissions.cpython-313-aarch64-linux-gnu.so create mode 100755 build/lib.linux-aarch64-cpython-313/app/core/tenancy.cpython-313-aarch64-linux-gnu.so create mode 100644 build/temp.linux-aarch64-cpython-313/app/core/permissions.o create mode 100644 build/temp.linux-aarch64-cpython-313/app/core/tenancy.o create mode 100644 tests/test_engine_permission_tenancy.py create mode 100644 tests/test_permissions.py create mode 100644 tests/test_role_hierarchy_fixtures.py create mode 100644 tests/test_tenancy.py diff --git a/app/core/engine.c b/app/core/engine.c index 2b21e2d..2c21cf7 100644 --- a/app/core/engine.c +++ b/app/core/engine.c @@ -1948,18 +1948,18 @@ static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, P #define __Pyx_VectorcallBuilder_AddArgStr(key, value, builder, args, n) PyDict_SetItemString(builder, key, value) #endif -/* PyObjectFastCallMethod.proto */ +/* PyObjectVectorCallMethodKwBuilder.proto */ #if CYTHON_VECTORCALL && PY_VERSION_HEX >= 0x03090000 -#define __Pyx_PyObject_FastCallMethod(name, args, nargsf) PyObject_VectorcallMethod(name, args, nargsf, NULL) +#define __Pyx_Object_VectorcallMethod_CallFromBuilder PyObject_VectorcallMethod #else -static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf); +static PyObject *__Pyx_Object_VectorcallMethod_CallFromBuilder(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames); #endif -/* PyObjectVectorCallMethodKwBuilder.proto */ +/* PyObjectFastCallMethod.proto */ #if CYTHON_VECTORCALL && PY_VERSION_HEX >= 0x03090000 -#define __Pyx_Object_VectorcallMethod_CallFromBuilder PyObject_VectorcallMethod +#define __Pyx_PyObject_FastCallMethod(name, args, nargsf) PyObject_VectorcallMethod(name, args, nargsf, NULL) #else -static PyObject *__Pyx_Object_VectorcallMethod_CallFromBuilder(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf); #endif /* HasAttr.proto (used by ImportImpl) */ @@ -2345,7 +2345,7 @@ typedef struct { __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_pop; __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_values; PyObject *__pyx_codeobj_tab[3]; - PyObject *__pyx_string_tab[72]; + PyObject *__pyx_string_tab[79]; PyObject *__pyx_number_tab[1]; /* #### Code section: module_state_contents ### */ /* CommonTypesMetaclass.module_state_decls */ @@ -2394,71 +2394,78 @@ static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_stati #define __pyx_n_u_ABAC __pyx_string_tab[4] #define __pyx_n_u_ALL_PASSED __pyx_string_tab[5] #define __pyx_n_u_CACHE __pyx_string_tab[6] -#define __pyx_n_u_PolicyCache __pyx_string_tab[7] -#define __pyx_n_u_PolicyDecision __pyx_string_tab[8] -#define __pyx_n_u_PolicyEngine __pyx_string_tab[9] -#define __pyx_n_u_PolicyEngine___init __pyx_string_tab[10] -#define __pyx_n_u_PolicyEngine__evaluate_core __pyx_string_tab[11] -#define __pyx_n_u_PolicyEngine_evaluate __pyx_string_tab[12] -#define __pyx_n_u_PolicyRequest __pyx_string_tab[13] -#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[14] -#define __pyx_n_u_RBAC __pyx_string_tab[15] -#define __pyx_n_u_RULES __pyx_string_tab[16] -#define __pyx_n_u_abac __pyx_string_tab[17] -#define __pyx_n_u_action __pyx_string_tab[18] -#define __pyx_n_u_allowed __pyx_string_tab[19] -#define __pyx_n_u_app_core __pyx_string_tab[20] -#define __pyx_n_u_app_core_engine __pyx_string_tab[21] -#define __pyx_n_u_app_models_decision __pyx_string_tab[22] -#define __pyx_n_u_app_models_request __pyx_string_tab[23] -#define __pyx_n_u_app_services_cache __pyx_string_tab[24] -#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[25] -#define __pyx_n_u_build_key __pyx_string_tab[26] -#define __pyx_n_u_cache __pyx_string_tab[27] -#define __pyx_n_u_cached __pyx_string_tab[28] -#define __pyx_n_u_cline_in_traceback __pyx_string_tab[29] -#define __pyx_n_u_context __pyx_string_tab[30] -#define __pyx_n_u_decision __pyx_string_tab[31] -#define __pyx_n_u_dict __pyx_string_tab[32] -#define __pyx_n_u_doc __pyx_string_tab[33] -#define __pyx_n_u_evaluate __pyx_string_tab[34] -#define __pyx_n_u_evaluate_abac __pyx_string_tab[35] -#define __pyx_n_u_evaluate_core __pyx_string_tab[36] -#define __pyx_n_u_evaluate_rbac __pyx_string_tab[37] -#define __pyx_n_u_evaluate_rules __pyx_string_tab[38] -#define __pyx_n_u_func __pyx_string_tab[39] -#define __pyx_n_u_get __pyx_string_tab[40] -#define __pyx_n_u_init __pyx_string_tab[41] -#define __pyx_n_u_is_coroutine __pyx_string_tab[42] -#define __pyx_n_u_items __pyx_string_tab[43] -#define __pyx_n_u_key __pyx_string_tab[44] -#define __pyx_n_u_main __pyx_string_tab[45] -#define __pyx_n_u_metaclass __pyx_string_tab[46] -#define __pyx_n_u_module __pyx_string_tab[47] -#define __pyx_n_u_name __pyx_string_tab[48] -#define __pyx_n_u_ok __pyx_string_tab[49] -#define __pyx_n_u_policy_source __pyx_string_tab[50] -#define __pyx_n_u_pop __pyx_string_tab[51] -#define __pyx_n_u_prepare __pyx_string_tab[52] -#define __pyx_n_u_qualname __pyx_string_tab[53] -#define __pyx_n_u_rbac __pyx_string_tab[54] -#define __pyx_n_u_reason __pyx_string_tab[55] -#define __pyx_n_u_req __pyx_string_tab[56] -#define __pyx_n_u_resource __pyx_string_tab[57] -#define __pyx_n_u_return __pyx_string_tab[58] -#define __pyx_n_u_roles __pyx_string_tab[59] -#define __pyx_n_u_rules __pyx_string_tab[60] -#define __pyx_n_u_self __pyx_string_tab[61] -#define __pyx_n_u_set __pyx_string_tab[62] -#define __pyx_n_u_set_name __pyx_string_tab[63] -#define __pyx_n_u_setdefault __pyx_string_tab[64] -#define __pyx_n_u_test __pyx_string_tab[65] -#define __pyx_n_u_ttl __pyx_string_tab[66] -#define __pyx_n_u_user_id __pyx_string_tab[67] -#define __pyx_n_u_values __pyx_string_tab[68] -#define __pyx_kp_b_iso88591_4A_IT_q_83a_4q_q_a_IT_q_S_4q_q __pyx_string_tab[69] -#define __pyx_kp_b_iso88591_a_IQ __pyx_string_tab[70] -#define __pyx_kp_b_iso88591_a_d_q_q_q_q_V4q_1_Cx_4_aq_F_auH __pyx_string_tab[71] +#define __pyx_n_u_PERMISSION __pyx_string_tab[7] +#define __pyx_n_u_PolicyCache __pyx_string_tab[8] +#define __pyx_n_u_PolicyDecision __pyx_string_tab[9] +#define __pyx_n_u_PolicyEngine __pyx_string_tab[10] +#define __pyx_n_u_PolicyEngine___init __pyx_string_tab[11] +#define __pyx_n_u_PolicyEngine__evaluate_core __pyx_string_tab[12] +#define __pyx_n_u_PolicyEngine_evaluate __pyx_string_tab[13] +#define __pyx_n_u_PolicyRequest __pyx_string_tab[14] +#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[15] +#define __pyx_n_u_RBAC __pyx_string_tab[16] +#define __pyx_n_u_RULES __pyx_string_tab[17] +#define __pyx_n_u_TENANCY __pyx_string_tab[18] +#define __pyx_n_u_abac __pyx_string_tab[19] +#define __pyx_n_u_action __pyx_string_tab[20] +#define __pyx_n_u_allowed __pyx_string_tab[21] +#define __pyx_n_u_app_core __pyx_string_tab[22] +#define __pyx_n_u_app_core_engine __pyx_string_tab[23] +#define __pyx_n_u_app_models_decision __pyx_string_tab[24] +#define __pyx_n_u_app_models_request __pyx_string_tab[25] +#define __pyx_n_u_app_services_cache __pyx_string_tab[26] +#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[27] +#define __pyx_n_u_build_key __pyx_string_tab[28] +#define __pyx_n_u_cache __pyx_string_tab[29] +#define __pyx_n_u_cached __pyx_string_tab[30] +#define __pyx_n_u_cline_in_traceback __pyx_string_tab[31] +#define __pyx_n_u_context __pyx_string_tab[32] +#define __pyx_n_u_decision __pyx_string_tab[33] +#define __pyx_n_u_dict __pyx_string_tab[34] +#define __pyx_n_u_doc __pyx_string_tab[35] +#define __pyx_n_u_evaluate __pyx_string_tab[36] +#define __pyx_n_u_evaluate_abac __pyx_string_tab[37] +#define __pyx_n_u_evaluate_core __pyx_string_tab[38] +#define __pyx_n_u_evaluate_permission __pyx_string_tab[39] +#define __pyx_n_u_evaluate_rbac __pyx_string_tab[40] +#define __pyx_n_u_evaluate_rules __pyx_string_tab[41] +#define __pyx_n_u_evaluate_tenancy __pyx_string_tab[42] +#define __pyx_n_u_func __pyx_string_tab[43] +#define __pyx_n_u_get __pyx_string_tab[44] +#define __pyx_n_u_init __pyx_string_tab[45] +#define __pyx_n_u_is_coroutine __pyx_string_tab[46] +#define __pyx_n_u_items __pyx_string_tab[47] +#define __pyx_n_u_key __pyx_string_tab[48] +#define __pyx_n_u_main __pyx_string_tab[49] +#define __pyx_n_u_metaclass __pyx_string_tab[50] +#define __pyx_n_u_module __pyx_string_tab[51] +#define __pyx_n_u_name __pyx_string_tab[52] +#define __pyx_n_u_ok __pyx_string_tab[53] +#define __pyx_n_u_org_id __pyx_string_tab[54] +#define __pyx_n_u_permissions __pyx_string_tab[55] +#define __pyx_n_u_policy_source __pyx_string_tab[56] +#define __pyx_n_u_pop __pyx_string_tab[57] +#define __pyx_n_u_prepare __pyx_string_tab[58] +#define __pyx_n_u_qualname __pyx_string_tab[59] +#define __pyx_n_u_rbac __pyx_string_tab[60] +#define __pyx_n_u_reason __pyx_string_tab[61] +#define __pyx_n_u_req __pyx_string_tab[62] +#define __pyx_n_u_resource __pyx_string_tab[63] +#define __pyx_n_u_return __pyx_string_tab[64] +#define __pyx_n_u_roles __pyx_string_tab[65] +#define __pyx_n_u_rules __pyx_string_tab[66] +#define __pyx_n_u_self __pyx_string_tab[67] +#define __pyx_n_u_set __pyx_string_tab[68] +#define __pyx_n_u_set_name __pyx_string_tab[69] +#define __pyx_n_u_setdefault __pyx_string_tab[70] +#define __pyx_n_u_tenancy __pyx_string_tab[71] +#define __pyx_n_u_test __pyx_string_tab[72] +#define __pyx_n_u_ttl __pyx_string_tab[73] +#define __pyx_n_u_user_id __pyx_string_tab[74] +#define __pyx_n_u_values __pyx_string_tab[75] +#define __pyx_kp_b_iso88591_4A_IT_q_83a_4q_q_a_I_4A_xs_9Cq __pyx_string_tab[76] +#define __pyx_kp_b_iso88591_a_IQ __pyx_string_tab[77] +#define __pyx_kp_b_iso88591_a_d_q_q_q_q_3a_1_V4q_1_Cx_4_aq __pyx_string_tab[78] #define __pyx_int_300 __pyx_number_tab[0] /* #### Code section: module_state_clear ### */ #if CYTHON_USE_MODULE_STATE @@ -2475,7 +2482,7 @@ static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { __Pyx_State_RemoveModule(NULL); #endif for (int i=0; i<3; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } - for (int i=0; i<72; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } + for (int i=0; i<79; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } for (int i=0; i<1; ++i) { Py_CLEAR(clear_module_state->__pyx_number_tab[i]); } /* #### Code section: module_state_clear_contents ### */ /* CommonTypesMetaclass.module_state_clear */ @@ -2500,7 +2507,7 @@ static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_bytes); __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); for (int i=0; i<3; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } - for (int i=0; i<72; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } + for (int i=0; i<79; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } for (int i=0; i<1; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_number_tab[i]); } /* #### Code section: module_state_traverse_contents ### */ /* CommonTypesMetaclass.module_state_traverse */ @@ -2768,6 +2775,8 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH PyObject *(*__pyx_t_7)(PyObject *); int __pyx_t_8; int __pyx_t_9; + PyObject *__pyx_t_10 = NULL; + PyObject *__pyx_t_11 = NULL; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; @@ -2939,20 +2948,32 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH /* "app/core/engine.py":25 * ) * - * ok, reason = abac.evaluate_abac(req.context, req.roles) # <<<<<<<<<<<<<< - * if not ok: - * return PolicyDecision( + * ok, reason = permissions.evaluate_permission( # <<<<<<<<<<<<<< + * req.roles, req.permissions, req.action, req.resource + * ) */ __pyx_t_4 = NULL; - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_abac); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_permissions); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_evaluate_abac); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_evaluate_permission); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_context); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error) + + /* "app/core/engine.py":26 + * + * ok, reason = permissions.evaluate_permission( + * req.roles, req.permissions, req.action, req.resource # <<<<<<<<<<<<<< + * ) + * if not ok: +*/ + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_roles); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_roles); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_permissions); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 26, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_action); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 26, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_resource); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 26, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); __pyx_t_6 = 1; #if CYTHON_UNPACK_METHODS if (unlikely(PyMethod_Check(__pyx_t_5))) { @@ -2966,11 +2987,13 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH } #endif { - PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_t_3, __pyx_t_2}; - __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (3-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + PyObject *__pyx_callargs[5] = {__pyx_t_4, __pyx_t_3, __pyx_t_2, __pyx_t_10, __pyx_t_11}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (5-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); @@ -2987,155 +3010,163 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH if (likely(PyTuple_CheckExact(sequence))) { __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); __Pyx_INCREF(__pyx_t_5); - __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_2); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_11); } else { __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error) __Pyx_XGOTREF(__pyx_t_5); - __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); - if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error) - __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_11 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_11); } #else __pyx_t_5 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 25, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_2); + __pyx_t_11 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); #endif __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } else { Py_ssize_t index = -1; - __pyx_t_3 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 25, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); + __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); - index = 0; __pyx_t_5 = __pyx_t_7(__pyx_t_3); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_5 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_5)) goto __pyx_L6_unpacking_failed; __Pyx_GOTREF(__pyx_t_5); - index = 1; __pyx_t_2 = __pyx_t_7(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L6_unpacking_failed; - __Pyx_GOTREF(__pyx_t_2); - if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 25, __pyx_L1_error) + index = 1; __pyx_t_11 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_11)) goto __pyx_L6_unpacking_failed; + __Pyx_GOTREF(__pyx_t_11); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_10), 2) < (0)) __PYX_ERR(0, 25, __pyx_L1_error) __pyx_t_7 = NULL; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; goto __pyx_L7_unpacking_done; __pyx_L6_unpacking_failed:; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __pyx_t_7 = NULL; if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); __PYX_ERR(0, 25, __pyx_L1_error) __pyx_L7_unpacking_done:; } + + /* "app/core/engine.py":25 + * ) + * + * ok, reason = permissions.evaluate_permission( # <<<<<<<<<<<<<< + * req.roles, req.permissions, req.action, req.resource + * ) +*/ __Pyx_DECREF_SET(__pyx_v_ok, __pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF_SET(__pyx_v_reason, __pyx_t_2); - __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_reason, __pyx_t_11); + __pyx_t_11 = 0; - /* "app/core/engine.py":26 - * - * ok, reason = abac.evaluate_abac(req.context, req.roles) + /* "app/core/engine.py":28 + * req.roles, req.permissions, req.action, req.resource + * ) * if not ok: # <<<<<<<<<<<<<< * return PolicyDecision( * allowed=False, */ - __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_v_ok); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 26, __pyx_L1_error) + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_v_ok); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 28, __pyx_L1_error) __pyx_t_8 = (!__pyx_t_9); if (__pyx_t_8) { - /* "app/core/engine.py":27 - * ok, reason = abac.evaluate_abac(req.context, req.roles) + /* "app/core/engine.py":29 + * ) * if not ok: * return PolicyDecision( # <<<<<<<<<<<<<< * allowed=False, * reason=reason, */ __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = NULL; - __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 27, __pyx_L1_error) + __pyx_t_11 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 29, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - /* "app/core/engine.py":29 + /* "app/core/engine.py":31 * return PolicyDecision( * allowed=False, * reason=reason, # <<<<<<<<<<<<<< - * policy_source="ABAC" + * policy_source="PERMISSION" * ) */ __pyx_t_6 = 1; #if CYTHON_UNPACK_METHODS if (unlikely(PyMethod_Check(__pyx_t_5))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5); - assert(__pyx_t_2); + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_11); PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); - __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx_t_11); __Pyx_INCREF(__pyx__function); __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); __pyx_t_6 = 0; } #endif { - PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_2, NULL}; - __pyx_t_3 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 27, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_allowed, Py_False, __pyx_t_3, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 27, __pyx_L1_error) - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_reason, __pyx_v_reason, __pyx_t_3, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 27, __pyx_L1_error) - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_ABAC, __pyx_t_3, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 27, __pyx_L1_error) - __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (1-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_3); - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_11, NULL}; + __pyx_t_10 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_allowed, Py_False, __pyx_t_10, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 29, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_reason, __pyx_v_reason, __pyx_t_10, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 29, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_PERMISSION, __pyx_t_10, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 29, __pyx_L1_error) + __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (1-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 27, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 29, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "app/core/engine.py":26 - * - * ok, reason = abac.evaluate_abac(req.context, req.roles) + /* "app/core/engine.py":28 + * req.roles, req.permissions, req.action, req.resource + * ) * if not ok: # <<<<<<<<<<<<<< * return PolicyDecision( * allowed=False, */ } - /* "app/core/engine.py":33 + /* "app/core/engine.py":35 * ) * - * ok, reason = rules.evaluate_rules(req.action, req.resource) # <<<<<<<<<<<<<< + * ok, reason = tenancy.evaluate_tenancy(req.org_id, req.context) # <<<<<<<<<<<<<< * if not ok: * return PolicyDecision( */ __pyx_t_5 = NULL; - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_rules); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_evaluate_rules); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_tenancy); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_evaluate_tenancy); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_org_id); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_context); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_action); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_resource); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); __pyx_t_6 = 1; #if CYTHON_UNPACK_METHODS - if (unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + if (unlikely(PyMethod_Check(__pyx_t_11))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_11); assert(__pyx_t_5); - PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_11); __Pyx_INCREF(__pyx_t_5); __Pyx_INCREF(__pyx__function); - __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __Pyx_DECREF_SET(__pyx_t_11, __pyx__function); __pyx_t_6 = 0; } #endif { - PyObject *__pyx_callargs[3] = {__pyx_t_5, __pyx_t_3, __pyx_t_4}; - __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_6, (3-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + PyObject *__pyx_callargs[3] = {__pyx_t_5, __pyx_t_10, __pyx_t_2}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_11, __pyx_callargs+__pyx_t_6, (3-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { @@ -3144,116 +3175,442 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH if (unlikely(size != 2)) { if (size > 2) __Pyx_RaiseTooManyValuesError(2); else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); - __PYX_ERR(0, 33, __pyx_L1_error) + __PYX_ERR(0, 35, __pyx_L1_error) } #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS if (likely(PyTuple_CheckExact(sequence))) { - __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_11); + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); __Pyx_INCREF(__pyx_t_2); - __pyx_t_4 = PyTuple_GET_ITEM(sequence, 1); - __Pyx_INCREF(__pyx_t_4); } else { - __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); - if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) + __pyx_t_11 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_11); + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) __Pyx_XGOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); - if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_XGOTREF(__pyx_t_4); } #else - __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error) + __pyx_t_11 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_4 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); #endif __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; } else { Py_ssize_t index = -1; - __pyx_t_3 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 33, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); + __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); - index = 0; __pyx_t_2 = __pyx_t_7(__pyx_t_3); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_11 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_11)) goto __pyx_L9_unpacking_failed; + __Pyx_GOTREF(__pyx_t_11); + index = 1; __pyx_t_2 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L9_unpacking_failed; __Pyx_GOTREF(__pyx_t_2); - index = 1; __pyx_t_4 = __pyx_t_7(__pyx_t_3); if (unlikely(!__pyx_t_4)) goto __pyx_L9_unpacking_failed; - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_3), 2) < (0)) __PYX_ERR(0, 33, __pyx_L1_error) + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_10), 2) < (0)) __PYX_ERR(0, 35, __pyx_L1_error) __pyx_t_7 = NULL; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; goto __pyx_L10_unpacking_done; __pyx_L9_unpacking_failed:; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __pyx_t_7 = NULL; if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); - __PYX_ERR(0, 33, __pyx_L1_error) + __PYX_ERR(0, 35, __pyx_L1_error) __pyx_L10_unpacking_done:; } - __Pyx_DECREF_SET(__pyx_v_ok, __pyx_t_2); + __Pyx_DECREF_SET(__pyx_v_ok, __pyx_t_11); + __pyx_t_11 = 0; + __Pyx_DECREF_SET(__pyx_v_reason, __pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF_SET(__pyx_v_reason, __pyx_t_4); - __pyx_t_4 = 0; - /* "app/core/engine.py":34 + /* "app/core/engine.py":36 * - * ok, reason = rules.evaluate_rules(req.action, req.resource) + * ok, reason = tenancy.evaluate_tenancy(req.org_id, req.context) * if not ok: # <<<<<<<<<<<<<< * return PolicyDecision( * allowed=False, */ - __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_ok); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 34, __pyx_L1_error) + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_ok); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 36, __pyx_L1_error) __pyx_t_9 = (!__pyx_t_8); if (__pyx_t_9) { - /* "app/core/engine.py":35 - * ok, reason = rules.evaluate_rules(req.action, req.resource) + /* "app/core/engine.py":37 + * ok, reason = tenancy.evaluate_tenancy(req.org_id, req.context) * if not ok: * return PolicyDecision( # <<<<<<<<<<<<<< * allowed=False, * reason=reason, */ __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = NULL; - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + + /* "app/core/engine.py":39 + * return PolicyDecision( + * allowed=False, + * reason=reason, # <<<<<<<<<<<<<< + * policy_source="TENANCY" + * ) +*/ + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_11))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_11); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_11); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_11, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_2, NULL}; + __pyx_t_10 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_allowed, Py_False, __pyx_t_10, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 37, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_reason, __pyx_v_reason, __pyx_t_10, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 37, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_TENANCY, __pyx_t_10, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 37, __pyx_L1_error) + __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_11, __pyx_callargs+__pyx_t_6, (1-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_10); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 37, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "app/core/engine.py":36 + * + * ok, reason = tenancy.evaluate_tenancy(req.org_id, req.context) + * if not ok: # <<<<<<<<<<<<<< + * return PolicyDecision( + * allowed=False, +*/ + } + + /* "app/core/engine.py":43 + * ) + * + * ok, reason = abac.evaluate_abac(req.context, req.roles) # <<<<<<<<<<<<<< + * if not ok: + * return PolicyDecision( +*/ + __pyx_t_11 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_abac); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_evaluate_abac); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_context); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_roles); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_2))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_11); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_11, __pyx_t_10, __pyx_t_5}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_6, (3-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 43, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_2); + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_5); + } else { + __pyx_t_2 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + } + #else + __pyx_t_2 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 43, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); + __pyx_t_5 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 43, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_2 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_2)) goto __pyx_L12_unpacking_failed; + __Pyx_GOTREF(__pyx_t_2); + index = 1; __pyx_t_5 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_5)) goto __pyx_L12_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_10), 2) < (0)) __PYX_ERR(0, 43, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L13_unpacking_done; + __pyx_L12_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 43, __pyx_L1_error) + __pyx_L13_unpacking_done:; + } + __Pyx_DECREF_SET(__pyx_v_ok, __pyx_t_2); + __pyx_t_2 = 0; + __Pyx_DECREF_SET(__pyx_v_reason, __pyx_t_5); + __pyx_t_5 = 0; - /* "app/core/engine.py":37 + /* "app/core/engine.py":44 + * + * ok, reason = abac.evaluate_abac(req.context, req.roles) + * if not ok: # <<<<<<<<<<<<<< + * return PolicyDecision( + * allowed=False, +*/ + __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_v_ok); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 44, __pyx_L1_error) + __pyx_t_8 = (!__pyx_t_9); + if (__pyx_t_8) { + + /* "app/core/engine.py":45 + * ok, reason = abac.evaluate_abac(req.context, req.roles) + * if not ok: + * return PolicyDecision( # <<<<<<<<<<<<<< + * allowed=False, + * reason=reason, +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + + /* "app/core/engine.py":47 * return PolicyDecision( * allowed=False, * reason=reason, # <<<<<<<<<<<<<< - * policy_source="RULES" + * policy_source="ABAC" * ) */ __pyx_t_6 = 1; #if CYTHON_UNPACK_METHODS if (unlikely(PyMethod_Check(__pyx_t_2))) { - __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_2); - assert(__pyx_t_4); + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2); + assert(__pyx_t_5); PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_2); - __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx_t_5); __Pyx_INCREF(__pyx__function); __Pyx_DECREF_SET(__pyx_t_2, __pyx__function); __pyx_t_6 = 0; } #endif { - PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_4, NULL}; - __pyx_t_3 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 35, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_allowed, Py_False, __pyx_t_3, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 35, __pyx_L1_error) - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_reason, __pyx_v_reason, __pyx_t_3, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 35, __pyx_L1_error) - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_RULES, __pyx_t_3, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 35, __pyx_L1_error) - __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_6, (1-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_3); - __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_5, NULL}; + __pyx_t_10 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_allowed, Py_False, __pyx_t_10, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 45, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_reason, __pyx_v_reason, __pyx_t_10, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 45, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_ABAC, __pyx_t_10, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 45, __pyx_L1_error) + __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_2, __pyx_callargs+__pyx_t_6, (1-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_10); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 35, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } __pyx_r = __pyx_t_1; __pyx_t_1 = 0; goto __pyx_L0; - /* "app/core/engine.py":34 + /* "app/core/engine.py":44 + * + * ok, reason = abac.evaluate_abac(req.context, req.roles) + * if not ok: # <<<<<<<<<<<<<< + * return PolicyDecision( + * allowed=False, +*/ + } + + /* "app/core/engine.py":51 + * ) + * + * ok, reason = rules.evaluate_rules(req.action, req.resource) # <<<<<<<<<<<<<< + * if not ok: + * return PolicyDecision( +*/ + __pyx_t_2 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_rules); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_evaluate_rules); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_10 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_action); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_resource); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_2); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_2); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_2, __pyx_t_10, __pyx_t_11}; + __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (3-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) { + PyObject* sequence = __pyx_t_1; + Py_ssize_t size = __Pyx_PySequence_SIZE(sequence); + if (unlikely(size != 2)) { + if (size > 2) __Pyx_RaiseTooManyValuesError(2); + else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size); + __PYX_ERR(0, 51, __pyx_L1_error) + } + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + if (likely(PyTuple_CheckExact(sequence))) { + __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); + __Pyx_INCREF(__pyx_t_5); + __pyx_t_11 = PyTuple_GET_ITEM(sequence, 1); + __Pyx_INCREF(__pyx_t_11); + } else { + __pyx_t_5 = __Pyx_PyList_GetItemRefFast(sequence, 0, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_5); + __pyx_t_11 = __Pyx_PyList_GetItemRefFast(sequence, 1, __Pyx_ReferenceSharing_SharedReference); + if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_XGOTREF(__pyx_t_11); + } + #else + __pyx_t_5 = __Pyx_PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_11 = __Pyx_PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + #endif + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + } else { + Py_ssize_t index = -1; + __pyx_t_10 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 51, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_10); + index = 0; __pyx_t_5 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_5)) goto __pyx_L15_unpacking_failed; + __Pyx_GOTREF(__pyx_t_5); + index = 1; __pyx_t_11 = __pyx_t_7(__pyx_t_10); if (unlikely(!__pyx_t_11)) goto __pyx_L15_unpacking_failed; + __Pyx_GOTREF(__pyx_t_11); + if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_10), 2) < (0)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_7 = NULL; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + goto __pyx_L16_unpacking_done; + __pyx_L15_unpacking_failed:; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __pyx_t_7 = NULL; + if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index); + __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_L16_unpacking_done:; + } + __Pyx_DECREF_SET(__pyx_v_ok, __pyx_t_5); + __pyx_t_5 = 0; + __Pyx_DECREF_SET(__pyx_v_reason, __pyx_t_11); + __pyx_t_11 = 0; + + /* "app/core/engine.py":52 + * + * ok, reason = rules.evaluate_rules(req.action, req.resource) + * if not ok: # <<<<<<<<<<<<<< + * return PolicyDecision( + * allowed=False, +*/ + __pyx_t_8 = __Pyx_PyObject_IsTrue(__pyx_v_ok); if (unlikely((__pyx_t_8 < 0))) __PYX_ERR(0, 52, __pyx_L1_error) + __pyx_t_9 = (!__pyx_t_8); + if (__pyx_t_9) { + + /* "app/core/engine.py":53 + * ok, reason = rules.evaluate_rules(req.action, req.resource) + * if not ok: + * return PolicyDecision( # <<<<<<<<<<<<<< + * allowed=False, + * reason=reason, +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_11 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 53, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + + /* "app/core/engine.py":55 + * return PolicyDecision( + * allowed=False, + * reason=reason, # <<<<<<<<<<<<<< + * policy_source="RULES" + * ) +*/ + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_11 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_11); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_11); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_11, NULL}; + __pyx_t_10 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 53, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_allowed, Py_False, __pyx_t_10, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 53, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_reason, __pyx_v_reason, __pyx_t_10, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 53, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_RULES, __pyx_t_10, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 53, __pyx_L1_error) + __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (1-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_r = __pyx_t_1; + __pyx_t_1 = 0; + goto __pyx_L0; + + /* "app/core/engine.py":52 * * ok, reason = rules.evaluate_rules(req.action, req.resource) * if not ok: # <<<<<<<<<<<<<< @@ -3262,7 +3619,7 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH */ } - /* "app/core/engine.py":41 + /* "app/core/engine.py":59 * ) * * return PolicyDecision( # <<<<<<<<<<<<<< @@ -3270,11 +3627,11 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH * reason="access granted", */ __Pyx_XDECREF(__pyx_r); - __pyx_t_2 = NULL; - __Pyx_GetModuleGlobalName(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 41, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_10, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_10)) __PYX_ERR(0, 59, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_10); - /* "app/core/engine.py":42 + /* "app/core/engine.py":60 * * return PolicyDecision( * allowed=True, # <<<<<<<<<<<<<< @@ -3283,28 +3640,28 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH */ __pyx_t_6 = 1; #if CYTHON_UNPACK_METHODS - if (unlikely(PyMethod_Check(__pyx_t_3))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_3); - assert(__pyx_t_2); - PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_3); - __Pyx_INCREF(__pyx_t_2); + if (unlikely(PyMethod_Check(__pyx_t_10))) { + __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_10); + assert(__pyx_t_5); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_10); + __Pyx_INCREF(__pyx_t_5); __Pyx_INCREF(__pyx__function); - __Pyx_DECREF_SET(__pyx_t_3, __pyx__function); + __Pyx_DECREF_SET(__pyx_t_10, __pyx__function); __pyx_t_6 = 0; } #endif { - PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_2, NULL}; - __pyx_t_4 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 41, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_allowed, Py_True, __pyx_t_4, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 41, __pyx_L1_error) - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_reason, __pyx_mstate_global->__pyx_kp_u_access_granted, __pyx_t_4, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 41, __pyx_L1_error) - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_ALL_PASSED, __pyx_t_4, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 41, __pyx_L1_error) - __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_3, __pyx_callargs+__pyx_t_6, (1-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_4); - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 41, __pyx_L1_error) + PyObject *__pyx_callargs[2 + ((CYTHON_VECTORCALL) ? 3 : 0)] = {__pyx_t_5, NULL}; + __pyx_t_11 = __Pyx_MakeVectorcallBuilderKwds(3); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 59, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_allowed, Py_True, __pyx_t_11, __pyx_callargs+1, 0) < (0)) __PYX_ERR(0, 59, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_reason, __pyx_mstate_global->__pyx_kp_u_access_granted, __pyx_t_11, __pyx_callargs+1, 1) < (0)) __PYX_ERR(0, 59, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_ALL_PASSED, __pyx_t_11, __pyx_callargs+1, 2) < (0)) __PYX_ERR(0, 59, __pyx_L1_error) + __pyx_t_1 = __Pyx_Object_Vectorcall_CallFromBuilder((PyObject*)__pyx_t_10, __pyx_callargs+__pyx_t_6, (1-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_11); + __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_10); __pyx_t_10 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 59, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } __pyx_r = __pyx_t_1; @@ -3326,6 +3683,8 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_5); + __Pyx_XDECREF(__pyx_t_10); + __Pyx_XDECREF(__pyx_t_11); __Pyx_AddTraceback("app.core.engine.PolicyEngine._evaluate_core", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -3336,7 +3695,7 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_2_evaluate_core(CYTH return __pyx_r; } -/* "app/core/engine.py":50 +/* "app/core/engine.py":68 * # PUBLIC ENTRY (CACHE-FIRST) * # ---------------------------- * def evaluate(self, req: PolicyRequest) -> PolicyDecision: # <<<<<<<<<<<<<< @@ -3384,39 +3743,39 @@ PyObject *__pyx_args, PyObject *__pyx_kwds { PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_req,0}; const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; - if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 50, __pyx_L3_error) + if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 68, __pyx_L3_error) if (__pyx_kwds_len > 0) { switch (__pyx_nargs) { case 2: values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 50, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 68, __pyx_L3_error) CYTHON_FALLTHROUGH; case 1: values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 50, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 68, __pyx_L3_error) CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "evaluate", 0) < (0)) __PYX_ERR(0, 50, __pyx_L3_error) + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "evaluate", 0) < (0)) __PYX_ERR(0, 68, __pyx_L3_error) for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { - if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("evaluate", 1, 2, 2, i); __PYX_ERR(0, 50, __pyx_L3_error) } + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("evaluate", 1, 2, 2, i); __PYX_ERR(0, 68, __pyx_L3_error) } } } else if (unlikely(__pyx_nargs != 2)) { goto __pyx_L5_argtuple_error; } else { values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 50, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 68, __pyx_L3_error) values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 50, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 68, __pyx_L3_error) } __pyx_v_self = values[0]; __pyx_v_req = values[1]; } goto __pyx_L6_skip; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("evaluate", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 50, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("evaluate", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 68, __pyx_L3_error) __pyx_L6_skip:; goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; @@ -3450,114 +3809,144 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_4evaluate(CYTHON_UNU PyObject *__pyx_t_5 = NULL; PyObject *__pyx_t_6 = NULL; PyObject *__pyx_t_7 = NULL; - size_t __pyx_t_8; - int __pyx_t_9; + PyObject *__pyx_t_8 = NULL; + PyObject *__pyx_t_9 = NULL; + size_t __pyx_t_10; + PyObject *__pyx_t_11 = NULL; + int __pyx_t_12; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("evaluate", 0); - /* "app/core/engine.py":52 + /* "app/core/engine.py":70 * def evaluate(self, req: PolicyRequest) -> PolicyDecision: * * key = self.cache.build_key( # <<<<<<<<<<<<<< * req.user_id, * req.action, */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_cache); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 52, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_cache); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_2 = __pyx_t_3; __Pyx_INCREF(__pyx_t_2); - /* "app/core/engine.py":53 + /* "app/core/engine.py":71 * * key = self.cache.build_key( * req.user_id, # <<<<<<<<<<<<<< * req.action, * req.resource, */ - __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_user_id); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 53, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_user_id); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 71, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - /* "app/core/engine.py":54 + /* "app/core/engine.py":72 * key = self.cache.build_key( * req.user_id, * req.action, # <<<<<<<<<<<<<< * req.resource, - * req.context + * req.context, */ - __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_action); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 54, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_action); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 72, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - /* "app/core/engine.py":55 + /* "app/core/engine.py":73 * req.user_id, * req.action, * req.resource, # <<<<<<<<<<<<<< - * req.context - * ) + * req.context, + * org_id=req.org_id, */ - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_resource); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 55, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_resource); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 73, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - /* "app/core/engine.py":56 + /* "app/core/engine.py":74 * req.action, * req.resource, - * req.context # <<<<<<<<<<<<<< + * req.context, # <<<<<<<<<<<<<< + * org_id=req.org_id, + * permissions=req.permissions, +*/ + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_context); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 74, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + + /* "app/core/engine.py":75 + * req.resource, + * req.context, + * org_id=req.org_id, # <<<<<<<<<<<<<< + * permissions=req.permissions, + * ) +*/ + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_org_id); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 75, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + + /* "app/core/engine.py":76 + * req.context, + * org_id=req.org_id, + * permissions=req.permissions, # <<<<<<<<<<<<<< * ) * */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_context); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 56, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_8 = 0; + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_v_req, __pyx_mstate_global->__pyx_n_u_permissions); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 76, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __pyx_t_10 = 0; { - PyObject *__pyx_callargs[5] = {__pyx_t_2, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7}; - __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_build_key, __pyx_callargs+__pyx_t_8, (5-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + PyObject *__pyx_callargs[5 + ((CYTHON_VECTORCALL) ? 2 : 0)] = {__pyx_t_2, __pyx_t_4, __pyx_t_5, __pyx_t_6, __pyx_t_7}; + __pyx_t_11 = __Pyx_MakeVectorcallBuilderKwds(2); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 70, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_org_id, __pyx_t_8, __pyx_t_11, __pyx_callargs+5, 0) < (0)) __PYX_ERR(0, 70, __pyx_L1_error) + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_permissions, __pyx_t_9, __pyx_t_11, __pyx_callargs+5, 1) < (0)) __PYX_ERR(0, 70, __pyx_L1_error) + __pyx_t_1 = __Pyx_Object_VectorcallMethod_CallFromBuilder((PyObject*)__pyx_mstate_global->__pyx_n_u_build_key, __pyx_callargs+__pyx_t_10, (5-__pyx_t_10) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_11); __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 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; __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 52, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 70, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } __pyx_v_key = __pyx_t_1; __pyx_t_1 = 0; - /* "app/core/engine.py":60 + /* "app/core/engine.py":80 * * # 1. CACHE HIT (sub-ms path) * cached = self.cache.get(key) # <<<<<<<<<<<<<< * if cached: * # `cached` is a previously stored decision.dict(), which always */ - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_cache); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 60, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __pyx_t_3 = __pyx_t_7; + __pyx_t_11 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_cache); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 80, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); + __pyx_t_3 = __pyx_t_11; __Pyx_INCREF(__pyx_t_3); - __pyx_t_8 = 0; + __pyx_t_10 = 0; { PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_v_key}; - __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_get, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_get, __pyx_callargs+__pyx_t_10, (2-__pyx_t_10) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 60, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 80, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } __pyx_v_cached = __pyx_t_1; __pyx_t_1 = 0; - /* "app/core/engine.py":61 + /* "app/core/engine.py":81 * # 1. CACHE HIT (sub-ms path) * cached = self.cache.get(key) * if cached: # <<<<<<<<<<<<<< * # `cached` is a previously stored decision.dict(), which always * # already has a policy_source key (RBAC/ABAC/RULES/ALL_PASSED) -- */ - __pyx_t_9 = __Pyx_PyObject_IsTrue(__pyx_v_cached); if (unlikely((__pyx_t_9 < 0))) __PYX_ERR(0, 61, __pyx_L1_error) - if (__pyx_t_9) { + __pyx_t_12 = __Pyx_PyObject_IsTrue(__pyx_v_cached); if (unlikely((__pyx_t_12 < 0))) __PYX_ERR(0, 81, __pyx_L1_error) + if (__pyx_t_12) { - /* "app/core/engine.py":67 + /* "app/core/engine.py":87 * # "got multiple values for keyword argument 'policy_source'". * # Override it in the dict instead of passing it twice. * return PolicyDecision(**{**cached, "policy_source": "CACHE"}) # <<<<<<<<<<<<<< @@ -3565,29 +3954,29 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_4evaluate(CYTHON_UNU * # 2. COMPUTE DECISION */ __Pyx_XDECREF(__pyx_r); - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 67, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_PolicyDecision); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 87, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); if (unlikely(__pyx_v_cached == Py_None)) { PyErr_SetString(PyExc_TypeError, "argument after ** must be a mapping, not NoneType"); - __PYX_ERR(0, 67, __pyx_L1_error) + __PYX_ERR(0, 87, __pyx_L1_error) } if (likely(PyDict_CheckExact(__pyx_v_cached))) { - __pyx_t_7 = PyDict_Copy(__pyx_v_cached); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); + __pyx_t_11 = PyDict_Copy(__pyx_v_cached); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 87, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); } else { - __pyx_t_7 = __Pyx_PyObject_CallOneArg((PyObject*)&PyDict_Type, __pyx_v_cached); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 67, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); + __pyx_t_11 = __Pyx_PyObject_CallOneArg((PyObject*)&PyDict_Type, __pyx_v_cached); if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 87, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_11); } - if (PyDict_SetItem(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_CACHE) < (0)) __PYX_ERR(0, 67, __pyx_L1_error) - __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_mstate_global->__pyx_empty_tuple, __pyx_t_7); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 67, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_11, __pyx_mstate_global->__pyx_n_u_policy_source, __pyx_mstate_global->__pyx_n_u_CACHE) < (0)) __PYX_ERR(0, 87, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_mstate_global->__pyx_empty_tuple, __pyx_t_11); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 87, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_11); __pyx_t_11 = 0; __pyx_r = __pyx_t_3; __pyx_t_3 = 0; goto __pyx_L0; - /* "app/core/engine.py":61 + /* "app/core/engine.py":81 * # 1. CACHE HIT (sub-ms path) * cached = self.cache.get(key) * if cached: # <<<<<<<<<<<<<< @@ -3596,64 +3985,64 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_4evaluate(CYTHON_UNU */ } - /* "app/core/engine.py":70 + /* "app/core/engine.py":90 * * # 2. COMPUTE DECISION * decision = self._evaluate_core(req) # <<<<<<<<<<<<<< * * # 3. STORE IN CACHE */ - __pyx_t_7 = __pyx_v_self; - __Pyx_INCREF(__pyx_t_7); - __pyx_t_8 = 0; + __pyx_t_11 = __pyx_v_self; + __Pyx_INCREF(__pyx_t_11); + __pyx_t_10 = 0; { - PyObject *__pyx_callargs[2] = {__pyx_t_7, __pyx_v_req}; - __pyx_t_3 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_evaluate_core, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error) + PyObject *__pyx_callargs[2] = {__pyx_t_11, __pyx_v_req}; + __pyx_t_3 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_evaluate_core, __pyx_callargs+__pyx_t_10, (2-__pyx_t_10) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 90, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); } __pyx_v_decision = __pyx_t_3; __pyx_t_3 = 0; - /* "app/core/engine.py":73 + /* "app/core/engine.py":93 * * # 3. STORE IN CACHE * self.cache.set(key, decision.dict(), ttl=300) # <<<<<<<<<<<<<< * * return decision */ - __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_cache); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_cache); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 93, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_7 = __pyx_t_1; - __Pyx_INCREF(__pyx_t_7); - __pyx_t_5 = __pyx_v_decision; - __Pyx_INCREF(__pyx_t_5); - __pyx_t_8 = 0; + __pyx_t_11 = __pyx_t_1; + __Pyx_INCREF(__pyx_t_11); + __pyx_t_8 = __pyx_v_decision; + __Pyx_INCREF(__pyx_t_8); + __pyx_t_10 = 0; { - PyObject *__pyx_callargs[2] = {__pyx_t_5, NULL}; - __pyx_t_6 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_dict, __pyx_callargs+__pyx_t_8, (1-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); - __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; - if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 73, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); + PyObject *__pyx_callargs[2] = {__pyx_t_8, NULL}; + __pyx_t_9 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_dict, __pyx_callargs+__pyx_t_10, (1-__pyx_t_10) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); } - __pyx_t_8 = 0; + __pyx_t_10 = 0; { - PyObject *__pyx_callargs[3 + ((CYTHON_VECTORCALL) ? 1 : 0)] = {__pyx_t_7, __pyx_v_key, __pyx_t_6}; - __pyx_t_5 = __Pyx_MakeVectorcallBuilderKwds(1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 73, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_5); - if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_ttl, __pyx_mstate_global->__pyx_int_300, __pyx_t_5, __pyx_callargs+3, 0) < (0)) __PYX_ERR(0, 73, __pyx_L1_error) - __pyx_t_3 = __Pyx_Object_VectorcallMethod_CallFromBuilder((PyObject*)__pyx_mstate_global->__pyx_n_u_set, __pyx_callargs+__pyx_t_8, (3-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_5); - __Pyx_XDECREF(__pyx_t_7); __pyx_t_7 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + PyObject *__pyx_callargs[3 + ((CYTHON_VECTORCALL) ? 1 : 0)] = {__pyx_t_11, __pyx_v_key, __pyx_t_9}; + __pyx_t_8 = __Pyx_MakeVectorcallBuilderKwds(1); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 93, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + if (__Pyx_VectorcallBuilder_AddArg(__pyx_mstate_global->__pyx_n_u_ttl, __pyx_mstate_global->__pyx_int_300, __pyx_t_8, __pyx_callargs+3, 0) < (0)) __PYX_ERR(0, 93, __pyx_L1_error) + __pyx_t_3 = __Pyx_Object_VectorcallMethod_CallFromBuilder((PyObject*)__pyx_mstate_global->__pyx_n_u_set, __pyx_callargs+__pyx_t_10, (3-__pyx_t_10) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET), __pyx_t_8); + __Pyx_XDECREF(__pyx_t_11); __pyx_t_11 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 73, __pyx_L1_error) + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 93, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "app/core/engine.py":75 + /* "app/core/engine.py":95 * self.cache.set(key, decision.dict(), ttl=300) * * return decision # <<<<<<<<<<<<<< @@ -3663,7 +4052,7 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_4evaluate(CYTHON_UNU __pyx_r = __pyx_v_decision; goto __pyx_L0; - /* "app/core/engine.py":50 + /* "app/core/engine.py":68 * # PUBLIC ENTRY (CACHE-FIRST) * # ---------------------------- * def evaluate(self, req: PolicyRequest) -> PolicyDecision: # <<<<<<<<<<<<<< @@ -3680,6 +4069,9 @@ static PyObject *__pyx_pf_3app_4core_6engine_12PolicyEngine_4evaluate(CYTHON_UNU __Pyx_XDECREF(__pyx_t_5); __Pyx_XDECREF(__pyx_t_6); __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_XDECREF(__pyx_t_11); __Pyx_AddTraceback("app.core.engine.PolicyEngine.evaluate", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -4043,19 +4435,19 @@ __Pyx_RefNannySetupContext("PyInit_engine", 0); /*--- Execution code ---*/ /* "app/core/engine.py":1 - * from app.core import rbac, abac, rules # <<<<<<<<<<<<<< + * from app.core import rbac, abac, rules, permissions, tenancy # <<<<<<<<<<<<<< * from app.models.request import PolicyRequest * from app.models.decision import PolicyDecision */ { - PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_rbac,__pyx_mstate_global->__pyx_n_u_abac,__pyx_mstate_global->__pyx_n_u_rules}; - __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_app_core, __pyx_imported_names, 3, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_rbac,__pyx_mstate_global->__pyx_n_u_abac,__pyx_mstate_global->__pyx_n_u_rules,__pyx_mstate_global->__pyx_n_u_permissions,__pyx_mstate_global->__pyx_n_u_tenancy}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_app_core, __pyx_imported_names, 5, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) } __pyx_t_2 = __pyx_t_1; __Pyx_GOTREF(__pyx_t_2); { - PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_rbac,__pyx_mstate_global->__pyx_n_u_abac,__pyx_mstate_global->__pyx_n_u_rules}; - for (__pyx_t_3=0; __pyx_t_3 < 3; __pyx_t_3++) { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_rbac,__pyx_mstate_global->__pyx_n_u_abac,__pyx_mstate_global->__pyx_n_u_rules,__pyx_mstate_global->__pyx_n_u_permissions,__pyx_mstate_global->__pyx_n_u_tenancy}; + for (__pyx_t_3=0; __pyx_t_3 < 5; __pyx_t_3++) { __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) @@ -4065,7 +4457,7 @@ __Pyx_RefNannySetupContext("PyInit_engine", 0); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "app/core/engine.py":2 - * from app.core import rbac, abac, rules + * from app.core import rbac, abac, rules, permissions, tenancy * from app.models.request import PolicyRequest # <<<<<<<<<<<<<< * from app.models.decision import PolicyDecision * from app.services.cache import PolicyCache @@ -4088,7 +4480,7 @@ __Pyx_RefNannySetupContext("PyInit_engine", 0); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "app/core/engine.py":3 - * from app.core import rbac, abac, rules + * from app.core import rbac, abac, rules, permissions, tenancy * from app.models.request import PolicyRequest * from app.models.decision import PolicyDecision # <<<<<<<<<<<<<< * from app.services.cache import PolicyCache @@ -4186,25 +4578,25 @@ __Pyx_RefNannySetupContext("PyInit_engine", 0); if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_evaluate_core, __pyx_t_4) < (0)) __PYX_ERR(0, 15, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - /* "app/core/engine.py":50 + /* "app/core/engine.py":68 * # PUBLIC ENTRY (CACHE-FIRST) * # ---------------------------- * def evaluate(self, req: PolicyRequest) -> PolicyDecision: # <<<<<<<<<<<<<< * * key = self.cache.build_key( */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 50, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_req, __pyx_mstate_global->__pyx_n_u_PolicyRequest) < (0)) __PYX_ERR(0, 50, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_return, __pyx_mstate_global->__pyx_n_u_PolicyDecision) < (0)) __PYX_ERR(0, 50, __pyx_L1_error) - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_3app_4core_6engine_12PolicyEngine_5evaluate, 0, __pyx_mstate_global->__pyx_n_u_PolicyEngine_evaluate, NULL, __pyx_mstate_global->__pyx_n_u_app_core_engine, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[2])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 50, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_req, __pyx_mstate_global->__pyx_n_u_PolicyRequest) < (0)) __PYX_ERR(0, 68, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_return, __pyx_mstate_global->__pyx_n_u_PolicyDecision) < (0)) __PYX_ERR(0, 68, __pyx_L1_error) + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_3app_4core_6engine_12PolicyEngine_5evaluate, 0, __pyx_mstate_global->__pyx_n_u_PolicyEngine_evaluate, NULL, __pyx_mstate_global->__pyx_n_u_app_core_engine, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[2])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 PyUnstable_Object_EnableDeferredRefcount(__pyx_t_5); #endif __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_4); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_evaluate, __pyx_t_5) < (0)) __PYX_ERR(0, 50, __pyx_L1_error) + if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_evaluate, __pyx_t_5) < (0)) __PYX_ERR(0, 68, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; /* "app/core/engine.py":7 @@ -4224,7 +4616,7 @@ __Pyx_RefNannySetupContext("PyInit_engine", 0); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; /* "app/core/engine.py":1 - * from app.core import rbac, abac, rules # <<<<<<<<<<<<<< + * from app.core import rbac, abac, rules, permissions, tenancy # <<<<<<<<<<<<<< * from app.models.request import PolicyRequest * from app.models.decision import PolicyDecision */ @@ -4295,31 +4687,31 @@ static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { CYTHON_UNUSED_VAR(__pyx_mstate); { - const struct { const unsigned int length: 8; } index[] = {{1},{1},{14},{18},{4},{10},{5},{11},{14},{12},{21},{27},{21},{13},{20},{4},{5},{4},{6},{7},{8},{15},{19},{18},{18},{18},{9},{5},{6},{18},{7},{8},{4},{7},{8},{13},{14},{13},{14},{8},{3},{8},{13},{5},{3},{8},{13},{10},{8},{2},{13},{3},{11},{12},{4},{6},{3},{8},{6},{5},{5},{4},{3},{12},{10},{8},{3},{7},{6},{180},{12},{118}}; - #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (680 bytes) */ -const char* const cstring = "BZh91AY&SYf\t\363\314\000\000<\177\377\355\177\374\325}\001\254Q\377e\177 \277\357\377\341\200@@@@@@@@\000@@@\000@\000@\0023V\332\225f\032$\241\346\251\352=OS\324yM\224i\220\000hd\032\003#\324\001\243\t\344\324\3656\324\310%\010U?\323F\225?\324\001\242\231\000b\003 \000\320\000\001\220\3654\300\320i\242\t\246\246\250\336\232\214\232jd\3234\2150\214\0010\206\206 h\311\265\032`\007\006A\243@\0314\3044\320d\030\206\0204\006\214LF\200\000\036\020YyC{\203\376\234<\007\022i\023\221\r)h\221\264!\001\006\037}\030\264\036\200\351Y4\322\376`9\261\273Ls\010\352c\034\224?\313\\!\032\215\037b\255\006\206p\341U}2WN\217\n\312+h\332\014\007\267S\273{|\237\244'\301\307\360T\242\357\305G'\317\211\200}\225X\301\364\256;\005\231\006]\345b\374\267l\337\346\336\235\230d]\211\206\230J\215\306\2508P\275\225Xp\3761\276\320\304\206Iq \244_\010\252u\275S\t\211\014I\0224\221f\021\370J\036d\221\232h\304\231\224\000A1\236\321\254\225\264r\224l\021j\352T\202\234\006R\206\222o\3607\227\006x\271\"p\344r\021\2021\207\212[\032\254\242\302B\250\027\261\311!\224\24195]W\224 \366\252\306\225\276\214\216!\224\276\263\352\266;\242\343\014\017\242\342\207\342\327\031\232\014X\232\244\366r\352IN8\224X\327\213\020\265\266\375w\020'\002\321>\365\007K\036\030\201\033\371\333\002\007\032\203\tV\3043%\241R\271\327\232\364\303\030(\001\323\023p{\000)\241Sv\300a*AiE\245\346X \036\264\240\225\rrj\325\335Ja\246\211\202\000[\266\305\021D\n\021H\243\221\361fTr\277\304]\311\024\341BA\230'\3170"; - PyObject *data = __Pyx_DecompressString(cstring, 680, 2); + const struct { const unsigned int length: 9; } index[] = {{1},{1},{14},{18},{4},{10},{5},{10},{11},{14},{12},{21},{27},{21},{13},{20},{4},{5},{7},{4},{6},{7},{8},{15},{19},{18},{18},{18},{9},{5},{6},{18},{7},{8},{4},{7},{8},{13},{14},{19},{13},{14},{16},{8},{3},{8},{13},{5},{3},{8},{13},{10},{8},{2},{6},{11},{13},{3},{11},{12},{4},{6},{3},{8},{6},{5},{5},{4},{3},{12},{10},{7},{8},{3},{7},{6},{291},{12},{132}}; + #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (764 bytes) */ +const char* const cstring = "BZh91AY&SYfM[/\000\000R\377\377\355\177\374\365}\003\254q\377g\377\250\277\357\377\341\200@@@@@@@@\000@@@\000@\000@\002}\231P\004\303DI\251\355L\2321M\250\302h\r\000\000\001\220\323!\243\323D4\033Hi\202\003M\020&Hi\244\323M\252=#OSA\352\006@\000\320\000\000\000z\200\311\241\303@\0004\032\r\001\202\000hi\246@44i\220\003\0204\0002\224\331&\223O\324\232\014\201\210i\221\221\2404\030\020\r\014 \310\006\324\320\364Oj$\025\"\027@\037\217~\221\205\017\034E\200\007\313\020PV\000m`\251D\230\0019d(\274\201\310\210\325R\264\033\356\202#.6\337\216P\201\242p\014a\3100\006\374-\031\362\256c>\237p\236\221\245X0*\265\302\214\367H\357\255\212\201[G.\3728&\337?{\267\270O\217\313!\203\251\005T\022\352\232\275d\213\020\327k\3060\014?%\365@\260+2T\343i\207j\023Y\351\341'x\320'e\3519qO_~X\225%y\2532\032u\005\035(l\006^F3 \220`;E\340\260\211\303\260\321s\370\245\305\225R/\204U>\377\3102i2,I$T\253B>\272G\306\245\305Y\"9\243\002\260\342\004\020A\206\2334\251.\255\210\330 (ei\317\316L\344\020\276\033Q\315\337\225\032u\321d\210\376\352\262\010\275\024b\335\253k2\220_P%\022@\340\303\216\211\034\202\301)\324\307C\205\204\035\325X\315x\010\310\342\003)}\247k\020\336\213\2146_,\212\036\230\360\306\206F-\230*\325}\345\216i\221\236\"\303\032c\306\r)\007r\251p\210\274\371\232\202tf\006\306\256\244\200\021\030x+j\007\033\341\205V1\001\231-\027\206\006{\356k\253\014`\240\007V+p{\004\024\222\246\345\243\030X\316\200\264\344\360\351\353\3144\220\003\241 K\006\241ykp\244\341\266\211\226\010-6\261A\254C\204\005\217\tK\323\256-x#\255\327v\"63\207 \031\320q\031\372\327Le\030\022\361\304p\335gV\217\"OaU\257'P.FX\325\263\020\370$\005\327\336\372\020\306\000\242\342]\026>\242\256\014Ar\300\001\023\tZ]xT\347_2\261\220\002\017\037-\302\2748\204\342\243\014\320\tI\332\356\031u\262X3\020\217 \276\225\331\357\005N\2300+\370\020\272@\372\354_\311\262-\031\003\034\240\031\217\217\237B\024sd[\005\025a\3572\255\274:\377\261\002gc\000+\217\301\375\220\035\254\307\021\324\245u\302\275B\363\030\346m\340\2260\342\320\205""\333N<\277\365\342\226\373\254wi\367\021+M\031\022\217\310@-\245\220H\202B\201mM5\000\204\250c\027rE8P\220fM[/"; + PyObject *data = __Pyx_DecompressString(cstring, 764, 2); if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) const char* const bytes = __Pyx_PyBytes_AsString(data); #if !CYTHON_ASSUME_SAFE_MACROS if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } #endif - #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (586 bytes) */ -const char* const cstring = "x\332\215\221\277o\323@\024\307[Q\241\024RHh$\020\252*Z\020\243\243\212\014\210\0010iP\221*\324&-\022\323\351z~)\247^|\366\335\271$\013\254\031=z\364\3501cG\376\204\214\036\363'\344O\340\235MB3\201%\237\357\375\376\274\257\235w\2241\320\372\331\245\242\276\001\217\006A\223I\005M\360/\271\017N0r?\270m\367\370\230\234\270\275^\347\260\355\266\217:'Rp6jS\366\r\312\353!0\256\271\364K\253S\224\336\276;\204p\237\033BV\235pMED\r\020;q%\264\210\224\316.\204\021h[>\032\342{\310\231!\237ah\272\320\357\"]\367\374\270\323\243\027\224Qf\020\202\n!\277\027\2338\266\357\342\353\224\033Ys =\020\332\361\376P\337r\251r\222\365hP\327\034\245q\230\335\223\352\221\317\270\264\235dd\260\217\276\210\270\360\310\025\214\212xqxL`\004W%FQ\006Ht\305$\252:4\213Q\236E'\236dd\271\374R\004\273\301\252$KCa\350\257\021\t\320\204\364#\037\273\\\202YhK\270&K\240\021\330\020\030\230\001\330\020\027\220q\330\020\036\230a\360\006\000\t\r\210I\220T\230\036\240q\250\003\250:\260S\270\001\330\010\013\2104\210q\330\014\023\220>\240\021\330\020\030\230\001\330\020\027\220q\330\020\036\230a\360\006\000\t\r\210I\220U\230/\250\021\250#\250Y\260c\270\021\330\010\013\2104\210q\330\014\023\220>\240\021\330\020\030\230\001\330\020\027\220q\330\020\036\230a\360\006\000\t\020\210~\230Q\330\014\024\220A\330\014\023\2201\330\014\032\230!\320\004\036\230a\330\010\014\210I\220Q\320\004\034\320\034.\250a\340\010\016\210d\220&\230\n\240!\330\014\017\210q\330\014\017\210q\330\014\017\210q\330\014\017\210q\360\010\000\t\022\220\024\220V\2304\230q\240\001\330\010\013\2101\360\014\000\r\024\220>\240\023\240C\240x\320/@\300\001\360\006\000\t\024\2204\220\177\240a\240q\360\006\000\t\r\210F\220$\220a\220u\230H\240E\250\024\250T\260\021\340\010\017\210q"; + #else /* compression: none (1161 bytes) */ +const char* const bytes = ".?access grantedapp/core/engine.pyABACALL_PASSEDCACHEPERMISSIONPolicyCachePolicyDecisionPolicyEnginePolicyEngine.__init__PolicyEngine._evaluate_corePolicyEngine.evaluatePolicyRequest__Pyx_PyDict_NextRefRBACRULESTENANCYabacactionallowedapp.coreapp.core.engineapp.models.decisionapp.models.requestapp.services.cacheasyncio.coroutinesbuild_keycachecachedcline_in_tracebackcontextdecisiondict__doc__evaluateevaluate_abac_evaluate_coreevaluate_permissionevaluate_rbacevaluate_rulesevaluate_tenancy__func__get__init___is_coroutineitemskey__main____metaclass____module____name__okorg_idpermissionspolicy_sourcepop__prepare____qualname__rbacreasonreqresourcereturnrolesrulesselfset__set_name__setdefaulttenancy__test__ttluser_idvalues\320\004\"\320\"4\260A\340\010\014\210I\220T\230\036\240q\250\003\2508\2603\260a\330\010\013\2104\210q\330\014\023\220>\240\021\330\020\030\230\001\330\020\027\220q\330\020\036\230a\360\006\000\t\r\210I\220[\320 4\260A\330\014\017\210x\220s\230.\250\003\2509\260C\260q\340\010\013\2104\210q\330\014\023\220>\240\021\330\020\030\230\001\330\020\027\220q\330\020\036\230a\360\006\000\t\r\210I\220W\320\034-\250Q\250c\260\031\270#\270Q\330\010\013\2104\210q\330\014\023\220>\240\021\330\020\030\230\001\330\020\027\220q\330\020\036\230a\360\006\000\t\r\210I\220T\230\036\240q\250\003\250:\260S\270\001\330\010\013\2104\210q\330\014\023\220>\240\021\330\020\030\230\001\330\020\027\220q\330\020\036\230a\360\006\000\t\r\210I\220U\230/\250\021\250#\250Y\260c\270\021\330\010\013\2104\210q\330\014\023\220>\240\021\330\020\030\230\001\330\020\027\220q\330\020\036\230a\360\006\000\t\020\210~\230Q\330\014\024\220A\330\014\023\2201\330\014\032\230!\320\004\036\230a\330\010\014\210I\220Q\320\004\034\320\034.\250a\340\010\016\210d\220&\230\n\240!\330\014\017\210q\330\014\017\210q\330\014\017\210q\330\014\017\210q\330\014\023\2203\220a\330\014\030\230\003\2301\360\010\000\t\022\220\024\220V\2304\230q\240\001\330\010\013\2101\360\014\000\r\024\220>\240\023\240C\240x\320/@\300""\001\360\006\000\t\024\2204\220\177\240a\240q\360\006\000\t\r\210F\220$\220a\220u\230H\240E\250\024\250T\260\021\340\010\017\210q"; PyObject *data = NULL; CYTHON_UNUSED_VAR(__Pyx_DecompressString); #endif PyObject **stringtab = __pyx_mstate->__pyx_string_tab; Py_ssize_t pos = 0; - for (int i = 0; i < 69; i++) { + for (int i = 0; i < 76; i++) { Py_ssize_t bytes_length = index[i].length; PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); if (likely(string) && i >= 4) PyUnicode_InternInPlace(&string); @@ -4330,7 +4722,7 @@ const char* const bytes = ".?access grantedapp/core/engine.pyABACALL_PASSEDCACHE stringtab[i] = string; pos += bytes_length; } - for (int i = 69; i < 72; i++) { + for (int i = 76; i < 79; i++) { Py_ssize_t bytes_length = index[i].length; PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); stringtab[i] = string; @@ -4341,14 +4733,14 @@ const char* const bytes = ".?access grantedapp/core/engine.pyABACALL_PASSEDCACHE } } Py_XDECREF(data); - for (Py_ssize_t i = 0; i < 72; i++) { + for (Py_ssize_t i = 0; i < 79; i++) { if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { __PYX_ERR(0, 1, __pyx_L1_error) } } #if CYTHON_IMMORTAL_CONSTANTS { - PyObject **table = stringtab + 69; + PyObject **table = stringtab + 76; for (Py_ssize_t i=0; i<3; ++i) { #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING #if PY_VERSION_HEX < 0x030E0000 @@ -4404,7 +4796,7 @@ typedef struct { unsigned int num_kwonly_args : 1; unsigned int nlocals : 3; unsigned int flags : 10; - unsigned int first_line : 6; + unsigned int first_line : 7; } __Pyx_PyCode_New_function_description; /* NewCodeObj.proto */ static PyObject* __Pyx_PyCode_New( @@ -4428,12 +4820,12 @@ static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) { { const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 15}; PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_req, __pyx_mstate->__pyx_n_u_ok, __pyx_mstate->__pyx_n_u_reason}; - __pyx_mstate_global->__pyx_codeobj_tab[1] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_engine_py, __pyx_mstate->__pyx_n_u_evaluate_core, __pyx_mstate->__pyx_kp_b_iso88591_4A_IT_q_83a_4q_q_a_IT_q_S_4q_q, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[1])) goto bad; + __pyx_mstate_global->__pyx_codeobj_tab[1] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_engine_py, __pyx_mstate->__pyx_n_u_evaluate_core, __pyx_mstate->__pyx_kp_b_iso88591_4A_IT_q_83a_4q_q_a_I_4A_xs_9Cq, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[1])) goto bad; } { - const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 50}; + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 68}; PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_req, __pyx_mstate->__pyx_n_u_key, __pyx_mstate->__pyx_n_u_cached, __pyx_mstate->__pyx_n_u_decision}; - __pyx_mstate_global->__pyx_codeobj_tab[2] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_engine_py, __pyx_mstate->__pyx_n_u_evaluate, __pyx_mstate->__pyx_kp_b_iso88591_a_d_q_q_q_q_V4q_1_Cx_4_aq_F_auH, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[2])) goto bad; + __pyx_mstate_global->__pyx_codeobj_tab[2] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_engine_py, __pyx_mstate->__pyx_n_u_evaluate, __pyx_mstate->__pyx_kp_b_iso88591_a_d_q_q_q_q_3a_1_V4q_1_Cx_4_aq, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[2])) goto bad; } Py_DECREF(tuple_dedup_map); return 0; @@ -5832,28 +6224,28 @@ CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyO } #endif -/* PyObjectFastCallMethod */ +/* PyObjectVectorCallMethodKwBuilder */ #if !CYTHON_VECTORCALL || PY_VERSION_HEX < 0x03090000 -static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf) { +static PyObject *__Pyx_Object_VectorcallMethod_CallFromBuilder(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames) { PyObject *result; - PyObject *attr = PyObject_GetAttr(args[0], name); - if (unlikely(!attr)) + PyObject *obj = PyObject_GetAttr(args[0], name); + if (unlikely(!obj)) return NULL; - result = __Pyx_PyObject_FastCall(attr, args+1, nargsf - 1); - Py_DECREF(attr); + result = __Pyx_Object_Vectorcall_CallFromBuilder(obj, args+1, nargsf-1, kwnames); + Py_DECREF(obj); return result; } #endif -/* PyObjectVectorCallMethodKwBuilder */ +/* PyObjectFastCallMethod */ #if !CYTHON_VECTORCALL || PY_VERSION_HEX < 0x03090000 -static PyObject *__Pyx_Object_VectorcallMethod_CallFromBuilder(PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames) { +static PyObject *__Pyx_PyObject_FastCallMethod(PyObject *name, PyObject *const *args, size_t nargsf) { PyObject *result; - PyObject *obj = PyObject_GetAttr(args[0], name); - if (unlikely(!obj)) + PyObject *attr = PyObject_GetAttr(args[0], name); + if (unlikely(!attr)) return NULL; - result = __Pyx_Object_Vectorcall_CallFromBuilder(obj, args+1, nargsf-1, kwnames); - Py_DECREF(obj); + result = __Pyx_PyObject_FastCall(attr, args+1, nargsf - 1); + Py_DECREF(attr); return result; } #endif diff --git a/app/core/engine.cpython-313-aarch64-linux-gnu.so b/app/core/engine.cpython-313-aarch64-linux-gnu.so index 02700d120408fc954fcc535fd6d6a1b22ae29523..24186c9af23115eeb8fd84d8183d5b299375e7a3 100755 GIT binary patch delta 28164 zcmbt-33wDm(|^xyE)od2$O&W-mqSqTU>RT$ z5jKEGM${l1A&R)c3y;?~94aX429!e(6T^|=aQ?sQnMpPa@B4k<^WW#$R8Mtvb#--h zRdvto*7tr}DUE&j;+1nN#f!pzK@uyCaYB|@ZHN<(8{&oaD0LB*iz&dG#L>n$ zag;Gl9N#2fXh)P{i7_5{s{Ng}JiyD##mIoc!b!0lTnYl>g+B=^x&np>Us7pJV7$kWX!dQa+3?NIc;_UjCl{{fdu0A~arD$mxu{bv|!h0PHZ{qbqcX z5Ke8^gvARla#R{hcHZPF7h@J@cbqq0#Q%OLmWOo_R`U)*8m9@@Inz;%hX^xxi>Cbg zP~&)E4yGZVUqxWT44i8W=l4GEtDs3p!s217T|}sWg@iB`$zoZ>9!HaV4Uto)E?AhG zH+yQ{jM-Bkek^x>zE~06LX3$?bUxli2yZ#CFmLL}+()MmoIii=eCA91Q0~k}#GjhJ zFK&yND27MAEat~VIxlq*g2hiF&x_Zh?iF`MjS#b=UlK1ww+|XIec_C``Qm*s%>stc zT(EG@|1uDMK55IG-insgW3!YW+8~pG+ zHF}pH-o1#^cVJ$>3ad7rT0cAtsYRM?rrJx-;D%#L(-c0$4}WZ`NKfFh~7Du(T*v6^kY8K3M$bYT%IwwX+xg+EH2f$(e28YWVnlMg z1ikSgKccifqm#c56He}F(J?6~*uvQA6c#A<@7i81djiF|U7uFV-Vm{->ypTY!ECM9 z7$?o=Fjgwq^K7?P!acmHxsii0vpn@5#o3s#7%yWb&2k3Gj|r^QYmAXNjVIKRg!-#S zCRsVYnG`Sno<4Qb0Cb*(Z=N^Qk!1>VP>a^gK1Ng&rw9 zd?(`%b;Tqu(naMOa!ybJ4l7CFV5B6jRMG<^`dK6`Tf(a&8ej)5q@ z;Y|T+R#vkt(6L>xkIBQl2nqHhUd##2S(YhPe6w$h;ISw#n3gDh-M4+_{V0EbuoLDd zR$AKDeneizz#~C&+)$ic4r?oigyGb{5*j!ZENL7@w9TZLeFGlE76k7aD~{ZU)#1nE@h6JdCZXn6+~m2n&F%I(}I0wW3yET zl&__l*Hj|)d#Ya-Tihy>mC3elLUqwCC5Kw*lp2*Z9TMg?jb2r1P-*Rq>^D{#AHdc^ z>oE(0n8VgjsJ8s0Qleu`Bu^vOwo^DyvqLNJdv=U8M@eAD#p>%}SNSerGPxnZp-X6cn6**XVJLYk*_$JFIHwM2lPrYbge+^U+M+zQ!WA+ro<5G-Yxqtk*RW77eQ*zS}guOG4~p zcBVpG;9HFL=eHS(A(kzjIwN`B{L##r?l@!SooxHtET4VNSX|f1MvGj7iE~Y1vZo1i zTMcH})3`Q+)O-cz`^k=Mv~MQmzhjnvi(_(rKa2cZGT<0M2$??%Fp0_556tpbOh^7R zxNc=*ax&)QGIY+;!4!?XXlz9zFB)0V$csj~V3vSJRy3*vQ*SFKfAHiJwdC6>jfv6~ zP30_uW|O74-)F453G<2(bYSK- zj%i_RE%^*H2u&aq$aR+pa=B2OnG(Pb3k*WRMQ^&UILYtDLI5ue5xlBc#b7xFFa>;Q zIqn5bJaxLqA}2Fe?Ty|t@ruA=h>tDTz~rKH3f54x^gIZ&;Khw#=1F6vqfjO*H?+3M zLYhS;scS*w?NXaL0(A$;!nucsr$OC4sAH%bi8?sH!x*7#s!@5*N8Nhht(Z1%r`k-d zUi><%QL|a7n+btDdA<4=|a4AfsHYO@%d;xmAVM!V&2k|)M6bzi zVginsjMJI4Y{=xI*eN?%Xv~=eawbbPCSRH5(ZodDl-(o*NYYDZad&oH@MjoSNT{z=52HHI}&#LWFXx{Pn=OVrw%$z27Xu%d9Sc z8LKTX-f<8;GA1~-LFL`V;(C=G6q;rxVpq%h#Y&yTCiAj)SqBDc3-_ zbc^nR@nYei1Y50H&W&U_qqV;6@QT#8IjS}zP3zkOpXJ;4AmF{x4g0nLX9n)mDO%s_ zX~2fMzJI|CQ{Sd2?n=szjzq*oz!oD0-xX4YsN0m~v=i?coMy)SC~=13g9sp`T{yKP z?F?*fG=wNe9nFOcgNY&`qG~hAz&+vWoSB=}W>kr94_?+N8guk8%>Og7*N}%(uGK2e z2|kO&dP!X*)xZ}3zfCM3(qH&h6o$riJ^|bk;8p?BWUNG);?g=e)C{KKS3VJY59<&=u@;ViJj<@ZGOFB{=-N2-d(l43C1meOx%Y8Fcwc;V zc!!o%Db_@X6;7uW$n(s>j=YE^8@V&G1~@9j%HflQyTp4&492O_vm;VNK_1L~)FyHF zh~Ay6QanNYk_P(&WWO>gs~8F&^Bu~`CgXSXHIX3Z5XUqzVdP)|d&7})>C|cD!#MEi zb>A znY?ut6D|m7BN$oEt*0!-SQIv?W^7jRl_VIHQE-p~FJHy-3?d_9ytB3FpvGvH_uNuS zn^0$fobhj93}K+jiWE;{uA_OVKMlQ{1rJ>};6s_bTe=Dl?303G(#pI>@tx5J4acvF z^T%w&>0gtviJ=v`{sY9WWAlVPd)AE|BLM4Z!n;^2R_8p`WCubzO#o?Ov-rfgKEhP7 zblg~>jo9e^`E4rDk4z1^K#rQR*~PDc6v@(&V}Lbd1B#2Tz}Us2`==yU+`=%of;`U^ z#rgB$*ux#6V!{JUlX&&1J5-;(BEJ8?6a6Z9Q%`tQ%9-z==j7~m4#pL#p3JZm)@ECvj2%Yi{RX!_|M!Q6{&-d$Kf_Xql8Qye2+2DK(fA zo~RKwPf8S)ie-}yHm#tApTZ)!R{p3FUzq%|utH3D@B>VvS)Imp;?ECu>sFzwh*Uz` z8C^xBo`DeOA|~wg4aMy>8l_W6a!jISN}MebQdK6yd0toCxuJYv*K@*TG~k4}>ug5&6!xsRt5 z{0+7m)d-ZYzP^%bbUmKO}pA;l$P?z9Jl-eTFbl`Y~?C;PQcVbOdxdx#I_^%Yy>cWH68`t}}D zJStVR_#2h~$=Ur0+*%Cv0^ml#^MG3c&jRiQ{2lNez|(+kz)HXm0DlGa0R9a4Ip9x# z-vFKfJOcOw;Bi25g14SJPz*1V=%@)}GA*8S(1|q`xeL4^_+%s}-Gm1n?$UCL@RvyfNg>`68lk(rXcxm0`0;`WxnXJRY(Lh(`J>RB;18{!al z3OTmkjK`(&n@ar-;-*si7No3%gvEg80Id*!M)h747g9VK0fy8V_P3hdWO-GN=&s%j>~7XgtK2$azX;3 zAtB^K(G7Lv2hmO({)nl4HHQ5If>|Y!?JF?oHoGkHpg`tsJ8D1~QUYu|9E6&fIZRCRDA5wM_Qoq4(!a&f|=g<92iv^Lptof zD*p3mE8HqfoijCMl(Ebn$Z}5c9a*#_w}L?+$uUA*bTszjC2{MVeuG?>XlkOR&FJ-6 z8feadvSfkH7D8E0JQE^GHo>-7{1)|RAe9MP^rGu8D>7DvpxgKyV_DEHvCZ68fspXk zzr>MqJBL02Vh5N#eo0(0_x|3wG$O9VSZNB%)IJEqSPUGq!wEw_E?IG>Vs}G2GP?)f zGVKy%(@rtApqmgS4lPKJ>V<|hhDgpRLF#cye7Rt0WOuYVjhtk~sYD0mcetfDuT_V; zfJGXC(^j_n3`VyUwUkP{LFue1$&q4Ca%6-0_eg%kL$%n6r{pL>+3dN1{XW5)+_%7taYF{4s ztC#akI0Syv;0S7-Ra`T+QE?3x>6J;L#iwv)c`Yxj_{M@J#W#_(vUs!nEQI;JKa&G7 z+B3-k#df$d#bzuP4=rdnr6!Y=a6s6xQKL>bEjmyf5T+Fd?qF1Ly(Ne zA{QT8d}Y$G;%j;LVt6Bpm1W{P_9P)${K}qatDm*zj?)+l4dX0!1+f^0NmlqUY(cDA zn8b2wkR7FuXKs0R)JerQ!7}}so`py>uB@j zz0BQ!rbOMRFV$#d(7cMWN@LSHpR6+4IznaS#SXxW{f)VfP^0r|%rv?iVD^+hO;45A zQk@s9#)}|#8?U~gn*iyvG{Rai8xLlc)G_Az^6Y?OIXJNRMmo$+2`Wy64PaqO=3dNA z8W7NtiPfvzguM^pa~ngwVd68Z5^Z$36|4-b>hIGyv}6@HbcjGTX1TTxlXJk5GR-B} z%b#v)mX{##rXcVxG2pNa$Ao5V(HKtR5Y`Txv7TKxdGq2Jka#V*2yxKH4>9W%(PF%vkmIU1eShncmGS(0=b6EdA>z^4+*{ExgqH%X&o#=i9(vN~q* zoY@$S$O@r67&VR13Zd}D2#wOPi*$fx8vwHJJ7P|JtxmJlQ~m0#?mCr?^>YDb@wuRE zg_KPbKr!X|q<~@;VUerB*9#?DFkS%)Hfaj>wuQxO;(&)uHupdzftI~}nfnx=2M&OJ zI#@0TOxZaYM_KH`F_hOH9E=0qEs4pD&C6z%>)8=G*DE7f4(q^rczu?T7fXn&!e6j! z_d&2)v-~v#qja(o7O{lcRCB0=IS7z!PoFz$Vkv~9HOto@X#6!{^%20T2|!vQjhqU$ zyjNpG=jY7wE_6<-AeVQJzHLxTE;?V*in))&?60?Cn0ot>^`}|!7N~DH8qjSB7N#wU zr2hx@7=Wc%8|a)0@UeEST_uN)#JdEqI5hd z${WPouupR1b$B~w)D=uTkjc<}00gsm9FfK%Ya&Hd2G?fN%`@^u zo0nZtraiFN7%z23`H+V1i1NoMw+E!QwYP`{Sq!e#wlPvF%9PW3jY(26%DZ?uQEHAd z@?m~rgw0)#xOgB=0O2z|b+bdE{yT(unk5BxPBTCoZL#2q7(6WZ(&9Lq2lA6wEw574 z$*5Ae6Qjv6@e@!aG=C`0XSDt=qkM^%6QpXCt5LoH5yJdepbO_g9a6zJ_&rm*%@?NZCI)koRVS|}K^V4vMnT1i1=b_sH%qJegBFe~Ol3C0J zR~&MDlwEYDid%{nq$d60IxX?I#f|myyrv0PJadz?pkt}6PnzYTEQ|aM>O4(rGtJO; zDf){xV<&5iqt3t#2VILGohO|2pj#nycu7vfiZdomrB1pxcIAOPaGM zEm>i{q{%<{sAKp^_e$_S;4P)ymk6?`Z)T6;^eaYCKRIE`p2h#mkDiFH2=x>QoTyKyf!U z{*yYVO_y)S{uaw%JK_$(p7e39mQ<9VNM(dZW7C7GdZ*-&|Es+4! zn2z-+vQXzb)4iZ2fy*I;@(JIzt)^|;cC-<#wrtyJgrn&=mY~$^V;oJqg_{lLFdX(^ zYhn!n#8$)_%yL9Lo6ro6P7e?qJGQpOb|#MR%HG8(DecO<9l;|+n`>w#5VSZysUqQM zKe`odNHBdrs%?RdM{IwHZR{_5VTH%rc^b}>@ceKxfrbvF4v zKO(+4i;<=QPYEPto(oX6LVzM@E#<|*5E$_fXM5KBSPsuxw+V31Nj#-i76cX7U?1}e z&e7@I#a}2hl2NP8KO?}d(&{6<6&-kbGIyJMaMB1>?nB4%&cUhxRSWglP~${VvDIV&mP#YlA5ZUm-|rolU};nZOu zWtA9MPgo^sko*&A&b*N2SW%X>jijOk7q_Zrv;KArNR-O!#t7AdLL@2<=Ym>O>#@krD?NN8z!gx#LU|l zhzWi9FAy88kfk6d%iT(IElRXv}HaKLmXP8f_8jG!!I%^rztm95IqXEW5o<|cbFVS33<>^L-93OlLfD=dMpu(Nnbh*sH+*}=tU2QZoLO`Syy(pQ^)IzTSK zg&<0rIJ3o2+zi?~vn8vT7Me~&3r(d-;xvuV*;FF450SZ!D3KExHAY@IK%J47>5PJ< zGZ66lS@3~SCLcbgIz9=Urdp%fF+pABmDtE6r)bN%az*{JUebc)lw(yp|Lu`9au z)HgI9^y|6*cB3y1?_><*o zS+`5hhE$&+>!W>}fHFB;c38>CG1$kDx+z;srVTH)S~d@Msdtjx-h}3ho??r^!{99) z3QkM!wE47R_q+bM;-=l~en?Dl>kJa;Ofp8yYbM7ih^cL3 zJ+9x?2-=`bJJ8mE?*W$zs5`UGz(0v=52cT-1fD)7Vzf8gn&tf;Dy1Uo*k8>IRjoNt0ug*Nmgkk^LWDu3dFDz^aPqGug&A8={_ z4xUj)=2k(^;n4FpG~x6N4&hVq3=SNW{5b?U1L5iE5w9^=`VqYFBzK%X&lDi_QIjT4 zLJ+%;@rj<50fJe4@TEAL2~WekdI?)?RGTkpTWxgV{gZaG2~ZZ34}d-CY8LMf=jgzd zX}Ajy4R;Z^w;>`q^~IPl31tcbD^d0n(Z*+nWTYbl35vJ_(`+38K|!tX2qX?~XGCB&T%OU>bB&tEE>Vf5TA=ASSP`M^*t1a-pyr zAYK4L=&*!r`)Q1haAe<)0{=}HY`ulrz5mzA8>>wo4JekjTV$JaxEiCSe01_Vn3JPU z$IM%OMrOsxGLXmVqqV=Ihw!;p zJZO&G$$vT)Mb}S{K7chj}FUFuY0-_bTnRsUxpq`bBYje9QyF%4X~vmY|N}QhEVdVE^yQ>`i1gz|l2j zTAso6*9&pH;pthMY4=&bv<%FBv1Ppqr(T0_jUT%}2t22a(aqs*E>`M|askR~0nO-C zjj%CNcL;f-EzIX-rSxsoc^ztCqnv`Y@gv%-Y|th_YD)t{o93@7r7qOD)}YPZXh4l9 zTKvymqIJ;z*9U4JiIc@!AZ~|#MNZxNPhNBL-Bc^-ONBdKy>!atYV65DFWT`Qg3*r2x@GT z(bmOJZeWU2On0M(|j&QOra2Bh1rsa z^JpPN-ScUuDq8sX2Tz=kX3RcX#Qv>-TKAxP$7uXZr{?K$`SopT%?ov>~Y3 zwJ1WHH3}m7@r(WO+mBy1fC+8b%=7i9y^SMoaS{HH8xI zM@q(8tU=xR%;&seKiI&gs0I7EiD>` zYyItE$7N=2$`PrPJ`{G0YM3$4qA-KoK)9ygS=k5GUmvPLHce+J_I|jj?l4w*oJQK#EI;{%Qd)&N`wDf#O^wOLwLqJ%8nlU#W}%IYHu55+^fc;BPt~`f zsiG-s%C*^Cnu>b5`7r@)Y~DPNuQ-X9JYV8Hd&cmtChIHLPM2njYurX+A z#)}=+r*?&mb#VnU$}T+cpl+0K3lef%)jZ}FJiJv7e{(~$yc~^DMoS7Geyr3CozV3S zT$45Hb3&@!k5SOZ#O^avI1}025s%5@v1yjfy8F%}tq6TC)4`86Mszzj7hcV0Gi2*( zhDxnaq3>>}e2bFv4;nqv0e4VX?cN)>^+E!jfzgmKH4tVIehsMaj%Gt}Qkw@uu5)+b zYxa+10qW)`m7f1VB$IJ^AWfhLLwrVsM#!%GLRpC#$_|cE8&YRK`iDF1`0^BR=wX2SBLNM;@5dw&3@mp1H%YB0z8Zm0()=T6}aHx}IfswW%_v2N0#McLdG_Xrl= zA(}nl6V1k{(aZv2M*g>(0(vO(V0t`0*5!e9d4{NdRX+o>LTmORe0O9*6%Sst1H!=T zf|tRp2Cpdd_3~Z_Uf7th<#;+EjrG`z+lFM*cI*g9VNBmWV$()u$Zr<_(s70Fq2hO^ z)Qt`uY0yCyc-sEIb~|tE@Zaq;4C(%x9lAxp9W?}_=P-XiMUE5FP_QCz-3BAG`^=IZ zvqT#5pG^~z{wqC{QW`Doab()}1gYWVA?{Rh1ee6*_89RQ>^+xZF}di;(fV7LCH&V& zHq2BA7DOm-6eG1jgXj4QPm&IzO!3I{p^`xnk)q++zCBuWvWdkn6HcYwnz z{&Xce!(mp5|6!JP-xT-&#~)~CyU7DulJqq$XrXv3mD}!RSrhAHlD-uphs#E)F^Gb! zzCAh%Kj#^$#U^Z#n!()=j-}ronpisS7t}!QS240Gu7M=!=Sszy%{74IdIY)?xTau< zA9P`~IK>3+SOZ*;RDtWKd406>FO(^HrX#1XP+o#^YYff`<5ss-3DT!DScI90+iXhd zJ-BdTQ@7AZwfOyITwH@j`1K#IXKfO zl&#puQEFiFNq9|^LPC2cpO|Q(mAT9wB|ceyAKOHiJHXRH?^JU^RSv>G%?V@C+Jew4=qa4(LvN_p`J{ej_IhL z@PFZ#skGqxLu9;GAdY@}!TQ&}Pjy+4#AhCCbrS&{$V5OBk^rWZ2xRivOq4o-(HA@| zjgc~N2a;x5w+<_(Ns?NF=59`dBM3~?MO>3$WZveRcgO|tfTAVXrY3`Zkqp|A{LyTC zaATQPK3(%O2!u%eIul29p5C`FHdiLH9CS)s;D69DwQGlwPeR%1leXO;pTo& zm(4H(UY>3-AshK`H;vy|)G!*H!ht2sjwdZ-^K`?QZWhx`V~PxVG@wW@4Z^5FAVJ!W z>9f}d0ULkd%!T{;{)R{@Ee%vpzi5Ql;hq)-tMmRF*HE-H3XI8#v(K@qfaY|Y7=?On zWIQ6o(8DY|BIqYOWMfOv7WZuIM+SnJIv}gor@{?GynzmhVKA(`o>@X2Gh$KzCV2G+ ztUW<`7Spv7^G}D|eNfk6t-({IAdr)%(6`1Z%kiV2yU~Cg?;BvX z9nDWFjDW}KP^n(#y z4WDc4j$+Rc@Sqqo9dtO}vq{-Nl<^plBw0}Yke3CiAIb+%)^(_x^L%ua4xwl<&gQg; zJ#c8-4enalG@GZ+eG~P{x0Rf^ zXegr*EmnF|jV4z96~7MT=p1uk%Pf2?QMy1a?jo>OqKzk&uQGFYnLsTQN zhxWSr((4QN9NN(t@-AqKeyvM;rN8(f6QwtSt5$48kSJ}(1xe=RmC@2JsF7~a-KkU9 zg`2YFqv)7&1^C47y2aCK=+8TCF1-St9l@i1vDbSJ()wIzIE6Ojv}0cm;s7iOlJGY! z1l@vV@-rkDIw9PDV)P&w9fZdIQ~fy9H*3(o-s|xB9|3|lxKTw*b1-u1knaYuGo%rP zVMJ^1uvxeJEhoD=r|N^gG^L^S!T%H=Xpl4v1M0@texfw^SHHDbh?sd(3 zUDi~e0x8u;kz=F|5Q=`9xAr#wNk{MgV|Ky*^@OJ_#)%=UR(BG72&?t?8vKbK!cniA zt!}bp?z=D?{o0M|ow(MwLf3v#=jTl>Y4d?n4G>vep)pbw%Dqw68&iOLRcm}6b@U^- zWIWz*>#2|F_rs1`PnGZV7^i-}$Mbr;L3C|1?K!?>s~|p8)J7~U>bB=dQ5!)_+nz4o z*!qU(*;cT}y8W0@2o<~T?1=YpPS`oNNi<`u3BKX@Mu@w2b_v8Q$yk{9^UnUZV3hDO zP=>7y5=q9WrWO28W5DJ3(x>ppm&SZN_oz8$&Uc}2tj@}6HG0&zE5Xw~8U0;j58Kdv z=el7t*2Ly?-So~`r}ew)69*OyjUAu<%elkb2EURZNB4d5n=PyRFX{8z_P67A-nHe| zS8n`rBX-<_0q0GBPIL`lSUXhyV7JHR|P!Y2HWAy?@ugub!B2K|hyFKam1X~awOEKf`r^mG&0W5Kf6)tRRqqV%)$yfvWgD72I&I9j=dVxx zJ~!^b%!G4MD<<^o(|FpKFXp_sZ)Kw)gPhC1>e{q+*Sew@)3T`UTgn&54lDoj%Wql) z??3Qm&XOk%iF@B|@v9-@TF>Lh+YDI#!GTUmSM2|O-#&cBnb6_kwx`?3t&V-M=Do$& zJzaOF<-Izf$%JteGA@1H<)iIWn!fsZkGM1W_h!9#y``|ScSx_6J&%7q>YZ2KZeG0e zt9#OBeO>+J>Z#Z4H#Yw{dT8Ige|!Gu_E}DgULz+4E!;h~x-50`ttOi$9hm$|>us%# z_pX0@&Fd3)-52`VVMos<83QsWzA)vp8(l}*!kP{$b-Wh)!>2!$Y+C>Qvd`R?v-i!M zneI9IR9MHiqN+QcSaZ%@JEMEV-4(5`J~sK4pTB&tWUBa*b9Bel>Z8?{_C5CIqV%P6 zPkmchJ@UCduEcfQem>W?&FQ~wk#8LSw`*N&$E*h)zk1}<9&4Wo>%Z*&+I<}-{4ylN z9dci2)4?kWBTqKnYg@PI+LpW#7sEEi{;=!~>)eUs$3Jm*hg0{C3Okv$?W4?2op;^e z`uWn5mf>suxbf>M>FI&TK7BW0<(zN-*;d%Oq-xnGC6VK{9^Kcs{h?DfcH^#tyYU{O zBx4_X4RUW7?mj%Iei@G#b)T;&<^aY<;r?h9AX}&?&G9(W+Q)2)@*E0%A6Jxb04oad zh%=VJ20YvSDVD&+rxfKTVCz+il8q%a1n@GL7Xs27688Z%2Ml=;^?>n!;{kgDJ_0x% z&JSbAvxfX*B~*~Z$>>F#bTGDECy`6T~SPU+gBl=88H40MX>^I0(=gz z-3~=50lWx!9B?08A;Zg2YKs*m4X~$#pW27wydr)V8c@aCigJu9N+1wkqqrEaU04h_ zc`pP2jQ?CwT9a2|;>fpKb{PIV_|O$T5%}JX?+oDj5(1yr_?q!u`@FdR?KZaks3JE< zA0l6j?>^w-34sscR^$7rA8tEv6~GZY`Viede7(T6BLqH#`v%`y;Fc2t9}~V_d}q7> z!+^+r-f0oL8s+Z5(Wg1S@i3(QbHq9Cv^1=KL45h0IkCfGPJD={HQ~D-6hl^tQSYW2 zHmnje06eS2iSK4~*atg`0Rere`%y37(YjxRnoz5a*nvZBy|`K=n)uM2#oPKv9W}kvtJL|9GE2rtTkq@ zGmH=Y`IqmG9t&rdFzS^IbU$cy<(Prn1zbRZ_j#jEeV5Hy)q`g(E2o_;|t z6l-GWy9Kk+bGU)CkExCnD(0ZGK$MlEO||Q$DJCq3&qBpc<~sD1)IcwfW1lB z*HLU4O19V<)>iVmII^@uP!5WoE#fn!iJ>$vg}6MqMZ8qnA#?~Xcj5B6B5`YJ)<`oh zYjN2eKNRYV*@ON~uLo>44iF7Pj%LxwHN;4*EE=eK#L+C#kVk(OA7xfF>x=ak|Av_Q z{*)jWinTk%74N6oNR8j%a@SjMDWpV8xK|kXdgIMu1H{m^jRvj@Ss&~S+7S4fVUu7O zj+y@HfuLfAcvI!Wc3nzZO@6~{fM#BT4Kc29JjpTm~zn=Ipi?Cw> ziOw+Y#E%v#uuVue*buDli)EOvj^Yb@JK8wIO~PvijjM&qhChha$)7A?hJQ}{_|r+= z3rX~39sUsEc|TmzYJOSA%=od95WHK?kyhL}^!&}Ea5z{`81|^wLpL`PJ^NaZHo>u+ z!vkwQoAL@PX(Nl2Ff@F1AZdk^LPMgij2{}qt%H8~`KOa7e$+LCX0#G!fY0%#6(wSi zrEG3msQym#hb`Q?s7EbA04m1qr49Pfm+huMb7e_ON>HX zr2eLHKXgxxT7TzvfipJ{)I;u!9F75$s`k!k{e9T_`>(SfBI-!}RoD8f ztt+^GLiIOS7t9tdWrGYoKXfJr2`%wrYG-f2M*5qnk2#Bigt!j+i>LJ$O)u58uR;Aq z)9yvitwBORgY`q|TPShLL3j`4OqD82Bi7#+-A%jJ-xEDpyJp(^q0_bNh=-lCf`$IV z7~&bBzv)?jv$NCD2=AsFRo0@3w@hsSFNI(-x-tIYf)HS+Dsy%S!EA+m;2aYo%n8-0 z(niw2oe_SNAos>UOT{IgsIbl;O#FL$OiLG_0BHM|CnYt~Nid~5Ot_;dgy=4sB|)LLIy3)NbN_kr?ix3iL}^+{}}wSK*>b!0fSknL1+n`mi%}}e? zY9f?r_>u`KzDfn`2Mzz}colI`!(Z3wA5am68onJuHdlm3&qFKf9#rwp$D0a~wxt@8 zZl>{C6FZEqDw#}=s9UTq3K*YNH|DxT*BDBjTUx>H=+QLWE_0~$$^R`pU5 zJffmF3KfLU?xW&)Kt&P1ZN#Suo1wjZpI_pSjxYGo`9Y-6MwsEOj6|?{25bcUUy>n> zQ~|BdMo~g?%BvcBr}oc4kR$O=k%ljE4viAp3hz4SMG0MmL(ZZotd(=TvKe#HMhzbm z|I1h-Bx(X{#(HZ12tdcT((oqjJ^L<=zMqC4???ZbhA;HPzo+7znbAUI!g-BopGGu8 zV=6myqlLI`O)(OZMSthNS*vcR;q`a>yEMEd#3@A!Eh9_HHG~H8oF}4% zY-m>e@dX;b!r4AXXq&K1yNu9$uFm6C=gb(POUfHum`G;2rJ1Ex|Bcqn>MR2n;kdIh zMo2acFLxT6VMgQZ?4h<4H2yBN`)PztRjX1&aqg60N1y88p6&1Xu zf*mT@$3ft~!6B7%IIrT3&cpG%0}k4%R~8kFP=QqibDdoiAf{8j+NFZ8Rd7lLmsJq# ztWE&WRw{T>q<_zpu3luTV4Mo3tKbFQNB2Z5t-0;5jCBPzmHhghQ`wgRDQcenE}@%dI|@FNFKYjYt!p%yg! ze;;YiM01fW+39GG7HKNzuYz$Zn5%+ko#jO0RIlDufrkU9y@e1j{H>yHsUXU^y9LNo zRM0~O16A;l3KnwUENF?wn^jba3O-c97tW%Vn6ls1t6M6Fb0Uw56Yf^QJFm%(m>N2C;q>`~X3m+pV1~0QRfu(NXd}e6oHM;};kY>kxp}h(&dDDz zV|w1~&Utg^ELd1De{MnNw7sQmgy?Wem-im(F1QSa%Qok%OrdkA?qQIvZp{=jqV(KX zhyBBye}FDh_aHhv>1^Lq=n~me^T0Y>ymw|#;bTGA;B4O;34JH0&`5}L+ItJ_nhenr nqy#vdRnF4hLdQn?QdBQ-=A+u3YvKp^1~W|Ba-4G;wZVM4eRlyIo1tTRMJ#4BUt z4&nk6Kp^84OajD<0TFR!-N-43IteNYs6nng4(I=^e(!~3aR0xZ&u3EI)z#J2)m7Ei z{U*b>q~H(o;nK^|{d(U$ zX#b9PHikcue?9!MqNZK%-FS(gmp+t|c)dPO`Zxc|FOGk$Gf0{Ig06>T=BdDbOKrSB zpCQ%ov8ew@SYD|&NMG_jx;Sa0==-FgP34h(`O<8`r^L@7xdg4#ZBILiOh!SLwdeSWU zFbLoY^OFR7DOe0Vn*Q>}pfV{{Xri;|`G}ax1W_I){@x=5jtDVGBL&@dL6ItYmjD|m zMsS70`D2rLs}>py()&y6n~%QdqR6i&kMSsuncLZU{??}479W? zABhPZ2s22bVz`GzdqlWF+AVl}CF(Z4ftQ2_#ZMfe*hPc_SWpmSkt~+2sj`QU)bX(q zHIdV%Em~YuJa=00oVn9xKT@=C2KSGg9MKXxtLTAwd|KqoVM7)!oOX9{@goZt&YZ!E zqNBMtvXS?X8qF`X8_u7JdYS*$Hi^eZcXm9SDaFSQSyDW0OwmI#(QE!fR`B@fnTzMl zpTP^Fqx}mXDVaC3YD)AA`UKNRMKt40#f0^KO1*Ie*BQE78$+@7_%!Jhs5N^+lzNc9 zHD05S@WCHY`51liTa@9t_~4CW1U`pl_%zIzu5=jYga2A(RN#X*@(TuoRqa&b)96t< zE%CvxRz_zwAN-|aW$-mV_(qkF(+98d;Va`KtXgNc4-wm{Fg@UdFHl#e&Iezj3h}cK zK0@Ua;n#Xej0!%T_4R4UP&=4>@Fm=w5EpM!Tj$)?x*#DgxIk?!<2@7N__l^H!YAz+l#oN@@Aph3lR`Z@{EmK=Fd|ESjQKG>*L(y1)Poq=qG|>m2 zF;=0s_~30SpCvx{N|lez2VYm9@Zn8~k=B_?+37>$R{L)A!Os|_&{z84>r~S`;EPxJ z)cN4c<|usH83J1C&9jxSP3o>I*uwvn)ZH4fNg=cNP^~Ue@JoE~#?1=e=7TS=D)==% z_%fBh(+9tJk)Tg!9-oGwZ3?3%AN&$t-af;sPO5KU>p4ZJ3LoZ!KQdKeHqi&~QT=v~ z4?bd+LchcZ?^f%)AlYnHjYPv~k#33V+XsC5R;%sLA@Ex_SoK88gY#{`5M+7>o8WRvFWGsQie;YCQUAm!PrSWlu!= z6+LrV1U|+U!GFx0Hn{@^Ps6v^c9%WJeV3hjbY!-1-0O8%SX0(zeU$4vuQ#rl&I3B* zAbY(&#--7&1g-l|Z+0_{X^=g~Hi&QN9n;)Tqc3)%%`>R#i{8nSG>M<>Gf7&)hh)u> z?&R-eomJ;Qm~Y7L@wYU4D5k@h?NG3Qtd2#b*aNh(JHf7RE+_Hp*{=o~F%jnJ&mDd1 zr8oKG{klocsyF)0mxA;BNqsS{9NvCFVR&xPSB0z1avGG@5Xhez5Ie}Ym=!{AW$d5% zGW6A$YHBBRT6DwffB@}Y(~}^`ApKZR6Jv!Ks8-kE4rohqnOE~e1JbgAYGk%3d(WFt zTmX}u@vK_l+)?&B2^Yd-2Hf-jlNiGC4>Mpi?>2CFW+(JLb86z@{ibO99VowHiw0{} zdr|Li-z?e26=Ol9c-tWl76XgbnB$J-TL-oe%tU$7^ho~2z^>U@C?A_{#KOe7bRBJn zU#JlX*y$&GEbn$#a&W1iU1zk7GY{wE?)tbrDIg~| z)}CsKwRgbCWL(dpC)wXq{BMIgcRpUq>^F*;JrOF1!urJETlCaZ+@p(mUWao3xkY{J z^$GmRK|QPq&l@dFw#G^q%5QoLsfR|XQn_YA!s%_Jp0Cj*JZ}Q6jgjHTx(fW*YG^%r zQ2?`B)1(XLKfQ%9>WI`n4DHS~QO`4rNsfkmDSm7_lUSifpX&7%+KhMD4!w;5oTZZN z2IDx0Mzmc%x+m>mJ{GwmQ@%anpJzqjCSSAWG>EV)@L~S3!Ue&>ORnHO=+}np3i`{ zf&M6XrbDtub|7EgG(E_^aeA=5yfoDAY@@GmuJW&N1_V`{Qkgh&c)BSu{!5c==^UTA zDF7w}^VoW?SvE$u&D{J1pK6M=n%c2y811;H@ihgq%zBV)d>CDVk}@~_p>*BaN$Ij> zkXil_R<$k1EZ4(YD!}TOC?;=y)GT+|z$!YmWpW6t*EtF6(pKTSN#$z}u#MZ+4%!0W z3iSVFldb|{Su<%cl4t87lVG~#JChh>(^->z=5>8V^B_-|<%?K2=Tx{$7^}AEOtLey zDT~y68Rq-RmOS*2an0Cbl7EO}@{Imw`3DGRdCw$Ihx%uXLp_nn9iaY86xn*Q>Y^=H zlN^sm3y3{|kO)K`5WWAz<4qK>V3)2xRduouRzrqxMIVz+ZR_ z7@~zmhuLqP{rI52_EI2?o$#pBhIyhm!vPW5A7NsP%w zh`VoG^ExP)r9c1=j10^gS)GVEb*W%PuI2`ffd+N(sX4I^?D@qDZ-{ce0`y1(;xKe| zXRw<4P$qlTMVn>GXqHJviP-jN%DxwEd&yQskdAWYplvAnGqg=W8^YLEn2&6_r0{+c zZ5#NvIf*fgPX4Q%;@j{l%d~9Bd6eBpa5geXUIqWsblf>Zeyl^9sH1}+cOM=EF zMsWF({|YX@@$eyuUC+o~$7T5J4(RLf3X^>%Eu0g4$GoS zl-T*6;|qo)n!iN%-B{6;=pqD;Wz~Bz{2ut|2H>2rP1*bIHOYtvWqVe^FNzKJy%>Tq z$-W6n9>D)Sq_5S_EKg$z=g0;d5ZTP_SmD#?%$BB%cei7G+&Xw|bW_%Jbr4SsY!LG9 zg_8Hc^OgYbj%mu?3+<7u>=|K}X(f%o?VF?wy5}VfYLmp^G;jnQ?+WIKjjft5AKG(H zqe(7`WQCK|acwcmxTbbZS^d;;-BGQ_y&HH>RO@j^0A~Vj-&A$nS7@@j=5f#P_W1*Y zem2SGwydxxFUrp_LF?W)UB&Z==cGc!u0vgQY;_by+k-YzxDyg5(rE3PvMtbtyG>J; z4barKDNE*G(f(pWs&O4% zy}5kqi1ei5Cb&FBjJNV-G*w@vx_;WR6r=tqcaCsMqpHj!ACshydF`n5JYgoi8QwH%6z00Nr22pUwQM(fzw)kLxF@ z9OEB{=$9wwRM4(+6lEHazD96EzGZ)q_ZyQhP2|hQ%$M@`g)y_GSbpE#--VPJjRWlF zjwZQ|n+sAT11~CABwgo63%&_%z(SibhqL^(amRIrt9;@3wYXynFH8t2(E?%;TP_CGWyFYXU@ZxyCiu%i5hn<&Cn3_;|Q_t)hL0;_k6a0mWoXkFg$4@Lx6wM8P z(cIw*-!bv=L6xGbhqdbJ1@{mH1uRw_+ng^}far)dNmgu;?5S?aewjaXUqYk+r)do~Dr_OHS%O=MKhk$ctFsr%2%O{s6 zi-xRAaJuW>J`$8i;mN5Re2kpb!_8ANrEmBnQ_=zjVf-b&eoBJ0m)B0&+qRNCBh{!E zT1mgeSKa@Tw4cXMeILtcQI_#2|8{DxUX_}PNF`}4R7C1|24kPcf}OtZt@h~ku7(tB zGTb~Z&N}I$*HNE>z;ex7T@<32crzy~Mk`KO%ZI^UFapgrKp!Qou4RrS$c^-F#WOA%0IwXrFs$NtHt>h^4wt+3sl@T zE)_?O-h`GPfvHd_i1$pDVkvOfQHEM7$p&G2Wz?SPQC4La+UwAMwKx!*gDM(%QSk)n z30_P*`s~dUyP9IQK-iAA7}LCug&O@9P?LH&H%xy z*B|`BnZw(ZrIB1LNZ=azo|(DQ8UFdK_HoCvTS}j53KSH7@_w@hshvzA0<{~RqWNpH zdPqCaF&$QB3lY)8M8Jc9@qmW_;{d+~q%e8&$&V`#WfJTc zLzzs@(*-)Q#9~iJ0Hpo;6kqT_oL{>O-Z(yQ?sNV@W_fKRzcx49f4@n#Uf@~tHvY}k z=yiMxesqf6it-thDJ1U{xG2{~;FgUu$-kg}o%=u3L-#T|K9nX6;;%h0A#yRAY3jcU za=ojpN_udC#9x`8&~*=*j#Dy=gyJ%U>r{qh(Vta!Hssb~pF(0BfTTGv{V+c|KeyeN zzaw1&m8}h{j_$&0vl@AN$+Lc*Q2Y11ret1wbl!r~lOYQ(|=vb{DmOxXS@;h%>FlcDW?=<5m*TWd~84^7yw>Cv$ zbEObgXkbz#$tGEs^7Ux{2~rs)C=^3~UYGTJ5Qa4*>1zYZ_^gE;{2}23jr^sB-9v_h z*bZj-zw`YI@9p1{W+c=S>*|g&^$)-_mIB9YI4MFuPT5+PLBHMH?M=jDnlx>>}jVAuoBa@{Pe)5qAt+UbbUC0GrDx*k1Luw*uL(=dxK@us)bV~#i z=Jh=K-U}XNax}PE8C;zF2jb{;68QaSr>OQ8p!XBqR~QSsLa2QoV?)Z8SLVw%pY*S| znJd`?l5#38jt{7~sMonJPY$fO@-%~?NUp2JK^4qklAnPfKXzuaKW6$+gM2xMN zol*9R*;xbFg+2MK@M2q&d~qnNmgfdnL?F|!hTv4zkrhtFsDxwsTbES~H%a6DOmY)= zS#-DXThVM&jwm^IDKytXGa2Qg0G!*K8Re;r1}a1{ zh-8#oG5T6zG+m{+0h*;K6OWD1xwr>ojek%?xinW-!48<@>$CM0H##u+Zmb^#v1K?x zEK}EdnN`PRa|#C3n{Wlyl#N+_Wr8nR+T&)T1?UA#47X626{(zNWyZyW z5fh*RjU92qGv!8GNBrt_Jkc9RVG0EM@?qwzEOlGHJWbEe9YJ~Z-h9~;w;>^gu?2a0 z^R>LF!fQn_xa~BsKFr6U{z{OhyCDdUk(V$IO+bP+H1$e))?coNdJ8jepSmzMT;7ne zHKC&+19vSg2ju3;C@T#~t4b@{5NLkyk`=>wO!83-M;6j*H8JmcEL=ZuYQo)w5q*yS z#45gT!{kRmPrI-aCQUr0IcC|hnnB>Ofp;LB6KDJen1|& z3rr~Q^O>VujurQ{439y%+tRGc0^vMyVv5a{!C);O+#MY2jP+?@F>cVBKx@-kZb^q# z#ochUtDIK4V^j9^MI$OwvD)Pz-h)JxF6~buw=lIZM-!PN+OW{Kn%)^m=$9+2T*(&Uhy7IyTWAtr@f<1^Y-;TRP-YHietlhucJ5i2ai6+vD*g%<*nCHY*d6#z*pP6Fl$_3wzc1Z%b-_(^;VNXQI1i5-kW75qS@%&9g>qfFI3gn9ZYQ? z{8rQru5{EH=*WvZqdZKMqg)+PHi>e)D;4Fwq8#f=MtO)RN4pYHju2&o%YbsaN&`X7 zhoXTX2KAe;8N%Vc2;+BSGbFz=UiKmtupL?yWE)47FhpEL4-s); zE7hvATbmJo<&aJYM{1_432kkzBiFQGosn}2h88%kNv7MRMAtzG@|h4S+VwfgH1JPq z{ZrH_MI%Gpi}G2NKRj>6tRQimD)C`RO9$Z{mGX9Zzqux;FQASr2~xXeiCIe#8U9c zM%j7_1viqEh7Jt7N0e(RF@O&)srS~C~o2!@D9f{`$(tgT&JCd38# zCG?#Jx@LdHpu@rYBKX-Fyft(OkI9-VC}Y}9LeNZqKynBnnwi>^gmf@Ek^u4Ol45Exj@4|KSg*WxsmP1(~<%5Xog_QqU0$Jfpy&5-LLP@Oo6pbyPXI~S-&5&faS^L*%vV(<2 zp~-S`xyF3C9_NBxC>tCkfOO6;V&b*b8LV(G>}^^QyO0WjQkdafQI{fCcq|NCUkmlS zq5h*0h*m9dP9FSRV$1_)v7v!2Wtw6rWSZaee$ORZ_vy^n>h&yrU%Q-Z<}Nr#V9C~E z3ChD*pNUV?UW`N-vEn#5&=NSOx88~|ky_GPU&IFr!K5|!ELLbi`FbY9%~e2!*Be+- zh5qD@mN`%a_)Bl$kpweYTV;9FAQC$;tk1@2XyEOc;A+sUSdZr;?U=j_dpVfYULF9g zxA-|gQ7n^ndefnt8wM9;jkI+2Z4A%YsLJ*2G-(b(N==uJq+Dv1391JtQwTL<_ z*x=h2%sq%zFUI_#^JZG;TxK{y$a6GH#CG?SR^9<#fW^MK< z8tipgAf4r!T|;%B=_+$^mZLJ(gcjF1rKL+GG`qwNtbrFnmP%SncO7n zFWdwtqW$9(m#D`jfaU^w9=_!QMfbD9J+ORogVYCDAl6Kv%pQ3*wJ!q5zVI&9T_^M zB(yBMAss~^+i`CedC_KPr3b&C zpwY+SU8DuV{rR(kn=f#Q0%w&~I+69nyODS}_Ds~+?;q2s9Uz%L)@xVjg+;54GwGpox8w}OhAjp8;x zZ&Lg`P2I_~EpQ-qt(Jany4%Nv)!i)(OG~>O8RC;Dw{r75t9q|fq!7^^%w?1*n3JE| zrnmI-TU#H++H-hz@>hQD9L1`gunkQ(C%lhvw~S7)IVYZ(&nmbFkCd_X(PbYU+&W^b zE1$;--Pr00E6M<%Vz$sJ6+MnXzLhOT^}d5mS!o83`zTF;NeC_SfnN$;XRNJ zXKdku-|N^p?aD=Li%}+dUpr-cT$aZQ*C0;N_85h2aXQu!I}}ccQLdlKUZ6eWqpaHM zyPg)Pvt_XGEWABf>;nS|Hn#sBEJUopQ~LiaR#@#THsT&a4HTH|ZF{4+RiH>fph#>E z6vrUQ?SVpBGtbQ1V}cVKj-^GMu;`H%u|Qlb?e*3y^23jLj_WEYV2~RGt3Dc!L4t*g zM7d&7mP9$x6@@annFq_a3uTH4oOWp@8%I2v1TB0TlL!ROPoSM3aPWQLbXFBP zT4hSen`aclToosy{=M++1lJXmKL@@9{cMPO+5s>VK}b1MgK-Lz&l3+k2vJI!r>xfRRW3n2O(Z=0R#lV^UDyKa1^jF10NQJ=TK79PABauPF#oju?rG51MDjJ6-1<+ememd zlkxir>smBa(hn$z(M-&Pn6#X`8-&iw%E{eLK>+s@^pt9$s>i9&BV`g8jv>^d(T@i%QMn2cS z#3Y;agO7;^)^{Na0Y`O;!|wjK>b60w=6(Ef!aW$jwt=r%URSRotdv8&uG~co!il2==@uks-AtLK~Gj-fM%X) z#Vg5m2TcyVp4{rK$%H?SUIzmAS;4H1n9*`HU=!AuNh&iU_5(x8m#9o9dOqJ=f!Q>x z+`@l#b+DSckcC9K450h~(;?3#<4l2ZlK5TFlf`+it0U_n ziRk#2>W&abLY8v`eQ15=gN{6x95xyK(bqaoi&3Y4@;Y)sU}|fwpdTz+TJF+})v8-b zv-n2fOf3Q-(nQ&VQvqde7*fhgD!-V4o~H?qR%tZ4_$n6Blt8LR$6Sr~rZ(aK-QUGQ@r#a*c1E2<_k z(4Y3PbgQaPcc0ty65oByjk^E~X4Nw34M2afk0G;famH(m@_XPFXiq991A5X36EB2al%NG-X-QC4OU;0i(c zIe`yw1)@y5RuQ06TmVvh!rdEL3}VXruXt;oK${H*McVHd!92;)&tQzK$Pj78BR2xStG+O0_vsV>Py!A)xRWaU@J%V0epeB`a6&~yQv_W$U03_$$` z9FF?zMg1daYKn2I!H{BHFED=t zW!h8zz>KunD0k@zE(%HI5Q0L{m!Rd7`N<7wue=#y^|aUacASSXHQL)L^Zx=rz}WL& z_jWw#!YFj8BlER^GevVU>m$IA!Y^sD8}6j-`tNv-K@!sRXj(ThW!hRTN)WwuyJv}J z)eX2-u=%szH^8{%{!aHzc66i#`vZFUU-t6ywcbM7Dd}W55d!u?e=6UD@^4Uq4(cmq z)~4(nJU_tMRoN+q@E(yD#3LCWxB{CwbGG?jPf$-|NCGq#=_A_jAaFrNl;OEYqhxER<-iY zbKaUxC|mG|SR_Okcr~;_*AJAG>d{83E{AaRNY6JirQ#v;Uulq*Ybp9#uU$ku6){d% zLF-9(7%lv>Svw5j?*?uIj1ud89Z`h(R6}rbN#%!Ji7p$2xGJ<2<)X*G%5NzXT~7e- z68J>dV<_(xAF!>BL1iJ39RP0`n0Q)KNo%SlnPVX>Y2Y5ro(AG;x0P?i1F-wPQ`%0z$2>IX4EAo>-fKk=WtWOmau7JANk#anm={HIBQg8zQM2@Ds>ip4(!c;PfQphj=+IsKs; zsCLeAZ#AB3#C-w$V}SUnpQ{+NoCXcx|9A>FVV0Y)EX9~5;hYe1KL$9$rR{Nk44*2) zc7v{}plYMU6KXQ}AJtv>shXs!Sv4UNckbB6GpdYy*v=AOvLlm6?M$pXwsVJ`mwnKM zfA~Rxe>fPl;qf2#-~}HJv<9JubRX9)3_mxZAkG;6_mn+~?~;=*+IP=CY>NJD^4Rj| zal__xjBuq-irBPiRoF@?(?EJ&so^_*hGMC-4;rE+=e)#UX$5!{OyLRG@jUP)d2blSA|IyaQ9<^=9WGo!K z>!GVnYyP?Gqp4>qf8FtN|IXt|vK}0NCH!CKQZwGEy)^R8@vFc4c);?K4T(ATt}7Wm zBriN-z=AufSFZlD`|`*+lLsXY~MSoq52IR(d)tZyt>^DRGX|Ie=Kbu(sEzWnjZU5y7~ zURbqc!IDuHzX^8?9UCxg@uwYK{d+$@cKwjf>u1cUy)n-3gFUW}BXf&>em63>ZuzAS zDIZKJy>HIQU7bb_eAwcQe5p(tlDss)(j}_!+}^U}N4IBhXw%s3-O`)~HqP8^@atvl zSP)TgPse8>V`gr&-eDeHb7^e4|IGJwQC+7E{~_Jed*#PFELXamYy8Q)VW{q-ElrO7 zD}(xUI#u=jvh@$2zx(RssK@TDcxmvbvp;`0Vb){s9p@9G)=v2C<;kZr-hKG9`G=pF z`s6EbovHb3!J6ZbM)lwQ!H(KT-fZ~y=Eti3oECFtc;=h4|5NpD)T86Qvxhu%qeDOI zzu$cE>zaOnk6(V^z3gw@cw)I>O!lK&282}CM;!P+sYLyN0|-ogVOuZYN5CE(v$7!kF5pgBb;oDD-cx`_0E6IP zbDr~hhXF?5N2@OYZhpb*bpy_O$?NS18+O0!^-cjivfk_640r?31Lk*b@Om!+&I6=> z*8UJM1MnbV9^iSviGX1UCi8T-B+Ed-2E-J=)qozrZGd-{d%Xt%Er8@AFKqOBO91}~ zxEwG7e!2~C3gAI%-|Y4JVFFG-1E3qw0yydoOaSmLz-qv-EnaVLOe6!a$%?`#6vE(p z1GgbM0p9th*ZVc#TYyb~rnkTl{&^=toe41M9j|u|;9J|#4p>m-^$vs|dv-trfTMOo zVEk|5c|apz$u4LT@CINBpc^rJ4d4s-^?QFe3I}m**9aK)k=GlI|8_b5F(d~(=!QlB zBR<7IfQ_F)_4rTjgNIQMY1pY1eEO%o5;FWSBsyt|#pGEYaDAQpolkQD$R0iA{K}_K1w@bq zZst$yPYB3B@vY5#Es6yw8sFgW?@z<)gc$qb4c>sFlL)r(kk3{HWRQVY@U@=}3RsL{ z*qi*j&(;qmGi`#I&cJYNe4B`My7khK@4jtARnm1|wCBNm*AT+2v`+{j0&{3bpeCYy z-#h&5fwTY{ipF0KeGb=+{O;SsV)$WTKMFLB@A0#r=Y-IDtU+~oHQ(`hdWZ$pgQ#Zg;7|N(YCs0O zA>w`h-M`YTb!eG_>OMHhDHuP*u9SwX3tJzW%R^QN=e!#9kH8U*fHnTQypV6dJO1_2 zV~3B>bS8zY)xYLv4$UJl;h)m$I^DTb-%LAsqTn^Zwffg}|CGjuocbm=H20fR!$VG< zFo)(6Zpk;NatNAFeKS_ni$R1o@mEJ6Cp1s=14ZtMlQ|kQRC7=jV^YUaf^>o)9ed*B zH>b>^iR2h@>YFaG-wg6_c=W_%zUqr^R%(H?1nwnL-R_eo?!nmF0J<-T%iUUa$jK99 zsC@T{lS5iiL8KAXJ5NkW_lW=n;_p2tP7b9W!%m#cB{)f$wfK8)h?P|EcTpKd0|`OI z;EM%v9RB7&sq|O3Qvvy+Wt8}<`{BgNk;Ik;14%Caww&}*K{a3eRrHOeq%bfAYie5N z<(&`q9J?CjDW!1awql(vw8}ZOw!_;r`q66BV$&d`Vf}mhHkP5^ef!O+6DPH0M>ld= zvXd@$uQ#G<`@z{6RqlgJqe8UzIpO_HX*b8{wympLc=IX$9PPbK+IySOTYNOU_I@S} ze_)GJQs2YGW=zNXzhc{IZ&_-Mj?~_xq`mLxlB1_yii^}K+b9$+D?NvGXYF&FpPNqgb%kf~KG*}u-JR`K1-DoejaoB_L);IUT_Tk!_X%K|5 z!Ho@z<0X=xZp{`)dJxv3a*JbJko0hfMinuJwBd*dmc|8jHTKNxp4lC5Zj#b=z7Q;h zNh7wcQ%7$B^eh~EY72x~)U!5Bd);2kRy}LW3f^`!gh;)`rx-cmyzHFp2673cAvEi#@_(i4T0%+nr zYV&ex!-ozt)I7tH8jj|Pn+3M{&(~^mrDJTklpp`YD5a$%f+Ky>0jYO{V>|WMTx+q? z%J6ap(Y)GGPtDr;QD~*ly5`=IZJ>gVj;?K_9`ShvO6y7mu-{awI>!Q{%5Xf_M#}G6 zruu_6&3Q;1NRsmuu<+TYj`4R#WLqiDx?XLroTxN6Du8{c;`dEZ5a(4qeySkYRo<&0 zmZAIpp~`De@C*+Z1*19@PydWYpVw5pd%RNr z8G_KKR>k8N0pjxl>h!@Q4@IE+mHK9t5B>#H;1wT24qv8rNc2-0W=vN)%uoR9t>Wuc z{2CR1kBToTRuIco{2~>vy&6u#zo_DEGZeyo1Ta2(Q*Fqb*`fi(FI0TQECoMMopFPT zFHoa|mM>pd@!H$OPN_3)kIajfrsP3|&(|uxJMj2-r%+ZfPideek3OT-4qANkr~{X( z_{ED9I+4<#xKqVz@or+W(*B2vZ|tYk3)O+?z(V8Z4PZS)i`X+!Ix1@6EMl9|LHn!W z4ci=NBc)Doh{$&E_Ws}_u~;@NSP`&`qhC8ICG{Q^T@t3CgH$&6tN103$JX>-@f#9vZwM>)cW}xF_l$0EK z;BA#q1u2f;Xep(qZA5EyIuu3A;)}mi#aBA+iNG(FMg!f?@ zZ>p=U4zg11W^()jF4Ag8WQ>%eoAI`zR}5A(#c?01T?gVP&@Dezf>~SUi)R$|dWS2ZqXPOUV59;jC}6q*77O72Jd*V^^pBF>Q1H7Ia7+QG6>w7l!H#kR21!yt zHwEM>V7vn62;j(whotKjRHXtwQNZ^Km_{#Xm3~($%&{jPd?OW*s(}6q7@>fP3YhQM zo&d^aO6_F@I0cB`g`;&ln5ge7SobSb#}x3p0+_>`D8>1Q;etn5j4lddKr>>Df|v>f zDL6`c$RQ{S9U{X+rU1chUU}t%%^r&uUuZ~iv&M~2r zlzOOq;;X5-rOJQwxn)*miUHBSxmlICRQv;&@(N~HH z(Lx91mwlzIc3QTo!B4^+)B8%@BeiT*g9jbueWf0e1#c@cL4%Du>-$Q(CCTC_?~eq$ po1-2e+@K~m@gRQA@wWj|x8RkjO5|wgC>kJT>(*vE)(((5{Xa~ip&9@H diff --git a/app/core/engine.py b/app/core/engine.py index db252df..8cbe24a 100644 --- a/app/core/engine.py +++ b/app/core/engine.py @@ -1,4 +1,4 @@ -from app.core import rbac, abac, rules +from app.core import rbac, abac, rules, permissions, tenancy from app.models.request import PolicyRequest from app.models.decision import PolicyDecision from app.services.cache import PolicyCache @@ -22,6 +22,24 @@ def _evaluate_core(self, req: PolicyRequest) -> PolicyDecision: policy_source="RBAC" ) + ok, reason = permissions.evaluate_permission( + req.roles, req.permissions, req.action, req.resource + ) + if not ok: + return PolicyDecision( + allowed=False, + reason=reason, + policy_source="PERMISSION" + ) + + ok, reason = tenancy.evaluate_tenancy(req.org_id, req.context) + if not ok: + return PolicyDecision( + allowed=False, + reason=reason, + policy_source="TENANCY" + ) + ok, reason = abac.evaluate_abac(req.context, req.roles) if not ok: return PolicyDecision( @@ -53,7 +71,9 @@ def evaluate(self, req: PolicyRequest) -> PolicyDecision: req.user_id, req.action, req.resource, - req.context + req.context, + org_id=req.org_id, + permissions=req.permissions, ) # 1. CACHE HIT (sub-ms path) diff --git a/app/core/permissions.c b/app/core/permissions.c new file mode 100644 index 0000000..924869b --- /dev/null +++ b/app/core/permissions.c @@ -0,0 +1,9297 @@ +/* Generated by Cython 3.2.5 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "name": "app.core.permissions", + "sources": [ + "app/core/permissions.py" + ] + }, + "module_name": "app.core.permissions" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +/* InitLimitedAPI */ +#if defined(Py_LIMITED_API) + #if !defined(CYTHON_LIMITED_API) + #define CYTHON_LIMITED_API 1 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef _MSC_VER + #pragma message ("Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead.") + #else + #warning Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead. + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x03080000 + #error Cython requires Python 3.8+. +#else +#define __PYX_ABI_VERSION "3_2_5" +#define CYTHON_HEX_VERSION 0x030205F0 +#define CYTHON_FUTURE_DIVISION 1 +/* CModulePreamble */ +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PYPY_VERSION_NUM >= 0x07030C00) + #endif + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_NUM >= 0x07031100) + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND (__PYX_LIMITED_VERSION_HEX >= 0x030A0000) + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 1 + #endif + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #ifdef Py_GIL_DISABLED + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 1 + #else + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #endif + #if PY_VERSION_HEX < 0x030A0000 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #elif !defined(CYTHON_USE_TYPE_SLOTS) + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLIST_INTERNALS) + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #elif !defined(CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS) + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #elif !defined(CYTHON_FAST_GIL) + #define CYTHON_FAST_GIL (PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #ifndef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING (PY_VERSION_HEX >= 0x030d00B1) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5 && !CYTHON_USE_MODULE_STATE) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS (!CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif + #if defined(CYTHON_IMMORTAL_CONSTANTS) && PY_VERSION_HEX < 0x030C0000 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 // definitely won't work + #elif !defined(CYTHON_IMMORTAL_CONSTANTS) + #define CYTHON_IMMORTAL_CONSTANTS (PY_VERSION_HEX >= 0x030C0000 && !CYTHON_USE_MODULE_STATE && CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif +#endif +#ifndef CYTHON_COMPRESS_STRINGS + #define CYTHON_COMPRESS_STRINGS 1 +#endif +#ifndef CYTHON_FAST_PYCCALL +#define CYTHON_FAST_PYCCALL CYTHON_FAST_PYCALL +#endif +#ifndef CYTHON_VECTORCALL +#if CYTHON_COMPILING_IN_LIMITED_API +#define CYTHON_VECTORCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) +#else +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL) +#endif +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#include +typedef uintptr_t __pyx_uintptr_t; +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifndef Py_UNREACHABLE + #define Py_UNREACHABLE() assert(0); abort() +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +/* CInitCode */ +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +/* PythonCompatibility */ +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#define __Pyx_BUILTIN_MODULE_NAME "builtins" +#define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + #ifndef CO_OPTIMIZED + static int CO_OPTIMIZED; + #endif + #ifndef CO_NEWLOCALS + static int CO_NEWLOCALS; + #endif + #ifndef CO_VARARGS + static int CO_VARARGS; + #endif + #ifndef CO_VARKEYWORDS + static int CO_VARKEYWORDS; + #endif + #ifndef CO_ASYNC_GENERATOR + static int CO_ASYNC_GENERATOR; + #endif + #ifndef CO_GENERATOR + static int CO_GENERATOR; + #endif + #ifndef CO_COROUTINE + static int CO_COROUTINE; + #endif +#else + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 + #endif +#endif +static int __Pyx_init_co_variables(void); +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef Py_TPFLAGS_IMMUTABLETYPE + #define Py_TPFLAGS_IMMUTABLETYPE (1UL << 8) +#endif +#ifndef Py_TPFLAGS_DISALLOW_INSTANTIATION + #define Py_TPFLAGS_DISALLOW_INSTANTIATION (1UL << 7) +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#ifndef METH_FASTCALL + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #if PY_VERSION_HEX >= 0x030d00A4 + # define __Pyx_PyCFunctionFast PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords + #else + # define __Pyx_PyCFunctionFast _PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #endif +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_VERSION_HEX >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void (*cfunc)(void)) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if PY_VERSION_HEX < 0x03090000 || (CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000) + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#elif CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) GraalPyFrame_SetLineNumber((frame), (lineno)) +#elif CYTHON_COMPILING_IN_GRAAL + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) _PyFrame_SetLineNumber((frame), (lineno)) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#endif +#if CYTHON_USE_MODULE_STATE +static CYTHON_INLINE void *__Pyx__PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#define __Pyx_PyModule_GetState(o) (__pyx_mstatetype *)__Pyx__PyModule_GetState(o) +#else +#define __Pyx_PyModule_GetState(op) ((void)op,__pyx_mstate_global) +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE((PyObject *) obj), name, func_ctype) +#define __Pyx_PyObject_TryGetSlot(obj, name, func_ctype) __Pyx_PyType_TryGetSlot(Py_TYPE(obj), name, func_ctype) +#define __Pyx_PyObject_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#define __Pyx_PyObject_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype) __Pyx_PyType_GetSlot(type, name, func_ctype) + #define __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) (((type)->sub) ? ((type)->sub->name) : NULL) + #define __Pyx_PyType_TryGetSubSlot(type, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype)\ + ((__PYX_LIMITED_VERSION_HEX >= 0x030A0000 ||\ + (PyType_GetFlags(type) & Py_TPFLAGS_HEAPTYPE) || __Pyx_get_runtime_version() >= 0x030A0000) ?\ + __Pyx_PyType_GetSlot(type, name, func_ctype) : NULL) + #define __Pyx_PyType_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSlot(obj, name, func_ctype) + #define __Pyx_PyType_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSlot(obj, name, func_ctype) +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) +#define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000 +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) +#endif +#define __Pyx_PyObject_GetIterNextFunc(iterator) __Pyx_PyObject_GetSlot(iterator, tp_iternext, iternextfunc) +#if CYTHON_USE_TYPE_SPECS +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#else + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && PyUnstable_Object_IsUniquelyReferenced(obj)) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#elif CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +enum __Pyx_ReferenceSharing { + __Pyx_ReferenceSharing_DefinitelyUnique, // We created it so we know it's unshared - no need to check + __Pyx_ReferenceSharing_OwnStrongReference, + __Pyx_ReferenceSharing_FunctionArgument, + __Pyx_ReferenceSharing_SharedReference, // Never trust it to be unshared because it's a global or similar +}; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && PY_VERSION_HEX >= 0x030E0000 +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing)\ + (sharing == __Pyx_ReferenceSharing_DefinitelyUnique ? 1 :\ + (sharing == __Pyx_ReferenceSharing_FunctionArgument ? PyUnstable_Object_IsUniqueReferencedTemporary(o) :\ + (sharing == __Pyx_ReferenceSharing_OwnStrongReference ? PyUnstable_Object_IsUniquelyReferenced(o) : 0))) +#elif (CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)sharing), Py_REFCNT(o) == 1) +#else +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)o), ((void)sharing), 0) +#endif +#if CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRef(o, i) (likely((i) >= 0) ? PySequence_GetItem(o, i) : (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) + #else + #define __Pyx_PyList_GetItemRef(o, i) PySequence_ITEM(o, i) + #endif +#elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_XNewRef(PyList_GetItem(o, i)) + #endif +#else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_NewRef(PyList_GET_ITEM(o, i)) +#endif +#if CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS && !CYTHON_COMPILING_IN_LIMITED_API && CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) (__Pyx_IS_UNIQUELY_REFERENCED(o, unsafe_shared) ?\ + __Pyx_NewRef(PyList_GET_ITEM(o, i)) : __Pyx_PyList_GetItemRef(o, i)) +#else + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) __Pyx_PyList_GetItemRef(o, i) +#endif +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyDict_GetItemRef(dict, key, result) PyDict_GetItemRef(dict, key, result) +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyObject_GetItem(dict, key); + if (*result == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + return 0; + } + return -1; + } + return 1; +} +#else +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyDict_GetItemWithError(dict, key); + if (*result == NULL) { + return PyErr_Occurred() ? -1 : 0; + } + Py_INCREF(*result); + return 1; +} +#endif +#if defined(CYTHON_DEBUG_VISIT_CONST) && CYTHON_DEBUG_VISIT_CONST + #define __Pyx_VISIT_CONST(obj) Py_VISIT(obj) +#else + #define __Pyx_VISIT_CONST(obj) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GET_ITEM(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GET_ITEM(o, i) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GetItem(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GetItem(o, i) +#endif +#if CYTHON_ASSUME_SAFE_SIZE + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GET_LENGTH(o) +#else + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GetLength(o) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_InternFromString) + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) +#endif +#define __Pyx_PyLong_FromHash_t PyLong_FromSsize_t +#define __Pyx_PyLong_AsHash_t __Pyx_PyIndex_AsSsize_t +#if __PYX_LIMITED_VERSION_HEX >= 0x030A0000 + #define __Pyx_PySendResult PySendResult +#else + typedef enum { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, + } __Pyx_PySendResult; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX < 0x030A00A3 + typedef __Pyx_PySendResult (*__Pyx_pyiter_sendfunc)(PyObject *iter, PyObject *value, PyObject **result); +#else + #define __Pyx_pyiter_sendfunc sendfunc +#endif +#if !CYTHON_USE_AM_SEND +#define __PYX_HAS_PY_AM_SEND 0 +#elif __PYX_LIMITED_VERSION_HEX >= 0x030A0000 +#define __PYX_HAS_PY_AM_SEND 1 +#else +#define __PYX_HAS_PY_AM_SEND 2 // our own backported implementation +#endif +#if __PYX_HAS_PY_AM_SEND < 2 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods +#else + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + __Pyx_pyiter_sendfunc am_send; + } __Pyx_PyAsyncMethodsStruct; + #define __Pyx_SlotTpAsAsync(s) ((PyAsyncMethods*)(s)) +#endif +#if CYTHON_USE_AM_SEND && PY_VERSION_HEX < 0x030A00F0 + #define __Pyx_TPFLAGS_HAVE_AM_SEND (1UL << 21) +#else + #define __Pyx_TPFLAGS_HAVE_AM_SEND (0) +#endif +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_PyInterpreterState_Get() PyInterpreterState_Get() +#else +#define __Pyx_PyInterpreterState_Get() PyThreadState_Get()->interp +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030A0000 +#ifdef __cplusplus +extern "C" +#endif +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_init_co_variable(PyObject *inspect, const char* name, int *write_to) { + int value; + PyObject *py_value = PyObject_GetAttrString(inspect, name); + if (!py_value) return 0; + value = (int) PyLong_AsLong(py_value); + Py_DECREF(py_value); + *write_to = value; + return value != -1 || !PyErr_Occurred(); +} +static int __Pyx_init_co_variables(void) { + PyObject *inspect; + int result; + inspect = PyImport_ImportModule("inspect"); + result = +#if !defined(CO_OPTIMIZED) + __Pyx_init_co_variable(inspect, "CO_OPTIMIZED", &CO_OPTIMIZED) && +#endif +#if !defined(CO_NEWLOCALS) + __Pyx_init_co_variable(inspect, "CO_NEWLOCALS", &CO_NEWLOCALS) && +#endif +#if !defined(CO_VARARGS) + __Pyx_init_co_variable(inspect, "CO_VARARGS", &CO_VARARGS) && +#endif +#if !defined(CO_VARKEYWORDS) + __Pyx_init_co_variable(inspect, "CO_VARKEYWORDS", &CO_VARKEYWORDS) && +#endif +#if !defined(CO_ASYNC_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_ASYNC_GENERATOR", &CO_ASYNC_GENERATOR) && +#endif +#if !defined(CO_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_GENERATOR", &CO_GENERATOR) && +#endif +#if !defined(CO_COROUTINE) + __Pyx_init_co_variable(inspect, "CO_COROUTINE", &CO_COROUTINE) && +#endif + 1; + Py_DECREF(inspect); + return result ? 0 : -1; +} +#else +static int __Pyx_init_co_variables(void) { + return 0; // It's a limited API-only feature +} +#endif + +/* MathInitCode */ +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #ifndef _USE_MATH_DEFINES + #define _USE_MATH_DEFINES + #endif +#endif +#include +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#ifndef CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#define CYTHON_CLINE_IN_TRACEBACK_RUNTIME 0 +#endif +#ifndef CYTHON_CLINE_IN_TRACEBACK +#define CYTHON_CLINE_IN_TRACEBACK CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#endif +#if CYTHON_CLINE_IN_TRACEBACK +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; __pyx_clineno = __LINE__; (void) __pyx_clineno; } +#else +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; (void) __pyx_clineno; } +#endif +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__app__core__permissions +#define __PYX_HAVE_API__app__core__permissions +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +#ifdef CYTHON_FREETHREADING_COMPATIBLE +#if CYTHON_FREETHREADING_COMPATIBLE +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_NOT_USED +#else +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_USED +#endif +#else +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_USED +#endif +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AS_STRING(s) +#else + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AsString(s) +#endif +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +static CYTHON_INLINE PyObject *__Pyx_NewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_NewRef) + return Py_NewRef(obj); +#else + Py_INCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_XNewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_XNewRef) + return Py_XNewRef(obj); +#else + Py_XINCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b); +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __Pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AS_DOUBLE(x) +#else +#define __Pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AsDouble(x) +#endif +#define __Pyx_PyFloat_AsFloat(x) ((float) __Pyx_PyFloat_AsDouble(x)) +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#elif __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeASCII(c_str, size, NULL) +#else + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +/* PretendToInitialize */ +#ifdef __cplusplus +#if __cplusplus > 201103L +#include +#endif +template +static void __Pyx_pretend_to_initialize(T* ptr) { +#if __cplusplus > 201103L + if ((std::is_trivially_default_constructible::value)) +#endif + *ptr = T(); + (void)ptr; +} +#else +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } +#endif + + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * const __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* #### Code section: filename_table ### */ + +static const char* const __pyx_f[] = { + "app/core/permissions.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* Atomics.proto (used by UnpackUnboundCMethod) */ +#include +#ifndef CYTHON_ATOMICS + #define CYTHON_ATOMICS 1 +#endif +#define __PYX_CYTHON_ATOMICS_ENABLED() CYTHON_ATOMICS +#define __PYX_GET_CYTHON_COMPILING_IN_CPYTHON_FREETHREADING() CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __pyx_atomic_int_type int +#define __pyx_nonatomic_int_type int +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__)) + #include +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ + (defined(_MSC_VER) && _MSC_VER >= 1700))) + #include +#endif +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type atomic_int + #define __pyx_atomic_ptr_type atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) atomic_fetch_add_explicit(value, 1, memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) atomic_fetch_add_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) atomic_fetch_sub_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) atomic_load(value) + #define __pyx_atomic_store(value, new_value) atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) atomic_load_explicit(value, memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) atomic_load_explicit(value, memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C atomics" + #endif +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ +\ + (defined(_MSC_VER) && _MSC_VER >= 1700)) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type std::atomic_int + #define __pyx_atomic_ptr_type std::atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) std::atomic_fetch_sub_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) std::atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) std::atomic_load(value) + #define __pyx_atomic_store(value, new_value) std::atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) std::atomic_load_explicit(value, std::memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) std::atomic_load_explicit(value, std::memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) std::atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C++ atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C++ atomics" + #endif +#elif CYTHON_ATOMICS && (__GNUC__ >= 5 || (__GNUC__ == 4 &&\ + (__GNUC_MINOR__ > 1 ||\ + (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 2)))) + #define __pyx_atomic_ptr_type void* + #define __pyx_nonatomic_ptr_type void* + #define __pyx_atomic_incr_relaxed(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_incr_acq_rel(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_decr_acq_rel(value) __sync_fetch_and_sub(value, 1) + #define __pyx_atomic_sub(value, arg) __sync_fetch_and_sub(value, arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_store(value, new_value) __sync_lock_test_and_set(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_load_acquire(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) __sync_lock_test_and_set(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_nonatomic_ptr_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #warning "Using GNU atomics" + #endif +#elif CYTHON_ATOMICS && defined(_MSC_VER) + #include + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type long + #define __pyx_atomic_ptr_type void* + #undef __pyx_nonatomic_int_type + #define __pyx_nonatomic_int_type long + #define __pyx_nonatomic_ptr_type void* + #pragma intrinsic (_InterlockedExchangeAdd, _InterlockedExchange, _InterlockedCompareExchange, _InterlockedCompareExchangePointer, _InterlockedExchangePointer) + #define __pyx_atomic_incr_relaxed(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_incr_acq_rel(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_decr_acq_rel(value) _InterlockedExchangeAdd(value, -1) + #define __pyx_atomic_sub(value, arg) _InterlockedExchangeAdd(value, -arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = _InterlockedCompareExchange(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) _InterlockedExchangeAdd(value, 0) + #define __pyx_atomic_store(value, new_value) _InterlockedExchange(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) *(void * volatile *)value + #define __pyx_atomic_pointer_load_acquire(value) _InterlockedCompareExchangePointer(value, 0, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) _InterlockedExchangePointer(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_atomic_ptr_type old = _InterlockedCompareExchangePointer(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #pragma message ("Using MSVC atomics") + #endif +#else + #undef CYTHON_ATOMICS + #define CYTHON_ATOMICS 0 + #ifdef __PYX_DEBUG_ATOMICS + #warning "Not using atomics" + #endif +#endif + +/* CriticalSectionsDefinition.proto (used by CriticalSections) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection void* +#define __Pyx_PyCriticalSection2 void* +#define __Pyx_PyCriticalSection_End(cs) +#define __Pyx_PyCriticalSection2_End(cs) +#else +#define __Pyx_PyCriticalSection PyCriticalSection +#define __Pyx_PyCriticalSection2 PyCriticalSection2 +#define __Pyx_PyCriticalSection_End PyCriticalSection_End +#define __Pyx_PyCriticalSection2_End PyCriticalSection2_End +#endif + +/* CriticalSections.proto (used by ParseKeywordsImpl) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection_Begin(cs, arg) (void)(cs) +#define __Pyx_PyCriticalSection2_Begin(cs, arg1, arg2) (void)(cs) +#else +#define __Pyx_PyCriticalSection_Begin PyCriticalSection_Begin +#define __Pyx_PyCriticalSection2_Begin PyCriticalSection2_Begin +#endif +#if PY_VERSION_HEX < 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_BEGIN_CRITICAL_SECTION(o) { +#define __Pyx_END_CRITICAL_SECTION() } +#else +#define __Pyx_BEGIN_CRITICAL_SECTION Py_BEGIN_CRITICAL_SECTION +#define __Pyx_END_CRITICAL_SECTION Py_END_CRITICAL_SECTION +#endif + +/* IncludeStructmemberH.proto (used by FixUpExtensionType) */ +#include + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* TupleAndListFromArray.proto (used by fastcall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +#endif +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto (used by BytesEquals) */ +#include + +/* BytesEquals.proto (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_PySequence_ITEM(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_NewRef(__Pyx_PyTuple_GET_ITEM(args, i)) +#else + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_XNewRef(PyTuple_GetItem(args, i)) +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_ArgRef_FASTCALL(args, i) __Pyx_NewRef(args[i]) + #define __Pyx_NumKwargs_FASTCALL(kwds) __Pyx_PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif +#else + #define __Pyx_ArgRef_FASTCALL __Pyx_ArgRef_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS +#endif +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#if CYTHON_METH_FASTCALL || (CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(args + start, stop - start) +#else +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* py_dict_items.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); + +/* CallCFunction.proto (used by CallUnboundCMethod0) */ +#define __Pyx_CallCFunction(cfunc, self, args)\ + ((PyCFunction)(void(*)(void))(cfunc)->func)(self, args) +#define __Pyx_CallCFunctionWithKeywords(cfunc, self, args, kwargs)\ + ((PyCFunctionWithKeywords)(void(*)(void))(cfunc)->func)(self, args, kwargs) +#define __Pyx_CallCFunctionFast(cfunc, self, args, nargs)\ + ((__Pyx_PyCFunctionFast)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs) +#define __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, nargs, kwnames)\ + ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs, kwnames) + +/* PyObjectCall.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto (used by PyObjectCallOneArg) */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs); + +/* PyObjectCallOneArg.proto (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyObjectGetAttrStr.proto (used by UnpackUnboundCMethod) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* UnpackUnboundCMethod.proto (used by CallUnboundCMethod0) */ +typedef struct { + PyObject *type; + PyObject **method_name; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && CYTHON_ATOMICS + __pyx_atomic_int_type initialized; +#endif + PyCFunction func; + PyObject *method; + int flag; +} __Pyx_CachedCFunction; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +static CYTHON_INLINE int __Pyx_CachedCFunction_GetAndSetInitializing(__Pyx_CachedCFunction *cfunc) { +#if !CYTHON_ATOMICS + return 1; +#else + __pyx_nonatomic_int_type expected = 0; + if (__pyx_atomic_int_cmp_exchange(&cfunc->initialized, &expected, 1)) { + return 0; + } + return expected; +#endif +} +static CYTHON_INLINE void __Pyx_CachedCFunction_SetFinishedInitializing(__Pyx_CachedCFunction *cfunc) { +#if CYTHON_ATOMICS + __pyx_atomic_store(&cfunc->initialized, 2); +#endif +} +#else +#define __Pyx_CachedCFunction_GetAndSetInitializing(cfunc) 2 +#define __Pyx_CachedCFunction_SetFinishedInitializing(cfunc) +#endif + +/* CallUnboundCMethod0.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#else +#define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) +#endif + +/* py_dict_values.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d); + +/* OwnedDictNext.proto (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue); +#else +CYTHON_INLINE +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue); +#endif + +/* RaiseDoubleKeywords.proto (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywordsImpl.export */ +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name +); +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* CallUnboundCMethod2.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2); +#else +#define __Pyx_CallUnboundCMethod2(cfunc, self, arg1, arg2) __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2) +#endif + +/* ParseKeywords.proto */ +static CYTHON_INLINE int __Pyx_ParseKeywords( + PyObject *kwds, PyObject *const *kwvalues, PyObject ** const argnames[], + PyObject *kwds2, PyObject *values[], + Py_ssize_t num_pos_args, Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* ArgTypeTestFunc.export */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) + +/* PyErrExceptionMatches.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto (used by PyErrFetchRestore) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStrNoError.proto (used by GetBuiltinName) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* GetBuiltinName.proto (used by GetModuleGlobalName) */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name); + +/* PyDictVersioning.proto (used by GetModuleGlobalName) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __Pyx_XNewRef(__pyx_dict_cached_value);\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* GetModuleGlobalName.proto */ +#if CYTHON_USE_DICT_VERSIONS +#define __Pyx_GetModuleGlobalName(var, name) do {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + (var) = (likely(__pyx_dict_version == __PYX_GET_DICT_VERSION(__pyx_mstate_global->__pyx_d))) ?\ + (likely(__pyx_dict_cached_value) ? __Pyx_NewRef(__pyx_dict_cached_value) : __Pyx_GetBuiltinName(name)) :\ + __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +#define __Pyx_GetModuleGlobalNameUncached(var, name) do {\ + PY_UINT64_T __pyx_dict_version;\ + PyObject *__pyx_dict_cached_value;\ + (var) = __Pyx__GetModuleGlobalName(name, &__pyx_dict_version, &__pyx_dict_cached_value);\ +} while(0) +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value); +#else +#define __Pyx_GetModuleGlobalName(var, name) (var) = __Pyx__GetModuleGlobalName(name) +#define __Pyx_GetModuleGlobalNameUncached(var, name) (var) = __Pyx__GetModuleGlobalName(name) +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name); +#endif + +/* PySequenceContains.proto */ +static CYTHON_INLINE int __Pyx_PySequence_ContainsTF(PyObject* item, PyObject* seq, int eq) { + int result = PySequence_Contains(seq, item); + return unlikely(result < 0) ? result : (result == (eq == Py_EQ)); +} + +/* DictGetItem.proto */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key); +#define __Pyx_PyObject_Dict_GetItem(obj, name)\ + (likely(PyDict_CheckExact(obj)) ?\ + __Pyx_PyDict_GetItem(obj, name) : PyObject_GetItem(obj, name)) +#else +#define __Pyx_PyDict_GetItem(d, key) PyObject_GetItem(d, key) +#define __Pyx_PyObject_Dict_GetItem(obj, name) PyObject_GetItem(obj, name) +#endif + +/* RaiseUnexpectedTypeError.proto */ +static int __Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj); + +/* IterFinish.proto (used by dict_iter) */ +static CYTHON_INLINE int __Pyx_IterFinish(void); + +/* PyObjectCallNoArg.proto (used by PyObjectCallMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func); + +/* PyObjectGetMethod.proto (used by PyObjectCallMethod0) */ +#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))) +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method); +#endif + +/* PyObjectCallMethod0.proto (used by dict_iter) */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name); + +/* RaiseNeedMoreValuesToUnpack.proto (used by UnpackTuple2) */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index); + +/* RaiseTooManyValuesToUnpack.proto (used by UnpackItemEndCheck) */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected); + +/* UnpackItemEndCheck.proto (used by UnpackTuple2) */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected); + +/* RaiseNoneIterError.proto (used by UnpackTupleError) */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void); + +/* UnpackTupleError.proto (used by UnpackTuple2) */ +static void __Pyx_UnpackTupleError(PyObject *, Py_ssize_t index); + +/* UnpackTuple2.proto (used by dict_iter) */ +static CYTHON_INLINE int __Pyx_unpack_tuple2( + PyObject* tuple, PyObject** value1, PyObject** value2, int is_tuple, int has_known_size, int decref_tuple); +static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( + PyObject* tuple, PyObject** value1, PyObject** value2, int decref_tuple); +static int __Pyx_unpack_tuple2_generic( + PyObject* tuple, PyObject** value1, PyObject** value2, int has_known_size, int decref_tuple); + +/* dict_iter.proto */ +static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* dict, int is_dict, PyObject* method_name, + Py_ssize_t* p_orig_length, int* p_is_dict); +static CYTHON_INLINE int __Pyx_dict_iter_next(PyObject* dict_or_iter, Py_ssize_t orig_length, Py_ssize_t* ppos, + PyObject** pkey, PyObject** pvalue, PyObject** pitem, int is_dict); + +/* unicode_tailmatch.proto */ +static int __Pyx_PyUnicode_Tailmatch( + PyObject* s, PyObject* substr, Py_ssize_t start, Py_ssize_t end, int direction); + +/* PyObjectFormatSimple.proto */ +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + PyObject_Format(s, f)) +#elif CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + likely(PyLong_CheckExact(s)) ? PyLong_Type.tp_repr(s) :\ + likely(PyFloat_CheckExact(s)) ? PyFloat_Type.tp_repr(s) :\ + PyObject_Format(s, f)) +#else + #define __Pyx_PyObject_FormatSimple(s, f) (\ + likely(PyUnicode_CheckExact(s)) ? (Py_INCREF(s), s) :\ + PyObject_Format(s, f)) +#endif + +/* HasAttr.proto (used by ImportImpl) */ +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_HasAttr(o, n) PyObject_HasAttrWithError(o, n) +#else +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); +#endif + +/* ImportImpl.export */ +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level); + +/* Import.proto */ +static CYTHON_INLINE PyObject *__Pyx_Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* dict_setdefault.proto (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value); + +/* LimitedApiGetTypeDict.proto (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp); +#endif + +/* SetItemOnTypeDict.proto (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v); +#define __Pyx_SetItemOnTypeDict(tp, k, v) __Pyx__SetItemOnTypeDict((PyTypeObject*)tp, k, v) + +/* FixUpExtensionType.proto (used by FetchCommonType) */ +static CYTHON_INLINE int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); + +/* AddModuleRef.proto (used by FetchSharedCythonModule) */ +#if ((CYTHON_COMPILING_IN_CPYTHON_FREETHREADING ) ||\ + __PYX_LIMITED_VERSION_HEX < 0x030d0000) + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name); +#else + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#endif + +/* FetchSharedCythonModule.proto (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto (used by CommonTypesMetaclass) */ +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases); + +/* CommonTypesMetaclass.proto (used by CythonFunctionShared) */ +static int __pyx_CommonTypesMetaclass_init(PyObject *module); +#define __Pyx_CommonTypesMetaclass_USED + +/* CallTypeTraverse.proto (used by CythonFunctionShared) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#define __Pyx_call_type_traverse(o, always_call, visit, arg) 0 +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg); +#endif + +/* PyMethodNew.proto (used by CythonFunctionShared) */ +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ); + +/* PyVectorcallFastCallDict.proto (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto (used by CythonFunction) */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && CYTHON_METH_FASTCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_dict; +#endif + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + PyObject *defaults; + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_mstate_global->__pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_mstate_global->__pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_mstate_global->__pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, + PyTypeObject *defaults_type); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* CLineInTraceback.proto (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#else +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#endif + +/* CodeObjectCache.proto (used by AddTraceback) */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject __Pyx_CachedCodeObjectType; +#else +typedef PyCodeObject __Pyx_CachedCodeObjectType; +#endif +typedef struct { + __Pyx_CachedCodeObjectType* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_int_type accessor_count; + #endif +}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyType_GetFullyQualifiedName PyType_GetFullyQualifiedName +#else +static __Pyx_TypeName __Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp); +#endif +#else // !LIMITED_API +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetFullyQualifiedName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* GCCDiagnostics.proto (used by CIntToPy) */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* PyObjectVectorCallKwBuilder.proto (used by CIntToPy) */ +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#if CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_Object_Vectorcall_CallFromBuilder PyObject_Vectorcall +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder _PyObject_Vectorcall +#endif +#define __Pyx_MakeVectorcallBuilderKwds(n) PyTuple_New(n) +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder __Pyx_PyObject_FastCallDict +#define __Pyx_MakeVectorcallBuilderKwds(n) __Pyx_PyDict_NewPresized(n) +#define __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n) PyDict_SetItem(builder, key, value) +#define __Pyx_VectorcallBuilder_AddArgStr(key, value, builder, args, n) PyDict_SetItemString(builder, key, value) +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2) { + return PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2); +} +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) +#ifdef PyExceptionInstance_Check + #define __Pyx_PyBaseException_Check(obj) PyExceptionInstance_Check(obj) +#else + #define __Pyx_PyBaseException_Check(obj) __Pyx_TypeCheck(obj, PyExc_BaseException) +#endif + +/* GetRuntimeVersion.proto */ +#if __PYX_LIMITED_VERSION_HEX < 0x030b0000 +static unsigned long __Pyx_cached_runtime_version = 0; +static void __Pyx_init_runtime_version(void); +#else +#define __Pyx_init_runtime_version() +#endif +static unsigned long __Pyx_get_runtime_version(void); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* DecompressString.proto */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo); + +/* MultiPhaseInitModuleState.proto */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +static PyObject *__Pyx_State_FindModule(void*); +static int __Pyx_State_AddModule(PyObject* module, void*); +static int __Pyx_State_RemoveModule(void*); +#elif CYTHON_USE_MODULE_STATE +#define __Pyx_State_FindModule PyState_FindModule +#define __Pyx_State_AddModule PyState_AddModule +#define __Pyx_State_RemoveModule PyState_RemoveModule +#endif + +/* #### Code section: module_declarations ### */ +/* CythonABIVersion.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API + #if CYTHON_METH_FASTCALL + #define __PYX_FASTCALL_ABI_SUFFIX "_fastcall" + #else + #define __PYX_FASTCALL_ABI_SUFFIX + #endif + #define __PYX_LIMITED_ABI_SUFFIX "limited" __PYX_FASTCALL_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#else + #define __PYX_LIMITED_ABI_SUFFIX +#endif +#if __PYX_HAS_PY_AM_SEND == 1 + #define __PYX_AM_SEND_ABI_SUFFIX +#elif __PYX_HAS_PY_AM_SEND == 2 + #define __PYX_AM_SEND_ABI_SUFFIX "amsendbackport" +#else + #define __PYX_AM_SEND_ABI_SUFFIX "noamsend" +#endif +#ifndef __PYX_MONITORING_ABI_SUFFIX + #define __PYX_MONITORING_ABI_SUFFIX +#endif +#if CYTHON_USE_TP_FINALIZE + #define __PYX_TP_FINALIZE_ABI_SUFFIX +#else + #define __PYX_TP_FINALIZE_ABI_SUFFIX "nofinalize" +#endif +#if CYTHON_USE_FREELISTS || !defined(__Pyx_AsyncGen_USED) + #define __PYX_FREELISTS_ABI_SUFFIX +#else + #define __PYX_FREELISTS_ABI_SUFFIX "nofreelists" +#endif +#define CYTHON_ABI __PYX_ABI_VERSION __PYX_LIMITED_ABI_SUFFIX __PYX_MONITORING_ABI_SUFFIX __PYX_TP_FINALIZE_ABI_SUFFIX __PYX_FREELISTS_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." + + +/* Module declarations from "app.core.permissions" */ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "app.core.permissions" +extern int __pyx_module_is_main_app__core__permissions; +int __pyx_module_is_main_app__core__permissions = 0; + +/* Implementation of "app.core.permissions" */ +/* #### Code section: global_var ### */ +/* #### Code section: string_decls ### */ +static const char __pyx_k_PR12_permission_aware_authorizat[] = "PR12: permission-aware authorization.\n\nThe Gateway's PolicyMiddleware already forwards the requester's JWT\n`permissions` claim on every /policy/evaluate call (see\nomnibioai-api-gateway app/services/policy_client.py), but until this PR\nnothing here ever read it -- authorization was role-name/action-string\nmatching only (app/core/rbac.py). This module adds a second, additive gate\nkeyed off the same permission-registry strings omnibioai-auth already\nreserves (app/core/permission_names.py there: workflow.execute,\ndataset.read, workflow.manage, etc) without inventing any new ones.\n\nDeliberately opt-in: enforced only when the caller actually populates\n`permissions` (a non-empty list). No role in the live system is granted\nthese registry permissions yet (they're reserved-but-unassigned in\nomnibioai-auth), so every real request today still carries permissions=[]\nand this gate is a no-op there, falling back to the pre-existing\nrole-based rbac.evaluate_rbac check -- exactly today's behavior, not a\nnew production restriction. It only actively deters/tests once a caller\n(a fixture in these tests, or eventually a real user once\nomnibioai-auth grants these permissions to a role) supplies a non-empty\npermissions list. This is intentional scope containment for PR12 -- see\nthis PR's report for why granting these permissions to real roles is out\nof scope (would require a DB/role change in omnibioai-auth).\n"; +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_3app_4core_11permissions_required_permission(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_action, PyObject *__pyx_v_resource); /* proto */ +static PyObject *__pyx_pf_3app_4core_11permissions_2evaluate_permission(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_roles, PyObject *__pyx_v_permissions, PyObject *__pyx_v_action, PyObject *__pyx_v_resource); /* proto */ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +/* SmallCodeConfig */ +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_items; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_pop; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_values; + PyObject *__pyx_tuple[5]; + PyObject *__pyx_codeobj_tab[2]; + PyObject *__pyx_string_tab[55]; +/* #### Code section: module_state_contents ### */ +/* CommonTypesMetaclass.module_state_decls */ +PyTypeObject *__pyx_CommonTypesMetaclassType; + +/* CachedMethodType.module_state_decls */ +#if CYTHON_COMPILING_IN_LIMITED_API +PyObject *__Pyx_CachedMethodType; +#endif + +/* CythonFunctionShared.module_state_decls */ +PyTypeObject *__pyx_CyFunctionType; + +/* CodeObjectCache.module_state_decls */ +struct __Pyx_CodeObjectCache __pyx_code_cache; + +/* #### Code section: module_state_end ### */ +} __pyx_mstatetype; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { +extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate_global (__Pyx_PyModule_GetState(__Pyx_State_FindModule(&__pyx_moduledef))) + +#define __pyx_m (__Pyx_State_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstatetype __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: constant_name_defines ### */ +#define __pyx_kp_u_ __pyx_string_tab[0] +#define __pyx_kp_u_List_str __pyx_string_tab[1] +#define __pyx_kp_u_Note_that_Cython_is_deliberately __pyx_string_tab[2] +#define __pyx_kp_u_Optional_str __pyx_string_tab[3] +#define __pyx_kp_u__2 __pyx_string_tab[4] +#define __pyx_kp_u_add_note __pyx_string_tab[5] +#define __pyx_kp_u_admin_override __pyx_string_tab[6] +#define __pyx_kp_u_app_core_permissions_py __pyx_string_tab[7] +#define __pyx_kp_u_dataset_read __pyx_string_tab[8] +#define __pyx_kp_u_missing_permission __pyx_string_tab[9] +#define __pyx_kp_u_no_permission_required __pyx_string_tab[10] +#define __pyx_kp_u_permission_check_skipped_no_perm __pyx_string_tab[11] +#define __pyx_kp_u_permission_granted __pyx_string_tab[12] +#define __pyx_kp_u_tes __pyx_string_tab[13] +#define __pyx_kp_u_tuple_bool_str __pyx_string_tab[14] +#define __pyx_kp_u_workflow_execute __pyx_string_tab[15] +#define __pyx_kp_u_workflow_manage __pyx_string_tab[16] +#define __pyx_n_u_ACTION_PERMISSION_MAP __pyx_string_tab[17] +#define __pyx_n_u_List __pyx_string_tab[18] +#define __pyx_n_u_Optional __pyx_string_tab[19] +#define __pyx_n_u_PREFIX_PERMISSION_MAP __pyx_string_tab[20] +#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[21] +#define __pyx_n_u_RESOURCE_ACTION_PERMISSION_MAP __pyx_string_tab[22] +#define __pyx_n_u_action __pyx_string_tab[23] +#define __pyx_n_u_admin __pyx_string_tab[24] +#define __pyx_n_u_app_core_permissions __pyx_string_tab[25] +#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[26] +#define __pyx_n_u_cline_in_traceback __pyx_string_tab[27] +#define __pyx_n_u_delete __pyx_string_tab[28] +#define __pyx_n_u_evaluate_permission __pyx_string_tab[29] +#define __pyx_n_u_func __pyx_string_tab[30] +#define __pyx_n_u_get __pyx_string_tab[31] +#define __pyx_n_u_is_coroutine __pyx_string_tab[32] +#define __pyx_n_u_items __pyx_string_tab[33] +#define __pyx_n_u_main __pyx_string_tab[34] +#define __pyx_n_u_model_registry __pyx_string_tab[35] +#define __pyx_n_u_module __pyx_string_tab[36] +#define __pyx_n_u_name __pyx_string_tab[37] +#define __pyx_n_u_permission __pyx_string_tab[38] +#define __pyx_n_u_permissions __pyx_string_tab[39] +#define __pyx_n_u_pop __pyx_string_tab[40] +#define __pyx_n_u_prefix __pyx_string_tab[41] +#define __pyx_n_u_qualname __pyx_string_tab[42] +#define __pyx_n_u_required_permission __pyx_string_tab[43] +#define __pyx_n_u_resource __pyx_string_tab[44] +#define __pyx_n_u_return __pyx_string_tab[45] +#define __pyx_n_u_roles __pyx_string_tab[46] +#define __pyx_n_u_set_name __pyx_string_tab[47] +#define __pyx_n_u_setdefault __pyx_string_tab[48] +#define __pyx_n_u_str __pyx_string_tab[49] +#define __pyx_n_u_test __pyx_string_tab[50] +#define __pyx_n_u_typing __pyx_string_tab[51] +#define __pyx_n_u_values __pyx_string_tab[52] +#define __pyx_kp_b_iso88591_6oQ_xs_vQ_t1_vQ_AXQ_Q_vQ_Q_vQ_7 __pyx_string_tab[53] +#define __pyx_kp_b_iso88591_xq_wc_AQ_36_6_AQ_1_Rz __pyx_string_tab[54] +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { + __pyx_mstatetype *clear_module_state = __Pyx_PyModule_GetState(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #if CYTHON_PEP489_MULTI_PHASE_INIT + __Pyx_State_RemoveModule(NULL); + #endif + for (int i=0; i<5; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } + for (int i=0; i<2; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<55; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } +/* #### Code section: module_state_clear_contents ### */ +/* CommonTypesMetaclass.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CommonTypesMetaclassType); + +/* CythonFunctionShared.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_clear_end ### */ +return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstatetype *traverse_module_state = __Pyx_PyModule_GetState(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_tuple); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_bytes); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); + for (int i=0; i<5; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } + for (int i=0; i<2; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<55; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } +/* #### Code section: module_state_traverse_contents ### */ +/* CommonTypesMetaclass.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CommonTypesMetaclassType); + +/* CythonFunctionShared.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_traverse_end ### */ +return 0; +} +#endif +/* #### Code section: module_code ### */ + +/* "app/core/permissions.py":44 + * + * + * def required_permission(action: str, resource: str) -> Optional[str]: # <<<<<<<<<<<<<< + * if action in ACTION_PERMISSION_MAP: + * return ACTION_PERMISSION_MAP[action] +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_3app_4core_11permissions_1required_permission(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_3app_4core_11permissions_1required_permission = {"required_permission", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_3app_4core_11permissions_1required_permission, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_3app_4core_11permissions_1required_permission(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_action = 0; + PyObject *__pyx_v_resource = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("required_permission (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_action,&__pyx_mstate_global->__pyx_n_u_resource,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 44, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 44, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 44, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "required_permission", 0) < (0)) __PYX_ERR(0, 44, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("required_permission", 1, 2, 2, i); __PYX_ERR(0, 44, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 44, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 44, __pyx_L3_error) + } + __pyx_v_action = ((PyObject*)values[0]); + __pyx_v_resource = ((PyObject*)values[1]); + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("required_permission", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 44, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("app.core.permissions.required_permission", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_action), (&PyUnicode_Type), 0, "action", 2))) __PYX_ERR(0, 44, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_resource), (&PyUnicode_Type), 0, "resource", 2))) __PYX_ERR(0, 44, __pyx_L1_error) + __pyx_r = __pyx_pf_3app_4core_11permissions_required_permission(__pyx_self, __pyx_v_action, __pyx_v_resource); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + goto __pyx_L7_cleaned_up; + __pyx_L0:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __pyx_L7_cleaned_up:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_3app_4core_11permissions_required_permission(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_action, PyObject *__pyx_v_resource) { + PyObject *__pyx_v_prefix = NULL; + PyObject *__pyx_v_permission = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + Py_ssize_t __pyx_t_4; + Py_ssize_t __pyx_t_5; + int __pyx_t_6; + PyObject *__pyx_t_7 = NULL; + int __pyx_t_8; + PyObject *__pyx_t_9 = NULL; + size_t __pyx_t_10; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("required_permission", 0); + + /* "app/core/permissions.py":45 + * + * def required_permission(action: str, resource: str) -> Optional[str]: + * if action in ACTION_PERMISSION_MAP: # <<<<<<<<<<<<<< + * return ACTION_PERMISSION_MAP[action] + * +*/ + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_ACTION_PERMISSION_MAP); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_v_action, __pyx_t_1, Py_EQ)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 45, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (__pyx_t_2) { + + /* "app/core/permissions.py":46 + * def required_permission(action: str, resource: str) -> Optional[str]: + * if action in ACTION_PERMISSION_MAP: + * return ACTION_PERMISSION_MAP[action] # <<<<<<<<<<<<<< + * + * for prefix, permission in PREFIX_PERMISSION_MAP.items(): +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_ACTION_PERMISSION_MAP); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 46, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_Dict_GetItem(__pyx_t_1, __pyx_v_action); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 46, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (!(likely(PyUnicode_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None) || __Pyx_RaiseUnexpectedTypeError("str", __pyx_t_3))) __PYX_ERR(0, 46, __pyx_L1_error) + __pyx_r = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "app/core/permissions.py":45 + * + * def required_permission(action: str, resource: str) -> Optional[str]: + * if action in ACTION_PERMISSION_MAP: # <<<<<<<<<<<<<< + * return ACTION_PERMISSION_MAP[action] + * +*/ + } + + /* "app/core/permissions.py":48 + * return ACTION_PERMISSION_MAP[action] + * + * for prefix, permission in PREFIX_PERMISSION_MAP.items(): # <<<<<<<<<<<<<< + * if action.startswith(prefix): + * return permission +*/ + __pyx_t_4 = 0; + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_PREFIX_PERMISSION_MAP); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 48, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + if (unlikely(__pyx_t_1 == Py_None)) { + PyErr_Format(PyExc_AttributeError, "'NoneType' object has no attribute '%.30s'", "items"); + __PYX_ERR(0, 48, __pyx_L1_error) + } + __pyx_t_7 = __Pyx_dict_iterator(__pyx_t_1, 0, __pyx_mstate_global->__pyx_n_u_items, (&__pyx_t_5), (&__pyx_t_6)); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 48, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_XDECREF(__pyx_t_3); + __pyx_t_3 = __pyx_t_7; + __pyx_t_7 = 0; + while (1) { + __pyx_t_8 = __Pyx_dict_iter_next(__pyx_t_3, __pyx_t_5, &__pyx_t_4, &__pyx_t_7, &__pyx_t_1, NULL, __pyx_t_6); + if (unlikely(__pyx_t_8 == 0)) break; + if (unlikely(__pyx_t_8 == -1)) __PYX_ERR(0, 48, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_GOTREF(__pyx_t_1); + __Pyx_XDECREF_SET(__pyx_v_prefix, __pyx_t_7); + __pyx_t_7 = 0; + __Pyx_XDECREF_SET(__pyx_v_permission, __pyx_t_1); + __pyx_t_1 = 0; + + /* "app/core/permissions.py":49 + * + * for prefix, permission in PREFIX_PERMISSION_MAP.items(): + * if action.startswith(prefix): # <<<<<<<<<<<<<< + * return permission + * +*/ + __pyx_t_2 = __Pyx_PyUnicode_Tailmatch(__pyx_v_action, __pyx_v_prefix, 0, PY_SSIZE_T_MAX, -1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 49, __pyx_L1_error) + if (__pyx_t_2) { + + /* "app/core/permissions.py":50 + * for prefix, permission in PREFIX_PERMISSION_MAP.items(): + * if action.startswith(prefix): + * return permission # <<<<<<<<<<<<<< + * + * return RESOURCE_ACTION_PERMISSION_MAP.get((resource, action)) +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = __pyx_v_permission; + __Pyx_INCREF(__pyx_t_1); + if (!(likely(PyUnicode_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None) || __Pyx_RaiseUnexpectedTypeError("str", __pyx_t_1))) __PYX_ERR(0, 50, __pyx_L1_error) + __pyx_r = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + goto __pyx_L0; + + /* "app/core/permissions.py":49 + * + * for prefix, permission in PREFIX_PERMISSION_MAP.items(): + * if action.startswith(prefix): # <<<<<<<<<<<<<< + * return permission + * +*/ + } + } + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + + /* "app/core/permissions.py":52 + * return permission + * + * return RESOURCE_ACTION_PERMISSION_MAP.get((resource, action)) # <<<<<<<<<<<<<< + * + * +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_1 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_RESOURCE_ACTION_PERMISSION_MAP); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __pyx_t_9 = __Pyx_PyObject_GetAttrStr(__pyx_t_7, __pyx_mstate_global->__pyx_n_u_get); if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_9); + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __pyx_t_7 = PyTuple_New(2); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_7); + __Pyx_INCREF(__pyx_v_resource); + __Pyx_GIVEREF(__pyx_v_resource); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 0, __pyx_v_resource) != (0)) __PYX_ERR(0, 52, __pyx_L1_error); + __Pyx_INCREF(__pyx_v_action); + __Pyx_GIVEREF(__pyx_v_action); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_7, 1, __pyx_v_action) != (0)) __PYX_ERR(0, 52, __pyx_L1_error); + __pyx_t_10 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_9))) { + __pyx_t_1 = PyMethod_GET_SELF(__pyx_t_9); + assert(__pyx_t_1); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_9); + __Pyx_INCREF(__pyx_t_1); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_9, __pyx__function); + __pyx_t_10 = 0; + } + #endif + { + PyObject *__pyx_callargs[2] = {__pyx_t_1, __pyx_t_7}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_9, __pyx_callargs+__pyx_t_10, (2-__pyx_t_10) | (__pyx_t_10*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; + __Pyx_DECREF(__pyx_t_9); __pyx_t_9 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 52, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + if (!(likely(PyUnicode_CheckExact(__pyx_t_3))||((__pyx_t_3) == Py_None) || __Pyx_RaiseUnexpectedTypeError("str", __pyx_t_3))) __PYX_ERR(0, 52, __pyx_L1_error) + __pyx_r = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "app/core/permissions.py":44 + * + * + * def required_permission(action: str, resource: str) -> Optional[str]: # <<<<<<<<<<<<<< + * if action in ACTION_PERMISSION_MAP: + * return ACTION_PERMISSION_MAP[action] +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_9); + __Pyx_AddTraceback("app.core.permissions.required_permission", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_prefix); + __Pyx_XDECREF(__pyx_v_permission); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +/* "app/core/permissions.py":55 + * + * + * def evaluate_permission( # <<<<<<<<<<<<<< + * roles: List[str], permissions: List[str], action: str, resource: str + * ) -> tuple[bool, str]: +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_3app_4core_11permissions_3evaluate_permission(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_3app_4core_11permissions_3evaluate_permission = {"evaluate_permission", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_3app_4core_11permissions_3evaluate_permission, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_3app_4core_11permissions_3evaluate_permission(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_roles = 0; + PyObject *__pyx_v_permissions = 0; + PyObject *__pyx_v_action = 0; + PyObject *__pyx_v_resource = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[4] = {0,0,0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("evaluate_permission (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_roles,&__pyx_mstate_global->__pyx_n_u_permissions,&__pyx_mstate_global->__pyx_n_u_action,&__pyx_mstate_global->__pyx_n_u_resource,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 55, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 4: + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 55, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 3: + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 55, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 55, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 55, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "evaluate_permission", 0) < (0)) __PYX_ERR(0, 55, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 4; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("evaluate_permission", 1, 4, 4, i); __PYX_ERR(0, 55, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 4)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 55, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 55, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 55, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 55, __pyx_L3_error) + } + __pyx_v_roles = ((PyObject*)values[0]); + __pyx_v_permissions = ((PyObject*)values[1]); + __pyx_v_action = ((PyObject*)values[2]); + __pyx_v_resource = ((PyObject*)values[3]); + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("evaluate_permission", 1, 4, 4, __pyx_nargs); __PYX_ERR(0, 55, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("app.core.permissions.evaluate_permission", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_roles), (&PyList_Type), 0, "roles", 2))) __PYX_ERR(0, 56, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_permissions), (&PyList_Type), 0, "permissions", 2))) __PYX_ERR(0, 56, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_action), (&PyUnicode_Type), 0, "action", 2))) __PYX_ERR(0, 56, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_resource), (&PyUnicode_Type), 0, "resource", 2))) __PYX_ERR(0, 56, __pyx_L1_error) + __pyx_r = __pyx_pf_3app_4core_11permissions_2evaluate_permission(__pyx_self, __pyx_v_roles, __pyx_v_permissions, __pyx_v_action, __pyx_v_resource); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + goto __pyx_L7_cleaned_up; + __pyx_L0:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __pyx_L7_cleaned_up:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_3app_4core_11permissions_2evaluate_permission(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_roles, PyObject *__pyx_v_permissions, PyObject *__pyx_v_action, PyObject *__pyx_v_resource) { + PyObject *__pyx_v_permission = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + int __pyx_t_1; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + PyObject *__pyx_t_4 = NULL; + PyObject *__pyx_t_5 = NULL; + size_t __pyx_t_6; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("evaluate_permission", 0); + + /* "app/core/permissions.py":58 + * roles: List[str], permissions: List[str], action: str, resource: str + * ) -> tuple[bool, str]: + * if "admin" in roles: # <<<<<<<<<<<<<< + * return True, "admin override" + * +*/ + __pyx_t_1 = (__Pyx_PySequence_ContainsTF(__pyx_mstate_global->__pyx_n_u_admin, __pyx_v_roles, Py_EQ)); if (unlikely((__pyx_t_1 < 0))) __PYX_ERR(0, 58, __pyx_L1_error) + if (__pyx_t_1) { + + /* "app/core/permissions.py":59 + * ) -> tuple[bool, str]: + * if "admin" in roles: + * return True, "admin override" # <<<<<<<<<<<<<< + * + * if not permissions: +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[0]); + __pyx_r = __pyx_mstate_global->__pyx_tuple[0]; + goto __pyx_L0; + + /* "app/core/permissions.py":58 + * roles: List[str], permissions: List[str], action: str, resource: str + * ) -> tuple[bool, str]: + * if "admin" in roles: # <<<<<<<<<<<<<< + * return True, "admin override" + * +*/ + } + + /* "app/core/permissions.py":61 + * return True, "admin override" + * + * if not permissions: # <<<<<<<<<<<<<< + * # Not permission-aware traffic (see module docstring) -- defer + * # entirely to rbac.evaluate_rbac, which already ran before this. +*/ + { + Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_v_permissions); + if (unlikely(((!CYTHON_ASSUME_SAFE_SIZE) && __pyx_temp < 0))) __PYX_ERR(0, 61, __pyx_L1_error) + __pyx_t_1 = (__pyx_temp != 0); + } + + __pyx_t_2 = (!__pyx_t_1); + if (__pyx_t_2) { + + /* "app/core/permissions.py":64 + * # Not permission-aware traffic (see module docstring) -- defer + * # entirely to rbac.evaluate_rbac, which already ran before this. + * return True, "permission check skipped: no permissions supplied" # <<<<<<<<<<<<<< + * + * permission = required_permission(action, resource) +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[1]); + __pyx_r = __pyx_mstate_global->__pyx_tuple[1]; + goto __pyx_L0; + + /* "app/core/permissions.py":61 + * return True, "admin override" + * + * if not permissions: # <<<<<<<<<<<<<< + * # Not permission-aware traffic (see module docstring) -- defer + * # entirely to rbac.evaluate_rbac, which already ran before this. +*/ + } + + /* "app/core/permissions.py":66 + * return True, "permission check skipped: no permissions supplied" + * + * permission = required_permission(action, resource) # <<<<<<<<<<<<<< + * if permission is None: + * return True, "no permission required" +*/ + __pyx_t_4 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_required_permission); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __pyx_t_6 = 1; + #if CYTHON_UNPACK_METHODS + if (unlikely(PyMethod_Check(__pyx_t_5))) { + __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_5); + assert(__pyx_t_4); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_5); + __Pyx_INCREF(__pyx_t_4); + __Pyx_INCREF(__pyx__function); + __Pyx_DECREF_SET(__pyx_t_5, __pyx__function); + __pyx_t_6 = 0; + } + #endif + { + PyObject *__pyx_callargs[3] = {__pyx_t_4, __pyx_v_action, __pyx_v_resource}; + __pyx_t_3 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_5, __pyx_callargs+__pyx_t_6, (3-__pyx_t_6) | (__pyx_t_6*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; + if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 66, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + } + __pyx_v_permission = __pyx_t_3; + __pyx_t_3 = 0; + + /* "app/core/permissions.py":67 + * + * permission = required_permission(action, resource) + * if permission is None: # <<<<<<<<<<<<<< + * return True, "no permission required" + * +*/ + __pyx_t_2 = (__pyx_v_permission == Py_None); + if (__pyx_t_2) { + + /* "app/core/permissions.py":68 + * permission = required_permission(action, resource) + * if permission is None: + * return True, "no permission required" # <<<<<<<<<<<<<< + * + * if permission in permissions: +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[2]); + __pyx_r = __pyx_mstate_global->__pyx_tuple[2]; + goto __pyx_L0; + + /* "app/core/permissions.py":67 + * + * permission = required_permission(action, resource) + * if permission is None: # <<<<<<<<<<<<<< + * return True, "no permission required" + * +*/ + } + + /* "app/core/permissions.py":70 + * return True, "no permission required" + * + * if permission in permissions: # <<<<<<<<<<<<<< + * return True, "permission granted" + * +*/ + __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_v_permission, __pyx_v_permissions, Py_EQ)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 70, __pyx_L1_error) + if (__pyx_t_2) { + + /* "app/core/permissions.py":71 + * + * if permission in permissions: + * return True, "permission granted" # <<<<<<<<<<<<<< + * + * return False, f"missing permission: {permission}" +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[3]); + __pyx_r = __pyx_mstate_global->__pyx_tuple[3]; + goto __pyx_L0; + + /* "app/core/permissions.py":70 + * return True, "no permission required" + * + * if permission in permissions: # <<<<<<<<<<<<<< + * return True, "permission granted" + * +*/ + } + + /* "app/core/permissions.py":73 + * return True, "permission granted" + * + * return False, f"missing permission: {permission}" # <<<<<<<<<<<<<< +*/ + __Pyx_XDECREF(__pyx_r); + __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_v_permission, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_5 = __Pyx_PyUnicode_Concat(__pyx_mstate_global->__pyx_kp_u_missing_permission, __pyx_t_3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_5); + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + __pyx_t_3 = PyTuple_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 73, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __Pyx_INCREF(Py_False); + __Pyx_GIVEREF(Py_False); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 0, Py_False) != (0)) __PYX_ERR(0, 73, __pyx_L1_error); + __Pyx_GIVEREF(__pyx_t_5); + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_t_5) != (0)) __PYX_ERR(0, 73, __pyx_L1_error); + __pyx_t_5 = 0; + __pyx_r = ((PyObject*)__pyx_t_3); + __pyx_t_3 = 0; + goto __pyx_L0; + + /* "app/core/permissions.py":55 + * + * + * def evaluate_permission( # <<<<<<<<<<<<<< + * roles: List[str], permissions: List[str], action: str, resource: str + * ) -> tuple[bool, str]: +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_3); + __Pyx_XDECREF(__pyx_t_4); + __Pyx_XDECREF(__pyx_t_5); + __Pyx_AddTraceback("app.core.permissions.evaluate_permission", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_permission); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +/* #### Code section: module_exttypes ### */ + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +/* #### Code section: initfunc_declarations ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate); /*proto*/ +/* #### Code section: init_module ### */ + +static int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_permissions(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_permissions}, + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + {Py_mod_gil, __Pyx_FREETHREADING_COMPATIBLE}, + #endif + #if PY_VERSION_HEX >= 0x030C0000 && CYTHON_USE_MODULE_STATE + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + #endif + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "permissions", + __pyx_k_PR12_permission_aware_authorizat, /* m_doc */ + #if CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstatetype), /* m_size */ + #else + (CYTHON_PEP489_MULTI_PHASE_INIT) ? 0 : -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif + +/* PyModInitFuncType */ +#ifndef CYTHON_NO_PYINIT_EXPORT + #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#else + #ifdef __cplusplus + #define __Pyx_PyMODINIT_FUNC extern "C" PyObject * + #else + #define __Pyx_PyMODINIT_FUNC PyObject * + #endif +#endif + +__Pyx_PyMODINIT_FUNC PyInit_permissions(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_permissions(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +/* ModuleCreationPEP489 */ +#if CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) +static PY_INT64_T __Pyx_GetCurrentInterpreterId(void) { + { + PyObject *module = PyImport_ImportModule("_interpreters"); // 3.13+ I think + if (!module) { + PyErr_Clear(); // just try the 3.8-3.12 version + module = PyImport_ImportModule("_xxsubinterpreters"); + if (!module) goto bad; + } + PyObject *current = PyObject_CallMethod(module, "get_current", NULL); + Py_DECREF(module); + if (!current) goto bad; + if (PyTuple_Check(current)) { + PyObject *new_current = PySequence_GetItem(current, 0); + Py_DECREF(current); + current = new_current; + if (!new_current) goto bad; + } + long long as_c_int = PyLong_AsLongLong(current); + Py_DECREF(current); + return as_c_int; + } + bad: + PySys_WriteStderr("__Pyx_GetCurrentInterpreterId failed. Try setting the C define CYTHON_PEP489_MULTI_PHASE_INIT=0\n"); + return -1; +} +#endif +#if !CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + static PY_INT64_T main_interpreter_id = -1; +#if CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + PY_INT64_T current_id = GraalPyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_GRAAL + PY_INT64_T current_id = PyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) + PY_INT64_T current_id = __Pyx_GetCurrentInterpreterId(); +#elif CYTHON_COMPILING_IN_LIMITED_API + PY_INT64_T current_id = PyInterpreterState_GetID(PyInterpreterState_Get()); +#else + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); +#endif + if (unlikely(current_id == -1)) { + return -1; + } + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return 0; + } else if (unlikely(main_interpreter_id != current_id)) { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#endif +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + #if !CYTHON_USE_MODULE_STATE + if (__Pyx_check_single_interpreter()) + return NULL; + #endif + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_permissions(PyObject *__pyx_pyinit_module) +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + __pyx_mstatetype *__pyx_mstate = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'permissions' has already been imported. Re-initialisation is not supported."); + return -1; + } + #else + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_t_1 = __pyx_pyinit_module; + Py_INCREF(__pyx_t_1); + #else + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #if CYTHON_USE_MODULE_STATE + { + int add_module_result = __Pyx_State_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "permissions" pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = __pyx_t_1; + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + PyUnstable_Module_SetGIL(__pyx_m, Py_MOD_GIL_USED); + #endif + __pyx_mstate = __pyx_mstate_global; + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_mstate->__pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_mstate->__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_mstate->__pyx_d); + __pyx_mstate->__pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_mstate->__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_cython_runtime = __Pyx_PyImport_AddModuleRef("cython_runtime"); if (unlikely(!__pyx_mstate->__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_mstate->__pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /* ImportRefnannyAPI */ + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + +__Pyx_RefNannySetupContext("PyInit_permissions", 0); + __Pyx_init_runtime_version(); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_mstate->__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Library function declarations ---*/ + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__pyx_module_is_main_app__core__permissions) { + if (PyObject_SetAttr(__pyx_m, __pyx_mstate_global->__pyx_n_u_name, __pyx_mstate_global->__pyx_n_u_main) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "app.core.permissions")) { + if (unlikely((PyDict_SetItemString(modules, "app.core.permissions", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_CreateCodeObjects(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(__pyx_mstate); + (void)__Pyx_modinit_variable_export_code(__pyx_mstate); + (void)__Pyx_modinit_function_export_code(__pyx_mstate); + (void)__Pyx_modinit_type_init_code(__pyx_mstate); + (void)__Pyx_modinit_type_import_code(__pyx_mstate); + (void)__Pyx_modinit_variable_import_code(__pyx_mstate); + (void)__Pyx_modinit_function_import_code(__pyx_mstate); + /*--- Execution code ---*/ + + /* "app/core/permissions.py":26 + * """ + * + * from typing import List, Optional # <<<<<<<<<<<<<< + * + * # action (exact match) -> required permission +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_List,__pyx_mstate_global->__pyx_n_u_Optional}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_typing, __pyx_imported_names, 2, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_List,__pyx_mstate_global->__pyx_n_u_Optional}; + for (__pyx_t_3=0; __pyx_t_3 < 2; __pyx_t_3++) { + __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 26, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 26, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "app/core/permissions.py":30 + * # action (exact match) -> required permission + * ACTION_PERMISSION_MAP = { + * "dataset.read": "dataset.read", # <<<<<<<<<<<<<< + * } + * +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_dataset_read, __pyx_mstate_global->__pyx_kp_u_dataset_read) < (0)) __PYX_ERR(0, 30, __pyx_L1_error) + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_ACTION_PERMISSION_MAP, __pyx_t_2) < (0)) __PYX_ERR(0, 29, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "app/core/permissions.py":35 + * # action prefix -> required permission + * PREFIX_PERMISSION_MAP = { + * "tes.": "workflow.execute", # <<<<<<<<<<<<<< + * } + * +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 35, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_kp_u_tes, __pyx_mstate_global->__pyx_kp_u_workflow_execute) < (0)) __PYX_ERR(0, 35, __pyx_L1_error) + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_PREFIX_PERMISSION_MAP, __pyx_t_2) < (0)) __PYX_ERR(0, 34, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "app/core/permissions.py":40 + * # (resource, action) -> required permission + * RESOURCE_ACTION_PERMISSION_MAP = { + * ("model_registry", "delete"): "workflow.manage", # <<<<<<<<<<<<<< + * } + * +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_tuple[4], __pyx_mstate_global->__pyx_kp_u_workflow_manage) < (0)) __PYX_ERR(0, 40, __pyx_L1_error) + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_RESOURCE_ACTION_PERMISSION_MAP, __pyx_t_2) < (0)) __PYX_ERR(0, 39, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "app/core/permissions.py":44 + * + * + * def required_permission(action: str, resource: str) -> Optional[str]: # <<<<<<<<<<<<<< + * if action in ACTION_PERMISSION_MAP: + * return ACTION_PERMISSION_MAP[action] +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_action, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 44, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_resource, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 44, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_return, __pyx_mstate_global->__pyx_kp_u_Optional_str) < (0)) __PYX_ERR(0, 44, __pyx_L1_error) + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_3app_4core_11permissions_1required_permission, 0, __pyx_mstate_global->__pyx_n_u_required_permission, NULL, __pyx_mstate_global->__pyx_n_u_app_core_permissions, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_required_permission, __pyx_t_4) < (0)) __PYX_ERR(0, 44, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "app/core/permissions.py":55 + * + * + * def evaluate_permission( # <<<<<<<<<<<<<< + * roles: List[str], permissions: List[str], action: str, resource: str + * ) -> tuple[bool, str]: +*/ + __pyx_t_4 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_roles, __pyx_mstate_global->__pyx_kp_u_List_str) < (0)) __PYX_ERR(0, 55, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_permissions, __pyx_mstate_global->__pyx_kp_u_List_str) < (0)) __PYX_ERR(0, 55, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_action, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 55, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_resource, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 55, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_return, __pyx_mstate_global->__pyx_kp_u_tuple_bool_str) < (0)) __PYX_ERR(0, 55, __pyx_L1_error) + __pyx_t_2 = __Pyx_CyFunction_New(&__pyx_mdef_3app_4core_11permissions_3evaluate_permission, 0, __pyx_mstate_global->__pyx_n_u_evaluate_permission, NULL, __pyx_mstate_global->__pyx_n_u_app_core_permissions, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[1])); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_2); + #endif + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_2, __pyx_t_4); + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_evaluate_permission, __pyx_t_2) < (0)) __PYX_ERR(0, 55, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "app/core/permissions.py":1 + * """PR12: permission-aware authorization. # <<<<<<<<<<<<<< + * + * The Gateway's PolicyMiddleware already forwards the requester's JWT +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_test, __pyx_t_2) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + if (__pyx_m) { + if (__pyx_mstate->__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init app.core.permissions", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init app.core.permissions"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #else + return __pyx_m; + #endif +} +/* #### Code section: pystring_table ### */ +/* #### Code section: cached_builtins ### */ + +static int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + + /* Cached unbound methods */ + __pyx_mstate->__pyx_umethod_PyDict_Type_items.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_items.method_name = &__pyx_mstate->__pyx_n_u_items; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.method_name = &__pyx_mstate->__pyx_n_u_pop; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.method_name = &__pyx_mstate->__pyx_n_u_values; + return 0; +} +/* #### Code section: cached_constants ### */ + +static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "app/core/permissions.py":59 + * ) -> tuple[bool, str]: + * if "admin" in roles: + * return True, "admin override" # <<<<<<<<<<<<<< + * + * if not permissions: +*/ + __pyx_mstate_global->__pyx_tuple[0] = PyTuple_Pack(2, Py_True, __pyx_mstate_global->__pyx_kp_u_admin_override); if (unlikely(!__pyx_mstate_global->__pyx_tuple[0])) __PYX_ERR(0, 59, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[0]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[0]); + + /* "app/core/permissions.py":64 + * # Not permission-aware traffic (see module docstring) -- defer + * # entirely to rbac.evaluate_rbac, which already ran before this. + * return True, "permission check skipped: no permissions supplied" # <<<<<<<<<<<<<< + * + * permission = required_permission(action, resource) +*/ + __pyx_mstate_global->__pyx_tuple[1] = PyTuple_Pack(2, Py_True, __pyx_mstate_global->__pyx_kp_u_permission_check_skipped_no_perm); if (unlikely(!__pyx_mstate_global->__pyx_tuple[1])) __PYX_ERR(0, 64, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[1]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[1]); + + /* "app/core/permissions.py":68 + * permission = required_permission(action, resource) + * if permission is None: + * return True, "no permission required" # <<<<<<<<<<<<<< + * + * if permission in permissions: +*/ + __pyx_mstate_global->__pyx_tuple[2] = PyTuple_Pack(2, Py_True, __pyx_mstate_global->__pyx_kp_u_no_permission_required); if (unlikely(!__pyx_mstate_global->__pyx_tuple[2])) __PYX_ERR(0, 68, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[2]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[2]); + + /* "app/core/permissions.py":71 + * + * if permission in permissions: + * return True, "permission granted" # <<<<<<<<<<<<<< + * + * return False, f"missing permission: {permission}" +*/ + __pyx_mstate_global->__pyx_tuple[3] = PyTuple_Pack(2, Py_True, __pyx_mstate_global->__pyx_kp_u_permission_granted); if (unlikely(!__pyx_mstate_global->__pyx_tuple[3])) __PYX_ERR(0, 71, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[3]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[3]); + + /* "app/core/permissions.py":40 + * # (resource, action) -> required permission + * RESOURCE_ACTION_PERMISSION_MAP = { + * ("model_registry", "delete"): "workflow.manage", # <<<<<<<<<<<<<< + * } + * +*/ + __pyx_mstate_global->__pyx_tuple[4] = PyTuple_Pack(2, __pyx_mstate_global->__pyx_n_u_model_registry, __pyx_mstate_global->__pyx_n_u_delete); if (unlikely(!__pyx_mstate_global->__pyx_tuple[4])) __PYX_ERR(0, 40, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[4]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[4]); + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_tuple; + for (Py_ssize_t i=0; i<5; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #if PY_VERSION_HEX < 0x030E0000 + if (_Py_IsOwnedByCurrentThread(table[i]) && Py_REFCNT(table[i]) == 1) + #else + if (PyUnstable_Object_IsUniquelyReferenced(table[i])) + #endif + { + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + } + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + { + const struct { const unsigned int length: 8; } index[] = {{1},{9},{179},{13},{1},{8},{14},{23},{12},{20},{22},{49},{18},{4},{16},{16},{15},{21},{4},{8},{21},{20},{30},{6},{5},{20},{18},{18},{6},{19},{8},{3},{13},{5},{8},{14},{10},{8},{10},{11},{3},{6},{12},{19},{8},{6},{5},{12},{10},{3},{8},{6},{6},{103},{72}}; + #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (727 bytes) */ +const char* const cstring = "BZh91AY&SY\274\233\207;\000\0006\177\377\347\355\374\tl\347\255\320\257'\376J\277\377\377\370@@@@@@@@@\000@@@\000@\000@\002B\325U)\203H\324\324\312mG\243S\324\365\007\250\000\365\006\203\324h\006\215\000\032\003\324=F\312<\247\251\372Ph\232\001\r4\023\"\233\325\036Q\352\000h\310\000\310\000\000\000\r\251\2404\023I1\023di4\364C@\320\000\000\000\000\000\000\000\016d\323C \001\210\3102\000i\202\006 \0324\320\001\2204\000\3057'\225k$\020EM\266@\310\"v\316\273\212\007C\014\025(t\326\343Ie\214E\031\336\226KRE\346\231m$M\300\0306\204h\214\304\226\350d\276\354\3314\264\323\231/<\201\016\246\263\261k\252\375\353\014\330\233\026pjy\n7!\335\347\270|+N~D\0227\267\342K\331\021\367\014\255\023\200\004w\370+\330\275\303e\354[\372R(\227\300\202\254\367\020\243K\252\213\212z\314(n\377\265\014\014`c\347n\335%(VI2\256*\244s\313\016YK\017y8\374O\361\204\207\r\257ld\276t\006\343\243\032\320\016T#\277UC\221\201\000n\374\323\364{L\366\030\355\353\341\010\\\014\344oR\310Orb\330\333(;L\0266pJ\255\220\252\300\352\302\226/\235\322F\037\001fB\202C\262\317\227Or\230b\200\2353\347\222\240\330\256,\024\220\006OLS\371\252Y,]\010\236\345\014\0135\022\304P+\211L\010\205\226\0052qzd\321i\207\2657\317\201[\r\212qwHN\216\260\350\212\241\212_7\001%\262\321\306\254\341-Q\022\020P\014\024\261\210\224b\001l\031\254\217\035T\211\212\257\2601\202rb\302-\217\007\264\345\006\313\024)J\211\020pgFT\rQ\001\203\nczg\264V\240Y\214\202 \256\370Df\003T\014\016\314\036\327,dd\013+\357\033\300\304r:\361\210\246\321\332\210C\300(\\G\257=\024\026\017\247\001j\357gDB\235\002\263\316CiP\200tJ0\231\235o\215\320\010D\"\304\010\310Q)\262\2039\315\225&a\024\264B\200J\317b\200\021-\260\321\033\214\231\255\242\n\034\223\320h\027%\032\216\204H7=S\244\014f\201\356\270\033E@<\302:\372Z\321\355\257\205\320\007\305A]Z\2639\352\222\205Z.L\0001\331ey\232\201:\226m\345\215xL\267Z\370\006\374Hy3\324!\315\354)+c\376\327\250_\353\026\300\233\245\377\300\221<\324sO\207\311K\257\324\2358\340i+\245\370\251\250VZB^I\n\220\217\361w$S\205\t\013""\311\270s\260"; + PyObject *data = __Pyx_DecompressString(cstring, 727, 2); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (636 bytes) */ +const char* const cstring = "x\332mR\317k\023A\024nAk%b\215z\023d\244B\025tKi\251\342EBM!`\333$U(\2242Lf\337&c&3\323\231\3314\253\227\036\367\270\307\036{\314\261\307\036\375\023r\314\321?\301?\3017\351\257\264\270\260\273\363\036\337\367\275y\357{\321W\341\374\276\363\366`[{ \276\303<\331\310|G+\"\034\211A\212\026X\346Af\004A\202{\260\001\244H\275Z\177\277\366q\2150\025\023\013?\200{G\\\332\342\2229\007\216\350\204\264R!\275P\304g\006\\Dj\t\311tJ\024@L\274&\006q\323\004\337\001E\034\370p KL)\355\231\027ZQ\244\013\325^\"\261\260XD\364!\2607\231t\020\355\230\200`rr\377\317,\216)\262\200\305=\254\252\373`\255\210\201\031\263\314\265\205e\003\266'\234C\202\213L\0263\317\260Zd'pL\2536\271A|\"JO\205\330\340a\212\345\343\251\024\357\000\357\022\327\025\306@|\007\037\0323F\212[\204\266e\312C\354q\026>5\022\366[Z\313wa\252\007G\332v\023\251\217\"\030\000O=\\\307=\246X\033*\033\337j;\333\264^mn\325vw\303q\253R\017\276]\365_oV7k{w\000\224\326\263\001\276_\3204\272\r\003\337\204\244Y\335\335\371\336\334\250\322\377J2>\221\013\343\303\251Eaj\321TS\314e\212\013\035\362:Ec\301q\211_*\320#\3138\264\030\357\342\302\200\007\3503\231\342\322\320\0336\245I\2528\245m\360T8z\255!<\364\034\245=\206*\264\247\221O-\264\2617\233M\342T\002\305G\261\036\376o\344\246\256e\2641\026\0221\240\3640e\362\002ye\330\024\305\202\323\251\345`\301\247VY-\001\353\342\n\\j\343)\206\204\245\322cmJ\321&O/w/t\003\356xv\\Z\034-\256\237\351\337\215\361\375\271\361\275\007\307\203\334\025\257\306\363\013y\277h\374\301\330\347+\177\347f\036>\271\210\313\243\362\353\323\312\351\336\260\021\260\277\212\305\2421\205\275\035\227\362\017\243\247o\206\263\303\362h\206\234.\014\007g\207\201t\224\363\242\214\240\321BPB\334|>_<\036\275\\=[?\307|)_/^\234TN\032\343G\317\212\025T\031\225\336\016\237\017\233\303\237\347\345\177\215}{\343"; + PyObject *data = __Pyx_DecompressString(cstring, 636, 1); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #else /* compression: none (985 bytes) */ +const char* const bytes = ".List[str]Note that Cython is deliberately stricter than PEP-484 and rejects subclasses of builtin types. If you need to pass subclasses then set the 'annotation_typing' directive to False.Optional[str]?add_noteadmin overrideapp/core/permissions.pydataset.readmissing permission: no permission requiredpermission check skipped: no permissions suppliedpermission grantedtes.tuple[bool, str]workflow.executeworkflow.manageACTION_PERMISSION_MAPListOptionalPREFIX_PERMISSION_MAP__Pyx_PyDict_NextRefRESOURCE_ACTION_PERMISSION_MAPactionadminapp.core.permissionsasyncio.coroutinescline_in_tracebackdeleteevaluate_permission__func__get_is_coroutineitems__main__model_registry__module____name__permissionpermissionspopprefix__qualname__required_permissionresourcereturnroles__set_name__setdefaultstr__test__typingvalues\200\001\330\013#\320#6\260o\300Q\330\005\006\330\004\007\200x\210s\220!\330\010\017\210v\220Q\340\004\007\200t\2101\360\006\000\t\020\210v\220Q\340\004\021\320\021$\240A\240X\250Q\330\004\007\200{\220#\220Q\330\010\017\210v\220Q\340\004\007\200{\220#\220Q\330\010\017\210v\220Q\340\004\013\2107\320\022(\250\001\250\021\320\000 \240\017\250x\260q\330\004\007\200w\210c\220\021\330\010\017\320\017$\240A\240Q\340\004\010\210\010\220\016\320\0363\2606\270\021\330\010\013\2106\220\033\230A\230Q\330\014\023\2201\340\004\013\320\013)\250\024\250R\250z\270\021"; + PyObject *data = NULL; + CYTHON_UNUSED_VAR(__Pyx_DecompressString); + #endif + PyObject **stringtab = __pyx_mstate->__pyx_string_tab; + Py_ssize_t pos = 0; + for (int i = 0; i < 53; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); + if (likely(string) && i >= 17) PyUnicode_InternInPlace(&string); + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + stringtab[i] = string; + pos += bytes_length; + } + for (int i = 53; i < 55; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); + stringtab[i] = string; + pos += bytes_length; + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + Py_XDECREF(data); + for (Py_ssize_t i = 0; i < 55; i++) { + if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = stringtab + 53; + for (Py_ssize_t i=0; i<2; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #if PY_VERSION_HEX < 0x030E0000 + if (_Py_IsOwnedByCurrentThread(table[i]) && Py_REFCNT(table[i]) == 1) + #else + if (PyUnstable_Object_IsUniquelyReferenced(table[i])) + #endif + { + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + } + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + } + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_codeobjects ### */ +typedef struct { + unsigned int argcount : 3; + unsigned int num_posonly_args : 1; + unsigned int num_kwonly_args : 1; + unsigned int nlocals : 3; + unsigned int flags : 10; + unsigned int first_line : 6; +} __Pyx_PyCode_New_function_description; +/* NewCodeObj.proto */ +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +); + + +static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) { + PyObject* tuple_dedup_map = PyDict_New(); + if (unlikely(!tuple_dedup_map)) return -1; + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 44}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_action, __pyx_mstate->__pyx_n_u_resource, __pyx_mstate->__pyx_n_u_prefix, __pyx_mstate->__pyx_n_u_permission}; + __pyx_mstate_global->__pyx_codeobj_tab[0] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_permissions_py, __pyx_mstate->__pyx_n_u_required_permission, __pyx_mstate->__pyx_kp_b_iso88591_xq_wc_AQ_36_6_AQ_1_Rz, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[0])) goto bad; + } + { + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 5, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 55}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_roles, __pyx_mstate->__pyx_n_u_permissions, __pyx_mstate->__pyx_n_u_action, __pyx_mstate->__pyx_n_u_resource, __pyx_mstate->__pyx_n_u_permission}; + __pyx_mstate_global->__pyx_codeobj_tab[1] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_permissions_py, __pyx_mstate->__pyx_n_u_evaluate_permission, __pyx_mstate->__pyx_kp_b_iso88591_6oQ_xs_vQ_t1_vQ_AXQ_Q_vQ_Q_vQ_7, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[1])) goto bad; + } + Py_DECREF(tuple_dedup_map); + return 0; + bad: + Py_DECREF(tuple_dedup_map); + return -1; +} +/* #### Code section: init_globals ### */ + +static int __Pyx_InitGlobals(void) { + /* PythonCompatibility.init */ + if (likely(__Pyx_init_co_variables() == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CommonTypesMetaclass.init */ + if (likely(__pyx_CommonTypesMetaclass_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CachedMethodType.init */ + #if CYTHON_COMPILING_IN_LIMITED_API + { + PyObject *typesModule=NULL; + typesModule = PyImport_ImportModule("types"); + if (typesModule) { + __pyx_mstate_global->__Pyx_CachedMethodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + } + } // error handling follows + #endif + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CythonFunctionShared.init */ + if (likely(__pyx_CyFunction_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* TupleAndListFromArray (used by fastcall) */ +#if !CYTHON_COMPILING_IN_CPYTHON && CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + Py_ssize_t i; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + for (i = 0; i < n; i++) { + Py_INCREF(src[i]); + if (unlikely(__Pyx_PyTuple_SET_ITEM(res, i, src[i]) < (0))) { + Py_DECREF(res); + return NULL; + } + } + return res; +} +#elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL ||\ + !(CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL + return PyObject_RichCompareBool(s1, s2, equals); +#else + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length, length2; + int kind; + void *data1, *data2; + #if !CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + #endif + length = __Pyx_PyUnicode_GET_LENGTH(s1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length < 0)) return -1; + #endif + length2 = __Pyx_PyUnicode_GET_LENGTH(s2); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length2 < 0)) return -1; + #endif + if (length != length2) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + return (equals == Py_EQ); +return_ne: + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = __Pyx_PyTuple_GET_SIZE(kwnames); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(n == -1)) return NULL; + #endif + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + if (s == namei) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + int eq = __Pyx_PyUnicode_Equals(s, namei, Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; + return kwvalues[i]; + } + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs; + PyObject *dict; +#if !CYTHON_ASSUME_SAFE_SIZE + nkwargs = PyTuple_Size(kwnames); + if (unlikely(nkwargs < 0)) return NULL; +#else + nkwargs = PyTuple_GET_SIZE(kwnames); +#endif + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; itp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall (used by PyObjectCallOneArg) */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) != (0)) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +#if CYTHON_VECTORCALL && !CYTHON_COMPILING_IN_LIMITED_API + #if PY_VERSION_HEX < 0x03090000 + #define __Pyx_PyVectorcall_Function(callable) _PyVectorcall_Function(callable) + #elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE vectorcallfunc __Pyx_PyVectorcall_Function(PyObject *callable) { + PyTypeObject *tp = Py_TYPE(callable); + #if defined(__Pyx_CyFunction_USED) + if (__Pyx_CyFunction_CheckExact(callable)) { + return __Pyx_CyFunction_func_vectorcall(callable); + } + #endif + if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { + return NULL; + } + assert(PyCallable_Check(callable)); + Py_ssize_t offset = tp->tp_vectorcall_offset; + assert(offset > 0); + vectorcallfunc ptr; + memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); + return ptr; +} + #else + #define __Pyx_PyVectorcall_Function(callable) PyVectorcall_Function(callable) + #endif +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject *const *args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if CYTHON_COMPILING_IN_LIMITED_API + return PyObject_Vectorcall(func, args, _nargs, NULL); + #else + vectorcallfunc f = __Pyx_PyVectorcall_Function(func); + if (f) { + return f(func, args, _nargs, NULL); + } + #endif + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_mstate_global->__pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* PyObjectCallOneArg (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetAttrStr (used by UnpackUnboundCMethod) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* UnpackUnboundCMethod (used by CallUnboundCMethod0) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *args, PyObject *kwargs) { + PyObject *result; + PyObject *selfless_args = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (unlikely(!selfless_args)) return NULL; + result = PyObject_Call(method, selfless_args, kwargs); + Py_DECREF(selfless_args); + return result; +} +#elif CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03090000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { + return _PyObject_Vectorcall + (method, args ? args+1 : NULL, nargs ? nargs-1 : 0, kwnames); +} +#else +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { + return +#if PY_VERSION_HEX < 0x03090000 + _PyObject_Vectorcall +#else + PyObject_Vectorcall +#endif + (method, args ? args+1 : NULL, nargs ? (size_t) nargs-1 : 0, kwnames); +} +#endif +static PyMethodDef __Pyx_UnboundCMethod_Def = { + "CythonUnboundCMethod", + __PYX_REINTERPRET_FUNCION(PyCFunction, __Pyx_SelflessCall), +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 + METH_VARARGS | METH_KEYWORDS, +#else + METH_FASTCALL | METH_KEYWORDS, +#endif + NULL +}; +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { + PyObject *method, *result=NULL; + method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); + if (unlikely(!method)) + return -1; + result = method; +#if CYTHON_COMPILING_IN_CPYTHON + if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) + { + PyMethodDescrObject *descr = (PyMethodDescrObject*) method; + target->func = descr->d_method->ml_meth; + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); + } else +#endif +#if CYTHON_COMPILING_IN_PYPY +#else + if (PyCFunction_Check(method)) +#endif + { + PyObject *self; + int self_found; +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + self = PyObject_GetAttrString(method, "__self__"); + if (!self) { + PyErr_Clear(); + } +#else + self = PyCFunction_GET_SELF(method); +#endif + self_found = (self && self != Py_None); +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + Py_XDECREF(self); +#endif + if (self_found) { + PyObject *unbound_method = PyCFunction_New(&__Pyx_UnboundCMethod_Def, method); + if (unlikely(!unbound_method)) return -1; + Py_DECREF(method); + result = unbound_method; + } + } +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + if (unlikely(target->method)) { + Py_DECREF(result); + } else +#endif + target->method = result; + return 0; +} + +/* CallUnboundCMethod0 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + if (likely(cfunc->flag == METH_NOARGS)) + return __Pyx_CallCFunction(cfunc, self, NULL); + if (likely(cfunc->flag == METH_FASTCALL)) + return __Pyx_CallCFunctionFast(cfunc, self, NULL, 0); + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, NULL, 0, NULL); + if (likely(cfunc->flag == (METH_VARARGS | METH_KEYWORDS))) + return __Pyx_CallCFunctionWithKeywords(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (cfunc->flag == METH_VARARGS) + return __Pyx_CallCFunction(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple); + return __Pyx__CallUnboundCMethod0(cfunc, self); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod0(&tmp_cfunc, self); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod0(cfunc, self); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + PyObject *result; + if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; + result = __Pyx_PyObject_CallOneArg(cfunc->method, self); + return result; +} + +/* py_dict_items (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_items, d); +} + +/* py_dict_values (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_values, d); +} + +/* OwnedDictNext (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue) { + PyObject *next = NULL; + if (!*ppos) { + if (pvalue) { + PyObject *dictview = pkey ? __Pyx_PyDict_Items(p) : __Pyx_PyDict_Values(p); + if (unlikely(!dictview)) goto bad; + *ppos = PyObject_GetIter(dictview); + Py_DECREF(dictview); + } else { + *ppos = PyObject_GetIter(p); + } + if (unlikely(!*ppos)) goto bad; + } + next = PyIter_Next(*ppos); + if (!next) { + if (PyErr_Occurred()) goto bad; + return 0; + } + if (pkey && pvalue) { + *pkey = __Pyx_PySequence_ITEM(next, 0); + if (unlikely(*pkey)) goto bad; + *pvalue = __Pyx_PySequence_ITEM(next, 1); + if (unlikely(*pvalue)) goto bad; + Py_DECREF(next); + } else if (pkey) { + *pkey = next; + } else { + assert(pvalue); + *pvalue = next; + } + return 1; + bad: + Py_XDECREF(next); +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 + PyErr_FormatUnraisable("Exception ignored in __Pyx_PyDict_NextRef"); +#else + PyErr_WriteUnraisable(__pyx_mstate_global->__pyx_n_u_Pyx_PyDict_NextRef); +#endif + if (pkey) *pkey = NULL; + if (pvalue) *pvalue = NULL; + return 0; +} +#else // !CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) { + int result = PyDict_Next(p, ppos, pkey, pvalue); + if (likely(result == 1)) { + if (pkey) Py_INCREF(*pkey); + if (pvalue) Py_INCREF(*pvalue); + } + return result; +} +#endif + +/* RaiseDoubleKeywords (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); +} + +/* CallUnboundCMethod2 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + PyObject *args[2] = {arg1, arg2}; + if (cfunc->flag == METH_FASTCALL) { + return __Pyx_CallCFunctionFast(cfunc, self, args, 2); + } + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, 2, NULL); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod2(&tmp_cfunc, self, arg1, arg2); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2){ + if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_COMPILING_IN_CPYTHON + if (cfunc->func && (cfunc->flag & METH_VARARGS)) { + PyObject *result = NULL; + PyObject *args = PyTuple_New(2); + if (unlikely(!args)) return NULL; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + if (cfunc->flag & METH_KEYWORDS) + result = __Pyx_CallCFunctionWithKeywords(cfunc, self, args, NULL); + else + result = __Pyx_CallCFunction(cfunc, self, args); + Py_DECREF(args); + return result; + } +#endif + { + PyObject *args[4] = {NULL, self, arg1, arg2}; + return __Pyx_PyObject_FastCall(cfunc->method, args+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } +} + +/* ParseKeywordsImpl (used by ParseKeywords) */ +static int __Pyx_ValidateDuplicatePosArgs( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char* function_name) +{ + PyObject ** const *name = argnames; + while (name != first_kw_arg) { + PyObject *key = **name; + int found = PyDict_Contains(kwds, key); + if (unlikely(found)) { + if (found == 1) __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; + } + name++; + } + return 0; +bad: + return -1; +} +#if CYTHON_USE_UNICODE_INTERNALS +static CYTHON_INLINE int __Pyx_UnicodeKeywordsEqual(PyObject *s1, PyObject *s2) { + int kind; + Py_ssize_t len = PyUnicode_GET_LENGTH(s1); + if (len != PyUnicode_GET_LENGTH(s2)) return 0; + kind = PyUnicode_KIND(s1); + if (kind != PyUnicode_KIND(s2)) return 0; + const void *data1 = PyUnicode_DATA(s1); + const void *data2 = PyUnicode_DATA(s2); + return (memcmp(data1, data2, (size_t) len * (size_t) kind) == 0); +} +#endif +static int __Pyx_MatchKeywordArg_str( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + #if CYTHON_USE_UNICODE_INTERNALS + Py_hash_t key_hash = ((PyASCIIObject*)key)->hash; + if (unlikely(key_hash == -1)) { + key_hash = PyObject_Hash(key); + if (unlikely(key_hash == -1)) + goto bad; + } + #endif + name = first_kw_arg; + while (*name) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (key_hash == ((PyASCIIObject*)name_str)->hash && __Pyx_UnicodeKeywordsEqual(name_str, key)) { + *index_found = (size_t) (name - argnames); + return 1; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + *index_found = (size_t) (name - argnames); + return 1; + } + } + #endif + name++; + } + name = argnames; + while (name != first_kw_arg) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (unlikely(key_hash == ((PyASCIIObject*)name_str)->hash)) { + if (__Pyx_UnicodeKeywordsEqual(name_str, key)) + goto arg_passed_twice; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + if (unlikely(name_str == key)) goto arg_passed_twice; + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + } + #endif + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +bad: + return -1; +} +static int __Pyx_MatchKeywordArg_nostr( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + if (unlikely(!PyUnicode_Check(key))) goto invalid_keyword_type; + name = first_kw_arg; + while (*name) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (cmp == 1) { + *index_found = (size_t) (name - argnames); + return 1; + } + if (unlikely(cmp == -1)) goto bad; + name++; + } + name = argnames; + while (name != first_kw_arg) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (unlikely(cmp != 0)) { + if (cmp == 1) goto arg_passed_twice; + else goto bad; + } + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +bad: + return -1; +} +static CYTHON_INLINE int __Pyx_MatchKeywordArg( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + return likely(PyUnicode_CheckExact(key)) ? + __Pyx_MatchKeywordArg_str(key, argnames, first_kw_arg, index_found, function_name) : + __Pyx_MatchKeywordArg_nostr(key, argnames, first_kw_arg, index_found, function_name); +} +static void __Pyx_RejectUnknownKeyword( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char *function_name) +{ + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos = NULL; + #else + Py_ssize_t pos = 0; + #endif + PyObject *key = NULL; + __Pyx_BEGIN_CRITICAL_SECTION(kwds); + while ( + #if CYTHON_AVOID_BORROWED_REFS + __Pyx_PyDict_NextRef(kwds, &pos, &key, NULL) + #else + PyDict_Next(kwds, &pos, &key, NULL) + #endif + ) { + PyObject** const *name = first_kw_arg; + while (*name && (**name != key)) name++; + if (!*name) { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp != 1) { + if (cmp == 0) { + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + break; + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + } + __Pyx_END_CRITICAL_SECTION(); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(pos); + #endif + assert(PyErr_Occurred()); +} +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t extracted = 0; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + name = first_kw_arg; + while (*name && num_kwargs > extracted) { + PyObject * key = **name; + PyObject *value; + int found = 0; + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + found = PyDict_GetItemRef(kwds, key, &value); + #else + value = PyDict_GetItemWithError(kwds, key); + if (value) { + Py_INCREF(value); + found = 1; + } else { + if (unlikely(PyErr_Occurred())) goto bad; + } + #endif + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + extracted++; + } + name++; + } + if (num_kwargs > extracted) { + if (ignore_unknown_kwargs) { + if (unlikely(__Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name) == -1)) + goto bad; + } else { + __Pyx_RejectUnknownKeyword(kwds, argnames, first_kw_arg, function_name); + goto bad; + } + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t len; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + if (PyDict_Update(kwds2, kwds) < 0) goto bad; + name = first_kw_arg; + while (*name) { + PyObject *key = **name; + PyObject *value; +#if !CYTHON_COMPILING_IN_LIMITED_API && (PY_VERSION_HEX >= 0x030d00A2 || defined(PyDict_Pop)) + int found = PyDict_Pop(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + int found = PyDict_GetItemRef(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + if (unlikely(PyDict_DelItem(kwds2, key) < 0)) goto bad; + } +#else + #if CYTHON_COMPILING_IN_CPYTHON + value = _PyDict_Pop(kwds2, key, kwds2); + #else + value = __Pyx_CallUnboundCMethod2(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_pop, kwds2, key, kwds2); + #endif + if (value == kwds2) { + Py_DECREF(value); + } else { + if (unlikely(!value)) goto bad; + values[name-argnames] = value; + } +#endif + name++; + } + len = PyDict_Size(kwds2); + if (len > 0) { + return __Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name); + } else if (unlikely(len == -1)) { + goto bad; + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject *key = NULL; + PyObject** const * name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + for (Py_ssize_t pos = 0; pos < num_kwargs; pos++) { +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); +#else + key = __Pyx_PyTuple_GET_ITEM(kwds, pos); +#endif +#if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!key)) goto bad; +#endif + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + PyObject *value = kwvalues[pos]; + values[name-argnames] = __Pyx_NewRef(value); + } else { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp == 1) { + PyObject *value = kwvalues[pos]; + values[index_found] = __Pyx_NewRef(value); + } else { + if (unlikely(cmp == -1)) goto bad; + if (kwds2) { + PyObject *value = kwvalues[pos]; + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else if (!ignore_unknown_kwargs) { + goto invalid_keyword; + } + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + key = NULL; + #endif + } + return 0; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + goto bad; +bad: + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(key); + #endif + return -1; +} + +/* ParseKeywords */ +static int __Pyx_ParseKeywords( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds))) + return __Pyx_ParseKeywordsTuple(kwds, kwvalues, argnames, kwds2, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); + else if (kwds2) + return __Pyx_ParseKeywordDictToDict(kwds, argnames, kwds2, values, num_pos_args, function_name); + else + return __Pyx_ParseKeywordDict(kwds, argnames, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* ArgTypeTestFunc (used by ArgTypeTest) */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + __Pyx_TypeName type_name; + __Pyx_TypeName obj_type_name; + PyObject *extra_info = __pyx_mstate_global->__pyx_empty_unicode; + int from_annotation_subclass = 0; + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (!exact) { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } else if (exact == 2) { + if (__Pyx_TypeCheck(obj, type)) { + from_annotation_subclass = 1; + extra_info = __pyx_mstate_global->__pyx_kp_u_Note_that_Cython_is_deliberately; + } + } + type_name = __Pyx_PyType_GetFullyQualifiedName(type); + obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME + ", got " __Pyx_FMT_TYPENAME ")" +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 + "%s%U" +#endif + , name, type_name, obj_type_name +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 + , (from_annotation_subclass ? ". " : ""), extra_info +#endif + ); +#if __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + if (exact == 2 && from_annotation_subclass) { + PyObject *res; + PyObject *vargs[2]; + vargs[0] = PyErr_GetRaisedException(); + vargs[1] = extra_info; + res = PyObject_VectorcallMethod(__pyx_mstate_global->__pyx_kp_u_add_note, vargs, 2, NULL); + Py_XDECREF(res); + PyErr_SetRaisedException(vargs[0]); + } +#endif + __Pyx_DECREF_TypeName(type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* PyErrExceptionMatches (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStrNoError (used by GetBuiltinName) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* GetBuiltinName (used by GetModuleGlobalName) */ +static PyObject *__Pyx_GetBuiltinName(PyObject *name) { + PyObject* result = __Pyx_PyObject_GetAttrStrNoError(__pyx_mstate_global->__pyx_b, name); + if (unlikely(!result) && !PyErr_Occurred()) { + PyErr_Format(PyExc_NameError, + "name '%U' is not defined", name); + } + return result; +} + +/* PyDictVersioning (used by GetModuleGlobalName) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* GetModuleGlobalName */ +#if CYTHON_USE_DICT_VERSIONS +static PyObject *__Pyx__GetModuleGlobalName(PyObject *name, PY_UINT64_T *dict_version, PyObject **dict_cached_value) +#else +static CYTHON_INLINE PyObject *__Pyx__GetModuleGlobalName(PyObject *name) +#endif +{ + PyObject *result; +#if CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(!__pyx_m)) { + if (!PyErr_Occurred()) + PyErr_SetNone(PyExc_NameError); + return NULL; + } + result = PyObject_GetAttr(__pyx_m, name); + if (likely(result)) { + return result; + } + PyErr_Clear(); +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + if (unlikely(__Pyx_PyDict_GetItemRef(__pyx_mstate_global->__pyx_d, name, &result) == -1)) PyErr_Clear(); + __PYX_UPDATE_DICT_CACHE(__pyx_mstate_global->__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return result; + } +#else + result = _PyDict_GetItem_KnownHash(__pyx_mstate_global->__pyx_d, name, ((PyASCIIObject *) name)->hash); + __PYX_UPDATE_DICT_CACHE(__pyx_mstate_global->__pyx_d, result, *dict_cached_value, *dict_version) + if (likely(result)) { + return __Pyx_NewRef(result); + } + PyErr_Clear(); +#endif + return __Pyx_GetBuiltinName(name); +} + +/* DictGetItem */ +#if !CYTHON_COMPILING_IN_PYPY +static PyObject *__Pyx_PyDict_GetItem(PyObject *d, PyObject* key) { + PyObject *value; + if (unlikely(__Pyx_PyDict_GetItemRef(d, key, &value) == 0)) { // no value, no error + if (unlikely(PyTuple_Check(key))) { + PyObject* args = PyTuple_Pack(1, key); + if (likely(args)) { + PyErr_SetObject(PyExc_KeyError, args); + Py_DECREF(args); + } + } else { + PyErr_SetObject(PyExc_KeyError, key); + } + } + return value; +} +#endif + +/* RaiseUnexpectedTypeError */ +static int +__Pyx_RaiseUnexpectedTypeError(const char *expected, PyObject *obj) +{ + __Pyx_TypeName obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, "Expected %s, got " __Pyx_FMT_TYPENAME, + expected, obj_type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* IterFinish (used by dict_iter) */ +static CYTHON_INLINE int __Pyx_IterFinish(void) { + PyObject* exc_type; + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + exc_type = __Pyx_PyErr_CurrentExceptionType(); + if (unlikely(exc_type)) { + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) + return -1; + __Pyx_PyErr_Clear(); + return 0; + } + return 0; +} + +/* PyObjectCallNoArg (used by PyObjectCallMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallNoArg(PyObject *func) { + PyObject *arg[2] = {NULL, NULL}; + return __Pyx_PyObject_FastCall(func, arg + 1, 0 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetMethod (used by PyObjectCallMethod0) */ +#if !(CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000))) +static int __Pyx_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) { + PyObject *attr; +#if CYTHON_UNPACK_METHODS && CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_PYTYPE_LOOKUP + __Pyx_TypeName type_name; + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + int meth_found = 0; + assert (*method == NULL); + if (unlikely(tp->tp_getattro != PyObject_GenericGetAttr)) { + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; + } + if (unlikely(tp->tp_dict == NULL) && unlikely(PyType_Ready(tp) < 0)) { + return 0; + } + descr = _PyType_Lookup(tp, name); + if (likely(descr != NULL)) { + Py_INCREF(descr); +#if defined(Py_TPFLAGS_METHOD_DESCRIPTOR) && Py_TPFLAGS_METHOD_DESCRIPTOR + if (__Pyx_PyType_HasFeature(Py_TYPE(descr), Py_TPFLAGS_METHOD_DESCRIPTOR)) +#else + #ifdef __Pyx_CyFunction_USED + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type) || __Pyx_CyFunction_Check(descr))) + #else + if (likely(PyFunction_Check(descr) || __Pyx_IS_TYPE(descr, &PyMethodDescr_Type))) + #endif +#endif + { + meth_found = 1; + } else { + f = Py_TYPE(descr)->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + } + } + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = __Pyx_PyDict_GetItemStr(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + Py_DECREF(dict); + Py_XDECREF(descr); + goto try_unpack; + } + Py_DECREF(dict); + } + if (meth_found) { + *method = descr; + return 1; + } + if (f != NULL) { + attr = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + goto try_unpack; + } + if (likely(descr != NULL)) { + *method = descr; + return 0; + } + type_name = __Pyx_PyType_GetFullyQualifiedName(tp); + PyErr_Format(PyExc_AttributeError, + "'" __Pyx_FMT_TYPENAME "' object has no attribute '%U'", + type_name, name); + __Pyx_DECREF_TypeName(type_name); + return 0; +#else + attr = __Pyx_PyObject_GetAttrStr(obj, name); + goto try_unpack; +#endif +try_unpack: +#if CYTHON_UNPACK_METHODS + if (likely(attr) && PyMethod_Check(attr) && likely(PyMethod_GET_SELF(attr) == obj)) { + PyObject *function = PyMethod_GET_FUNCTION(attr); + Py_INCREF(function); + Py_DECREF(attr); + *method = function; + return 1; + } +#endif + *method = attr; + return 0; +} +#endif + +/* PyObjectCallMethod0 (used by dict_iter) */ +static PyObject* __Pyx_PyObject_CallMethod0(PyObject* obj, PyObject* method_name) { +#if CYTHON_VECTORCALL && (__PYX_LIMITED_VERSION_HEX >= 0x030C0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x03090000)) + PyObject *args[1] = {obj}; + (void) __Pyx_PyObject_CallOneArg; + (void) __Pyx_PyObject_CallNoArg; + return PyObject_VectorcallMethod(method_name, args, 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#else + PyObject *method = NULL, *result = NULL; + int is_method = __Pyx_PyObject_GetMethod(obj, method_name, &method); + if (likely(is_method)) { + result = __Pyx_PyObject_CallOneArg(method, obj); + Py_DECREF(method); + return result; + } + if (unlikely(!method)) goto bad; + result = __Pyx_PyObject_CallNoArg(method); + Py_DECREF(method); +bad: + return result; +#endif +} + +/* RaiseNeedMoreValuesToUnpack (used by UnpackTuple2) */ +static CYTHON_INLINE void __Pyx_RaiseNeedMoreValuesError(Py_ssize_t index) { + PyErr_Format(PyExc_ValueError, + "need more than %" CYTHON_FORMAT_SSIZE_T "d value%.1s to unpack", + index, (index == 1) ? "" : "s"); +} + +/* RaiseTooManyValuesToUnpack (used by UnpackItemEndCheck) */ +static CYTHON_INLINE void __Pyx_RaiseTooManyValuesError(Py_ssize_t expected) { + PyErr_Format(PyExc_ValueError, + "too many values to unpack (expected %" CYTHON_FORMAT_SSIZE_T "d)", expected); +} + +/* UnpackItemEndCheck (used by UnpackTuple2) */ +static int __Pyx_IternextUnpackEndCheck(PyObject *retval, Py_ssize_t expected) { + if (unlikely(retval)) { + Py_DECREF(retval); + __Pyx_RaiseTooManyValuesError(expected); + return -1; + } + return __Pyx_IterFinish(); +} + +/* RaiseNoneIterError (used by UnpackTupleError) */ +static CYTHON_INLINE void __Pyx_RaiseNoneNotIterableError(void) { + PyErr_SetString(PyExc_TypeError, "'NoneType' object is not iterable"); +} + +/* UnpackTupleError (used by UnpackTuple2) */ +static void __Pyx_UnpackTupleError(PyObject *t, Py_ssize_t index) { + if (t == Py_None) { + __Pyx_RaiseNoneNotIterableError(); + } else { + Py_ssize_t size = __Pyx_PyTuple_GET_SIZE(t); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(size < 0)) return; + #endif + if (size < index) { + __Pyx_RaiseNeedMoreValuesError(size); + } else { + __Pyx_RaiseTooManyValuesError(index); + } + } +} + +/* UnpackTuple2 (used by dict_iter) */ +static CYTHON_INLINE int __Pyx_unpack_tuple2( + PyObject* tuple, PyObject** value1, PyObject** value2, int is_tuple, int has_known_size, int decref_tuple) { + if (likely(is_tuple || PyTuple_Check(tuple))) { + Py_ssize_t size; + if (has_known_size) { + return __Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple); + } + size = __Pyx_PyTuple_GET_SIZE(tuple); + if (likely(size == 2)) { + return __Pyx_unpack_tuple2_exact(tuple, value1, value2, decref_tuple); + } + if (size >= 0) { + __Pyx_UnpackTupleError(tuple, 2); + } + return -1; + } else { + return __Pyx_unpack_tuple2_generic(tuple, value1, value2, has_known_size, decref_tuple); + } +} +static CYTHON_INLINE int __Pyx_unpack_tuple2_exact( + PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, int decref_tuple) { + PyObject *value1 = NULL, *value2 = NULL; +#if CYTHON_AVOID_BORROWED_REFS || !CYTHON_ASSUME_SAFE_MACROS + value1 = __Pyx_PySequence_ITEM(tuple, 0); if (unlikely(!value1)) goto bad; + value2 = __Pyx_PySequence_ITEM(tuple, 1); if (unlikely(!value2)) goto bad; +#else + value1 = PyTuple_GET_ITEM(tuple, 0); Py_INCREF(value1); + value2 = PyTuple_GET_ITEM(tuple, 1); Py_INCREF(value2); +#endif + if (decref_tuple) { + Py_DECREF(tuple); + } + *pvalue1 = value1; + *pvalue2 = value2; + return 0; +#if CYTHON_AVOID_BORROWED_REFS || !CYTHON_ASSUME_SAFE_MACROS +bad: + Py_XDECREF(value1); + Py_XDECREF(value2); + if (decref_tuple) { Py_XDECREF(tuple); } + return -1; +#endif +} +static int __Pyx_unpack_tuple2_generic(PyObject* tuple, PyObject** pvalue1, PyObject** pvalue2, + int has_known_size, int decref_tuple) { + Py_ssize_t index; + PyObject *value1 = NULL, *value2 = NULL, *iter = NULL; + iternextfunc iternext; + iter = PyObject_GetIter(tuple); + if (unlikely(!iter)) goto bad; + if (decref_tuple) { Py_DECREF(tuple); tuple = NULL; } + iternext = __Pyx_PyObject_GetIterNextFunc(iter); + value1 = iternext(iter); if (unlikely(!value1)) { index = 0; goto unpacking_failed; } + value2 = iternext(iter); if (unlikely(!value2)) { index = 1; goto unpacking_failed; } + if (!has_known_size && unlikely(__Pyx_IternextUnpackEndCheck(iternext(iter), 2))) goto bad; + Py_DECREF(iter); + *pvalue1 = value1; + *pvalue2 = value2; + return 0; +unpacking_failed: + if (!has_known_size && __Pyx_IterFinish() == 0) + __Pyx_RaiseNeedMoreValuesError(index); +bad: + Py_XDECREF(iter); + Py_XDECREF(value1); + Py_XDECREF(value2); + if (decref_tuple) { Py_XDECREF(tuple); } + return -1; +} + +/* dict_iter */ +#if CYTHON_AVOID_BORROWED_REFS +#include +#endif +static CYTHON_INLINE PyObject* __Pyx_dict_iterator(PyObject* iterable, int is_dict, PyObject* method_name, + Py_ssize_t* p_orig_length, int* p_source_is_dict) { + is_dict = is_dict || likely(PyDict_CheckExact(iterable)); + *p_source_is_dict = is_dict; + if (is_dict) { +#if !CYTHON_AVOID_BORROWED_REFS + *p_orig_length = PyDict_Size(iterable); + Py_INCREF(iterable); + return iterable; +#else + static PyObject *py_items = NULL, *py_keys = NULL, *py_values = NULL; + PyObject **pp = NULL; + if (method_name) { + const char *name = PyUnicode_AsUTF8(method_name); + if (strcmp(name, "iteritems") == 0) pp = &py_items; + else if (strcmp(name, "iterkeys") == 0) pp = &py_keys; + else if (strcmp(name, "itervalues") == 0) pp = &py_values; + if (pp) { + if (!*pp) { + *pp = PyUnicode_FromString(name + 4); + if (!*pp) + return NULL; + } + method_name = *pp; + } + } +#endif + } + *p_orig_length = 0; + if (method_name) { + PyObject* iter; + iterable = __Pyx_PyObject_CallMethod0(iterable, method_name); + if (!iterable) + return NULL; +#if !CYTHON_AVOID_BORROWED_REFS + if (PyTuple_CheckExact(iterable) || PyList_CheckExact(iterable)) + return iterable; +#endif + iter = PyObject_GetIter(iterable); + Py_DECREF(iterable); + return iter; + } + return PyObject_GetIter(iterable); +} +#if !CYTHON_AVOID_BORROWED_REFS +static CYTHON_INLINE int __Pyx_dict_iter_next_source_is_dict( + PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos, + PyObject** pkey, PyObject** pvalue, PyObject** pitem) { + PyObject *key, *value; + if (unlikely(orig_length != PyDict_Size(iter_obj))) { + PyErr_SetString(PyExc_RuntimeError, "dictionary changed size during iteration"); + return -1; + } + if (unlikely(!PyDict_Next(iter_obj, ppos, &key, &value))) { + return 0; + } + if (pitem) { + PyObject* tuple = PyTuple_New(2); + if (unlikely(!tuple)) { + return -1; + } + Py_INCREF(key); + Py_INCREF(value); + #if CYTHON_ASSUME_SAFE_MACROS + PyTuple_SET_ITEM(tuple, 0, key); + PyTuple_SET_ITEM(tuple, 1, value); + #else + if (unlikely(PyTuple_SetItem(tuple, 0, key) < 0)) { + Py_DECREF(value); + Py_DECREF(tuple); + return -1; + } + if (unlikely(PyTuple_SetItem(tuple, 1, value) < 0)) { + Py_DECREF(tuple); + return -1; + } + #endif + *pitem = tuple; + } else { + if (pkey) { + Py_INCREF(key); + *pkey = key; + } + if (pvalue) { + Py_INCREF(value); + *pvalue = value; + } + } + return 1; +} +#endif +static CYTHON_INLINE int __Pyx_dict_iter_next( + PyObject* iter_obj, CYTHON_NCP_UNUSED Py_ssize_t orig_length, CYTHON_NCP_UNUSED Py_ssize_t* ppos, + PyObject** pkey, PyObject** pvalue, PyObject** pitem, int source_is_dict) { + PyObject* next_item; +#if !CYTHON_AVOID_BORROWED_REFS + if (source_is_dict) { + int result; +#if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_BEGIN_CRITICAL_SECTION(iter_obj); +#endif + result = __Pyx_dict_iter_next_source_is_dict(iter_obj, orig_length, ppos, pkey, pvalue, pitem); +#if PY_VERSION_HEX >= 0x030d0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_END_CRITICAL_SECTION(); +#endif + return result; + } else if (PyTuple_CheckExact(iter_obj)) { + Py_ssize_t pos = *ppos; + Py_ssize_t tuple_size = __Pyx_PyTuple_GET_SIZE(iter_obj); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(tuple_size < 0)) return -1; + #endif + if (unlikely(pos >= tuple_size)) return 0; + *ppos = pos + 1; + #if CYTHON_ASSUME_SAFE_MACROS + next_item = PyTuple_GET_ITEM(iter_obj, pos); + #else + next_item = PyTuple_GetItem(iter_obj, pos); + if (unlikely(!next_item)) return -1; + #endif + Py_INCREF(next_item); + } else if (PyList_CheckExact(iter_obj)) { + Py_ssize_t pos = *ppos; + Py_ssize_t list_size = __Pyx_PyList_GET_SIZE(iter_obj); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(list_size < 0)) return -1; + #endif + if (unlikely(pos >= list_size)) return 0; + *ppos = pos + 1; + next_item = __Pyx_PyList_GetItemRef(iter_obj, pos); + if (unlikely(!next_item)) return -1; + } else +#endif + { + next_item = PyIter_Next(iter_obj); + if (unlikely(!next_item)) { + return __Pyx_IterFinish(); + } + } + if (pitem) { + *pitem = next_item; + } else if (pkey && pvalue) { + if (__Pyx_unpack_tuple2(next_item, pkey, pvalue, source_is_dict, source_is_dict, 1)) + return -1; + } else if (pkey) { + *pkey = next_item; + } else { + *pvalue = next_item; + } + return 1; +} + +/* unicode_tailmatch */ +static int __Pyx_PyUnicode_TailmatchTuple(PyObject* s, PyObject* substrings, + Py_ssize_t start, Py_ssize_t end, int direction) { + Py_ssize_t i, count = __Pyx_PyTuple_GET_SIZE(substrings); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(count < 0)) return -1; + #endif + for (i = 0; i < count; i++) { + Py_ssize_t result; +#if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + result = PyUnicode_Tailmatch(s, PyTuple_GET_ITEM(substrings, i), + start, end, direction); +#else + PyObject* sub = __Pyx_PySequence_ITEM(substrings, i); + if (unlikely(!sub)) return -1; + result = PyUnicode_Tailmatch(s, sub, start, end, direction); + Py_DECREF(sub); +#endif + if (result) { + return (int) result; + } + } + return 0; +} +static int __Pyx_PyUnicode_Tailmatch(PyObject* s, PyObject* substr, + Py_ssize_t start, Py_ssize_t end, int direction) { + if (unlikely(PyTuple_Check(substr))) { + return __Pyx_PyUnicode_TailmatchTuple(s, substr, start, end, direction); + } + return (int) PyUnicode_Tailmatch(s, substr, start, end, direction); +} + +/* HasAttr (used by ImportImpl) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!PyUnicode_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; + } + r = __Pyx_PyObject_GetAttrStrNoError(o, n); + if (!r) { + return (unlikely(PyErr_Occurred())) ? -1 : 0; + } else { + Py_DECREF(r); + return 1; + } +} +#endif + +/* ImportImpl (used by Import) */ +static int __Pyx__Import_GetModule(PyObject *qualname, PyObject **module) { + PyObject *imported_module = PyImport_GetModule(qualname); + if (unlikely(!imported_module)) { + *module = NULL; + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + *module = imported_module; + return 1; +} +static int __Pyx__Import_Lookup(PyObject *qualname, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject **module) { + PyObject *imported_module; + PyObject *top_level_package_name; + Py_ssize_t i; + int status, module_found; + Py_ssize_t dot_index; + module_found = __Pyx__Import_GetModule(qualname, &imported_module); + if (unlikely(!module_found || module_found == -1)) { + *module = NULL; + return module_found; + } + if (imported_names) { + for (i = 0; i < len_imported_names; i++) { + PyObject *imported_name = imported_names[i]; +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 + int has_imported_attribute = PyObject_HasAttr(imported_module, imported_name); +#else + int has_imported_attribute = PyObject_HasAttrWithError(imported_module, imported_name); + if (unlikely(has_imported_attribute == -1)) goto error; +#endif + if (!has_imported_attribute) { + goto not_found; + } + } + *module = imported_module; + return 1; + } + dot_index = PyUnicode_FindChar(qualname, '.', 0, PY_SSIZE_T_MAX, 1); + if (dot_index == -1) { + *module = imported_module; + return 1; + } + if (unlikely(dot_index == -2)) goto error; + top_level_package_name = PyUnicode_Substring(qualname, 0, dot_index); + if (unlikely(!top_level_package_name)) goto error; + Py_DECREF(imported_module); + status = __Pyx__Import_GetModule(top_level_package_name, module); + Py_DECREF(top_level_package_name); + return status; +error: + Py_DECREF(imported_module); + *module = NULL; + return -1; +not_found: + Py_DECREF(imported_module); + *module = NULL; + return 0; +} +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *from_list = 0; + int module_found; + if (!qualname) { + qualname = name; + } + module_found = __Pyx__Import_Lookup(qualname, imported_names, len_imported_names, &module); + if (likely(module_found == 1)) { + return module; + } else if (unlikely(module_found == -1)) { + return NULL; + } + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + if (imported_names) { +#if CYTHON_COMPILING_IN_CPYTHON + from_list = __Pyx_PyList_FromArray(imported_names, len_imported_names); + if (unlikely(!from_list)) + goto bad; +#else + from_list = PyList_New(len_imported_names); + if (unlikely(!from_list)) goto bad; + for (Py_ssize_t i=0; i__pyx_d, level); +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_mstate_global->__pyx_kp_u_); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) ||\ + CYTHON_COMPILING_IN_GRAAL + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, "cannot import name %S", name); + } + return value; +} + +/* dict_setdefault (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value) { + PyObject* value; +#if __PYX_LIMITED_VERSION_HEX >= 0x030F0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4) + PyDict_SetDefaultRef(d, key, default_value, &value); +#elif CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + PyObject *args[] = {d, key, default_value}; + value = PyObject_VectorcallMethod(__pyx_mstate_global->__pyx_n_u_setdefault, args, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#elif CYTHON_COMPILING_IN_LIMITED_API + value = PyObject_CallMethodObjArgs(d, __pyx_mstate_global->__pyx_n_u_setdefault, key, default_value, NULL); +#else + value = PyDict_SetDefault(d, key, default_value); + if (unlikely(!value)) return NULL; + Py_INCREF(value); +#endif + return value; +} + +/* LimitedApiGetTypeDict (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static Py_ssize_t __Pyx_GetTypeDictOffset(void) { + PyObject *tp_dictoffset_o; + Py_ssize_t tp_dictoffset; + tp_dictoffset_o = PyObject_GetAttrString((PyObject*)(&PyType_Type), "__dictoffset__"); + if (unlikely(!tp_dictoffset_o)) return -1; + tp_dictoffset = PyLong_AsSsize_t(tp_dictoffset_o); + Py_DECREF(tp_dictoffset_o); + if (unlikely(tp_dictoffset == 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' doesn't have a dictoffset"); + return -1; + } else if (unlikely(tp_dictoffset < 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' has an unexpected negative dictoffset. " + "Please report this as Cython bug"); + return -1; + } + return tp_dictoffset; +} +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp) { + static Py_ssize_t tp_dictoffset = 0; + if (unlikely(tp_dictoffset == 0)) { + tp_dictoffset = __Pyx_GetTypeDictOffset(); + if (unlikely(tp_dictoffset == -1 && PyErr_Occurred())) { + tp_dictoffset = 0; // try again next time? + return NULL; + } + } + return *(PyObject**)((char*)tp + tp_dictoffset); +} +#endif + +/* SetItemOnTypeDict (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v) { + int result; + PyObject *tp_dict; +#if CYTHON_COMPILING_IN_LIMITED_API + tp_dict = __Pyx_GetTypeDict(tp); + if (unlikely(!tp_dict)) return -1; +#else + tp_dict = tp->tp_dict; +#endif + result = PyDict_SetItem(tp_dict, k, v); + if (likely(!result)) { + PyType_Modified(tp); + if (unlikely(PyObject_HasAttr(v, __pyx_mstate_global->__pyx_n_u_set_name))) { + PyObject *setNameResult = PyObject_CallMethodObjArgs(v, __pyx_mstate_global->__pyx_n_u_set_name, (PyObject *) tp, k, NULL); + if (!setNameResult) return -1; + Py_DECREF(setNameResult); + } + } + return result; +} + +/* FixUpExtensionType (used by FetchCommonType) */ +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if __PYX_LIMITED_VERSION_HEX > 0x030900B1 + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#else + const PyType_Slot *slot = spec->slots; + int changed = 0; +#if !CYTHON_COMPILING_IN_LIMITED_API + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { +#if !CYTHON_COMPILING_IN_CPYTHON + const +#endif // !CYTHON_COMPILING_IN_CPYTHON) + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_vectorcall_offset = memb->offset; + changed = 1; + } +#endif // CYTHON_METH_FASTCALL +#if !CYTHON_COMPILING_IN_PYPY + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } +#endif // !CYTHON_COMPILING_IN_PYPY + } + memb++; + } + } +#endif // !CYTHON_COMPILING_IN_LIMITED_API +#if !CYTHON_COMPILING_IN_PYPY + slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_getset) + slot++; + if (slot && slot->slot == Py_tp_getset) { + PyGetSetDef *getset = (PyGetSetDef*) slot->pfunc; + while (getset && getset->name) { + if (getset->name[0] == '_' && getset->name[1] == '_' && strcmp(getset->name, "__module__") == 0) { + PyObject *descr = PyDescr_NewGetSet(type, getset); + if (unlikely(!descr)) + return -1; + #if CYTHON_COMPILING_IN_LIMITED_API + PyObject *pyname = PyUnicode_FromString(getset->name); + if (unlikely(!pyname)) { + Py_DECREF(descr); + return -1; + } + int set_item_result = __Pyx_SetItemOnTypeDict(type, pyname, descr); + Py_DECREF(pyname); + #else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + #endif + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } + ++getset; + } + } +#else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#endif // !CYTHON_COMPILING_IN_PYPY + if (changed) + PyType_Modified(type); +#endif // PY_VERSION_HEX > 0x030900B1 + return 0; +} + +/* AddModuleRef (used by FetchSharedCythonModule) */ +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + static PyObject *__Pyx_PyImport_AddModuleObjectRef(PyObject *name) { + PyObject *module_dict = PyImport_GetModuleDict(); + PyObject *m; + if (PyMapping_GetOptionalItem(module_dict, name, &m) < 0) { + return NULL; + } + if (m != NULL && PyModule_Check(m)) { + return m; + } + Py_XDECREF(m); + m = PyModule_NewObject(name); + if (m == NULL) + return NULL; + if (PyDict_CheckExact(module_dict)) { + PyObject *new_m; + (void)PyDict_SetDefaultRef(module_dict, name, m, &new_m); + Py_DECREF(m); + return new_m; + } else { + if (PyObject_SetItem(module_dict, name, m) != 0) { + Py_DECREF(m); + return NULL; + } + return m; + } + } + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *py_name = PyUnicode_FromString(name); + if (!py_name) return NULL; + PyObject *module = __Pyx_PyImport_AddModuleObjectRef(py_name); + Py_DECREF(py_name); + return module; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif + +/* FetchSharedCythonModule (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef(__PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType (used by CommonTypesMetaclass) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject* __Pyx_PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *result = __Pyx_PyType_FromModuleAndSpec(module, spec, bases); + if (result && metaclass) { + PyObject *old_tp = (PyObject*)Py_TYPE(result); + Py_INCREF((PyObject*)metaclass); +#if __PYX_LIMITED_VERSION_HEX >= 0x03090000 + Py_SET_TYPE(result, metaclass); +#else + result->ob_type = metaclass; +#endif + Py_DECREF(old_tp); + } + return result; +} +#else +#define __Pyx_PyType_FromMetaclass(me, mo, s, b) PyType_FromMetaclass(me, mo, s, b) +#endif +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t expected_basicsize) { + Py_ssize_t basicsize; + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (expected_basicsize == 0) { + return 0; // size is inherited, nothing useful to check + } +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) return -1; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = NULL; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) return -1; +#else + basicsize = ((PyTypeObject*) cached_type)->tp_basicsize; +#endif + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module = NULL, *cached_type = NULL, *abi_module_dict, *new_cached_type, *py_object_name; + int get_item_ref_result; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + py_object_name = PyUnicode_FromString(object_name); + if (!py_object_name) return NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) goto done; + abi_module_dict = PyModule_GetDict(abi_module); + if (!abi_module_dict) goto done; + get_item_ref_result = __Pyx_PyDict_GetItemRef(abi_module_dict, py_object_name, &cached_type); + if (get_item_ref_result == 1) { + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else if (unlikely(get_item_ref_result == -1)) { + goto bad; + } + cached_type = __Pyx_PyType_FromMetaclass( + metaclass, + CYTHON_USE_MODULE_STATE ? module : abi_module, + spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + new_cached_type = __Pyx_PyDict_SetDefault(abi_module_dict, py_object_name, cached_type); + if (unlikely(new_cached_type != cached_type)) { + if (unlikely(!new_cached_type)) goto bad; + Py_DECREF(cached_type); + cached_type = new_cached_type; + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else { + Py_DECREF(new_cached_type); + } +done: + Py_XDECREF(abi_module); + Py_DECREF(py_object_name); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} + +/* CommonTypesMetaclass (used by CythonFunctionShared) */ +static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) { + return PyUnicode_FromString(__PYX_ABI_MODULE_NAME); +} +#if __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject* __pyx_CommonTypesMetaclass_call(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *args, CYTHON_UNUSED PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, "Cannot instantiate Cython internal types"); + return NULL; +} +static int __pyx_CommonTypesMetaclass_setattr(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *attr, CYTHON_UNUSED PyObject *value) { + PyErr_SetString(PyExc_TypeError, "Cython internal types are immutable"); + return -1; +} +#endif +static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = { + {"__module__", __pyx_CommonTypesMetaclass_get_module, NULL, NULL, NULL}, + {0, 0, 0, 0, 0} +}; +static PyType_Slot __pyx_CommonTypesMetaclass_slots[] = { + {Py_tp_getset, (void *)__pyx_CommonTypesMetaclass_getset}, + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {Py_tp_call, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_new, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_setattro, (void*)__pyx_CommonTypesMetaclass_setattr}, + #endif + {0, 0} +}; +static PyType_Spec __pyx_CommonTypesMetaclass_spec = { + __PYX_TYPE_MODULE_PREFIX "_common_types_metatype", + 0, + 0, + Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT, + __pyx_CommonTypesMetaclass_slots +}; +static int __pyx_CommonTypesMetaclass_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + PyObject *bases = PyTuple_Pack(1, &PyType_Type); + if (unlikely(!bases)) { + return -1; + } + mstate->__pyx_CommonTypesMetaclassType = __Pyx_FetchCommonTypeFromSpec(NULL, module, &__pyx_CommonTypesMetaclass_spec, bases); + Py_DECREF(bases); + if (unlikely(mstate->__pyx_CommonTypesMetaclassType == NULL)) { + return -1; + } + return 0; +} + +/* CallTypeTraverse (used by CythonFunctionShared) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg) { + #if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x03090000 + if (__Pyx_get_runtime_version() < 0x03090000) return 0; + #endif + if (!always_call) { + PyTypeObject *base = __Pyx_PyObject_GetSlot(o, tp_base, PyTypeObject*); + unsigned long flags = PyType_GetFlags(base); + if (flags & Py_TPFLAGS_HEAPTYPE) { + return 0; + } + } + Py_VISIT((PyObject*)Py_TYPE(o)); + return 0; +} +#endif + +/* PyMethodNew (used by CythonFunctionShared) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *result; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + #if __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + { + PyObject *args[] = {func, self}; + result = PyObject_Vectorcall(__pyx_mstate_global->__Pyx_CachedMethodType, args, 2, NULL); + } + #else + result = PyObject_CallFunctionObjArgs(__pyx_mstate_global->__Pyx_CachedMethodType, func, self, NULL); + #endif + return result; +} +#else +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#endif + +/* PyVectorcallFastCallDict (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i; + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos; + #else + Py_ssize_t pos; + #endif + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + #if !CYTHON_ASSUME_SAFE_SIZE + Py_ssize_t nkw = PyDict_Size(kw); + if (unlikely(nkw == -1)) return NULL; + #else + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + #endif + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = 0; + i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (__Pyx_PyDict_NextRef(kw, &pos, &key, &value)) { + keys_are_strings &= + #if CYTHON_COMPILING_IN_LIMITED_API + PyType_GetFlags(Py_TYPE(key)); + #else + Py_TYPE(key)->tp_flags; + #endif + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(PyTuple_SetItem(kwnames, i, key) < 0)) goto cleanup; + #else + PyTuple_SET_ITEM(kwnames, i, key); + #endif + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(pos); + #endif + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + Py_ssize_t kw_size = + likely(kw == NULL) ? + 0 : +#if !CYTHON_ASSUME_SAFE_SIZE + PyDict_Size(kw); +#else + PyDict_GET_SIZE(kw); +#endif + if (kw_size == 0) { + return vc(func, args, nargs, NULL); + } +#if !CYTHON_ASSUME_SAFE_SIZE + else if (unlikely(kw_size == -1)) { + return NULL; + } +#endif + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared (used by CythonFunction) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunctionNoMethod(PyObject *func, void (*cfunc)(void)) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if ((PyObject*)Py_TYPE(func) == __pyx_mstate_global->__Pyx_CachedMethodType) { + int result; + PyObject *newFunc = PyObject_GetAttr(func, __pyx_mstate_global->__pyx_n_u_func); + if (unlikely(!newFunc)) { + PyErr_Clear(); // It's only an optimization, so don't throw an error + return 0; + } + result = __Pyx__IsSameCyOrCFunctionNoMethod(newFunc, cfunc); + Py_DECREF(newFunc); + return result; + } + return __Pyx__IsSameCyOrCFunctionNoMethod(func, cfunc); +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if (PyMethod_Check(func)) { + func = PyMethod_GET_FUNCTION(func); + } + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) { + PyObject *result; + CYTHON_UNUSED_VAR(closure); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_doc_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#else + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_name_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_name, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + PyObject *result; + __Pyx_BEGIN_CRITICAL_SECTION(op); + Py_INCREF(op->func_qualname); + result = op->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +#endif +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_tuple; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_defaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_kwdict; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_kwdefaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->func_annotations; + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_annotations_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine_value(__pyx_CyFunctionObject *op) { + int is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; + if (is_coroutine) { + PyObject *is_coroutine_value, *module, *fromlist, *marker = __pyx_mstate_global->__pyx_n_u_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_mstate_global->__pyx_n_u_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + is_coroutine_value = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(is_coroutine_value)) { + return is_coroutine_value; + } +ignore: + PyErr_Clear(); + } + return __Pyx_PyBool_FromLong(is_coroutine); +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + result = __Pyx_CyFunction_get_is_coroutine_value(op); + if (unlikely(!result)) + return NULL; + __Pyx_BEGIN_CRITICAL_SECTION(op); + if (op->func_is_coroutine) { + Py_DECREF(result); + result = __Pyx_NewRef(op->func_is_coroutine); + } else { + op->func_is_coroutine = __Pyx_NewRef(result); + } + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static void __Pyx_CyFunction_raise_argument_count_error(__pyx_CyFunctionObject *func, const char* message, Py_ssize_t size) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, message, size); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + name, message, size); +#endif +} +static void __Pyx_CyFunction_raise_type_error(__pyx_CyFunctionObject *func, const char* message) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s", + py_name, message); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s", + name, message); +#endif +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {"func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {"func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, +#else + {"func_dict", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, +#endif + {"func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {"__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {"_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {"__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + {"__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#endif +#if CYTHON_METH_FASTCALL +#if CYTHON_COMPILING_IN_LIMITED_API + {"__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else + {"__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + {"__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {"__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(args); + __Pyx_BEGIN_CRITICAL_SECTION(m); + Py_INCREF(m->func_qualname); + result = m->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + op->func_dict = NULL; +#endif + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func_dict); +#elif PY_VERSION_HEX < 0x030d0000 + _PyObject_ClearManagedDict((PyObject*)m); +#else + PyObject_ClearManagedDict((PyObject*)m); +#endif + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + Py_CLEAR(m->defaults); + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + { + int e = __Pyx_call_type_traverse((PyObject*)m, 1, visit, arg); + if (e) return e; + } + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func_dict); +#else + { + int e = +#if PY_VERSION_HEX < 0x030d0000 + _PyObject_VisitManagedDict +#else + PyObject_VisitManagedDict +#endif + ((PyObject*)m, visit, arg); + if (e != 0) return e; + } +#endif + __Pyx_VISIT_CONST(m->func_name); + __Pyx_VISIT_CONST(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + __Pyx_VISIT_CONST(m->func_code); + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_annotations); + Py_VISIT(m->func_is_coroutine); + Py_VISIT(m->defaults); + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ + PyObject *repr; + __Pyx_BEGIN_CRITICAL_SECTION(op); + repr = PyUnicode_FromFormat("", + op->func_qualname, (void *)op); + __Pyx_END_CRITICAL_SECTION(); + return repr; +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes no arguments", size); + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes exactly one argument", size); + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } + __Pyx_CyFunction_raise_type_error( + (__pyx_CyFunctionObject*)func, "takes no keyword arguments"); + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_SIZE + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(argc < 0)) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "needs an argument"); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(__Pyx_PyTuple_GET_SIZE(kwnames))) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "takes no keyword arguments"); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes no arguments", nargs); + return NULL; + } + return meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes exactly one argument", nargs); + return NULL; + } + return meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + #if PY_VERSION_HEX < 0x030e00A6 + size_t nargs_value = (size_t) nargs; + #else + Py_ssize_t nargs_value = nargs; + #endif + return ((__Pyx_PyCMethod)(void(*)(void))meth)(self, cls, args, nargs_value, kwnames); +} +#endif +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if CYTHON_METH_FASTCALL +#if defined(Py_TPFLAGS_HAVE_VECTORCALL) + Py_TPFLAGS_HAVE_VECTORCALL | +#elif defined(_Py_TPFLAGS_HAVE_VECTORCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif +#endif // CYTHON_METH_FASTCALL +#if PY_VERSION_HEX >= 0x030C0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_TPFLAGS_MANAGED_DICT | +#endif + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +static int __pyx_CyFunction_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + mstate->__pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec( + mstate->__pyx_CommonTypesMetaclassType, module, &__pyx_CyFunctionType_spec, NULL); + if (unlikely(mstate->__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, PyTypeObject *defaults_type) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_CallObject((PyObject*)defaults_type, NULL); // _PyObject_New(defaults_type); + if (unlikely(!m->defaults)) + return NULL; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_mstate_global->__pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* CLineInTraceback (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +#define __Pyx_PyProbablyModule_GetDict(o) __Pyx_XNewRef(PyModule_GetDict(o)) +#elif !CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyProbablyModule_GetDict(o) PyObject_GenericGetDict(o, NULL); +#else +PyObject* __Pyx_PyProbablyModule_GetDict(PyObject *o) { + PyObject **dict_ptr = _PyObject_GetDictPtr(o); + return dict_ptr ? __Pyx_XNewRef(*dict_ptr) : NULL; +} +#endif +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline = NULL; + PyObject *ptype, *pvalue, *ptraceback; + PyObject *cython_runtime_dict; + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_mstate_global->__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + cython_runtime_dict = __Pyx_PyProbablyModule_GetDict(__pyx_mstate_global->__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, cython_runtime_dict, + __Pyx_PyDict_SetDefault(cython_runtime_dict, __pyx_mstate_global->__pyx_n_u_cline_in_traceback, Py_False)) + } + if (use_cline == NULL || use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + Py_XDECREF(use_cline); + Py_XDECREF(cython_runtime_dict); + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache (used by AddTraceback) */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static __Pyx_CachedCodeObjectType *__pyx__find_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line) { + __Pyx_CachedCodeObjectType* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!code_cache->entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if (unlikely(pos >= code_cache->count) || unlikely(code_cache->entries[pos].code_line != code_line)) { + return NULL; + } + code_object = code_cache->entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__find_code_object; + return NULL; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just miss. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type old_count = __pyx_atomic_incr_acq_rel(&code_cache->accessor_count); + if (old_count < 0) { + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); + return NULL; + } +#endif + __Pyx_CachedCodeObjectType *result = __pyx__find_code_object(code_cache, code_line); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); +#endif + return result; +#endif +} +static void __pyx__insert_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line, __Pyx_CachedCodeObjectType* code_object) +{ + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = code_cache->entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + code_cache->entries = entries; + code_cache->max_count = 64; + code_cache->count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if ((pos < code_cache->count) && unlikely(code_cache->entries[pos].code_line == code_line)) { + __Pyx_CachedCodeObjectType* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_INCREF(code_object); + Py_DECREF(tmp); + return; + } + if (code_cache->count == code_cache->max_count) { + int new_max = code_cache->max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + code_cache->entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + code_cache->entries = entries; + code_cache->max_count = new_max; + } + for (i=code_cache->count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + code_cache->count++; + Py_INCREF(code_object); +} +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__insert_code_object; + return; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just fail. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type expected = 0; + if (!__pyx_atomic_int_cmp_exchange(&code_cache->accessor_count, &expected, INT_MIN)) { + return; + } +#endif + __pyx__insert_code_object(code_cache, code_line, code_object); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_sub(&code_cache->accessor_count, INT_MIN); +#endif +#endif +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION) + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result = PyObject_Call(replace, __pyx_mstate_global->__pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + c_line = __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!code_object) { + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + } else { + py_funcname = PyUnicode_FromString(funcname); + } + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, code_object); + } else { + dict = PyDict_New(); + } + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + } + py_code = PyCode_NewEmpty(filename, funcname, py_line); + Py_XDECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_mstate_global->__pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static __Pyx_TypeName +__Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp) +{ + PyObject *module = NULL, *name = NULL, *result = NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_qualname); + #else + name = PyType_GetQualName(tp); + #endif + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) goto bad; + module = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_module); + if (unlikely(module == NULL) || unlikely(!PyUnicode_Check(module))) goto bad; + if (PyUnicode_CompareWithASCIIString(module, "builtins") == 0) { + result = name; + name = NULL; + goto done; + } + result = PyUnicode_FromFormat("%U.%U", module, name); + if (unlikely(result == NULL)) goto bad; + done: + Py_XDECREF(name); + Py_XDECREF(module); + return result; + bad: + PyErr_Clear(); + if (name) { + result = name; + name = NULL; + } else { + result = __Pyx_NewRef(__pyx_mstate_global->__pyx_kp_u__2); + } + goto done; +} +#endif + +/* PyObjectVectorCallKwBuilder (used by CIntToPy) */ +#if CYTHON_VECTORCALL +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_PyObject_FastCallDict; + Py_INCREF(key); + if (__Pyx_PyTuple_SET_ITEM(builder, n, key) != (0)) return -1; + args[n] = value; + return 0; +} +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_VectorcallBuilder_AddArgStr; + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n); +} +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + PyObject *pyKey = PyUnicode_FromString(key); + if (!pyKey) return -1; + return __Pyx_VectorcallBuilder_AddArg(pyKey, value, builder, args, n); +} +#else // CYTHON_VECTORCALL +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, CYTHON_UNUSED PyObject **args, CYTHON_UNUSED int n) { + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return PyDict_SetItem(builder, key, value); +} +#endif + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#if !CYTHON_COMPILING_IN_PYPY + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 + if (is_unsigned) { + return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); + } else { + return PyLong_FromNativeBytes(bytes, sizeof(value), -1); + } +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + int one = 1; int little = (int)*(unsigned char *)&one; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + int one = 1; int little = (int)*(unsigned char *)&one; + PyObject *from_bytes, *result = NULL, *kwds = NULL; + PyObject *py_bytes = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + { + PyObject *args[3+(CYTHON_VECTORCALL ? 1 : 0)] = { NULL, py_bytes, order_str }; + if (!is_unsigned) { + kwds = __Pyx_MakeVectorcallBuilderKwds(1); + if (!kwds) goto limited_bad; + if (__Pyx_VectorcallBuilder_AddArgStr("signed", __Pyx_NewRef(Py_True), kwds, args+3, 0) < 0) goto limited_bad; + } + result = __Pyx_Object_Vectorcall_CallFromBuilder(from_bytes, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, kwds); + } + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntFromPyVerify (used by CIntFromPy) */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + long val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (long) -1; + val = __Pyx_PyLong_As_long(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + long val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (long) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (long) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = v; + } + v = NULL; + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((long) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (long) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + int val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (int) -1; + val = __Pyx_PyLong_As_int(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + int val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (int) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (int) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = v; + } + v = NULL; + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((int) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (int) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); + for (i=0; i>= 8; + ++i; + } + __Pyx_cached_runtime_version = version; + } +} +#endif +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + return Py_Version & ~0xFFUL; +#else + return __Pyx_cached_runtime_version; +#endif +} + +/* CheckBinaryVersion */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* NewCodeObj */ +#if CYTHON_COMPILING_IN_LIMITED_API + static PyObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + PyObject *version_info; + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + minor_version = 11; + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } +#elif PY_VERSION_HEX >= 0x030B0000 + static PyCodeObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, __pyx_mstate_global->__pyx_empty_bytes); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030c00A1 + if (likely(result)) + result->_co_firsttraceable = 0; + #endif + return result; + } +#elif !CYTHON_COMPILING_IN_PYPY + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +) { + PyObject *code_obj = NULL, *varnames_tuple_dedup = NULL, *code_bytes = NULL; + Py_ssize_t var_count = (Py_ssize_t) descr.nlocals; + PyObject *varnames_tuple = PyTuple_New(var_count); + if (unlikely(!varnames_tuple)) return NULL; + for (Py_ssize_t i=0; i < var_count; i++) { + Py_INCREF(varnames[i]); + if (__Pyx_PyTuple_SET_ITEM(varnames_tuple, i, varnames[i]) != (0)) goto done; + } + #if CYTHON_COMPILING_IN_LIMITED_API + varnames_tuple_dedup = PyDict_GetItem(tuple_dedup_map, varnames_tuple); + if (!varnames_tuple_dedup) { + if (unlikely(PyDict_SetItem(tuple_dedup_map, varnames_tuple, varnames_tuple) < 0)) goto done; + varnames_tuple_dedup = varnames_tuple; + } + #else + varnames_tuple_dedup = PyDict_SetDefault(tuple_dedup_map, varnames_tuple, varnames_tuple); + if (unlikely(!varnames_tuple_dedup)) goto done; + #endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(varnames_tuple_dedup); + #endif + if (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table != NULL && !CYTHON_COMPILING_IN_GRAAL) { + Py_ssize_t line_table_length = __Pyx_PyBytes_GET_SIZE(line_table); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(line_table_length == -1)) goto done; + #endif + Py_ssize_t code_len = (line_table_length * 2 + 4) & ~3LL; + code_bytes = PyBytes_FromStringAndSize(NULL, code_len); + if (unlikely(!code_bytes)) goto done; + char* c_code_bytes = PyBytes_AsString(code_bytes); + if (unlikely(!c_code_bytes)) goto done; + memset(c_code_bytes, 0, (size_t) code_len); + } + code_obj = (PyObject*) __Pyx__PyCode_New( + (int) descr.argcount, + (int) descr.num_posonly_args, + (int) descr.num_kwonly_args, + (int) descr.nlocals, + 0, + (int) descr.flags, + code_bytes ? code_bytes : __pyx_mstate_global->__pyx_empty_bytes, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + varnames_tuple_dedup, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + filename, + funcname, + (int) descr.first_line, + (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table) ? line_table : __pyx_mstate_global->__pyx_empty_bytes + ); +done: + Py_XDECREF(code_bytes); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(varnames_tuple_dedup); + #endif + Py_DECREF(varnames_tuple); + return code_obj; +} + +/* DecompressString */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo) { + PyObject *module = NULL, *decompress, *compressed_bytes, *decompressed; + const char* module_name = algo == 3 ? "compression.zstd" : algo == 2 ? "bz2" : "zlib"; + PyObject *methodname = PyUnicode_FromString("decompress"); + if (unlikely(!methodname)) return NULL; + #if __PYX_LIMITED_VERSION_HEX >= 0x030e0000 + if (algo == 3) { + PyObject *fromlist = Py_BuildValue("[O]", methodname); + if (unlikely(!fromlist)) goto bad; + module = PyImport_ImportModuleLevel("compression.zstd", NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + } else + #endif + module = PyImport_ImportModule(module_name); + if (unlikely(!module)) goto import_failed; + decompress = PyObject_GetAttr(module, methodname); + if (unlikely(!decompress)) goto import_failed; + { + #ifdef __cplusplus + char *memview_bytes = const_cast(s); + #else + #if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wcast-qual" + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + char *memview_bytes = (char*) s; + #if defined(__clang__) + #pragma clang diagnostic pop + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic pop + #endif + #endif + #if CYTHON_COMPILING_IN_LIMITED_API && !defined(PyBUF_READ) + int memview_flags = 0x100; + #else + int memview_flags = PyBUF_READ; + #endif + compressed_bytes = PyMemoryView_FromMemory(memview_bytes, length, memview_flags); + } + if (unlikely(!compressed_bytes)) { + Py_DECREF(decompress); + goto bad; + } + decompressed = PyObject_CallFunctionObjArgs(decompress, compressed_bytes, NULL); + Py_DECREF(compressed_bytes); + Py_DECREF(decompress); + Py_DECREF(module); + Py_DECREF(methodname); + return decompressed; +import_failed: + PyErr_Format(PyExc_ImportError, + "Failed to import '%.20s.decompress' - cannot initialise module strings. " + "String compression was configured with the C macro 'CYTHON_COMPRESS_STRINGS=%d'.", + module_name, algo); +bad: + Py_XDECREF(module); + Py_DECREF(methodname); + return NULL; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + { + const char* result; + Py_ssize_t unicode_length; + CYTHON_MAYBE_UNUSED_VAR(unicode_length); // only for __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + if (unlikely(PyArg_Parse(o, "s#", &result, length) < 0)) return NULL; + #else + result = PyUnicode_AsUTF8AndSize(o, length); + #endif + #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + unicode_length = PyUnicode_GetLength(o); + if (unlikely(unicode_length < 0)) return NULL; + if (unlikely(unicode_length != *length)) { + PyUnicode_AsASCIIString(o); + return NULL; + } + #endif + return result; + } +#else +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +#endif +} +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + if (PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif + if (PyByteArray_Check(o)) { +#if (CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) || (CYTHON_COMPILING_IN_PYPY && (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))) + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); +#else + *length = PyByteArray_Size(o); + if (*length == -1) return NULL; + return PyByteArray_AsString(o); +#endif + } else + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_LongWrongResultType(PyObject* result) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(result)); + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME ")", + result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + PyObject *res = NULL; + if (likely(PyLong_Check(x))) + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + if (likely(m && m->nb_int)) { + res = m->nb_int(x); + } +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Long(x); + } +#endif + if (likely(res)) { + if (unlikely(!PyLong_CheckExact(res))) { + return __Pyx_PyNumber_LongWrongResultType(res); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyLong_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyLong_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b) { + CYTHON_UNUSED_VAR(b); + return __Pyx_NewRef(Py_None); +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return __Pyx_NewRef(b ? Py_True: Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t ival) { + return PyLong_FromSize_t(ival); +} + + +/* MultiPhaseInitModuleState */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +#ifndef CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#if (CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030C0000) + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 1 +#else + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 0 +#endif +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE && !CYTHON_ATOMICS +#error "Module state with PEP489 requires atomics. Currently that's one of\ + C11, C++11, gcc atomic intrinsics or MSVC atomic intrinsics" +#endif +#if !CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#define __Pyx_ModuleStateLookup_Lock() +#define __Pyx_ModuleStateLookup_Unlock() +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 +static PyMutex __Pyx_ModuleStateLookup_mutex = {0}; +#define __Pyx_ModuleStateLookup_Lock() PyMutex_Lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() PyMutex_Unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(__cplusplus) && __cplusplus >= 201103L +#include +static std::mutex __Pyx_ModuleStateLookup_mutex; +#define __Pyx_ModuleStateLookup_Lock() __Pyx_ModuleStateLookup_mutex.lock() +#define __Pyx_ModuleStateLookup_Unlock() __Pyx_ModuleStateLookup_mutex.unlock() +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201112L) && !defined(__STDC_NO_THREADS__) +#include +static mtx_t __Pyx_ModuleStateLookup_mutex; +static once_flag __Pyx_ModuleStateLookup_mutex_once_flag = ONCE_FLAG_INIT; +static void __Pyx_ModuleStateLookup_initialize_mutex(void) { + mtx_init(&__Pyx_ModuleStateLookup_mutex, mtx_plain); +} +#define __Pyx_ModuleStateLookup_Lock()\ + call_once(&__Pyx_ModuleStateLookup_mutex_once_flag, __Pyx_ModuleStateLookup_initialize_mutex);\ + mtx_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() mtx_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(HAVE_PTHREAD_H) +#include +static pthread_mutex_t __Pyx_ModuleStateLookup_mutex = PTHREAD_MUTEX_INITIALIZER; +#define __Pyx_ModuleStateLookup_Lock() pthread_mutex_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() pthread_mutex_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(_WIN32) +#include // synchapi.h on its own doesn't work +static SRWLOCK __Pyx_ModuleStateLookup_mutex = SRWLOCK_INIT; +#define __Pyx_ModuleStateLookup_Lock() AcquireSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() ReleaseSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#else +#error "No suitable lock available for CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE.\ + Requires C standard >= C11, or C++ standard >= C++11,\ + or pthreads, or the Windows 32 API, or Python >= 3.13." +#endif +typedef struct { + int64_t id; + PyObject *module; +} __Pyx_InterpreterIdAndModule; +typedef struct { + char interpreter_id_as_index; + Py_ssize_t count; + Py_ssize_t allocated; + __Pyx_InterpreterIdAndModule table[1]; +} __Pyx_ModuleStateLookupData; +#define __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE 32 +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_int_type __Pyx_ModuleStateLookup_read_counter = 0; +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_ptr_type __Pyx_ModuleStateLookup_data = 0; +#else +static __Pyx_ModuleStateLookupData* __Pyx_ModuleStateLookup_data = NULL; +#endif +static __Pyx_InterpreterIdAndModule* __Pyx_State_FindModuleStateLookupTableLowerBound( + __Pyx_InterpreterIdAndModule* table, + Py_ssize_t count, + int64_t interpreterId) { + __Pyx_InterpreterIdAndModule* begin = table; + __Pyx_InterpreterIdAndModule* end = begin + count; + if (begin->id == interpreterId) { + return begin; + } + while ((end - begin) > __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + __Pyx_InterpreterIdAndModule* halfway = begin + (end - begin)/2; + if (halfway->id == interpreterId) { + return halfway; + } + if (halfway->id < interpreterId) { + begin = halfway; + } else { + end = halfway; + } + } + for (; begin < end; ++begin) { + if (begin->id >= interpreterId) return begin; + } + return begin; +} +static PyObject *__Pyx_State_FindModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return NULL; +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData* data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + { + __pyx_atomic_incr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + if (likely(data)) { + __Pyx_ModuleStateLookupData* new_data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_acquire(&__Pyx_ModuleStateLookup_data); + if (likely(data == new_data)) { + goto read_finished; + } + } + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + __Pyx_ModuleStateLookup_Lock(); + __pyx_atomic_incr_relaxed(&__Pyx_ModuleStateLookup_read_counter); + data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + __Pyx_ModuleStateLookup_Unlock(); + } + read_finished:; +#else + __Pyx_ModuleStateLookupData* data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_InterpreterIdAndModule* found = NULL; + if (unlikely(!data)) goto end; + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + found = data->table+interpreter_id; + } + } else { + found = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + } + end: + { + PyObject *result=NULL; + if (found && found->id == interpreter_id) { + result = found->module; + } +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); +#endif + return result; + } +} +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static void __Pyx_ModuleStateLookup_wait_until_no_readers(void) { + while (__pyx_atomic_load(&__Pyx_ModuleStateLookup_read_counter) != 0); +} +#else +#define __Pyx_ModuleStateLookup_wait_until_no_readers() +#endif +static int __Pyx_State_AddModuleInterpIdAsIndex(__Pyx_ModuleStateLookupData **old_data, PyObject* module, int64_t interpreter_id) { + Py_ssize_t to_allocate = (*old_data)->allocated; + while (to_allocate <= interpreter_id) { + if (to_allocate == 0) to_allocate = 1; + else to_allocate *= 2; + } + __Pyx_ModuleStateLookupData *new_data = *old_data; + if (to_allocate != (*old_data)->allocated) { + new_data = (__Pyx_ModuleStateLookupData *)realloc( + *old_data, + sizeof(__Pyx_ModuleStateLookupData)+(to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + PyErr_NoMemory(); + return -1; + } + for (Py_ssize_t i = new_data->allocated; i < to_allocate; ++i) { + new_data->table[i].id = i; + new_data->table[i].module = NULL; + } + new_data->allocated = to_allocate; + } + new_data->table[interpreter_id].module = module; + if (new_data->count < interpreter_id+1) { + new_data->count = interpreter_id+1; + } + *old_data = new_data; + return 0; +} +static void __Pyx_State_ConvertFromInterpIdAsIndex(__Pyx_ModuleStateLookupData *data) { + __Pyx_InterpreterIdAndModule *read = data->table; + __Pyx_InterpreterIdAndModule *write = data->table; + __Pyx_InterpreterIdAndModule *end = read + data->count; + for (; readmodule) { + write->id = read->id; + write->module = read->module; + ++write; + } + } + data->count = write - data->table; + for (; writeid = 0; + write->module = NULL; + } + data->interpreter_id_as_index = 0; +} +static int __Pyx_State_AddModule(PyObject* module, CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + int result = 0; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *old_data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *old_data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_ModuleStateLookupData *new_data = old_data; + if (!new_data) { + new_data = (__Pyx_ModuleStateLookupData *)calloc(1, sizeof(__Pyx_ModuleStateLookupData)); + if (!new_data) { + result = -1; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = 1; + new_data->interpreter_id_as_index = 1; + } + __Pyx_ModuleStateLookup_wait_until_no_readers(); + if (new_data->interpreter_id_as_index) { + if (interpreter_id < __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + result = __Pyx_State_AddModuleInterpIdAsIndex(&new_data, module, interpreter_id); + goto end; + } + __Pyx_State_ConvertFromInterpIdAsIndex(new_data); + } + { + Py_ssize_t insert_at = 0; + { + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + new_data->table, new_data->count, interpreter_id); + assert(lower_bound); + insert_at = lower_bound - new_data->table; + if (unlikely(insert_at < new_data->count && lower_bound->id == interpreter_id)) { + lower_bound->module = module; + goto end; // already in table, nothing more to do + } + } + if (new_data->count+1 >= new_data->allocated) { + Py_ssize_t to_allocate = (new_data->count+1)*2; + new_data = + (__Pyx_ModuleStateLookupData*)realloc( + new_data, + sizeof(__Pyx_ModuleStateLookupData) + + (to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + result = -1; + new_data = old_data; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = to_allocate; + } + ++new_data->count; + int64_t last_id = interpreter_id; + PyObject *last_module = module; + for (Py_ssize_t i=insert_at; icount; ++i) { + int64_t current_id = new_data->table[i].id; + new_data->table[i].id = last_id; + last_id = current_id; + PyObject *current_module = new_data->table[i].module; + new_data->table[i].module = last_module; + last_module = current_module; + } + } + end: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, new_data); +#else + __Pyx_ModuleStateLookup_data = new_data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return result; +} +static int __Pyx_State_RemoveModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *data = __Pyx_ModuleStateLookup_data; +#endif + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + data->table[interpreter_id].module = NULL; + } + goto done; + } + { + __Pyx_ModuleStateLookup_wait_until_no_readers(); + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + if (!lower_bound) goto done; + if (lower_bound->id != interpreter_id) goto done; + __Pyx_InterpreterIdAndModule *end = data->table+data->count; + for (;lower_boundid = (lower_bound+1)->id; + lower_bound->module = (lower_bound+1)->module; + } + } + --data->count; + if (data->count == 0) { + free(data); + data = NULL; + } + done: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, data); +#else + __Pyx_ModuleStateLookup_data = data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return 0; +} +#endif + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/app/core/permissions.cpython-313-aarch64-linux-gnu.so b/app/core/permissions.cpython-313-aarch64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..8266bae5ad9cef75c4aae604c06f039180357ada GIT binary patch literal 80872 zcmeFa3v^UPwm)3m9g+|bBMA^5!bt#$41{-rh|=8&1dx{yl~Km-PNyL;PxIg*j5Ns1 zaK)LS1r;A74eAW(aqh%xP&4DBgO6d_ryIF=iG8nbRVunN4R2C>hFz zaN1t7ayRKEpAO2D3GT!#o{BE(MZIJ}FVlcvBhy4t zJq{`T9Ter!=_o-bQ=+BMlFw?3=sNF7p6!ypEcnS(*1H+?c>nZj|MLH2L9tY{7fUb9 zBnU++n&*8>MG?XIi*8}Zt~%YI?f=;gf7pHX*y5DOOD33Cy-77me;e^f^|*X-Ok+ku zb$rDG+m_Tnc*m<8i1D9^^=2*Ox)z$)02UOyWa*O$jP;ipCH)H5vd;?4R-*&m;t;Vr z{QVewPQ;)egN}E{XATCgJNzV!yE{A^%Igj%OjA1~uJ4aQ|9lMmkr?ORCz8L*-$Kd~V41FfY(kJ?z(TyIGWAIrDJLyjTKgN*fnHc?ziy=>Q418M*{-)mD z%kx!?aWTZur#}Y$*%*2l7h}9u#^~?X7<{gZAx}7lJP*X6e=dgJK8u07V#w1!#`sQ+ zfmgzIy0eF$$7nY(M!%df#`pag{k=H`|Lf7O?)+G74EY;l@b49493P0$-~Wn1UmQcu zcVp-w5Ce~gy>-{G2V=DRYz#fDjA6GBlWF*i{yYXgS4D%!e;uP=wK4F#7<#@shWxk0 zz{4@*e82FJG^87SLze-}zx5vP5!5DNm?>5Eg*YFtl zPhyPA-Wc@X#~9zD81noshW>Ag!T*{V`Wza=&yS5E|GhEVeI|ySBV*|KPci7NG5qK5 z82WiF#<?Eivd1#GwCk4EY;l=)We0{Ig^5c{9d%9gV@~QVjY}VL$y@A2xBGt|2)_ z*8;za4P+DhLSTHrR{z*+tI8`YY&Erx>ROwP+2$22v=zCkU8_oJYF*U@3vN;mFTe2>%#93=w!;=;RJpj=wwEY7VguX0qotd*5zD7dAf#93M7vdyWkEC<(; zid70YuL6=*bSe^zZY`-Psa@!(aIA6_kqk;DA{XtFxOpx|Sy`nsB168b)>2zr-O(8D z!ZKIwyjoX80_qG=l@!+1cIpudTvfFtl@$vewa#K!4fs+=bIV)~>U2SIwaZbotkzNM zvY{a$ybo2?F7%`Wo|i|}(8Rp*s>DTIr}OBT205YF#yoqAe9g%V1m#u9dPc=rawGj*y}8uAu)8XPKjh1|q7(*3O7Xhj(cU9DOa9-qEtJ)cfz$e5UM_El| zMl8Ve5~>iL(G$Ht3tX#RWnwhRIt!}nB2}fLbOVJ{xpV3&oMdc#VgaztrWvu+<*ci& zDOv5xg=rJIz~xx&iblyS7dt^&?J5G1V16s6VP&-w6@>v=9W^dd#(UI3DVXa@)$K&L zFAT)8vJxj5P6t3EgZx5Qxox4GZfMYaF%jSQ}345R#rhL)eagx*)&EBz3bvX=2Sb%`RoE6^~hzV z*)bQc8i1U6v&*Y$Np+;ur5!G0++TvH)tf^aCJu5{0+>Qo&$YA)t(&{0Ni5-n1%7oj6iGI#$ADl1k=vz=2` z>8O<%F)AHP1D8ZJr`warkp3`}I!`*xVXP=lnzPg*=BjLvMi*Mp*^6RfWRgT0gziZ| z(+QBhfFG#q=!P!Q5?!l;9IbR(L2S3WFdg|gFJ5M=si?v-R!e?MYA>>aNuOH|H&jLA z*^Q3?s?U^LOI&M&lM@q12tZR)x&}bp6-QdjbJ2==OTnD!iU|5rIX=%}fi_Pf$|<@tY(kP3*)4Pwux zA^(WyVMOL8whS13sC4-1o)(3-C+YNB6uwK)PmIDP{q!hY($9^;lXvRA-rQ`l6e7fLsFbbD^TB2~t=X4Z4SMX_% z!Y2xQ2u9)VB3+*3xX$CgT=1D5g%=Cl9)+(JcyScIM6|m#3g0T|w@2ZUz99;Vp}G{oAAP zf|WYHHVQv2__(8R$!BX6F8O$)@SxzcFAA>`@-#%@+lAd8jKUKi(&cQ4!t-v@@#9f= zK+MPXC_GK@2}a?k=->_?bA0FV$`tg=qwsx+I-NZV-?c;Mvo;FPOwj4wQTX!hI{nrt z+`LZ5y;1nuU+eh3DBOOxj-QUglLi0wDBQnGr)NSg>4%fWc|~Frp4MBJe_|AFFVXp! zqwt1BI=&#eyl1A*H-ED?kN1A$ZwCr6UDfAqj2fp8=~-uOLYE{pVWh2 zjAKg_eSx5t?MV6-K|fKnFY$oDmq+12fj30q2Sr|{l8@xy5=GxA)+0@fkE92Zk3f`dLcPaQw3SO$1NxatF7`XoA2mZ%=!I5>xCy_r9qT?v) z_#`Vhj*dG%X$p>`>5dN`BH`D>A4kU>pG*ZuSl;oOsNhK*D8rLQ5k7qs+^pcq3O-lC z)%%G{6kNT(xm>|h6h3wZPgU?@1s|Z`RSG^(!PhGIAO&|Txav2yD)?Z9e!GGXQSe;~ zK2*WI3O-E1_bK?*3f`dL!xj7`1s|c{eg#ig@Pi7Tq2MhFK2pJtEBGh{4=DI(1wXCe z*C=?qf{#(~pn_*AI5R}-YOI1MD)^5SJXyi%9+Lc|DfoB^BGnW;OTjZ0e3F7sRPf0P zK3&15D7aa{#nQ-2=PLL#g?@>GXDj$}1{ ze5QhLRqz`We7l0rQt(|0ZdP!wf?E`PpMtCFV}pXvR_I?+@Hq%?h1;0bV=PLM56nu$-+ZBAdf)^^d zUBR6SUaa6n3SOn)V#~)%*DAOO{WlECt;HwqFZTR~oWT*2>A=mQGAUcpZ*_yz@USMZ-I z_z2DP{^j+r)n7I-&)@{M^YZ%UeSVYes3d7eSvzA5SACx!N^YCw(TpRGQXTn+vX-li z<`AA!xbPeR_RAuatx7%%`9dW>8TrjhJ{$SHN`40N2bBDc$hRqZEAmETr2RR_XDIpk$Xk{CBIFB| z{8HpMEBRZI->c+rNB)44zZ3a3C0~fV(G+QaCGr_c{x0OLO1=X5LM2~~{AMM;8u`6S z{vPBHDEWJlZ&UJ{kvGOg+W$H78A|?sH9 zl>A=gjlCl6{}%ZSCGSJts^tG2`9dZCAINW3@-HC2SIPeg`2!vKhO1shzD>y=K;9TH z+i$q)E#xzl{M*P|mHdApU#R2{BfnY6A4PtzlK&9-14{lA z19_{G{~zQFmHgMpZ&vc(BEMJ3e~0`5CI3D0ZA#u~LHmi3_T!PyQ1VI0Ta|o2+*pM`v(lAnzHW+k7E{9YwL z1Nj3={zl~6l)M#rV^XC3Iml-y`T59OmHZ;)3zhs*u2coiQ6& zK_`0iwVeKW(1WHwb|BbVx|hl|>GJwl_&RlNnW6riDQ@gHcNpuxfgImLhE~Y*==b4A z{6^Mz-o$**Gd7L$eknh++sMxN87pWt4fF*}10Z{u>khA}}WtRGH?y%NhUjI5@ zLsfZ6CXzRq>Li*&Z-K{%IQE>~#0uJ=D~sC_nuWXra+=+S5cc?~Bbea~ZqMmDdROSw zK91|?x2R7#gqcC7en0 zhE3>1vk^4j%Mlt`->FUTSnU%$acFZjXxx{=IW!g|D~*dBlkn@tLzmb0s=u6T@O*Pe z0_=y4{nixc3zhb+ZyG-P$ak=#fN3!5#MhrU_3~YCCe~kojRj$27i*I0$sR~YEQvK< z1f9XoJVxl%#s;4mOJj9UVbH|PO-`X-6Jt%<+Kiwzj(IMS9igvnkf{}a{|R0p@PaMv z9|j(&_`_Z}H5)d3EQ!yP!xxfJ@4JmhE_{3MgRQ1PzSEb(k6fZU--jDpQJ?Hei(`## zC^Mk%dBDgXi67YpGmrL!5?E-riJko}g@yLsx%9|M)6lWc%$a+{kZKME2eA<8ECKWK z8ur9vpBmZO&rK|JwEw2ZJ|AJI_a?Fa!J#bFc0Fs_+duEfw+V6ed-~-b`IBfHHqm;>`Sll^bL&H;^Xf0w z%&*57c_;?Gy#D3-&(H_*GZ&nudMMUMW8u9tJ48Ofvz5s6x>a&`06YcGGngzQPv1P zZiSB<7-$x=6mwJS&F-bOlfjD_k~Yo&-}x+L&v4&h-~4YgM`-MB4Rifn@EOrpzaEjS zr@f%35s5}#J|Z#cZZqft0+6E({8=vs zzn1DdnXB{72H(IDb3Lsc0nF=E%rOJ{u}Ant17jfz=4~qIs6A?z>YoR{9JH+&g4ro( z+YLSVQHRD0wt}@r_tWvjA2M7m=8UAFG1X~Oe3v2LIrNF_gZkDVw4}GM<$462w_Rxt zkz7`+6`22r&Cr7ryf3epzAqQ^D-Yu`yFN6<9K!gCx%DT$mPW?T06MIv&^yhwP-z_I zVlT|aghS8!@*y>Jht1ao?cy6oTLw3;guQah#$k&uE z{2}z#)My>;@%rNU_`Bm-NSnlU+l5Bsww&ns8~U>|gL#P7KY`mu3o|Er{tDckg!;fX z$D1kUXz@bUba$d>FWR?f1#@`+8nJHQxaqLh;r)6H`tkXRwGRdudwayps;_bXpn&8d z+oU!|5zl^@513a@1N6Qkc^S@8TRuOr{K#AWM9*kkKf`*%URl%m`{F!L8{A8s(1l?z z{4K^GYha7j-rMtcwBO3}?!&};GxC9JgE^mJ>~Ox=auo4CjX#Z94a(f`LxD`PK^HV<_lMxcedgMI0!$93dQ^2`T4tp)yTSmO-Pn@=WrdI2M! zNppu}xf^+!OB(Wl%_fggb1&Vr80`c9j&Q^Ze%PxPuiL91w&?Grul={9Eu8nJ(ppb8 zKyng)i^&|i08GXU7OWi(ZsS9I3sHyoN!uoVc3w8nHwR@5b!8btJ-sZ=Hw$HMl0*18 zH_5^MT&iz6%4l8%$Uo{aQHvFQO=o>PBQXvP<2w>^(HzHjRCjVd!z1(0f3-gUt^uDj z;B(v6tdYk5yUol)8+-rz82IAjDX*zbuX8l z#o1H=t$o!TC*RB(H}y-~mX^RgM~y?bX;oN%jMW>@4UD0{v3A zu_|+@0di1WnH~-oJP#Uf{|)&e4LrWZ+>V28$WGiChjpO!PGS460v-84&^C~*rnAAG zpTmc3!WaY=89HLYO&AA#Y*T$lA*-L}%@RwJc=1?d65D?aIPoGrq`P!C{5$qI zcY|l(Rs+Ty{iE?~;qi2n7qL36SGRx%=JI}u51PRvU1J_U`JN!=cAO{Bzd5whpFnbLPk%W-YLj?q`A)c zd`|P_L9bUp*HmsE5h)K0r+J#@n~C!CD5p7)4cP|a4`ZH6wr9Y&4mDds!?6Dx{4#76 z^K%B$-=Pl05oXM7l5q_36a#2iBZj-0O>H#|!I-A_(gkiG#tInl56N!fTg?<(KyQ3} zvF96#w%H2*4Xucu11X5-u-3F<-8IgoHdA~#Yu5+4Zyt`h%w`?cMnd)!_yYK%6=;JE zXVd(!72&TMC{|B*U*Vw`ooL7(oQDs&)#P59gZ>fEK_<47){_B9_rMOlkj(GfAL-T5sC-bqrCv; zzbaEYc#tf~C?h^27(3gVvitUpSOe|w1McC$>}OC$dJT+bjmII6@e#5Cqwmka{i88< zh*4;7WB9W<^a3z9Fsf_6I+*>isB1>uqo~{LGlve~-0fN58tDAcDb;O$OCP_$D7~(E zSTOq+qONxoYrKH@8$^9WDfIuMIrId|?4a#v`)}sZBg9kGXG4S8YefCPNY+So2V#5; zM^OKIOXvZV1x5yQ3}Y;OED59b%)pHI>EmnoktMVlm^UMsV?rN;kl~HHFutb2o&z|m zL%i>4#$0<3bCt)c8f!$qn~p4kor}1~j(q~@!aOLL-3l4nuzqS7%XG~WDg|#hY~PP^ zhVq+`CqC{GtT6=IDUi2twK?R#+_Iz04qD378tlN_yaSjYYn%h~m9RpbU)>5!BMkFW zVmAYGUyZuZJ+F&%vIW2b!-6>@(J$&xQ3X=B!BdESIWWg}qfa#E{-LZ9@-?ki`s7ES zNM^0S>{E)~r_<(8Hpw(ZAH%>^!R&#^^Eug{?WcK6^Z5d7cQ*X#G1#RW_DHsA2R}E) zjP@XMKFkCS;cQ4SI}UuvACjG$L328!uLWK@hv-K!gSqKC#ya$_Ax<*`n-QmDfq^(* z0k$7)Q5*0lh-C)(@O^d6w=~~%NRNDqvmdlM8f{&H^cRqi=Hw=%e#l8N+hF`roIrDU z0C@caWn8XsxY4o(u{!F~-rh`dfqy^bTS;!@1K4xl3;NbU<`C`WDZVG3#H(ZPj(zSx zF4JINs*nu_VmnWK9Hy^CrcymK#*BEk!FPN}GJYJ+aVs&EyCbH;-W+=Rs5QL*dbH8< zeRvS;lJ6hwz^HF+C{ILRCGKw1@e{zWQgH7{9X|?uh=K=B>39q9Q3~!ot>bS4w+b9~ z6AEyApzjUfc?$0TZ=xUQdlh)8!iW8j&gUiI<-jlSIRsw>ztM{G*vHU+Z-Q=b?89(m zfBb=7&xd+%qu*qAM}?oo8QLIu{S>ZW5V%*+t&Y?EG0uDj$!nZ34!Tv~4-2}1SXaq! zKZv}%{xz<@6?6{>x`zebR^-p4k7R!myHC&%_AS<4;&-n?C$V+FX6{MFQ3j+8sDTm z&Ur>?k^709UgPoO_H?APn0|K4*WxYt6n{3hV{S0qhorjE^y!SflW}R|5li1q+tM#t zcA#G40rbOqIzLp%>l!=iQoFN8(*4g@^>gJuEOZX?+B00&VczEWssG#aLvGaL?QF1w z;?VD7IA7GDTYJXn>(2Ethc2%_uiX>Y6cnT`AB<-FfG z!`85e#@w7_hVC`&q5UKqaN@-#(s?anQRHdeX33i#Lk!Suo1eiJM&i6A4`)nqEhD$l z_-#rwH_c+kQfzbz?la7;MS!xq4|!!Jh5EOkqKeh$6k zOuo^M_2*kfzjQ`O=Y#rrAb4R-)z1p!eDL%ke|#W&Hf)#9HZI@{SHE9i^qoW8@-z7I ztI$u^ugpRGK1-t)bhJ;lLS7@+U3*1kR_4We&Si~Tlk4_(m1D4ep zGZQwvGv+k`vv$T9VRJfTb|bJwoiV=w*wW6JM%WBpS2X@4e>=`FX>93!2KhkhBjvG% zb3ZKab4dR~`+Bkujg9kI;EQ%$;64~JggLYs=aN>$0f;AXeu(%E^DKaJIbH_rZ_bfV z1P_hPI*PtD8es<(_?AK|!=7CCM;7=aW3s^KbjC5KLz|Q{(>-X1<~8OK?&}@kYsBl& zJ^2NJ_m?>JLCQk&J0;H?nu2+1M;ywOxSHY@{T`3bkK`uXptk-Kz8do{X9vcB&P|WN zPuBb?KlBx@yYM&v@A>bS{4wr=e~ZeW^bh?sz6!l!j(5myhRy=8Q_}fATO%&7|1r0 z(=i?+!DAyEaK?c%qLGP+nK2$4vCfi@(=d*suy-{k8<+hIf3Ly6rvvvUX69(a%%L|D zGIP>L&|b|r*1Ey;co1W!T@Fv%WK4NS!Ice5eY=_heM{1n4kIS1&;2p?8_e!w_JZCua&dkFI+_O#)N6x&XfD0}E!IAUwGU?uzfZ*3BG#hyIL~Z_omfh> z;7QmL=aq8DcMC8sq_YvGp=W-XzzTvRaj(wAJmHP3p7_!lM|%|FYeHM_Kaa3@Hgz+` zo7TVp_Am!9Kdfkf1ma7qD+PrQn1h>f|J{hS{1kj%GxU)j!1zI48}4(^{d@A;n_xH7 zG5`2FeTmLj`8f+8Yx3iyz%Dt1)IrSJDe(!{Mv}3F&B|kzs#4`?qKE`?1#~f!NBif>NXgvP{`9D|2lkSnx zc+tJFoGatDwUO>IW=7(JG5SyRi^lmojPbXocprpq+258Qx>%D?e-W|oCHR3fJI++0 z54wLv_Cfm^YVUK>HFTS@zBcG)Y`=zi7Jxqe@ZF>bx@WTqbE_ETpR>X5Fhj&AAqH#O zS~@1k&y|fs&d`~))WOA?d_Ff~>8!Pvt}}k0Nzs)Z`?E0C5E{o3@HyB67tpxSJfyQZ zvWvgqT$sj?LGMT>VcnxRiH{?V-$~HWc+wbBAASVgl3X-~bZ?7f`w)6}pigbEQBCo) z=zr6u^%=o;P)_!vwoCUz+JKY(NZ+L2ov?lNxs8-1|7uOppY`Ce$Xaug-;kEWb@Vju zhhnUxEa(r9+wDg`p{8sM>%L3HRzoBOELz~SMs46U*qK3tm}#J z=g?mo_czf$nlJQB&H-Fg+)L#zit<;0QJZw;ehvELC!4@|J7FXzVwfhxFOv+g7sti$ zeyU6Qd=&IAfSzcu{trTY)8zOryr1~=!kY41=qYX{?wJP75B?55W($kIe|IuF>xSGE z=eC;?_#SaD{F1iCOwVo{k{Fi(YY9CEg>|)^_8xm-lTPzAZkuGU>DnaEX0*@Hj(m2B z<|h3mp#9ls*NFD_q5KQ9Z)J)1{~fwJg?Vkj8f$|rXot&k5P%JBYkmQ*(Y_#e??u@4Kkct~GVkwM(5W``uloBL=)3m!mHM}#$GJiC*K(gs^TKQy?O6#Q zzzT4tjCFfNFW4OV{V8HCmJI)ky|dPLdA1++Sag>?_;eqffnd(IBi5ieiPmzt2YC~A z_sp01A*%aE^6c;ISF(b?JZlb(No9>+Kqs>d?Ccddcl{h|7S*G8be6$%2C-SeskP3a z6VHF_M%^u_Yr)!7g#G4y$>ye$7e{21U)1mYm_rZ29&=e{PAz;NBiqoXcpf;9_!Iji z@?~_tMC|W;i=c}sz1e;6d)Hl=rD~ zgK{V~iFGl20 zyhwUc&#P!2o~JbvbA-+;;$ZXN;2z_azO4TM*gDpvyS=cx2hcwJ(A{P{!?YXEj_u*{ zrt-4@vX?eG*TSBSp3x%Tv>VTwZ9<)=@a)DY@FpK-KpdYA-%Ykhb@(}gQb*Nmx_I8~ z3h0z*$p=aPv|l|5KTmv#7uoX`-2ZoA&XRxUe6T)}&(46als=sN_bcG{C5;JuaR4&6 z;W>(}=Wrhc`$_W8^n9AcHw&C$Zgk;|^`jGSZIb7=;7w;;vVOIw??-*oeHR|^v7LB8 zzK6i$4bX<~Galmh%47C8?7s~-U+jfv3Jn-9+JnX8xi=%82kl)yEDiU`(9c%%g>*49 z0r!WncJ9S>Iy2rs3u`CYQZqddL3<7KmD-hijpj6poAdBYHJ$6s!B~9#T(vGE)(56ME~f5Dkh?q8;l(;C1Y?u!jjerSG=__aO!E0QQYX@T^Z5b9N}!woqwe z{b08D@DT97ifkG8_n_BK=kRSq^>eax#I0t;coxK_2F&$z_!s;78NtGPW(04?Ui&(e z;ePD5p))+Qh&|2QkOzCCyY1MM!6!@`jPav=E9q3DIMcHU8pc7!@ET(w zGvc!WkSmPmd!I$S^z8V4JUl756q~VQ-wCy!kQAA0GFU{xYCHVf1$~fq4&7pI(t7A# zN_I=JADy{T9Q0eXLwIz2PBhexY?Ek5C0oC9(jUo3GBsn*CFLnJ2D-{K3i6EVUY<=+ z@{k;bXe)YL((T!Nu5A-?Ncn%T3>sw6ez**l?qtw%xD0ni$q>*;>IKiQ%`o$inPZ~G9K!TWILY&U(d zq7T*|-iJ2upz-g%563$9LDSpqrSzf8c!>K3bblrw^tdsbb<*V~_;-7MrM!RV^5(vJ z{QGAbqYQ;EBZ>}w-Hx@Pqn&Fymm8>jtWrLoy{1i9OKa;AI3$sDN6#%VRIejusyYW6MVgWky5^>b9pn?d^^rWI_l#L zM6GY2a@KBPAz{dc5`kv1Y- zi1bfLZ$e7v<@1ofg)|>2t<|%U(wTQI(&I>V|EAoF$698mu^))F5i(MolL%T$S0b*V zlw_p)Mb@)={jkY!=rhcF#BU8w9>3||RfxxYv|}#I?;*@$@qC}r{48QO=$FUIboPq9 za5~mGqkP z+ItbhLFUQ$J4OAuAMK6Q_rX@Qaq0-GKZY`fy&lC*2b6nqg^caL)UKZ+(>eLiKu71E zei^r6ohSb!<2D2Q9GzR!x&}S)SWVq$y#`-s{tod2)^*MU`!T}2p-6v7cIpesPJN+% z{0;4%#Q0EO7vNgnlY11`#_2foz}VzMzxP32YFpmFYlfWZ$LV_kIIk1_0M7`Vaq#_% z(MR8rA^G;FESZAa?< z{zA6&yZkE%h!1IOw_uFX_p?_Z_945w4`WMXP4a0M!v&-l z8fP&F`qTL_?P+;AbVz$zsl!>Ibwh{WfX4mZvFvNn2Az3~$Gr?`OQQt;jV$hr77Q1l zobykFETh*J2fd;nW@9kh3z?a*J$obe#r|)@1uG#te$K7&FW?)7%;O>RTf#=)5PV+) zU;8)V0+j1~d!a9e#53uL7xfs~h~D={&XyzEeyw4 zABAlkfQ{3+@|+cx&`S7~{03{2Rik(~9&u>u*j7`**i|^6ha9El*t?oGY}nyvrft~c zHtjaD(q`D`kz!}i9<}DuGocjg(sz33jOai-p6SK7Q(FO?-=t=;riYM6y^gpRYc$AQWe{-L{XED{k1pA@;q_4q-(yn5SgE6NxJR68{pJYZXso}Z6L5SI3 zBwwS*7eGuva#8;nbimvNA!>IKx02FM)pmJjk|HKimviKLCz4 zJNke&xxB~pHal>%8S;ZSJ?9(`UB~yw_~V*n_+04w^gb)(N*vn<`o=xCu_Fwul>Cw4>5A_A z%5epAGM)c?Vu0@7Iy%^~_)E=lI;WV+`rO@t?oa@6A$uIi@cF zBbr9=bHi?B|5|Zx6W{;4itN#_al?)v%KwgW!XAg~@~xZZ{o z_cI4YkGqDrfGM`XU<-c8d5peeOE!(~xnhhCku7MK;q#ym+MALNq^zW$8m@~p-`!~E zEN^>|uL9T7c4)80-0s7h(1$>fKR?<+<7nPzy{th8+H%8X2gWpou~2FvvD~3e#AHKPxH+}!m z105|6mG;3IMc;asjCB(2ewM@Vy*c+`Z-2z>N$d}J&g~EPAr5rGhtiq?KX~@{>6jO= zmvi^wzH%b&|6pDE&*389mz_1k&)RT)vj^Bntb>ItvhT#2*F^Q4{a9!uct)2wlYqmg zcfsRH9?BfwAb~#~cG#Bfm#H5cfu~ZZPm{#WSnSJkmX8`tn!05UazS#_a&&zQyoiGc|-t55Wx*6BU z(T`!dqdkuzKBIG$bbLo3@IRO{X~7(R_JZ>)KhC_|$#{-tgeBC9d+%=4&wxx>&>KH{ zLEfKEXAYhFx(RYXm)n_}pJSY1kcZ;G){zF@mXYD)gT8b5BNp0$XWr;p9_XuMJ%GMK zcI=0)18>fU&O>ls<;Hhf=p2UbrSFHV=5$@wz!0owqHpQ2b4}3~)|{qqK%a)b()l%e z9N&!+@_W%{?LgKj&yKuk*UZ1y;y(N__|tj}*&CbDmvr3Y)|7r~m=k*r8|u*(`ik#l zz|PPX#qM~fd$4aF>XU6bU|U)&+d?d^+SUc1?AS-8=Lvv78b$Ge^8g;C6nzhm4nb{+G=8n~fj zZd?H!5g$Br0>6dt=79GTxSndfFmg>;+LnH_JSF3#%w~Ke_yI^00r~Rur*^F2rT5mKLp94=mR_*yXn`JFz zD^@e}ya2xL&%@LHp|{z>+jNuN5Ao6W*~}=Tn4j0hvp0I(p+2jZd47j-@884IK0-Nz zyq1K>+^@nj6~6%PuEttL^Fy&aH|(wzHW_U*?kGDC(7qpZWSfQP!zD2<{u91$6Ksp- zhK#E=!M+^uQRhKF746b@G5`4An2X3yBsqi~LccsFOYaR?Av5WQ{8b+0E#UPA`1YV) zkm^7l>?gSWx@q2Fzd_^uD9Y(x0?nHNt0Lp)KCO?R6=kPzPo8`?J=^pqe60Rk4+DJn z<6bm)K9|u$({&f*dzIAPMpHo zJ@&c=j4M5Z#$dNaprQU*5+h^M2Yt){f0`%7;C}_Kn^8_{ZV~d;l&AT8ko=|I-Y?W01 z3b63&k@a1!>6h2{#_w?$J@LbG@yt~c?z0#Xw3PvuK#^R zLcJgBKzL(({YmUY)OEcN{Jt5_Bhg&fum_>F9e$`_?-<6PDLa3k!9(lp=A|v!14ws$ zQ?}7~okBeM+d>1zY@qK!jF-QEFlS>tJKGofaNkoC^uq7gVBOuA#Ln8W?h=N3<&EcT zbLxj-z3XnhKZ!V`+x3153(>PL#H%%f6->d{*_CzB4u6n?_3<3&0ty}gegQn~SWmEC zZBIK%`cFIK$izCp*SfSbmTXoKD!rl}dyNJSV=_czo?Bjo-GCp>slD(+n=ux&UInIg zU8^YeEJa>9`I_{fOJF<-u(S|vvYa1QwA-uRzBRfr7pU)sh3NYfzP@&eRSftJ zT>$HbzneJ5Fc{yjD_vO6Z6C2^AYZ>XhwrNJ@3}bcqV;7S)|X*eU*=~<5rPsIENPYV1oeRquRzufXV_M&50#~38aF~E0|Ay23Hi_4BU zB7om_!QT9g`36?788$@Y+D!fcW5a@Y9tl2S56Wmq$hsG7> z4DKJHAJ^lzsnGB9SZlultvwi?N_~6tjQ*WK>hGQ`JSU0y(3XoiF_L1$VZOi8xc6mK zFaD@&|GvXKF^fKHIG;j)n&{kz>l){jWRr3aAZ?QDlh$rSslR7=yqVeZ1brS->WYgAx0Z891YA zgH1~Lu*c`}ZI7yhcZi}6+s05Q0Qwn-t7RQ;yI$u$)FC^30kQoM^D7VWu}*w)<< z+Ya+Rh;o`YL*Z*Tyd!<>FyChAV2rR?KhAK}IY?tfHhdlG8RtTGu!r<>So^bJ+jtg} z;v5UwYeGCO;~fjy+%t~K@jD=BljedO&shbc)(AWDw_$!kmy^s`tL&Jg>1b;i_FG`s&i*t{ihr@gxnGZ+etiT~X&YFdO(RU{IKu&t@8{^qP=N=S$Cem2` zH9YN?80S5pBmL>?#sJ?9(DQlBgVeXf`w!4~U|bpM?h$^H#_=HP*MT?bx)r(@1-e%F z2AcPD9`QgF&rHFy@o0GeA5g|-=sXRy--Yibp3j4)9Xx*;Rd=wgdoaBJNh*UMBzc+@ zd7ehyo4Gs#dc$p7ei z80Nc(Jo$qe_%5v**K9g#+yQx05uZuDgf5Tt*=*taXOwU!2uVLWL+XR0%{IVTB`2?Qt zrDwp&5Bw4JRv>>A`6=K@ey|q432WThh410}B8aW|dV}$&dpz_U#BMwXVLuWspxn z4q85z_?;xub9%tUd8jV@OUMaX$sg0YMD5c#EY0on_zuWSlo7u`8h(oraa$Pc^QF4diN;mLBAYO7&CvTL$ovHS6Y-(?2CkoB_>RH=-$KYv z&o*$Lh%5 z6QVeO0nYKL4$io?r@P}lPCD1(--87ob1%DQG zx0CNMf(O+nolv{vL#_ZVoox*ga*^Mb&qB#(qm~uprP@VW?mD~=xpiv6S(7JD ztkFtpw2I1F&7p&p{7u}9#ilQI)M&NEE^SRUUg4_M;MKq5wA$)*S~cD)T3%Ix7h|r% z;ONXVuhmNR*Cp3z<#jc+TA@qB+nhmC0~-2_t^v&|v|o<5P?zBS)Y@u#ziN%Pva(v% z)g0no%i5UHw~W#2*_^y5wkfvBwrPN7I@hffZ$s8b-=aBcwb4~K0$1LztvQPw6{}oY z5ni_Ktc5bhqaWzK{%%vv>8Q{u@#boh5ig`I0s-FBS_#ZW7p`jkE!`Skc&b%ZS2|ra zHTY4~3VPcpJ~kV#Q;k=t^N*e*d}RsVkS$QgDyvIYl~fR3g_p+S{p6yE-g#b8tK+rB z5&D|CLhS&U|!{H?)4fmTNmBrhw|R+c$d=~~NOCtv;wNjmh4-qlsO)>i3V z7o*ZuvmN6$T5q7%QHsH+sO&NpqWz9?IYt6k_-L7%fsXlw8~*vh(E%|-7N#u$NCyt$RXoSHNI z7v{(6Dhey>DvGpn{-Sh!PAr2-R=8Y6H5!!GSv-uJqXN@K9|D^#V%4r%4aVZoitxI5 zO-f7Sd3T+ojI5+PVtpjyv^HDmnj-z(?KRzTjuM0EwvU-xsYPZ=Ruq>tB`_p% z2K=?)6*NMQl`CN}e8P)~S%(`l{{qw2~s7bzF*XHolEYWuMo z2fac@Y#8Pny@Hxy>QvTMJGsvyoUDzzRk;p8@g)_mA}XU#HQo+hf|Vn>f8ELxix_-h z>73te>48Sqs9I(vctbq(bIc<61bX}Q7-1%Syx@Nvc>i-rVO=drn>A%(jaUcB&Pk0} zfOHct;!BcNR7b0f2DaiQ>%8^u_>1+AQx=v<#nAl6%24fs>B9@qka7FxgM>*`S3&-p zvD(T?4exngCzq{`BGstwDH2x1nEnoGZHzKLx=A|9s$GsET76sae7ipC%{nS_X9j5fMP6Af#fXu+?DM+vY( zA?ZEhmDqFe=5}Zt>eKs9qda+HO;&_{4AyI`(d3>wG~$v?i=ZM)TgIacjl`x#U>e#Q zOnAJ1du7S0Itqbk)!_at7kzhDS88K&e_Swk@giI9;)P3=&R(|6wya?3yhZuTZWvuO z1}nV&kuCFq(fF(xy$nSpiq_p^5cN96DOqAvr0cX*R@?N22jc_T>YOqhKwd2SB66_V zR>NIYR+F=>T)DEwRjZGq&9=tnD1~vm~A3kNyZt!5`6@@JDSDjchYXTvOTye?&udNDf&~@+FMuh=%GDPJa}q&&3~o z)_z#N^lzmpmedMM>FB~=-jh=Fv~@u3O(pehv#kr$?H`T0C3ENG1uH+j#(B+@BaePC z_4khqzwpvuhOdA3xxWm*oKpSnp;^tdnsdJRW8+H=e?B+-(+jVx`)d86+gdNZdhT2M z9qYAMU!VEG!43I8${6-EV+qqxfJ@Ce9{lC5A_IK7edt{ReI#jUiUDy46uKs$)Y-jV`|7IK8GV-12jcH%C9dIX{p7Lnh;g+G<&&=~p zf2O>>VER3ONS}Fr*fTf$d~DP*kbkgJ* zw6`iR;a+>ZV-0phnxhUOes#$`eCf+dN-Ds{GaupB8ppaZHQJKOvJ&UIg(XErWk85r zETY&vB98!`HmVerxM~mxpvL^$3X<%RR%+~;v&>Oaj*W=s!cw(Pn^47hPLQFMzPZY* zak-Kz%PUF>ODY{D;~iBc<5%fYknf*RQ~|%^bqRYsYB_Sr9DLmXtvj zgc?hhCSe6Drr4y|1&OIuNQhk=){*h!J9n5bT@(S1CyzZrkKxAaYh4mwxQP$nv}TeV zJV323bU3N$EUiG<-8zbBJEPTL`K>4#ry+}=Vzo=7ZX{uogoP0c2-jB)g@h3ujjwjC z!tw&$h(%UY6oKK9N>9Ri3q2sLh{zJ*!k3vE$VE+5yJl!>DyvIZmQ}9Fa;~cgDCTp~ z_OhxL(bEjgRRM!=QWt4|zor-w78wSurO-aqiY*!nsw%7M%22Z=%0x09*c4Taca>Mw zuG46#g>DyBYBVsk5h7M)q|2Ihu(EOr&{kDDaAHuDgrXWUK%u~hI%>3a*f3_IeBBsW zflyu1cv#E$x(WxTz$ygc;I3L7lnsNbsT8IPJ(Wr0M&MNBpb?@SoYPTVU4n5?n!DkS zpCmc3&E+;oV@^_1x5igi=_4{uTL~qQMqxjt6o^s35JZi4twonnki;#q5MxxNaU+v+ z#6~%U-!9aH3Cqnr7YTE&&{gbMT~b*+j&Cg;Nin$wNba2$Y%RUyXJfi|EjY+S23 zizuDyqs4s%I4DXZC7>>b`C5&_ZOm$2X~GtgR9dnNG3B6IIxvEL^8Ht8~klMR3T^3HJhW!%V_{!lo)1%b?I zqzym zsRq7ZBAtq~@3Z0XT%_ZWu0Xm3X%*59NVgzme+Y+nAzgs<1kx&ek!yho$ zg`Yq=@y&49jKJ{;q;{k;@c^b9sUPV+qznE6Jt0j#2>l>EfmB1VHtd~ncnQ)KNNbV$ z-wlVKM*0LEra4aKN5bJE1b&xrbFl>}#hLUm+_RL$tsQO{+IIxU(tzdR=D|c>s?&|b zwH??@fsI0H#@_?LmJntcZ|SG~Chkd-b%$}$Cm$c_2Lv#+QH;Mv(4lMmL)ZrVH2|Zw z=tJ0c{Jk87Jq_$2FlvuJME4T@jswdi03X8M#a}zHEd=1B;V*zcJ8UZtDT_!qFG&}# z&oIDou&A*i4{@({I6&T-7b<+=`c^5QApjm+H?)o|va64#dPT{v$h-Tt%;-Bng-4VCb zl>3nJVZ%?MmiLeHPV|AO`X!es6LV+_<`(Te=tKIRDKL!yd}u6|0NW0_tpo@;b9WeT zlllf%m<4o-zYU;m2ki=l7M8Qqz(-(ax(rtgz|tPdqV zoRIry++(J^9Z5TTTOWzv)hqXL;}Zts?H_;g(TNW}Ja$~@bRu|c0FN*6LOCG=w<~T^ zd1OCUG701DWH6!*jUU|*UI3qZP;a-&@|&b5ds`ohf4JA|9f>;=9*Ns!%6-&mbbb8E z2OagO52sPD7`m2ojphUHud*s&WE0TAk`7k6#L6mo6=Uc+cv;Y4E3H zf8gUbgnKD)6~Te-64+=mk$N}TfNc?{Xtl+7o57C_l-Fu*GSLhZ+(LI2&WUN_FU@dz9wgG;;Z+YY&mVsFB$#Ux3 zviFbjbn(&mb45YFi9|;ZWljg}Y@%J%9nC75lXKrcx`NW#(0Ugx%nT8{BoEfor*&ON zeD9ox;ufQs_jQ>TL@wt?E~!5LPJzdzm%`!gdY`<}_GzUV`r{;;q0;#kcFI|H^?D@! z=Hth56_S454zs1|WIs2P71|#&JsP*}_%X|eALL1^oc+Ov)}-UdtbMp^n0xH_2On~l z7NUi(hm2bh1Dr-oP=sq~2k@1A4WjaWD4&X0VHcH)aVDoqPLjr#Vu(hRZ&Au=$f*1# z!H4MDL6`i>zott|#2Gc{-q88UReh)7Ct#}Uocm@x@4%Ar5YIoO8wVc6plbvjtr?JC z@-tQtI}$QaUg+!gF3`V$hcjn(ZXaFY%LgN#FM}oknj&Evc@%mq-)Y!kT=CwK`4~as zTR?gEdeDCf`qTp*^OnmnSLi5jhjBsD5lf$Z`tQd{M=(9vR@BiDTfO``VuLtjq>m)` zm`gsl61AntSaz8niL=7@-VQ_gfZL{6NvUg+Dwn+KqsFB$2g?U=Ga~)5o<`_y<$$%% zGC@#`=AVTu4T$>!7(>X?V#p(_<0}pKvp4C!6RVA#4A%Ioh;BD<=yyMvMxdh*P>^Qedwgv3d5G#(tgJ$p2;$i96ZkSDNaHT=jga!B@69 zWW>h#AAX>>C089wpCS^+xaETn7t@6`=|l9l^n(v?BTe?EdA^x#ca7=%3hGP4%QRKF6*3ziadUblz)cEyeOyN zdZmvn|K|H}CFS{VG$X~&`0~$0{>!lX`*;XQqu*7<2S0PkKlcdv@H3|TBY*dqegc<1 zr^C8Dq8d9b8kE29O+PV8A9_a-eNK|v5EgmaZoA0) zL_>JLGVd?FBkTXhCt2wE{|4{>FY;^`cH5Kcqt~N{|9|KqXw*Fr{1N}`>!atZMB1LD z=XZ&`oZGSRWc~x~_&xRoI%Ta>*65sSKaeg{&`n*a*N<~`<|A{{e<0mlK{rvXckUv| zp>w)i&~-+;=8AtH-C9AnM6}zLla6ftfpohBUDdzfx97LLJXc(9`AH^#b!cJ>4wmWU}_x`j!3e?#pTNO4@&xCX06byE;=P_toV{ z>#e7qOC!0d;?iECUsy%HVUd0@S>#WN_ipBkyj#rQDI%|}(l5*+e^BUQuE-|}z0DK( zxh7pMdbbjNCN9y_=>Ppf&jq4f#;wtGvGOgVK3do(2TbfLme?)cpLMr?FyYOq?cYm_i8Nxun_A^Q zD}vJdR0rVwL(-xmB__NDc5XL*$kee5i_lVQaqMgt->2`#`Y^McFro_W1C4m&tHe_U zuG4oNFCFiyf7-^yZnrlJi2a0MFZQv0Sz6S1jrga0`Y;)%NIvu)F_K^6a(_w79pN&* zka)4cWt=cdF#4Im<$9kf@ZAFUi#UMZfkB@p{1Jb-uF^Xx=<^}}zpEYUdh2S>AA_Fw zNIT!a>oay<;M=Jq`0#g(Ax*{r6TS3jeR(O~u_y43I8)$@1uo-7=>|&#F4rOc-Y?X- zPvCO>lJ@YZz~2z-nkM+u`*%p5Qv%;A@Ye+{__G3+aqSy|{#}8~_*vrr5V(w^`1^!V$AE(| z(!Y$)W(qz-1nw1a8-G_2%B~Z5T&Yed^)_GNfifNE@BP7LiR3ThQ2q`c;9h~t_?5pe z2lz38%XopmzXrJU8%v_%W{KOQ@blnfzN2ecv#RLYae6B_SXP~!)3taa{ za623y$d-%s7#?6{&TgoHjRVh-DkVoS5-aYzAdUJed z`F|?tC9ZL5#(pDkxv!A;s{*$RJ`z7JaJkR$3O?rq?vA1#hl5Shn>Pw~3EVI6V!@|Q z;BwzEQQ+GIF5`N$z@HYljPJbye?`)ZxK_9Wp`R<+T1hDAKLvg4^%wRZweJ4|^n6}K z;a>`TdlW9mB|1I{3wn7@F2rF2U>F7^Zh_n9ADvIvI4Ygfcg5!dCpqPLyyUO*N$wJ- z6>vUXah?83mgY##gcQDft9_o%z)8cCTd7I8k*sE}MA2y2eqz;C#Bqfjc>V zHXI#i{suT>UE|vZ!6!Oyq<5nk5FbXzrH6qVS*&=kYkYnj^!=&nsLwxuL;GDm^n%y! z@TA_|Vi_HU^#@1GmJ$m&L&E0-n*09=61we=-KXKL&mv27V$2PVaT=Zrm@% zz>^SycSoNQ1D_lNr}qPP$7fLt+!+Jk90Pwe2LAgP_!}|sV=?e^F>rdfc6a?UVFS_~ zo*Dxm9RtsffzOG7+hX7~G4T6h;GP)xKH%N?w?D<8KNti5;Qy)YYCR|Kq_w zi0{Mu^!afQ{y7gm^59?f;17ZK>G@?3{VN{)#~%FG9vuI-Y43X9^5E}!@F(%nSfAd8 z9{ful{DB8Q@!%I8{ACaRT@U_>2mgr&|D^|i(}Tb5!AWU-db{btpYq@{4=z1;4*Vwe z+qd2K7I+;t*Q*}-pL+1uJ^1fE_}d=*pC0@PBms0?xjyW{Kjpzk9(>`!W8j~-B6TqM zricFf9{dL${1+blw;uej9-NX!pMIY7;2-tipY`Bh_TYm+m(egA+`1S9GLFT$l4s&1 zB{&6~E1g6|5oKvH3ID7vg5De-ZP*~)2x&0Aj@EVPgUoc z4oCV_q*+mFCvco4NtP0EaiB^W#Ih*NVv{V~#5_Vr5n<-hP``FcEgvae^bDp|t_Sl< zd}VtwUQDJ}br+>kDMEE3H?dC>XXn@VcY1>?uSAinK$MxN7fHI$D?ExoD_QbX=M|K) z270K@-Q?!gn2gf^E!_Yd2Czt(>ntDMzPgMU78N5iPlvTq?;g`0r2)b%gxT@*lb39~!T z+m3>=M>}njVztR*)kDY4gR z6cI4~)!qVg=#2sDXh-IiG(rUaG(x@oAw)gbIXd-s9KE&DAXbtBzLV2Jg;my}ERY%~ z53E$tXQ#bV=_$goSi6BnVYt#VP{%Sj>zK?$)46z7=DBzdmQv!*omPGo&#Ff<-XP3G zgJRVG#db%lhnonl*TZIFS6v{in;|K6(wJvrzPR&Dt3$|hiAl)~%&Vi9WI0G=l!_?D z8gs4iS483P8ONR!NVH1W{4VGrqVz{2C)^rGVR;$p|8K+dCNpd|D;sib~q}H+$ zDlK(2IMLVwh;Wl66$WiR!GBP!+N45E7o&rTm>g~kF)%~XJc>-LWg1d--G1?Kbg(xD zx^s9WCcBPdcY6V7buebuo&DL?XkW~x)8%9(R->)`2?ivA1E?s-tGhe&PQV-LE0??Kcll-L!^+*0dH6q)sOnjksM|5Y2<}5V*>P?X zgbt~HFUd1q3J7$Du>RDDA-6aKAx#8S3yJ-3SUV1Nz;hQkY7`~PF5S_>c2JRXFtZ^+ z%-cRJhz--MeC#5DMO&jf0a(GN86FbJHCfzVQze$BFkqg0+u&THI;k{JVw|NV>IuoW zK1vjb3OtiDEowv2Dz8i$@m#3#ve(R(qDXVZR7p-}VrL7A61xZ#037aSYUy4&k5QL_ zyTvUcv$xAp^R}{#>}a)58a|}=8LKA~E3MI1GK!Hof;II+39zTtfuJG?>A@N=P$0TI z*RG8RMX7bL)@>^C*C}3>6b!RLN)h4|Zy_`+yaS1?CE#=;b=c-*rP}CRt+8JZYeTrD zz~on5$7C&&WNOWTjsnSX%>rZrY%lQW7GWE!tpO(8P5|Ownw_TzMbeMhS9r&{oJL^C zAjvOJ-C3l04{(83`^hqn+NPs?#P6WsMR<`{wWr}+8&kmBAHBY!pZ#H5Q585^O`oU9 zBLSqW@ZJ^ft4AufGsGZns&0WDJs+ib#|+M(D;jvEH_gDEyuj17<}#hm2Ik%+lPy^& zC-Aa`c9cm`FcgtD(`q#6HtDEuS$fLlfHlx0+J@CeBN?5kY}{O;J;GZY6&(b#ecPjC zJI{()8duH=6cg4#I5qInO|ZKiqA57^#$vXZv?Hc>7lq#D0|!in1|wIDjyGkUYHYC> z6}63tYFTDEJpXq&i{iuG6I}XS`0QT1q?hu7HN5B*1H6+D02qiE7fuWn-Ak z(cU7MD(x@itiDk-~HhT z1-^T?7oQK~_LjrB;m>vXd5D{T;J0zi&*#Os{fr~Tu`hGsYxqmo^LWBnezko5yeut<^T*u2&oS`)Sq`^H;HTdb z@-v@P=Ju`=MDr&ap1*?!A#S*jFh0-BE&qOzI~4G|Mxole9oKOpF96ynO*s>b@&Ga(Dj=6 zJNOsQ3$!n`A7ekn4ZcD%v0*SiAO3Gk(WU2SZhrqe!K9;>{yPW%l{|fM0wlwbHn^kGvHb~s^uYw zo;xB8<%N@f;R5(0K);25ET7{V$9w9z8%Fo%@h7dM7w~;e`(pWw;cKK`{x3XdDgVZV IuI=*w7sV!8Jpcdz literal 0 HcmV?d00001 diff --git a/app/core/permissions.py b/app/core/permissions.py new file mode 100644 index 0000000..9465276 --- /dev/null +++ b/app/core/permissions.py @@ -0,0 +1,73 @@ +"""PR12: permission-aware authorization. + +The Gateway's PolicyMiddleware already forwards the requester's JWT +`permissions` claim on every /policy/evaluate call (see +omnibioai-api-gateway app/services/policy_client.py), but until this PR +nothing here ever read it -- authorization was role-name/action-string +matching only (app/core/rbac.py). This module adds a second, additive gate +keyed off the same permission-registry strings omnibioai-auth already +reserves (app/core/permission_names.py there: workflow.execute, +dataset.read, workflow.manage, etc) without inventing any new ones. + +Deliberately opt-in: enforced only when the caller actually populates +`permissions` (a non-empty list). No role in the live system is granted +these registry permissions yet (they're reserved-but-unassigned in +omnibioai-auth), so every real request today still carries permissions=[] +and this gate is a no-op there, falling back to the pre-existing +role-based rbac.evaluate_rbac check -- exactly today's behavior, not a +new production restriction. It only actively deters/tests once a caller +(a fixture in these tests, or eventually a real user once +omnibioai-auth grants these permissions to a role) supplies a non-empty +permissions list. This is intentional scope containment for PR12 -- see +this PR's report for why granting these permissions to real roles is out +of scope (would require a DB/role change in omnibioai-auth). +""" + +from typing import List, Optional + +# action (exact match) -> required permission +ACTION_PERMISSION_MAP = { + "dataset.read": "dataset.read", +} + +# action prefix -> required permission +PREFIX_PERMISSION_MAP = { + "tes.": "workflow.execute", +} + +# (resource, action) -> required permission +RESOURCE_ACTION_PERMISSION_MAP = { + ("model_registry", "delete"): "workflow.manage", +} + + +def required_permission(action: str, resource: str) -> Optional[str]: + if action in ACTION_PERMISSION_MAP: + return ACTION_PERMISSION_MAP[action] + + for prefix, permission in PREFIX_PERMISSION_MAP.items(): + if action.startswith(prefix): + return permission + + return RESOURCE_ACTION_PERMISSION_MAP.get((resource, action)) + + +def evaluate_permission( + roles: List[str], permissions: List[str], action: str, resource: str +) -> tuple[bool, str]: + if "admin" in roles: + return True, "admin override" + + if not permissions: + # Not permission-aware traffic (see module docstring) -- defer + # entirely to rbac.evaluate_rbac, which already ran before this. + return True, "permission check skipped: no permissions supplied" + + permission = required_permission(action, resource) + if permission is None: + return True, "no permission required" + + if permission in permissions: + return True, "permission granted" + + return False, f"missing permission: {permission}" diff --git a/app/core/rbac.c b/app/core/rbac.c index 6f666ce..516df01 100644 --- a/app/core/rbac.c +++ b/app/core/rbac.c @@ -2247,7 +2247,7 @@ typedef struct { __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_values; PyObject *__pyx_tuple[4]; PyObject *__pyx_codeobj_tab[1]; - PyObject *__pyx_string_tab[37]; + PyObject *__pyx_string_tab[38]; /* #### Code section: module_state_contents ### */ /* CommonTypesMetaclass.module_state_decls */ PyTypeObject *__pyx_CommonTypesMetaclassType; @@ -2294,37 +2294,38 @@ static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_stati #define __pyx_kp_u_admin_override __pyx_string_tab[3] #define __pyx_kp_u_app_core_rbac_py __pyx_string_tab[4] #define __pyx_kp_u_dataset __pyx_string_tab[5] -#define __pyx_kp_u_list_str __pyx_string_tab[6] -#define __pyx_kp_u_missing_role_data_scientist __pyx_string_tab[7] -#define __pyx_kp_u_missing_role_researcher __pyx_string_tab[8] -#define __pyx_kp_u_rbac_passed __pyx_string_tab[9] -#define __pyx_kp_u_tes __pyx_string_tab[10] -#define __pyx_kp_u_tuple_bool_str __pyx_string_tab[11] -#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[12] -#define __pyx_n_u_action __pyx_string_tab[13] -#define __pyx_n_u_admin __pyx_string_tab[14] -#define __pyx_n_u_app_core_rbac __pyx_string_tab[15] -#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[16] -#define __pyx_n_u_cline_in_traceback __pyx_string_tab[17] -#define __pyx_n_u_data_scientist __pyx_string_tab[18] -#define __pyx_n_u_evaluate_rbac __pyx_string_tab[19] -#define __pyx_n_u_func __pyx_string_tab[20] -#define __pyx_n_u_is_coroutine __pyx_string_tab[21] -#define __pyx_n_u_items __pyx_string_tab[22] -#define __pyx_n_u_main __pyx_string_tab[23] -#define __pyx_n_u_module __pyx_string_tab[24] -#define __pyx_n_u_name __pyx_string_tab[25] -#define __pyx_n_u_pop __pyx_string_tab[26] -#define __pyx_n_u_qualname __pyx_string_tab[27] -#define __pyx_n_u_researcher __pyx_string_tab[28] -#define __pyx_n_u_return __pyx_string_tab[29] -#define __pyx_n_u_set_name __pyx_string_tab[30] -#define __pyx_n_u_setdefault __pyx_string_tab[31] -#define __pyx_n_u_str __pyx_string_tab[32] -#define __pyx_n_u_test __pyx_string_tab[33] -#define __pyx_n_u_user_roles __pyx_string_tab[34] -#define __pyx_n_u_values __pyx_string_tab[35] -#define __pyx_kp_b_iso88591_1_xs_vQ_v_wa_v_T_wa_6 __pyx_string_tab[36] +#define __pyx_kp_u_dataset_read __pyx_string_tab[6] +#define __pyx_kp_u_list_str __pyx_string_tab[7] +#define __pyx_kp_u_missing_role_data_scientist __pyx_string_tab[8] +#define __pyx_kp_u_missing_role_researcher __pyx_string_tab[9] +#define __pyx_kp_u_rbac_passed __pyx_string_tab[10] +#define __pyx_kp_u_tes __pyx_string_tab[11] +#define __pyx_kp_u_tuple_bool_str __pyx_string_tab[12] +#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[13] +#define __pyx_n_u_action __pyx_string_tab[14] +#define __pyx_n_u_admin __pyx_string_tab[15] +#define __pyx_n_u_app_core_rbac __pyx_string_tab[16] +#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[17] +#define __pyx_n_u_cline_in_traceback __pyx_string_tab[18] +#define __pyx_n_u_data_scientist __pyx_string_tab[19] +#define __pyx_n_u_evaluate_rbac __pyx_string_tab[20] +#define __pyx_n_u_func __pyx_string_tab[21] +#define __pyx_n_u_is_coroutine __pyx_string_tab[22] +#define __pyx_n_u_items __pyx_string_tab[23] +#define __pyx_n_u_main __pyx_string_tab[24] +#define __pyx_n_u_module __pyx_string_tab[25] +#define __pyx_n_u_name __pyx_string_tab[26] +#define __pyx_n_u_pop __pyx_string_tab[27] +#define __pyx_n_u_qualname __pyx_string_tab[28] +#define __pyx_n_u_researcher __pyx_string_tab[29] +#define __pyx_n_u_return __pyx_string_tab[30] +#define __pyx_n_u_set_name __pyx_string_tab[31] +#define __pyx_n_u_setdefault __pyx_string_tab[32] +#define __pyx_n_u_str __pyx_string_tab[33] +#define __pyx_n_u_test __pyx_string_tab[34] +#define __pyx_n_u_user_roles __pyx_string_tab[35] +#define __pyx_n_u_values __pyx_string_tab[36] +#define __pyx_kp_b_iso88591_1_xs_vQ_v_wa_k_G3a_WA_wa_6 __pyx_string_tab[37] /* #### Code section: module_state_clear ### */ #if CYTHON_USE_MODULE_STATE static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { @@ -2341,7 +2342,7 @@ static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { #endif for (int i=0; i<4; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } for (int i=0; i<1; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } - for (int i=0; i<37; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } + for (int i=0; i<38; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } /* #### Code section: module_state_clear_contents ### */ /* CommonTypesMetaclass.module_state_clear */ Py_CLEAR(clear_module_state->__pyx_CommonTypesMetaclassType); @@ -2366,7 +2367,7 @@ static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); for (int i=0; i<4; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } for (int i=0; i<1; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } - for (int i=0; i<37; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } + for (int i=0; i<38; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } /* #### Code section: module_state_traverse_contents ### */ /* CommonTypesMetaclass.module_state_traverse */ Py_VISIT(traverse_module_state->__pyx_CommonTypesMetaclassType); @@ -2552,7 +2553,7 @@ static PyObject *__pyx_pf_3app_4core_4rbac_evaluate_rbac(CYTHON_UNUSED PyObject * if action.startswith("tes.") and "researcher" not in user_roles: * return False, "missing role: researcher" # <<<<<<<<<<<<<< * - * if action.startswith("dataset.") and "data_scientist" not in user_roles: + * # PR12: dataset.read is exempted from the blanket data_scientist */ __Pyx_XDECREF(__pyx_r); __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[1]); @@ -2568,27 +2569,57 @@ static PyObject *__pyx_pf_3app_4core_4rbac_evaluate_rbac(CYTHON_UNUSED PyObject */ } - /* "app/core/rbac.py":8 - * return False, "missing role: researcher" - * - * if action.startswith("dataset.") and "data_scientist" not in user_roles: # <<<<<<<<<<<<<< - * return False, "missing role: data_scientist" - * + /* "app/core/rbac.py":17 + * # still gated here exactly as before. + * if ( + * action.startswith("dataset.") # <<<<<<<<<<<<<< + * and action != "dataset.read" + * and "data_scientist" not in user_roles +*/ + __pyx_t_2 = __Pyx_PyUnicode_Tailmatch(__pyx_v_action, __pyx_mstate_global->__pyx_kp_u_dataset, 0, PY_SSIZE_T_MAX, -1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 17, __pyx_L1_error) + if (__pyx_t_2) { + } else { + __pyx_t_1 = __pyx_t_2; + goto __pyx_L8_bool_binop_done; + } + + /* "app/core/rbac.py":18 + * if ( + * action.startswith("dataset.") + * and action != "dataset.read" # <<<<<<<<<<<<<< + * and "data_scientist" not in user_roles + * ): */ - __pyx_t_2 = __Pyx_PyUnicode_Tailmatch(__pyx_v_action, __pyx_mstate_global->__pyx_kp_u_dataset, 0, PY_SSIZE_T_MAX, -1); if (unlikely(__pyx_t_2 == ((int)-1))) __PYX_ERR(0, 8, __pyx_L1_error) + __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_v_action, __pyx_mstate_global->__pyx_kp_u_dataset_read, Py_NE)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 18, __pyx_L1_error) if (__pyx_t_2) { } else { __pyx_t_1 = __pyx_t_2; goto __pyx_L8_bool_binop_done; } - __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_mstate_global->__pyx_n_u_data_scientist, __pyx_v_user_roles, Py_NE)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 8, __pyx_L1_error) + + /* "app/core/rbac.py":19 + * action.startswith("dataset.") + * and action != "dataset.read" + * and "data_scientist" not in user_roles # <<<<<<<<<<<<<< + * ): + * return False, "missing role: data_scientist" +*/ + __pyx_t_2 = (__Pyx_PySequence_ContainsTF(__pyx_mstate_global->__pyx_n_u_data_scientist, __pyx_v_user_roles, Py_NE)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 19, __pyx_L1_error) __pyx_t_1 = __pyx_t_2; __pyx_L8_bool_binop_done:; + + /* "app/core/rbac.py":16 + * # granting write/delete). Write/delete actions are unaffected -- + * # still gated here exactly as before. + * if ( # <<<<<<<<<<<<<< + * action.startswith("dataset.") + * and action != "dataset.read" +*/ if (__pyx_t_1) { - /* "app/core/rbac.py":9 - * - * if action.startswith("dataset.") and "data_scientist" not in user_roles: + /* "app/core/rbac.py":21 + * and "data_scientist" not in user_roles + * ): * return False, "missing role: data_scientist" # <<<<<<<<<<<<<< * * return True, "rbac passed" @@ -2598,16 +2629,16 @@ static PyObject *__pyx_pf_3app_4core_4rbac_evaluate_rbac(CYTHON_UNUSED PyObject __pyx_r = __pyx_mstate_global->__pyx_tuple[2]; goto __pyx_L0; - /* "app/core/rbac.py":8 - * return False, "missing role: researcher" - * - * if action.startswith("dataset.") and "data_scientist" not in user_roles: # <<<<<<<<<<<<<< - * return False, "missing role: data_scientist" - * + /* "app/core/rbac.py":16 + * # granting write/delete). Write/delete actions are unaffected -- + * # still gated here exactly as before. + * if ( # <<<<<<<<<<<<<< + * action.startswith("dataset.") + * and action != "dataset.read" */ } - /* "app/core/rbac.py":11 + /* "app/core/rbac.py":23 * return False, "missing role: data_scientist" * * return True, "rbac passed" # <<<<<<<<<<<<<< @@ -3076,29 +3107,29 @@ static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { * if action.startswith("tes.") and "researcher" not in user_roles: * return False, "missing role: researcher" # <<<<<<<<<<<<<< * - * if action.startswith("dataset.") and "data_scientist" not in user_roles: + * # PR12: dataset.read is exempted from the blanket data_scientist */ __pyx_mstate_global->__pyx_tuple[1] = PyTuple_Pack(2, Py_False, __pyx_mstate_global->__pyx_kp_u_missing_role_researcher); if (unlikely(!__pyx_mstate_global->__pyx_tuple[1])) __PYX_ERR(0, 6, __pyx_L1_error) __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[1]); __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[1]); - /* "app/core/rbac.py":9 - * - * if action.startswith("dataset.") and "data_scientist" not in user_roles: + /* "app/core/rbac.py":21 + * and "data_scientist" not in user_roles + * ): * return False, "missing role: data_scientist" # <<<<<<<<<<<<<< * * return True, "rbac passed" */ - __pyx_mstate_global->__pyx_tuple[2] = PyTuple_Pack(2, Py_False, __pyx_mstate_global->__pyx_kp_u_missing_role_data_scientist); if (unlikely(!__pyx_mstate_global->__pyx_tuple[2])) __PYX_ERR(0, 9, __pyx_L1_error) + __pyx_mstate_global->__pyx_tuple[2] = PyTuple_Pack(2, Py_False, __pyx_mstate_global->__pyx_kp_u_missing_role_data_scientist); if (unlikely(!__pyx_mstate_global->__pyx_tuple[2])) __PYX_ERR(0, 21, __pyx_L1_error) __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[2]); __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[2]); - /* "app/core/rbac.py":11 + /* "app/core/rbac.py":23 * return False, "missing role: data_scientist" * * return True, "rbac passed" # <<<<<<<<<<<<<< */ - __pyx_mstate_global->__pyx_tuple[3] = PyTuple_Pack(2, Py_True, __pyx_mstate_global->__pyx_kp_u_rbac_passed); if (unlikely(!__pyx_mstate_global->__pyx_tuple[3])) __PYX_ERR(0, 11, __pyx_L1_error) + __pyx_mstate_global->__pyx_tuple[3] = PyTuple_Pack(2, Py_True, __pyx_mstate_global->__pyx_kp_u_rbac_passed); if (unlikely(!__pyx_mstate_global->__pyx_tuple[3])) __PYX_ERR(0, 23, __pyx_L1_error) __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[3]); __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[3]); #if CYTHON_IMMORTAL_CONSTANTS @@ -3131,34 +3162,34 @@ static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { CYTHON_UNUSED_VAR(__pyx_mstate); { - const struct { const unsigned int length: 8; } index[] = {{1},{179},{8},{14},{16},{8},{9},{28},{24},{11},{4},{16},{20},{6},{5},{13},{18},{18},{14},{13},{8},{13},{5},{8},{10},{8},{3},{12},{10},{6},{12},{10},{3},{8},{10},{6},{86}}; - #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (525 bytes) */ -const char* const cstring = "BZh91AY&SY\374\025\"\325\000\000,\177\377d\310\244E`\247\245P\217!t\n\277\377\377\340@@@@@\000@@@\000@@@\000@\001\245@A\250\232j\237\210\324\236\005=M\244\320i\2657\252=@h\014\215\036\247\251\3413T\022\246CA4\022m\032&\246F\200\000\000\r\000z\232\003\230\0020L@0\t\202h\310h`\023\004bc\230\0020L@0\t\202h\310h`\023\004bl\030-\r\r*\010\341\n\242_\210n)i__\255\225s\325\247c,\320{L\342v\374\243\350\035\230$]\014&qH\341\312\363&\236o\357\205\256\331`\225\323\235\312u\3707\220\343\307\2669\340p3\323\334\306\031c\242\345\274\346 \304?\252\357\252\034\363\320~\217\321\"\225\244Z\010?\256\243\322?a]!\030\254\003\227F\244\242\375[\260\016\222\336:L\222d\214P%L\204\\H\206p`\0368\272\350&\020\025\3224\036\375\243\366\364\356Z\215bi\227U\272\032\\\220\036K\277\234w\343\250\3208;\0261ct\272\255\t~\344\254\263-\220\262\333\003\007\234#J\013\216\366\010C\217'\034\215\365s\006\261.\343R\005\2666\332>p01\233\314\364\234\311\304\301\022Y \205,\260\207-\346\326R7+\257:.\365\264n\243\320\324\217#\205aw\n?R8\\\332\342\304y%k\335\272&\374\363\013nLfU\212\251\003,r6.\255NDJ\363B,T\312\3422\242V\004\030\253\244\222\321]\256\014?4#D)s\017\024$\346B<\365WB=\305T;s\330\217\203\260TTJ\307\226\322\250k\307\022\223\330$\244#\246\217\226\273\331\257\3764\304\335\205\264\310\024\240\372\2423D\244\223\200\331)\314\250\2267\236\242~\3203VM\357:\321\314,\027_~\024\273\256\262\277\271\273q(m\003\374]\311\024\341BC\360T\213T"; - PyObject *data = __Pyx_DecompressString(cstring, 525, 2); + const struct { const unsigned int length: 8; } index[] = {{1},{179},{8},{14},{16},{8},{12},{9},{28},{24},{11},{4},{16},{20},{6},{5},{13},{18},{18},{14},{13},{8},{13},{5},{8},{10},{8},{3},{12},{10},{6},{12},{10},{3},{8},{10},{6},{99}}; + #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (557 bytes) */ +const char* const cstring = "BZh91AY&SY\315\023\375\\\000\0000\177\373\347\315\244C`\207\255P\257\241p\212\277\377\377\340@@@@@\000@@@@@\000@\000@\001\246\356\325g\010\246\000\246\3212\237\250\2154\323#\t\246\236\243F\201\3524\r\007\240\332OMPjja=T\375OT\336\202OL\243 \000\014\002a0L\200z\201\206\246\t\0324\223\312\r\352\207\244\000\0001\000d\000\000\001(\202zMS\324dz#M\032h=@\000\000\000\000\000^\376\300\246\272\304u(\n\000Q\r\013\010*M`\372\310\366&-;\250\303F_\231\267d5$\032~\265#\354\r\324\344\203d\220\203R#\267\307\014\334[~!\206\226F\302\214\306&u\371h}\323\207o4\267$\032\005\267\317\211\020Ud\242s\332#0_\323w\231\013\323\310$\222D\305D\031\352A4\014!7\240\344ah=B+\206\311\r\365g\177\341\004\370\275\254\371&)\220X\\\225aV;[\276\217\003V)\245\363\007\222!\025\302S0L\332g\201\241\216\006Q~;\224\3419\026\022\203\353\254\272\037`\220\026\272\267\251V\361\232\277qY\276\2467\234\3425\203\232\352\213\210-h@\036Fs\334\025T\311LB\206\241\200J\n\247\323B\203\267\2316\342MB\250y\244V\256f\rb\251\024<\361\230!EF\313MB\353\3144M\3145i\302\366\242\010B\302@\327(ZoA,'\003\313e@\340\271!v\352'X\242Y@t\344\363\r`l\001B'\304,A\034h\"&\360\251l&:\336!\026\245g\002\014M\031Z\363\222\270P>\342\221\245Jj(\0368\031(R8f\344\204r\334\345K%u_\000\306r\271Vq\277SL+\265h\246WEf\025\022\"!\221\034\3618\351\001\\\215x\230\nPB\251H\373P0\344\212k\252\225aQ\277\003\367\327'\365\352 j\367\236\247\206\034\373gk^\327h,\366mj\260\354\256\031\036W\213\374]\311\024\341BC4O\365p"; + PyObject *data = __Pyx_DecompressString(cstring, 557, 2); if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) const char* const bytes = __Pyx_PyBytes_AsString(data); #if !CYTHON_ASSUME_SAFE_MACROS if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } #endif - #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (442 bytes) */ -const char* const cstring = "x\332UQ=o\0241\020\005\t\t$\n\024\211\"\005\212\206\352\204\004\033!E\010\245\241\340C\242\211\016Dw:Y\263\366\034g\360\332\213g\274\334v)\257\2742\345\375\204\224)\371\tW\246\344\2470\016\210$+\255w\274\363\346\371\275\3477'I\010d\211\002oGY\246\010\236\301Q\360-e\024\n#\260do\205r\005E\230\276\237\2768z}\004\030\035d\372FV\030\270\2646 31\244\005\264\305\007\361\021d\354\211\033\370\270\2001\025\210D\016$A\257\270\233\003\262\244\010LR\013\230`\214IP|\212F\307}\374:\001\347\263\036\342\007\252\323\037005\350\234Q\034\241\353\364\2344P\316\336\021\366\375\241M\231\016s\213\266\351G\207\202J\334\004\3172S\023\363\3163+%\344\024\350\030j\333\260\365\024E\001\267{\231\2300\333\245\022+\327\225fr\242n\244\364\201fmJ\341y\315en\314t\\\351\373N\0232'\264\222\317\264@[\365_iSIM\225\324T\032\3441Z\237\352\217T4 b\033t5^\275f\264\244\220\357\267E\321\200\241\350%\230:n\314\242D]\215g\363\237\302\013ulL\207J\242O\227\\\tT\253\210\235~\373\324\033\363\243`\370\273\275a\213\244d\035\321|\376A\265r\252\275\004Q_\306\250Y1\2460eS#\341\252\204xw\347`w\360\362|\377b\357\362\336\375\323\325\2327O/\037__pyx_string_tab; Py_ssize_t pos = 0; - for (int i = 0; i < 36; i++) { + for (int i = 0; i < 37; i++) { Py_ssize_t bytes_length = index[i].length; PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); - if (likely(string) && i >= 12) PyUnicode_InternInPlace(&string); + if (likely(string) && i >= 13) PyUnicode_InternInPlace(&string); if (unlikely(!string)) { Py_XDECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) @@ -3166,7 +3197,7 @@ const char* const bytes = "?Note that Cython is deliberately stricter than PEP-4 stringtab[i] = string; pos += bytes_length; } - for (int i = 36; i < 37; i++) { + for (int i = 37; i < 38; i++) { Py_ssize_t bytes_length = index[i].length; PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); stringtab[i] = string; @@ -3177,14 +3208,14 @@ const char* const bytes = "?Note that Cython is deliberately stricter than PEP-4 } } Py_XDECREF(data); - for (Py_ssize_t i = 0; i < 37; i++) { + for (Py_ssize_t i = 0; i < 38; i++) { if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { __PYX_ERR(0, 1, __pyx_L1_error) } } #if CYTHON_IMMORTAL_CONSTANTS { - PyObject **table = stringtab + 36; + PyObject **table = stringtab + 37; for (Py_ssize_t i=0; i<1; ++i) { #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING #if PY_VERSION_HEX < 0x030E0000 @@ -3232,7 +3263,7 @@ static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) { { const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 2, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 1}; PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_user_roles, __pyx_mstate->__pyx_n_u_action}; - __pyx_mstate_global->__pyx_codeobj_tab[0] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_rbac_py, __pyx_mstate->__pyx_n_u_evaluate_rbac, __pyx_mstate->__pyx_kp_b_iso88591_1_xs_vQ_v_wa_v_T_wa_6, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[0])) goto bad; + __pyx_mstate_global->__pyx_codeobj_tab[0] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_rbac_py, __pyx_mstate->__pyx_n_u_evaluate_rbac, __pyx_mstate->__pyx_kp_b_iso88591_1_xs_vQ_v_wa_k_G3a_WA_wa_6, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[0])) goto bad; } Py_DECREF(tuple_dedup_map); return 0; diff --git a/app/core/rbac.cpython-313-aarch64-linux-gnu.so b/app/core/rbac.cpython-313-aarch64-linux-gnu.so index cf67bde0c4ec159345348dc32ef07019dd4f9d8c..d5479f416775787148209fdd95d72adfbd3d700d 100755 GIT binary patch delta 13486 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 O>Jg=HDaZ0?>i+}Y&1kLw delta 12689 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 t%(*VJz7&)yjzOreksP3` tuple[bool, str]: if action.startswith("tes.") and "researcher" not in user_roles: return False, "missing role: researcher" - if action.startswith("dataset.") and "data_scientist" not in user_roles: + # PR12: dataset.read is exempted from the blanket data_scientist + # requirement -- read access is now governed by the finer-grained + # permissions.py gate (the "dataset.read" permission) instead, which + # is what lets a read-only "Viewer" tier exist at all (this legacy + # rule previously made ANY dataset.* action, including read, + # data_scientist-only, with no way to grant read without also + # granting write/delete). Write/delete actions are unaffected -- + # still gated here exactly as before. + if ( + action.startswith("dataset.") + and action != "dataset.read" + and "data_scientist" not in user_roles + ): return False, "missing role: data_scientist" return True, "rbac passed" \ No newline at end of file diff --git a/app/core/tenancy.c b/app/core/tenancy.c new file mode 100644 index 0000000..97bb541 --- /dev/null +++ b/app/core/tenancy.c @@ -0,0 +1,8284 @@ +/* Generated by Cython 3.2.5 */ + +/* BEGIN: Cython Metadata +{ + "distutils": { + "name": "app.core.tenancy", + "sources": [ + "app/core/tenancy.py" + ] + }, + "module_name": "app.core.tenancy" +} +END: Cython Metadata */ + +#ifndef PY_SSIZE_T_CLEAN +#define PY_SSIZE_T_CLEAN +#endif /* PY_SSIZE_T_CLEAN */ +/* InitLimitedAPI */ +#if defined(Py_LIMITED_API) + #if !defined(CYTHON_LIMITED_API) + #define CYTHON_LIMITED_API 1 + #endif +#elif defined(CYTHON_LIMITED_API) + #ifdef _MSC_VER + #pragma message ("Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead.") + #else + #warning Limited API usage is enabled with 'CYTHON_LIMITED_API' but 'Py_LIMITED_API' does not define a Python target version. Consider setting 'Py_LIMITED_API' instead. + #endif +#endif + +#include "Python.h" +#ifndef Py_PYTHON_H + #error Python headers needed to compile C extensions, please install development version of Python. +#elif PY_VERSION_HEX < 0x03080000 + #error Cython requires Python 3.8+. +#else +#define __PYX_ABI_VERSION "3_2_5" +#define CYTHON_HEX_VERSION 0x030205F0 +#define CYTHON_FUTURE_DIVISION 1 +/* CModulePreamble */ +#include +#ifndef offsetof + #define offsetof(type, member) ( (size_t) & ((type*)0) -> member ) +#endif +#if !defined(_WIN32) && !defined(WIN32) && !defined(MS_WINDOWS) + #ifndef __stdcall + #define __stdcall + #endif + #ifndef __cdecl + #define __cdecl + #endif + #ifndef __fastcall + #define __fastcall + #endif +#endif +#ifndef DL_IMPORT + #define DL_IMPORT(t) t +#endif +#ifndef DL_EXPORT + #define DL_EXPORT(t) t +#endif +#define __PYX_COMMA , +#ifndef PY_LONG_LONG + #define PY_LONG_LONG LONG_LONG +#endif +#ifndef Py_HUGE_VAL + #define Py_HUGE_VAL HUGE_VAL +#endif +#define __PYX_LIMITED_VERSION_HEX PY_VERSION_HEX +#if defined(GRAALVM_PYTHON) + /* For very preliminary testing purposes. Most variables are set the same as PyPy. + The existence of this section does not imply that anything works or is even tested */ + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 1 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #undef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(PYPY_VERSION) + #define CYTHON_COMPILING_IN_PYPY 1 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #undef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 1 + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 0 + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #if PY_VERSION_HEX < 0x03090000 + #undef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 0 + #elif !defined(CYTHON_PEP489_MULTI_PHASE_INIT) + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #undef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE (PYPY_VERSION_NUM >= 0x07030C00) + #endif + #undef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 0 + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC (PYPY_VERSION_NUM >= 0x07031100) + #endif + #undef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 0 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#elif defined(CYTHON_LIMITED_API) + #ifdef Py_LIMITED_API + #undef __PYX_LIMITED_VERSION_HEX + #define __PYX_LIMITED_VERSION_HEX Py_LIMITED_API + #endif + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 0 + #define CYTHON_COMPILING_IN_LIMITED_API 1 + #define CYTHON_COMPILING_IN_GRAAL 0 + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 0 + #undef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 1 + #undef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 0 + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #undef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 0 + #ifndef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #endif + #undef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 0 + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #ifndef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #undef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 0 + #undef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 0 + #undef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 0 + #undef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 0 + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #undef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) + #undef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 0 + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #undef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING 0 + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 0 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND (__PYX_LIMITED_VERSION_HEX >= 0x030A0000) + #endif + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #undef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 0 + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 0 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS 1 + #endif + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 +#else + #define CYTHON_COMPILING_IN_PYPY 0 + #define CYTHON_COMPILING_IN_CPYTHON 1 + #define CYTHON_COMPILING_IN_LIMITED_API 0 + #define CYTHON_COMPILING_IN_GRAAL 0 + #ifdef Py_GIL_DISABLED + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 1 + #else + #define CYTHON_COMPILING_IN_CPYTHON_FREETHREADING 0 + #endif + #if PY_VERSION_HEX < 0x030A0000 + #undef CYTHON_USE_TYPE_SLOTS + #define CYTHON_USE_TYPE_SLOTS 1 + #elif !defined(CYTHON_USE_TYPE_SLOTS) + #define CYTHON_USE_TYPE_SLOTS 1 + #endif + #ifndef CYTHON_USE_TYPE_SPECS + #define CYTHON_USE_TYPE_SPECS 0 + #endif + #ifndef CYTHON_USE_PYTYPE_LOOKUP + #define CYTHON_USE_PYTYPE_LOOKUP 1 + #endif + #ifndef CYTHON_USE_PYLONG_INTERNALS + #define CYTHON_USE_PYLONG_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_PYLIST_INTERNALS + #define CYTHON_USE_PYLIST_INTERNALS 0 + #elif !defined(CYTHON_USE_PYLIST_INTERNALS) + #define CYTHON_USE_PYLIST_INTERNALS 1 + #endif + #ifndef CYTHON_USE_UNICODE_INTERNALS + #define CYTHON_USE_UNICODE_INTERNALS 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING || PY_VERSION_HEX >= 0x030B00A2 + #undef CYTHON_USE_UNICODE_WRITER + #define CYTHON_USE_UNICODE_WRITER 0 + #elif !defined(CYTHON_USE_UNICODE_WRITER) + #define CYTHON_USE_UNICODE_WRITER 1 + #endif + #ifndef CYTHON_AVOID_BORROWED_REFS + #define CYTHON_AVOID_BORROWED_REFS 0 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 1 + #elif !defined(CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS) + #define CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS 0 + #endif + #ifndef CYTHON_ASSUME_SAFE_MACROS + #define CYTHON_ASSUME_SAFE_MACROS 1 + #endif + #ifndef CYTHON_ASSUME_SAFE_SIZE + #define CYTHON_ASSUME_SAFE_SIZE 1 + #endif + #ifndef CYTHON_UNPACK_METHODS + #define CYTHON_UNPACK_METHODS 1 + #endif + #ifndef CYTHON_FAST_THREAD_STATE + #define CYTHON_FAST_THREAD_STATE 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_FAST_GIL + #define CYTHON_FAST_GIL 0 + #elif !defined(CYTHON_FAST_GIL) + #define CYTHON_FAST_GIL (PY_VERSION_HEX < 0x030C00A6) + #endif + #ifndef CYTHON_METH_FASTCALL + #define CYTHON_METH_FASTCALL 1 + #endif + #ifndef CYTHON_FAST_PYCALL + #define CYTHON_FAST_PYCALL 1 + #endif + #ifndef CYTHON_PEP487_INIT_SUBCLASS + #define CYTHON_PEP487_INIT_SUBCLASS 1 + #endif + #ifndef CYTHON_PEP489_MULTI_PHASE_INIT + #define CYTHON_PEP489_MULTI_PHASE_INIT 1 + #endif + #ifndef CYTHON_USE_MODULE_STATE + #define CYTHON_USE_MODULE_STATE 0 + #endif + #ifndef CYTHON_USE_SYS_MONITORING + #define CYTHON_USE_SYS_MONITORING (PY_VERSION_HEX >= 0x030d00B1) + #endif + #ifndef CYTHON_USE_TP_FINALIZE + #define CYTHON_USE_TP_FINALIZE 1 + #endif + #ifndef CYTHON_USE_AM_SEND + #define CYTHON_USE_AM_SEND 1 + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #undef CYTHON_USE_DICT_VERSIONS + #define CYTHON_USE_DICT_VERSIONS 0 + #elif !defined(CYTHON_USE_DICT_VERSIONS) + #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX < 0x030C00A5 && !CYTHON_USE_MODULE_STATE) + #endif + #ifndef CYTHON_USE_EXC_INFO_STACK + #define CYTHON_USE_EXC_INFO_STACK 1 + #endif + #ifndef CYTHON_UPDATE_DESCRIPTOR_DOC + #define CYTHON_UPDATE_DESCRIPTOR_DOC 1 + #endif + #ifndef CYTHON_USE_FREELISTS + #define CYTHON_USE_FREELISTS (!CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif + #if defined(CYTHON_IMMORTAL_CONSTANTS) && PY_VERSION_HEX < 0x030C0000 + #undef CYTHON_IMMORTAL_CONSTANTS + #define CYTHON_IMMORTAL_CONSTANTS 0 // definitely won't work + #elif !defined(CYTHON_IMMORTAL_CONSTANTS) + #define CYTHON_IMMORTAL_CONSTANTS (PY_VERSION_HEX >= 0x030C0000 && !CYTHON_USE_MODULE_STATE && CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) + #endif +#endif +#ifndef CYTHON_COMPRESS_STRINGS + #define CYTHON_COMPRESS_STRINGS 1 +#endif +#ifndef CYTHON_FAST_PYCCALL +#define CYTHON_FAST_PYCCALL CYTHON_FAST_PYCALL +#endif +#ifndef CYTHON_VECTORCALL +#if CYTHON_COMPILING_IN_LIMITED_API +#define CYTHON_VECTORCALL (__PYX_LIMITED_VERSION_HEX >= 0x030C0000) +#else +#define CYTHON_VECTORCALL (CYTHON_FAST_PYCCALL) +#endif +#endif +#if CYTHON_USE_PYLONG_INTERNALS + #undef SHIFT + #undef BASE + #undef MASK + #ifdef SIZEOF_VOID_P + enum { __pyx_check_sizeof_voidp = 1 / (int)(SIZEOF_VOID_P == sizeof(void*)) }; + #endif +#endif +#ifndef __has_attribute + #define __has_attribute(x) 0 +#endif +#ifndef __has_cpp_attribute + #define __has_cpp_attribute(x) 0 +#endif +#ifndef CYTHON_RESTRICT + #if defined(__GNUC__) + #define CYTHON_RESTRICT __restrict__ + #elif defined(_MSC_VER) && _MSC_VER >= 1400 + #define CYTHON_RESTRICT __restrict + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_RESTRICT restrict + #else + #define CYTHON_RESTRICT + #endif +#endif +#ifndef CYTHON_UNUSED + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(maybe_unused) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(maybe_unused) + #define CYTHON_UNUSED [[maybe_unused]] + #endif + #endif + #endif +#endif +#ifndef CYTHON_UNUSED +# if defined(__GNUC__) +# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +# elif defined(__ICC) || (defined(__INTEL_COMPILER) && !defined(_MSC_VER)) +# define CYTHON_UNUSED __attribute__ ((__unused__)) +# else +# define CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_UNUSED_VAR +# if defined(__cplusplus) + template void CYTHON_UNUSED_VAR( const T& ) { } +# else +# define CYTHON_UNUSED_VAR(x) (void)(x) +# endif +#endif +#ifndef CYTHON_MAYBE_UNUSED_VAR + #define CYTHON_MAYBE_UNUSED_VAR(x) CYTHON_UNUSED_VAR(x) +#endif +#ifndef CYTHON_NCP_UNUSED +# if CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +# define CYTHON_NCP_UNUSED +# else +# define CYTHON_NCP_UNUSED CYTHON_UNUSED +# endif +#endif +#ifndef CYTHON_USE_CPP_STD_MOVE + #if defined(__cplusplus) && (\ + __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)) + #define CYTHON_USE_CPP_STD_MOVE 1 + #else + #define CYTHON_USE_CPP_STD_MOVE 0 + #endif +#endif +#define __Pyx_void_to_None(void_result) ((void)(void_result), Py_INCREF(Py_None), Py_None) +#include +typedef uintptr_t __pyx_uintptr_t; +#ifndef CYTHON_FALLTHROUGH + #if defined(__cplusplus) + /* for clang __has_cpp_attribute(fallthrough) is true even before C++17 + * but leads to warnings with -pedantic, since it is a C++17 feature */ + #if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L) + #if __has_cpp_attribute(fallthrough) + #define CYTHON_FALLTHROUGH [[fallthrough]] + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_cpp_attribute(clang::fallthrough) + #define CYTHON_FALLTHROUGH [[clang::fallthrough]] + #elif __has_cpp_attribute(gnu::fallthrough) + #define CYTHON_FALLTHROUGH [[gnu::fallthrough]] + #endif + #endif + #endif + #ifndef CYTHON_FALLTHROUGH + #if __has_attribute(fallthrough) + #define CYTHON_FALLTHROUGH __attribute__((fallthrough)) + #else + #define CYTHON_FALLTHROUGH + #endif + #endif + #if defined(__clang__) && defined(__apple_build_version__) + #if __apple_build_version__ < 7000000 + #undef CYTHON_FALLTHROUGH + #define CYTHON_FALLTHROUGH + #endif + #endif +#endif +#ifndef Py_UNREACHABLE + #define Py_UNREACHABLE() assert(0); abort() +#endif +#ifdef __cplusplus + template + struct __PYX_IS_UNSIGNED_IMPL {static const bool value = T(0) < T(-1);}; + #define __PYX_IS_UNSIGNED(type) (__PYX_IS_UNSIGNED_IMPL::value) +#else + #define __PYX_IS_UNSIGNED(type) (((type)-1) > 0) +#endif +#if CYTHON_COMPILING_IN_PYPY == 1 + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x030A0000) +#else + #define __PYX_NEED_TP_PRINT_SLOT (PY_VERSION_HEX < 0x03090000) +#endif +#define __PYX_REINTERPRET_FUNCION(func_pointer, other_pointer) ((func_pointer)(void(*)(void))(other_pointer)) + +/* CInitCode */ +#ifndef CYTHON_INLINE + #if defined(__clang__) + #define CYTHON_INLINE __inline__ __attribute__ ((__unused__)) + #elif defined(__GNUC__) + #define CYTHON_INLINE __inline__ + #elif defined(_MSC_VER) + #define CYTHON_INLINE __inline + #elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define CYTHON_INLINE inline + #else + #define CYTHON_INLINE + #endif +#endif + +/* PythonCompatibility */ +#define __PYX_BUILD_PY_SSIZE_T "n" +#define CYTHON_FORMAT_SSIZE_T "z" +#define __Pyx_BUILTIN_MODULE_NAME "builtins" +#define __Pyx_DefaultClassType PyType_Type +#if CYTHON_COMPILING_IN_LIMITED_API + #ifndef CO_OPTIMIZED + static int CO_OPTIMIZED; + #endif + #ifndef CO_NEWLOCALS + static int CO_NEWLOCALS; + #endif + #ifndef CO_VARARGS + static int CO_VARARGS; + #endif + #ifndef CO_VARKEYWORDS + static int CO_VARKEYWORDS; + #endif + #ifndef CO_ASYNC_GENERATOR + static int CO_ASYNC_GENERATOR; + #endif + #ifndef CO_GENERATOR + static int CO_GENERATOR; + #endif + #ifndef CO_COROUTINE + static int CO_COROUTINE; + #endif +#else + #ifndef CO_COROUTINE + #define CO_COROUTINE 0x80 + #endif + #ifndef CO_ASYNC_GENERATOR + #define CO_ASYNC_GENERATOR 0x200 + #endif +#endif +static int __Pyx_init_co_variables(void); +#if PY_VERSION_HEX >= 0x030900A4 || defined(Py_IS_TYPE) + #define __Pyx_IS_TYPE(ob, type) Py_IS_TYPE(ob, type) +#else + #define __Pyx_IS_TYPE(ob, type) (((const PyObject*)ob)->ob_type == (type)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_Is) + #define __Pyx_Py_Is(x, y) Py_Is(x, y) +#else + #define __Pyx_Py_Is(x, y) ((x) == (y)) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsNone) + #define __Pyx_Py_IsNone(ob) Py_IsNone(ob) +#else + #define __Pyx_Py_IsNone(ob) __Pyx_Py_Is((ob), Py_None) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsTrue) + #define __Pyx_Py_IsTrue(ob) Py_IsTrue(ob) +#else + #define __Pyx_Py_IsTrue(ob) __Pyx_Py_Is((ob), Py_True) +#endif +#if PY_VERSION_HEX >= 0x030A00B1 || defined(Py_IsFalse) + #define __Pyx_Py_IsFalse(ob) Py_IsFalse(ob) +#else + #define __Pyx_Py_IsFalse(ob) __Pyx_Py_Is((ob), Py_False) +#endif +#define __Pyx_NoneAsNull(obj) (__Pyx_Py_IsNone(obj) ? NULL : (obj)) +#if PY_VERSION_HEX >= 0x030900F0 && !CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyObject_GC_IsFinalized(o) PyObject_GC_IsFinalized(o) +#else + #define __Pyx_PyObject_GC_IsFinalized(o) _PyGC_FINALIZED(o) +#endif +#ifndef Py_TPFLAGS_CHECKTYPES + #define Py_TPFLAGS_CHECKTYPES 0 +#endif +#ifndef Py_TPFLAGS_HAVE_INDEX + #define Py_TPFLAGS_HAVE_INDEX 0 +#endif +#ifndef Py_TPFLAGS_HAVE_NEWBUFFER + #define Py_TPFLAGS_HAVE_NEWBUFFER 0 +#endif +#ifndef Py_TPFLAGS_HAVE_FINALIZE + #define Py_TPFLAGS_HAVE_FINALIZE 0 +#endif +#ifndef Py_TPFLAGS_SEQUENCE + #define Py_TPFLAGS_SEQUENCE 0 +#endif +#ifndef Py_TPFLAGS_MAPPING + #define Py_TPFLAGS_MAPPING 0 +#endif +#ifndef Py_TPFLAGS_IMMUTABLETYPE + #define Py_TPFLAGS_IMMUTABLETYPE (1UL << 8) +#endif +#ifndef Py_TPFLAGS_DISALLOW_INSTANTIATION + #define Py_TPFLAGS_DISALLOW_INSTANTIATION (1UL << 7) +#endif +#ifndef METH_STACKLESS + #define METH_STACKLESS 0 +#endif +#ifndef METH_FASTCALL + #ifndef METH_FASTCALL + #define METH_FASTCALL 0x80 + #endif + typedef PyObject *(*__Pyx_PyCFunctionFast) (PyObject *self, PyObject *const *args, Py_ssize_t nargs); + typedef PyObject *(*__Pyx_PyCFunctionFastWithKeywords) (PyObject *self, PyObject *const *args, + Py_ssize_t nargs, PyObject *kwnames); +#else + #if PY_VERSION_HEX >= 0x030d00A4 + # define __Pyx_PyCFunctionFast PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords PyCFunctionFastWithKeywords + #else + # define __Pyx_PyCFunctionFast _PyCFunctionFast + # define __Pyx_PyCFunctionFastWithKeywords _PyCFunctionFastWithKeywords + #endif +#endif +#if CYTHON_METH_FASTCALL + #define __Pyx_METH_FASTCALL METH_FASTCALL + #define __Pyx_PyCFunction_FastCall __Pyx_PyCFunctionFast + #define __Pyx_PyCFunction_FastCallWithKeywords __Pyx_PyCFunctionFastWithKeywords +#else + #define __Pyx_METH_FASTCALL METH_VARARGS + #define __Pyx_PyCFunction_FastCall PyCFunction + #define __Pyx_PyCFunction_FastCallWithKeywords PyCFunctionWithKeywords +#endif +#if CYTHON_VECTORCALL + #define __pyx_vectorcallfunc vectorcallfunc + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET PY_VECTORCALL_ARGUMENTS_OFFSET + #define __Pyx_PyVectorcall_NARGS(n) PyVectorcall_NARGS((size_t)(n)) +#else + #define __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET 0 + #define __Pyx_PyVectorcall_NARGS(n) ((Py_ssize_t)(n)) +#endif +#if PY_VERSION_HEX >= 0x030900B1 +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_CheckExact(func) +#else +#define __Pyx_PyCFunction_CheckExact(func) PyCFunction_Check(func) +#endif +#define __Pyx_CyOrPyCFunction_Check(func) PyCFunction_Check(func) +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) (((PyCFunctionObject*)(func))->m_ml->ml_meth) +#elif !CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyOrPyCFunction_GET_FUNCTION(func) PyCFunction_GET_FUNCTION(func) +#endif +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_CyOrPyCFunction_GET_FLAGS(func) (((PyCFunctionObject*)(func))->m_ml->ml_flags) +static CYTHON_INLINE PyObject* __Pyx_CyOrPyCFunction_GET_SELF(PyObject *func) { + return (__Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_STATIC) ? NULL : ((PyCFunctionObject*)func)->m_self; +} +#endif +static CYTHON_INLINE int __Pyx__IsSameCFunction(PyObject *func, void (*cfunc)(void)) { +#if CYTHON_COMPILING_IN_LIMITED_API + return PyCFunction_Check(func) && PyCFunction_GetFunction(func) == (PyCFunction) cfunc; +#else + return PyCFunction_Check(func) && PyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +#endif +} +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCFunction(func, cfunc) +#if PY_VERSION_HEX < 0x03090000 || (CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000) + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) ((void)m, PyType_FromSpecWithBases(s, b)) + typedef PyObject *(*__Pyx_PyCMethod)(PyObject *, PyTypeObject *, PyObject *const *, size_t, PyObject *); +#else + #define __Pyx_PyType_FromModuleAndSpec(m, s, b) PyType_FromModuleAndSpec(m, s, b) + #define __Pyx_PyCMethod PyCMethod +#endif +#ifndef METH_METHOD + #define METH_METHOD 0x200 +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyObject_Malloc) + #define PyObject_Malloc(s) PyMem_Malloc(s) + #define PyObject_Free(p) PyMem_Free(p) + #define PyObject_Realloc(p) PyMem_Realloc(p) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) +#elif CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) GraalPyFrame_SetLineNumber((frame), (lineno)) +#elif CYTHON_COMPILING_IN_GRAAL + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) _PyFrame_SetLineNumber((frame), (lineno)) +#else + #define __Pyx_PyCode_HasFreeVars(co) (PyCode_GetNumFree(co) > 0) + #define __Pyx_PyFrame_SetLineNumber(frame, lineno) (frame)->f_lineno = (lineno) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyThreadState_Current PyThreadState_Get() +#elif !CYTHON_FAST_THREAD_STATE + #define __Pyx_PyThreadState_Current PyThreadState_GET() +#elif PY_VERSION_HEX >= 0x030d00A1 + #define __Pyx_PyThreadState_Current PyThreadState_GetUnchecked() +#else + #define __Pyx_PyThreadState_Current _PyThreadState_UncheckedGet() +#endif +#if CYTHON_USE_MODULE_STATE +static CYTHON_INLINE void *__Pyx__PyModule_GetState(PyObject *op) +{ + void *result; + result = PyModule_GetState(op); + if (!result) + Py_FatalError("Couldn't find the module state"); + return result; +} +#define __Pyx_PyModule_GetState(o) (__pyx_mstatetype *)__Pyx__PyModule_GetState(o) +#else +#define __Pyx_PyModule_GetState(op) ((void)op,__pyx_mstate_global) +#endif +#define __Pyx_PyObject_GetSlot(obj, name, func_ctype) __Pyx_PyType_GetSlot(Py_TYPE((PyObject *) obj), name, func_ctype) +#define __Pyx_PyObject_TryGetSlot(obj, name, func_ctype) __Pyx_PyType_TryGetSlot(Py_TYPE(obj), name, func_ctype) +#define __Pyx_PyObject_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#define __Pyx_PyObject_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSubSlot(Py_TYPE(obj), sub, name, func_ctype) +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((type)->name) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype) __Pyx_PyType_GetSlot(type, name, func_ctype) + #define __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) (((type)->sub) ? ((type)->sub->name) : NULL) + #define __Pyx_PyType_TryGetSubSlot(type, sub, name, func_ctype) __Pyx_PyType_GetSubSlot(type, sub, name, func_ctype) +#else + #define __Pyx_PyType_GetSlot(type, name, func_ctype) ((func_ctype) PyType_GetSlot((type), Py_##name)) + #define __Pyx_PyType_TryGetSlot(type, name, func_ctype)\ + ((__PYX_LIMITED_VERSION_HEX >= 0x030A0000 ||\ + (PyType_GetFlags(type) & Py_TPFLAGS_HEAPTYPE) || __Pyx_get_runtime_version() >= 0x030A0000) ?\ + __Pyx_PyType_GetSlot(type, name, func_ctype) : NULL) + #define __Pyx_PyType_GetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_GetSlot(obj, name, func_ctype) + #define __Pyx_PyType_TryGetSubSlot(obj, sub, name, func_ctype) __Pyx_PyType_TryGetSlot(obj, name, func_ctype) +#endif +#if CYTHON_COMPILING_IN_CPYTHON || defined(_PyDict_NewPresized) +#define __Pyx_PyDict_NewPresized(n) ((n <= 8) ? PyDict_New() : _PyDict_NewPresized(n)) +#else +#define __Pyx_PyDict_NewPresized(n) PyDict_New() +#endif +#define __Pyx_PyNumber_Divide(x,y) PyNumber_TrueDivide(x,y) +#define __Pyx_PyNumber_InPlaceDivide(x,y) PyNumber_InPlaceTrueDivide(x,y) +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_UNICODE_INTERNALS +#define __Pyx_PyDict_GetItemStrWithError(dict, name) _PyDict_GetItem_KnownHash(dict, name, ((PyASCIIObject *) name)->hash) +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStr(PyObject *dict, PyObject *name) { + PyObject *res = __Pyx_PyDict_GetItemStrWithError(dict, name); + if (res == NULL) PyErr_Clear(); + return res; +} +#elif !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000 +#define __Pyx_PyDict_GetItemStrWithError PyDict_GetItemWithError +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#else +static CYTHON_INLINE PyObject * __Pyx_PyDict_GetItemStrWithError(PyObject *dict, PyObject *name) { +#if CYTHON_COMPILING_IN_PYPY + return PyDict_GetItem(dict, name); +#else + PyDictEntry *ep; + PyDictObject *mp = (PyDictObject*) dict; + long hash = ((PyStringObject *) name)->ob_shash; + assert(hash != -1); + ep = (mp->ma_lookup)(mp, name, hash); + if (ep == NULL) { + return NULL; + } + return ep->me_value; +#endif +} +#define __Pyx_PyDict_GetItemStr PyDict_GetItem +#endif +#if CYTHON_USE_TYPE_SLOTS + #define __Pyx_PyType_GetFlags(tp) (((PyTypeObject *)tp)->tp_flags) + #define __Pyx_PyType_HasFeature(type, feature) ((__Pyx_PyType_GetFlags(type) & (feature)) != 0) +#else + #define __Pyx_PyType_GetFlags(tp) (PyType_GetFlags((PyTypeObject *)tp)) + #define __Pyx_PyType_HasFeature(type, feature) PyType_HasFeature(type, feature) +#endif +#define __Pyx_PyObject_GetIterNextFunc(iterator) __Pyx_PyObject_GetSlot(iterator, tp_iternext, iternextfunc) +#if CYTHON_USE_TYPE_SPECS +#define __Pyx_PyHeapTypeObject_GC_Del(obj) {\ + PyTypeObject *type = Py_TYPE((PyObject*)obj);\ + assert(__Pyx_PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE));\ + PyObject_GC_Del(obj);\ + Py_DECREF(type);\ +} +#else +#define __Pyx_PyHeapTypeObject_GC_Del(obj) PyObject_GC_Del(obj) +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_PyUnicode_READY(op) (0) + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_ReadChar(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) ((void)u, 1114111U) + #define __Pyx_PyUnicode_KIND(u) ((void)u, (0)) + #define __Pyx_PyUnicode_DATA(u) ((void*)u) + #define __Pyx_PyUnicode_READ(k, d, i) ((void)k, PyUnicode_ReadChar((PyObject*)(d), i)) + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GetLength(u)) +#else + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_READY(op) (0) + #else + #define __Pyx_PyUnicode_READY(op) (likely(PyUnicode_IS_READY(op)) ?\ + 0 : _PyUnicode_Ready((PyObject *)(op))) + #endif + #define __Pyx_PyUnicode_READ_CHAR(u, i) PyUnicode_READ_CHAR(u, i) + #define __Pyx_PyUnicode_MAX_CHAR_VALUE(u) PyUnicode_MAX_CHAR_VALUE(u) + #define __Pyx_PyUnicode_KIND(u) ((int)PyUnicode_KIND(u)) + #define __Pyx_PyUnicode_DATA(u) PyUnicode_DATA(u) + #define __Pyx_PyUnicode_READ(k, d, i) PyUnicode_READ(k, d, i) + #define __Pyx_PyUnicode_WRITE(k, d, i, ch) PyUnicode_WRITE(k, d, i, (Py_UCS4) ch) + #if PY_VERSION_HEX >= 0x030C0000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != PyUnicode_GET_LENGTH(u)) + #else + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x03090000 + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : ((PyCompactUnicodeObject *)(u))->wstr_length)) + #else + #define __Pyx_PyUnicode_IS_TRUE(u) (0 != (likely(PyUnicode_IS_READY(u)) ? PyUnicode_GET_LENGTH(u) : PyUnicode_GET_SIZE(u))) + #endif + #endif +#endif +#if CYTHON_COMPILING_IN_PYPY + #define __Pyx_PyUnicode_Concat(a, b) PyNumber_Add(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) PyNumber_Add(a, b) +#else + #define __Pyx_PyUnicode_Concat(a, b) PyUnicode_Concat(a, b) + #define __Pyx_PyUnicode_ConcatSafe(a, b) ((unlikely((a) == Py_None) || unlikely((b) == Py_None)) ?\ + PyNumber_Add(a, b) : __Pyx_PyUnicode_Concat(a, b)) +#endif +#if CYTHON_COMPILING_IN_PYPY + #if !defined(PyUnicode_DecodeUnicodeEscape) + #define PyUnicode_DecodeUnicodeEscape(s, size, errors) PyUnicode_Decode(s, size, "unicode_escape", errors) + #endif + #if !defined(PyUnicode_Contains) + #define PyUnicode_Contains(u, s) PySequence_Contains(u, s) + #endif + #if !defined(PyByteArray_Check) + #define PyByteArray_Check(obj) PyObject_TypeCheck(obj, &PyByteArray_Type) + #endif + #if !defined(PyObject_Format) + #define PyObject_Format(obj, fmt) PyObject_CallMethod(obj, "__format__", "O", fmt) + #endif +#endif +#define __Pyx_PyUnicode_FormatSafe(a, b) ((unlikely((a) == Py_None || (PyUnicode_Check(b) && !PyUnicode_CheckExact(b)))) ? PyNumber_Remainder(a, b) : PyUnicode_Format(a, b)) +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && PyUnstable_Object_IsUniquelyReferenced(obj)) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#elif CYTHON_COMPILING_IN_CPYTHON + #define __Pyx_PySequence_ListKeepNew(obj)\ + (likely(PyList_CheckExact(obj) && Py_REFCNT(obj) == 1) ? __Pyx_NewRef(obj) : PySequence_List(obj)) +#else + #define __Pyx_PySequence_ListKeepNew(obj) PySequence_List(obj) +#endif +#ifndef PySet_CheckExact + #define PySet_CheckExact(obj) __Pyx_IS_TYPE(obj, &PySet_Type) +#endif +#if PY_VERSION_HEX >= 0x030900A4 + #define __Pyx_SET_REFCNT(obj, refcnt) Py_SET_REFCNT(obj, refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SET_SIZE(obj, size) +#else + #define __Pyx_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt) + #define __Pyx_SET_SIZE(obj, size) Py_SIZE(obj) = (size) +#endif +enum __Pyx_ReferenceSharing { + __Pyx_ReferenceSharing_DefinitelyUnique, // We created it so we know it's unshared - no need to check + __Pyx_ReferenceSharing_OwnStrongReference, + __Pyx_ReferenceSharing_FunctionArgument, + __Pyx_ReferenceSharing_SharedReference, // Never trust it to be unshared because it's a global or similar +}; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && PY_VERSION_HEX >= 0x030E0000 +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing)\ + (sharing == __Pyx_ReferenceSharing_DefinitelyUnique ? 1 :\ + (sharing == __Pyx_ReferenceSharing_FunctionArgument ? PyUnstable_Object_IsUniqueReferencedTemporary(o) :\ + (sharing == __Pyx_ReferenceSharing_OwnStrongReference ? PyUnstable_Object_IsUniquelyReferenced(o) : 0))) +#elif (CYTHON_COMPILING_IN_CPYTHON && !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING) || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)sharing), Py_REFCNT(o) == 1) +#else +#define __Pyx_IS_UNIQUELY_REFERENCED(o, sharing) (((void)o), ((void)sharing), 0) +#endif +#if CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRef(o, i) (likely((i) >= 0) ? PySequence_GetItem(o, i) : (PyErr_SetString(PyExc_IndexError, "list index out of range"), (PyObject*)NULL)) + #else + #define __Pyx_PyList_GetItemRef(o, i) PySequence_ITEM(o, i) + #endif +#elif CYTHON_COMPILING_IN_LIMITED_API || !CYTHON_ASSUME_SAFE_MACROS + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyList_GetItemRef(o, i) PyList_GetItemRef(o, i) + #else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_XNewRef(PyList_GetItem(o, i)) + #endif +#else + #define __Pyx_PyList_GetItemRef(o, i) __Pyx_NewRef(PyList_GET_ITEM(o, i)) +#endif +#if CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS && !CYTHON_COMPILING_IN_LIMITED_API && CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) (__Pyx_IS_UNIQUELY_REFERENCED(o, unsafe_shared) ?\ + __Pyx_NewRef(PyList_GET_ITEM(o, i)) : __Pyx_PyList_GetItemRef(o, i)) +#else + #define __Pyx_PyList_GetItemRefFast(o, i, unsafe_shared) __Pyx_PyList_GetItemRef(o, i) +#endif +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyDict_GetItemRef(dict, key, result) PyDict_GetItemRef(dict, key, result) +#elif CYTHON_AVOID_BORROWED_REFS || CYTHON_AVOID_THREAD_UNSAFE_BORROWED_REFS +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyObject_GetItem(dict, key); + if (*result == NULL) { + if (PyErr_ExceptionMatches(PyExc_KeyError)) { + PyErr_Clear(); + return 0; + } + return -1; + } + return 1; +} +#else +static CYTHON_INLINE int __Pyx_PyDict_GetItemRef(PyObject *dict, PyObject *key, PyObject **result) { + *result = PyDict_GetItemWithError(dict, key); + if (*result == NULL) { + return PyErr_Occurred() ? -1 : 0; + } + Py_INCREF(*result); + return 1; +} +#endif +#if defined(CYTHON_DEBUG_VISIT_CONST) && CYTHON_DEBUG_VISIT_CONST + #define __Pyx_VISIT_CONST(obj) Py_VISIT(obj) +#else + #define __Pyx_VISIT_CONST(obj) +#endif +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PySequence_ITEM(o, i) PySequence_ITEM(o, i) + #define __Pyx_PySequence_SIZE(seq) Py_SIZE(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) (PyTuple_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GET_ITEM(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) (PyList_SET_ITEM(o, i, v), (0)) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GET_ITEM(o, i) +#else + #define __Pyx_PySequence_ITEM(o, i) PySequence_GetItem(o, i) + #define __Pyx_PySequence_SIZE(seq) PySequence_Size(seq) + #define __Pyx_PyTuple_SET_ITEM(o, i, v) PyTuple_SetItem(o, i, v) + #define __Pyx_PyTuple_GET_ITEM(o, i) PyTuple_GetItem(o, i) + #define __Pyx_PyList_SET_ITEM(o, i, v) PyList_SetItem(o, i, v) + #define __Pyx_PyList_GET_ITEM(o, i) PyList_GetItem(o, i) +#endif +#if CYTHON_ASSUME_SAFE_SIZE + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_GET_SIZE(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_GET_SIZE(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_GET_SIZE(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_GET_SIZE(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_GET_SIZE(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GET_LENGTH(o) +#else + #define __Pyx_PyTuple_GET_SIZE(o) PyTuple_Size(o) + #define __Pyx_PyList_GET_SIZE(o) PyList_Size(o) + #define __Pyx_PySet_GET_SIZE(o) PySet_Size(o) + #define __Pyx_PyBytes_GET_SIZE(o) PyBytes_Size(o) + #define __Pyx_PyByteArray_GET_SIZE(o) PyByteArray_Size(o) + #define __Pyx_PyUnicode_GET_LENGTH(o) PyUnicode_GetLength(o) +#endif +#if CYTHON_COMPILING_IN_PYPY && !defined(PyUnicode_InternFromString) + #define PyUnicode_InternFromString(s) PyUnicode_FromString(s) +#endif +#define __Pyx_PyLong_FromHash_t PyLong_FromSsize_t +#define __Pyx_PyLong_AsHash_t __Pyx_PyIndex_AsSsize_t +#if __PYX_LIMITED_VERSION_HEX >= 0x030A0000 + #define __Pyx_PySendResult PySendResult +#else + typedef enum { + PYGEN_RETURN = 0, + PYGEN_ERROR = -1, + PYGEN_NEXT = 1, + } __Pyx_PySendResult; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX < 0x030A00A3 + typedef __Pyx_PySendResult (*__Pyx_pyiter_sendfunc)(PyObject *iter, PyObject *value, PyObject **result); +#else + #define __Pyx_pyiter_sendfunc sendfunc +#endif +#if !CYTHON_USE_AM_SEND +#define __PYX_HAS_PY_AM_SEND 0 +#elif __PYX_LIMITED_VERSION_HEX >= 0x030A0000 +#define __PYX_HAS_PY_AM_SEND 1 +#else +#define __PYX_HAS_PY_AM_SEND 2 // our own backported implementation +#endif +#if __PYX_HAS_PY_AM_SEND < 2 + #define __Pyx_PyAsyncMethodsStruct PyAsyncMethods +#else + typedef struct { + unaryfunc am_await; + unaryfunc am_aiter; + unaryfunc am_anext; + __Pyx_pyiter_sendfunc am_send; + } __Pyx_PyAsyncMethodsStruct; + #define __Pyx_SlotTpAsAsync(s) ((PyAsyncMethods*)(s)) +#endif +#if CYTHON_USE_AM_SEND && PY_VERSION_HEX < 0x030A00F0 + #define __Pyx_TPFLAGS_HAVE_AM_SEND (1UL << 21) +#else + #define __Pyx_TPFLAGS_HAVE_AM_SEND (0) +#endif +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_PyInterpreterState_Get() PyInterpreterState_Get() +#else +#define __Pyx_PyInterpreterState_Get() PyThreadState_Get()->interp +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030A0000 +#ifdef __cplusplus +extern "C" +#endif +PyAPI_FUNC(void *) PyMem_Calloc(size_t nelem, size_t elsize); +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static int __Pyx_init_co_variable(PyObject *inspect, const char* name, int *write_to) { + int value; + PyObject *py_value = PyObject_GetAttrString(inspect, name); + if (!py_value) return 0; + value = (int) PyLong_AsLong(py_value); + Py_DECREF(py_value); + *write_to = value; + return value != -1 || !PyErr_Occurred(); +} +static int __Pyx_init_co_variables(void) { + PyObject *inspect; + int result; + inspect = PyImport_ImportModule("inspect"); + result = +#if !defined(CO_OPTIMIZED) + __Pyx_init_co_variable(inspect, "CO_OPTIMIZED", &CO_OPTIMIZED) && +#endif +#if !defined(CO_NEWLOCALS) + __Pyx_init_co_variable(inspect, "CO_NEWLOCALS", &CO_NEWLOCALS) && +#endif +#if !defined(CO_VARARGS) + __Pyx_init_co_variable(inspect, "CO_VARARGS", &CO_VARARGS) && +#endif +#if !defined(CO_VARKEYWORDS) + __Pyx_init_co_variable(inspect, "CO_VARKEYWORDS", &CO_VARKEYWORDS) && +#endif +#if !defined(CO_ASYNC_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_ASYNC_GENERATOR", &CO_ASYNC_GENERATOR) && +#endif +#if !defined(CO_GENERATOR) + __Pyx_init_co_variable(inspect, "CO_GENERATOR", &CO_GENERATOR) && +#endif +#if !defined(CO_COROUTINE) + __Pyx_init_co_variable(inspect, "CO_COROUTINE", &CO_COROUTINE) && +#endif + 1; + Py_DECREF(inspect); + return result ? 0 : -1; +} +#else +static int __Pyx_init_co_variables(void) { + return 0; // It's a limited API-only feature +} +#endif + +/* MathInitCode */ +#if defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS) + #ifndef _USE_MATH_DEFINES + #define _USE_MATH_DEFINES + #endif +#endif +#include +#if defined(__CYGWIN__) && defined(_LDBL_EQ_DBL) +#define __Pyx_truncl trunc +#else +#define __Pyx_truncl truncl +#endif + +#ifndef CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#define CYTHON_CLINE_IN_TRACEBACK_RUNTIME 0 +#endif +#ifndef CYTHON_CLINE_IN_TRACEBACK +#define CYTHON_CLINE_IN_TRACEBACK CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#endif +#if CYTHON_CLINE_IN_TRACEBACK +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; __pyx_clineno = __LINE__; (void) __pyx_clineno; } +#else +#define __PYX_MARK_ERR_POS(f_index, lineno) { __pyx_filename = __pyx_f[f_index]; (void) __pyx_filename; __pyx_lineno = lineno; (void) __pyx_lineno; (void) __pyx_clineno; } +#endif +#define __PYX_ERR(f_index, lineno, Ln_error) \ + { __PYX_MARK_ERR_POS(f_index, lineno) goto Ln_error; } + +#ifdef CYTHON_EXTERN_C + #undef __PYX_EXTERN_C + #define __PYX_EXTERN_C CYTHON_EXTERN_C +#elif defined(__PYX_EXTERN_C) + #ifdef _MSC_VER + #pragma message ("Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead.") + #else + #warning Please do not define the '__PYX_EXTERN_C' macro externally. Use 'CYTHON_EXTERN_C' instead. + #endif +#else + #ifdef __cplusplus + #define __PYX_EXTERN_C extern "C" + #else + #define __PYX_EXTERN_C extern + #endif +#endif + +#define __PYX_HAVE__app__core__tenancy +#define __PYX_HAVE_API__app__core__tenancy +/* Early includes */ +#ifdef _OPENMP +#include +#endif /* _OPENMP */ + +#if defined(PYREX_WITHOUT_ASSERTIONS) && !defined(CYTHON_WITHOUT_ASSERTIONS) +#define CYTHON_WITHOUT_ASSERTIONS +#endif + +#ifdef CYTHON_FREETHREADING_COMPATIBLE +#if CYTHON_FREETHREADING_COMPATIBLE +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_NOT_USED +#else +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_USED +#endif +#else +#define __Pyx_FREETHREADING_COMPATIBLE Py_MOD_GIL_USED +#endif +#define __PYX_DEFAULT_STRING_ENCODING_IS_ASCII 0 +#define __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 0 +#define __PYX_DEFAULT_STRING_ENCODING "" +#define __Pyx_PyObject_FromString __Pyx_PyBytes_FromString +#define __Pyx_PyObject_FromStringAndSize __Pyx_PyBytes_FromStringAndSize +#define __Pyx_uchar_cast(c) ((unsigned char)c) +#define __Pyx_long_cast(x) ((long)x) +#define __Pyx_fits_Py_ssize_t(v, type, is_signed) (\ + (sizeof(type) < sizeof(Py_ssize_t)) ||\ + (sizeof(type) > sizeof(Py_ssize_t) &&\ + likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX) &&\ + (!is_signed || likely(v > (type)PY_SSIZE_T_MIN ||\ + v == (type)PY_SSIZE_T_MIN))) ||\ + (sizeof(type) == sizeof(Py_ssize_t) &&\ + (is_signed || likely(v < (type)PY_SSIZE_T_MAX ||\ + v == (type)PY_SSIZE_T_MAX))) ) +static CYTHON_INLINE int __Pyx_is_valid_index(Py_ssize_t i, Py_ssize_t limit) { + return (size_t) i < (size_t) limit; +} +#if defined (__cplusplus) && __cplusplus >= 201103L + #include + #define __Pyx_sst_abs(value) std::abs(value) +#elif SIZEOF_INT >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) abs(value) +#elif SIZEOF_LONG >= SIZEOF_SIZE_T + #define __Pyx_sst_abs(value) labs(value) +#elif defined (_MSC_VER) + #define __Pyx_sst_abs(value) ((Py_ssize_t)_abs64(value)) +#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L + #define __Pyx_sst_abs(value) llabs(value) +#elif defined (__GNUC__) + #define __Pyx_sst_abs(value) __builtin_llabs(value) +#else + #define __Pyx_sst_abs(value) ((value<0) ? -value : value) +#endif +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s); +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject*); +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject*, Py_ssize_t* length); +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char*); +#define __Pyx_PyByteArray_FromStringAndSize(s, l) PyByteArray_FromStringAndSize((const char*)s, l) +#define __Pyx_PyBytes_FromString PyBytes_FromString +#define __Pyx_PyBytes_FromStringAndSize PyBytes_FromStringAndSize +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char*); +#if CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AS_STRING(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AS_STRING(s) +#else + #define __Pyx_PyBytes_AsWritableString(s) ((char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableSString(s) ((signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsWritableUString(s) ((unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsString(s) ((const char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsSString(s) ((const signed char*) PyBytes_AsString(s)) + #define __Pyx_PyBytes_AsUString(s) ((const unsigned char*) PyBytes_AsString(s)) + #define __Pyx_PyByteArray_AsString(s) PyByteArray_AsString(s) +#endif +#define __Pyx_PyObject_AsWritableString(s) ((char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableSString(s) ((signed char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsWritableUString(s) ((unsigned char*)(__pyx_uintptr_t) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsSString(s) ((const signed char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_AsUString(s) ((const unsigned char*) __Pyx_PyObject_AsString(s)) +#define __Pyx_PyObject_FromCString(s) __Pyx_PyObject_FromString((const char*)s) +#define __Pyx_PyBytes_FromCString(s) __Pyx_PyBytes_FromString((const char*)s) +#define __Pyx_PyByteArray_FromCString(s) __Pyx_PyByteArray_FromString((const char*)s) +#define __Pyx_PyUnicode_FromCString(s) __Pyx_PyUnicode_FromString((const char*)s) +#define __Pyx_PyUnicode_FromOrdinal(o) PyUnicode_FromOrdinal((int)o) +#define __Pyx_PyUnicode_AsUnicode PyUnicode_AsUnicode +static CYTHON_INLINE PyObject *__Pyx_NewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_NewRef) + return Py_NewRef(obj); +#else + Py_INCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_XNewRef(PyObject *obj) { +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030a0000 || defined(Py_XNewRef) + return Py_XNewRef(obj); +#else + Py_XINCREF(obj); + return obj; +#endif +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b); +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b); +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject*); +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x); +#define __Pyx_PySequence_Tuple(obj)\ + (likely(PyTuple_CheckExact(obj)) ? __Pyx_NewRef(obj) : PySequence_Tuple(obj)) +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t); +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*); +#if CYTHON_ASSUME_SAFE_MACROS +#define __Pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AS_DOUBLE(x) +#else +#define __Pyx_PyFloat_AsDouble(x) PyFloat_AsDouble(x) +#define __Pyx_PyFloat_AS_DOUBLE(x) PyFloat_AsDouble(x) +#endif +#define __Pyx_PyFloat_AsFloat(x) ((float) __Pyx_PyFloat_AsDouble(x)) +#define __Pyx_PyNumber_Int(x) (PyLong_CheckExact(x) ? __Pyx_NewRef(x) : PyNumber_Long(x)) +#if CYTHON_USE_PYLONG_INTERNALS + #if PY_VERSION_HEX >= 0x030C00A7 + #ifndef _PyLong_SIGN_MASK + #define _PyLong_SIGN_MASK 3 + #endif + #ifndef _PyLong_NON_SIZE_BITS + #define _PyLong_NON_SIZE_BITS 3 + #endif + #define __Pyx_PyLong_Sign(x) (((PyLongObject*)x)->long_value.lv_tag & _PyLong_SIGN_MASK) + #define __Pyx_PyLong_IsNeg(x) ((__Pyx_PyLong_Sign(x) & 2) != 0) + #define __Pyx_PyLong_IsNonNeg(x) (!__Pyx_PyLong_IsNeg(x)) + #define __Pyx_PyLong_IsZero(x) (__Pyx_PyLong_Sign(x) & 1) + #define __Pyx_PyLong_IsPos(x) (__Pyx_PyLong_Sign(x) == 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) (__Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) ((Py_ssize_t) (((PyLongObject*)x)->long_value.lv_tag >> _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_SignedDigitCount(x)\ + ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * __Pyx_PyLong_DigitCount(x)) + #if defined(PyUnstable_Long_IsCompact) && defined(PyUnstable_Long_CompactValue) + #define __Pyx_PyLong_IsCompact(x) PyUnstable_Long_IsCompact((PyLongObject*) x) + #define __Pyx_PyLong_CompactValue(x) PyUnstable_Long_CompactValue((PyLongObject*) x) + #else + #define __Pyx_PyLong_IsCompact(x) (((PyLongObject*)x)->long_value.lv_tag < (2 << _PyLong_NON_SIZE_BITS)) + #define __Pyx_PyLong_CompactValue(x) ((1 - (Py_ssize_t) __Pyx_PyLong_Sign(x)) * (Py_ssize_t) __Pyx_PyLong_Digits(x)[0]) + #endif + typedef Py_ssize_t __Pyx_compact_pylong; + typedef size_t __Pyx_compact_upylong; + #else + #define __Pyx_PyLong_IsNeg(x) (Py_SIZE(x) < 0) + #define __Pyx_PyLong_IsNonNeg(x) (Py_SIZE(x) >= 0) + #define __Pyx_PyLong_IsZero(x) (Py_SIZE(x) == 0) + #define __Pyx_PyLong_IsPos(x) (Py_SIZE(x) > 0) + #define __Pyx_PyLong_CompactValueUnsigned(x) ((Py_SIZE(x) == 0) ? 0 : __Pyx_PyLong_Digits(x)[0]) + #define __Pyx_PyLong_DigitCount(x) __Pyx_sst_abs(Py_SIZE(x)) + #define __Pyx_PyLong_SignedDigitCount(x) Py_SIZE(x) + #define __Pyx_PyLong_IsCompact(x) (Py_SIZE(x) == 0 || Py_SIZE(x) == 1 || Py_SIZE(x) == -1) + #define __Pyx_PyLong_CompactValue(x)\ + ((Py_SIZE(x) == 0) ? (sdigit) 0 : ((Py_SIZE(x) < 0) ? -(sdigit)__Pyx_PyLong_Digits(x)[0] : (sdigit)__Pyx_PyLong_Digits(x)[0])) + typedef sdigit __Pyx_compact_pylong; + typedef digit __Pyx_compact_upylong; + #endif + #if PY_VERSION_HEX >= 0x030C00A5 + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->long_value.ob_digit) + #else + #define __Pyx_PyLong_Digits(x) (((PyLongObject*)x)->ob_digit) + #endif +#endif +#if __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeUTF8(c_str, size, NULL) +#elif __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_DecodeASCII(c_str, size, NULL) +#else + #define __Pyx_PyUnicode_FromStringAndSize(c_str, size) PyUnicode_Decode(c_str, size, __PYX_DEFAULT_STRING_ENCODING, NULL) +#endif + + +/* Test for GCC > 2.95 */ +#if defined(__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && (__GNUC_MINOR__ > 95))) + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else /* !__GNUC__ or GCC < 2.95 */ + #define likely(x) (x) + #define unlikely(x) (x) +#endif /* __GNUC__ */ +/* PretendToInitialize */ +#ifdef __cplusplus +#if __cplusplus > 201103L +#include +#endif +template +static void __Pyx_pretend_to_initialize(T* ptr) { +#if __cplusplus > 201103L + if ((std::is_trivially_default_constructible::value)) +#endif + *ptr = T(); + (void)ptr; +} +#else +static CYTHON_INLINE void __Pyx_pretend_to_initialize(void* ptr) { (void)ptr; } +#endif + + +#if !CYTHON_USE_MODULE_STATE +static PyObject *__pyx_m = NULL; +#endif +static int __pyx_lineno; +static int __pyx_clineno = 0; +static const char * const __pyx_cfilenm = __FILE__; +static const char *__pyx_filename; + +/* #### Code section: filename_table ### */ + +static const char* const __pyx_f[] = { + "app/core/tenancy.py", +}; +/* #### Code section: utility_code_proto_before_types ### */ +/* Atomics.proto (used by UnpackUnboundCMethod) */ +#include +#ifndef CYTHON_ATOMICS + #define CYTHON_ATOMICS 1 +#endif +#define __PYX_CYTHON_ATOMICS_ENABLED() CYTHON_ATOMICS +#define __PYX_GET_CYTHON_COMPILING_IN_CPYTHON_FREETHREADING() CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __pyx_atomic_int_type int +#define __pyx_nonatomic_int_type int +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__)) + #include +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ + (defined(_MSC_VER) && _MSC_VER >= 1700))) + #include +#endif +#if CYTHON_ATOMICS && (defined(__STDC_VERSION__) &&\ + (__STDC_VERSION__ >= 201112L) &&\ + !defined(__STDC_NO_ATOMICS__) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type atomic_int + #define __pyx_atomic_ptr_type atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) atomic_fetch_add_explicit(value, 1, memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) atomic_fetch_add_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) atomic_fetch_sub_explicit(value, 1, memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) atomic_load(value) + #define __pyx_atomic_store(value, new_value) atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) atomic_load_explicit(value, memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) atomic_load_explicit(value, memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C atomics" + #endif +#elif CYTHON_ATOMICS && (defined(__cplusplus) && (\ + (__cplusplus >= 201103L) ||\ +\ + (defined(_MSC_VER) && _MSC_VER >= 1700)) &&\ + ATOMIC_INT_LOCK_FREE == 2) + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type std::atomic_int + #define __pyx_atomic_ptr_type std::atomic_uintptr_t + #define __pyx_nonatomic_ptr_type uintptr_t + #define __pyx_atomic_incr_relaxed(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_relaxed) + #define __pyx_atomic_incr_acq_rel(value) std::atomic_fetch_add_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_decr_acq_rel(value) std::atomic_fetch_sub_explicit(value, 1, std::memory_order_acq_rel) + #define __pyx_atomic_sub(value, arg) std::atomic_fetch_sub(value, arg) + #define __pyx_atomic_int_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #define __pyx_atomic_load(value) std::atomic_load(value) + #define __pyx_atomic_store(value, new_value) std::atomic_store(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) std::atomic_load_explicit(value, std::memory_order_relaxed) + #define __pyx_atomic_pointer_load_acquire(value) std::atomic_load_explicit(value, std::memory_order_acquire) + #define __pyx_atomic_pointer_exchange(value, new_value) std::atomic_exchange(value, (__pyx_nonatomic_ptr_type)new_value) + #define __pyx_atomic_pointer_cmp_exchange(value, expected, desired) std::atomic_compare_exchange_strong(value, expected, desired) + #if defined(__PYX_DEBUG_ATOMICS) && defined(_MSC_VER) + #pragma message ("Using standard C++ atomics") + #elif defined(__PYX_DEBUG_ATOMICS) + #warning "Using standard C++ atomics" + #endif +#elif CYTHON_ATOMICS && (__GNUC__ >= 5 || (__GNUC__ == 4 &&\ + (__GNUC_MINOR__ > 1 ||\ + (__GNUC_MINOR__ == 1 && __GNUC_PATCHLEVEL__ >= 2)))) + #define __pyx_atomic_ptr_type void* + #define __pyx_nonatomic_ptr_type void* + #define __pyx_atomic_incr_relaxed(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_incr_acq_rel(value) __sync_fetch_and_add(value, 1) + #define __pyx_atomic_decr_acq_rel(value) __sync_fetch_and_sub(value, 1) + #define __pyx_atomic_sub(value, arg) __sync_fetch_and_sub(value, arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_store(value, new_value) __sync_lock_test_and_set(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_load_acquire(value) __sync_fetch_and_add(value, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) __sync_lock_test_and_set(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_nonatomic_ptr_type old = __sync_val_compare_and_swap(value, *expected, desired); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #warning "Using GNU atomics" + #endif +#elif CYTHON_ATOMICS && defined(_MSC_VER) + #include + #undef __pyx_atomic_int_type + #define __pyx_atomic_int_type long + #define __pyx_atomic_ptr_type void* + #undef __pyx_nonatomic_int_type + #define __pyx_nonatomic_int_type long + #define __pyx_nonatomic_ptr_type void* + #pragma intrinsic (_InterlockedExchangeAdd, _InterlockedExchange, _InterlockedCompareExchange, _InterlockedCompareExchangePointer, _InterlockedExchangePointer) + #define __pyx_atomic_incr_relaxed(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_incr_acq_rel(value) _InterlockedExchangeAdd(value, 1) + #define __pyx_atomic_decr_acq_rel(value) _InterlockedExchangeAdd(value, -1) + #define __pyx_atomic_sub(value, arg) _InterlockedExchangeAdd(value, -arg) + static CYTHON_INLINE int __pyx_atomic_int_cmp_exchange(__pyx_atomic_int_type* value, __pyx_nonatomic_int_type* expected, __pyx_nonatomic_int_type desired) { + __pyx_nonatomic_int_type old = _InterlockedCompareExchange(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #define __pyx_atomic_load(value) _InterlockedExchangeAdd(value, 0) + #define __pyx_atomic_store(value, new_value) _InterlockedExchange(value, new_value) + #define __pyx_atomic_pointer_load_relaxed(value) *(void * volatile *)value + #define __pyx_atomic_pointer_load_acquire(value) _InterlockedCompareExchangePointer(value, 0, 0) + #define __pyx_atomic_pointer_exchange(value, new_value) _InterlockedExchangePointer(value, (__pyx_atomic_ptr_type)new_value) + static CYTHON_INLINE int __pyx_atomic_pointer_cmp_exchange(__pyx_atomic_ptr_type* value, __pyx_nonatomic_ptr_type* expected, __pyx_nonatomic_ptr_type desired) { + __pyx_atomic_ptr_type old = _InterlockedCompareExchangePointer(value, desired, *expected); + int result = old == *expected; + *expected = old; + return result; + } + #ifdef __PYX_DEBUG_ATOMICS + #pragma message ("Using MSVC atomics") + #endif +#else + #undef CYTHON_ATOMICS + #define CYTHON_ATOMICS 0 + #ifdef __PYX_DEBUG_ATOMICS + #warning "Not using atomics" + #endif +#endif + +/* CriticalSectionsDefinition.proto (used by CriticalSections) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection void* +#define __Pyx_PyCriticalSection2 void* +#define __Pyx_PyCriticalSection_End(cs) +#define __Pyx_PyCriticalSection2_End(cs) +#else +#define __Pyx_PyCriticalSection PyCriticalSection +#define __Pyx_PyCriticalSection2 PyCriticalSection2 +#define __Pyx_PyCriticalSection_End PyCriticalSection_End +#define __Pyx_PyCriticalSection2_End PyCriticalSection2_End +#endif + +/* CriticalSections.proto (used by ParseKeywordsImpl) */ +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyCriticalSection_Begin(cs, arg) (void)(cs) +#define __Pyx_PyCriticalSection2_Begin(cs, arg1, arg2) (void)(cs) +#else +#define __Pyx_PyCriticalSection_Begin PyCriticalSection_Begin +#define __Pyx_PyCriticalSection2_Begin PyCriticalSection2_Begin +#endif +#if PY_VERSION_HEX < 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_BEGIN_CRITICAL_SECTION(o) { +#define __Pyx_END_CRITICAL_SECTION() } +#else +#define __Pyx_BEGIN_CRITICAL_SECTION Py_BEGIN_CRITICAL_SECTION +#define __Pyx_END_CRITICAL_SECTION Py_END_CRITICAL_SECTION +#endif + +/* IncludeStructmemberH.proto (used by FixUpExtensionType) */ +#include + +/* #### Code section: numeric_typedefs ### */ +/* #### Code section: complex_type_declarations ### */ +/* #### Code section: type_declarations ### */ + +/*--- Type declarations ---*/ +/* #### Code section: utility_code_proto ### */ + +/* --- Runtime support code (head) --- */ +/* Refnanny.proto */ +#ifndef CYTHON_REFNANNY + #define CYTHON_REFNANNY 0 +#endif +#if CYTHON_REFNANNY + typedef struct { + void (*INCREF)(void*, PyObject*, Py_ssize_t); + void (*DECREF)(void*, PyObject*, Py_ssize_t); + void (*GOTREF)(void*, PyObject*, Py_ssize_t); + void (*GIVEREF)(void*, PyObject*, Py_ssize_t); + void* (*SetupContext)(const char*, Py_ssize_t, const char*); + void (*FinishContext)(void**); + } __Pyx_RefNannyAPIStruct; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNanny = NULL; + static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname); + #define __Pyx_RefNannyDeclarations void *__pyx_refnanny = NULL; + #define __Pyx_RefNannySetupContext(name, acquire_gil)\ + if (acquire_gil) {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + PyGILState_Release(__pyx_gilstate_save);\ + } else {\ + __pyx_refnanny = __Pyx_RefNanny->SetupContext((name), (__LINE__), (__FILE__));\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContextNogil() {\ + PyGILState_STATE __pyx_gilstate_save = PyGILState_Ensure();\ + __Pyx_RefNannyFinishContext();\ + PyGILState_Release(__pyx_gilstate_save);\ + } + #define __Pyx_RefNannyFinishContext()\ + __Pyx_RefNanny->FinishContext(&__pyx_refnanny) + #define __Pyx_INCREF(r) __Pyx_RefNanny->INCREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_DECREF(r) __Pyx_RefNanny->DECREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GOTREF(r) __Pyx_RefNanny->GOTREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_GIVEREF(r) __Pyx_RefNanny->GIVEREF(__pyx_refnanny, (PyObject *)(r), (__LINE__)) + #define __Pyx_XINCREF(r) do { if((r) == NULL); else {__Pyx_INCREF(r); }} while(0) + #define __Pyx_XDECREF(r) do { if((r) == NULL); else {__Pyx_DECREF(r); }} while(0) + #define __Pyx_XGOTREF(r) do { if((r) == NULL); else {__Pyx_GOTREF(r); }} while(0) + #define __Pyx_XGIVEREF(r) do { if((r) == NULL); else {__Pyx_GIVEREF(r);}} while(0) +#else + #define __Pyx_RefNannyDeclarations + #define __Pyx_RefNannySetupContext(name, acquire_gil) + #define __Pyx_RefNannyFinishContextNogil() + #define __Pyx_RefNannyFinishContext() + #define __Pyx_INCREF(r) Py_INCREF(r) + #define __Pyx_DECREF(r) Py_DECREF(r) + #define __Pyx_GOTREF(r) + #define __Pyx_GIVEREF(r) + #define __Pyx_XINCREF(r) Py_XINCREF(r) + #define __Pyx_XDECREF(r) Py_XDECREF(r) + #define __Pyx_XGOTREF(r) + #define __Pyx_XGIVEREF(r) +#endif +#define __Pyx_Py_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; Py_XDECREF(tmp);\ + } while (0) +#define __Pyx_XDECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_XDECREF(tmp);\ + } while (0) +#define __Pyx_DECREF_SET(r, v) do {\ + PyObject *tmp = (PyObject *) r;\ + r = v; __Pyx_DECREF(tmp);\ + } while (0) +#define __Pyx_CLEAR(r) do { PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);} while(0) +#define __Pyx_XCLEAR(r) do { if((r) != NULL) {PyObject* tmp = ((PyObject*)(r)); r = NULL; __Pyx_DECREF(tmp);}} while(0) + +/* TupleAndListFromArray.proto (used by fastcall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n); +#endif +#if CYTHON_COMPILING_IN_CPYTHON || CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject* __Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n); +#endif + +/* IncludeStringH.proto (used by BytesEquals) */ +#include + +/* BytesEquals.proto (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); + +/* UnicodeEquals.proto (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); + +/* fastcall.proto */ +#if CYTHON_AVOID_BORROWED_REFS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_PySequence_ITEM(args, i) +#elif CYTHON_ASSUME_SAFE_MACROS + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_NewRef(__Pyx_PyTuple_GET_ITEM(args, i)) +#else + #define __Pyx_ArgRef_VARARGS(args, i) __Pyx_XNewRef(PyTuple_GetItem(args, i)) +#endif +#define __Pyx_NumKwargs_VARARGS(kwds) PyDict_Size(kwds) +#define __Pyx_KwValues_VARARGS(args, nargs) NULL +#define __Pyx_GetKwValue_VARARGS(kw, kwvalues, s) __Pyx_PyDict_GetItemStrWithError(kw, s) +#define __Pyx_KwargsAsDict_VARARGS(kw, kwvalues) PyDict_Copy(kw) +#if CYTHON_METH_FASTCALL + #define __Pyx_ArgRef_FASTCALL(args, i) __Pyx_NewRef(args[i]) + #define __Pyx_NumKwargs_FASTCALL(kwds) __Pyx_PyTuple_GET_SIZE(kwds) + #define __Pyx_KwValues_FASTCALL(args, nargs) ((args) + (nargs)) + static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API + CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues); + #else + #define __Pyx_KwargsAsDict_FASTCALL(kw, kwvalues) _PyStack_AsDict(kwvalues, kw) + #endif +#else + #define __Pyx_ArgRef_FASTCALL __Pyx_ArgRef_VARARGS + #define __Pyx_NumKwargs_FASTCALL __Pyx_NumKwargs_VARARGS + #define __Pyx_KwValues_FASTCALL __Pyx_KwValues_VARARGS + #define __Pyx_GetKwValue_FASTCALL __Pyx_GetKwValue_VARARGS + #define __Pyx_KwargsAsDict_FASTCALL __Pyx_KwargsAsDict_VARARGS +#endif +#define __Pyx_ArgsSlice_VARARGS(args, start, stop) PyTuple_GetSlice(args, start, stop) +#if CYTHON_METH_FASTCALL || (CYTHON_COMPILING_IN_CPYTHON && CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) __Pyx_PyTuple_FromArray(args + start, stop - start) +#else +#define __Pyx_ArgsSlice_FASTCALL(args, start, stop) PyTuple_GetSlice(args, start, stop) +#endif + +/* py_dict_items.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d); + +/* CallCFunction.proto (used by CallUnboundCMethod0) */ +#define __Pyx_CallCFunction(cfunc, self, args)\ + ((PyCFunction)(void(*)(void))(cfunc)->func)(self, args) +#define __Pyx_CallCFunctionWithKeywords(cfunc, self, args, kwargs)\ + ((PyCFunctionWithKeywords)(void(*)(void))(cfunc)->func)(self, args, kwargs) +#define __Pyx_CallCFunctionFast(cfunc, self, args, nargs)\ + ((__Pyx_PyCFunctionFast)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs) +#define __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, nargs, kwnames)\ + ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))(PyCFunction)(cfunc)->func)(self, args, nargs, kwnames) + +/* PyObjectCall.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call(PyObject *func, PyObject *arg, PyObject *kw); +#else +#define __Pyx_PyObject_Call(func, arg, kw) PyObject_Call(func, arg, kw) +#endif + +/* PyObjectCallMethO.proto (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg); +#endif + +/* PyObjectFastCall.proto (used by PyObjectCallOneArg) */ +#define __Pyx_PyObject_FastCall(func, args, nargs) __Pyx_PyObject_FastCallDict(func, args, (size_t)(nargs), NULL) +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs); + +/* PyObjectCallOneArg.proto (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg); + +/* PyObjectGetAttrStr.proto (used by UnpackUnboundCMethod) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name); +#else +#define __Pyx_PyObject_GetAttrStr(o,n) PyObject_GetAttr(o,n) +#endif + +/* UnpackUnboundCMethod.proto (used by CallUnboundCMethod0) */ +typedef struct { + PyObject *type; + PyObject **method_name; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && CYTHON_ATOMICS + __pyx_atomic_int_type initialized; +#endif + PyCFunction func; + PyObject *method; + int flag; +} __Pyx_CachedCFunction; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +static CYTHON_INLINE int __Pyx_CachedCFunction_GetAndSetInitializing(__Pyx_CachedCFunction *cfunc) { +#if !CYTHON_ATOMICS + return 1; +#else + __pyx_nonatomic_int_type expected = 0; + if (__pyx_atomic_int_cmp_exchange(&cfunc->initialized, &expected, 1)) { + return 0; + } + return expected; +#endif +} +static CYTHON_INLINE void __Pyx_CachedCFunction_SetFinishedInitializing(__Pyx_CachedCFunction *cfunc) { +#if CYTHON_ATOMICS + __pyx_atomic_store(&cfunc->initialized, 2); +#endif +} +#else +#define __Pyx_CachedCFunction_GetAndSetInitializing(cfunc) 2 +#define __Pyx_CachedCFunction_SetFinishedInitializing(cfunc) +#endif + +/* CallUnboundCMethod0.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self); +#else +#define __Pyx_CallUnboundCMethod0(cfunc, self) __Pyx__CallUnboundCMethod0(cfunc, self) +#endif + +/* py_dict_values.proto (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d); + +/* OwnedDictNext.proto (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue); +#else +CYTHON_INLINE +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue); +#endif + +/* RaiseDoubleKeywords.proto (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError(const char* func_name, PyObject* kw_name); + +/* ParseKeywordsImpl.export */ +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name +); +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* CallUnboundCMethod2.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2); +#else +#define __Pyx_CallUnboundCMethod2(cfunc, self, arg1, arg2) __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2) +#endif + +/* ParseKeywords.proto */ +static CYTHON_INLINE int __Pyx_ParseKeywords( + PyObject *kwds, PyObject *const *kwvalues, PyObject ** const argnames[], + PyObject *kwds2, PyObject *values[], + Py_ssize_t num_pos_args, Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs +); + +/* RaiseArgTupleInvalid.proto */ +static void __Pyx_RaiseArgtupleInvalid(const char* func_name, int exact, + Py_ssize_t num_min, Py_ssize_t num_max, Py_ssize_t num_found); + +/* ArgTypeTestFunc.export */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact); + +/* ArgTypeTest.proto */ +#define __Pyx_ArgTypeTest(obj, type, none_allowed, name, exact)\ + ((likely(__Pyx_IS_TYPE(obj, type) | (none_allowed && (obj == Py_None)))) ? 1 :\ + __Pyx__ArgTypeTest(obj, type, name, exact)) + +/* dict_getitem_default.proto */ +static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value); + +/* PyObjectCall2Args.proto (used by CallUnboundCMethod1) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2); + +/* CallUnboundCMethod1.proto */ +CYTHON_UNUSED +static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg); +#else +#define __Pyx_CallUnboundCMethod1(cfunc, self, arg) __Pyx__CallUnboundCMethod1(cfunc, self, arg) +#endif + +/* PyObject_Unicode.proto */ +#define __Pyx_PyObject_Unicode(obj)\ + (likely(PyUnicode_CheckExact(obj)) ? __Pyx_NewRef(obj) : PyObject_Str(obj)) + +/* PyErrExceptionMatches.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_ExceptionMatches(err) __Pyx_PyErr_ExceptionMatchesInState(__pyx_tstate, err) +static CYTHON_INLINE int __Pyx_PyErr_ExceptionMatchesInState(PyThreadState* tstate, PyObject* err); +#else +#define __Pyx_PyErr_ExceptionMatches(err) PyErr_ExceptionMatches(err) +#endif + +/* PyThreadStateGet.proto (used by PyErrFetchRestore) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyThreadState_declare PyThreadState *__pyx_tstate; +#define __Pyx_PyThreadState_assign __pyx_tstate = __Pyx_PyThreadState_Current; +#if PY_VERSION_HEX >= 0x030C00A6 +#define __Pyx_PyErr_Occurred() (__pyx_tstate->current_exception != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->current_exception ? (PyObject*) Py_TYPE(__pyx_tstate->current_exception) : (PyObject*) NULL) +#else +#define __Pyx_PyErr_Occurred() (__pyx_tstate->curexc_type != NULL) +#define __Pyx_PyErr_CurrentExceptionType() (__pyx_tstate->curexc_type) +#endif +#else +#define __Pyx_PyThreadState_declare +#define __Pyx_PyThreadState_assign +#define __Pyx_PyErr_Occurred() (PyErr_Occurred() != NULL) +#define __Pyx_PyErr_CurrentExceptionType() PyErr_Occurred() +#endif + +/* PyErrFetchRestore.proto (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +#define __Pyx_PyErr_Clear() __Pyx_ErrRestore(NULL, NULL, NULL) +#define __Pyx_ErrRestoreWithState(type, value, tb) __Pyx_ErrRestoreInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) __Pyx_ErrFetchInState(PyThreadState_GET(), type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) __Pyx_ErrRestoreInState(__pyx_tstate, type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) __Pyx_ErrFetchInState(__pyx_tstate, type, value, tb) +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb); +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb); +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A6 +#define __Pyx_PyErr_SetNone(exc) (Py_INCREF(exc), __Pyx_ErrRestore((exc), NULL, NULL)) +#else +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#endif +#else +#define __Pyx_PyErr_Clear() PyErr_Clear() +#define __Pyx_PyErr_SetNone(exc) PyErr_SetNone(exc) +#define __Pyx_ErrRestoreWithState(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchWithState(type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestoreInState(tstate, type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetchInState(tstate, type, value, tb) PyErr_Fetch(type, value, tb) +#define __Pyx_ErrRestore(type, value, tb) PyErr_Restore(type, value, tb) +#define __Pyx_ErrFetch(type, value, tb) PyErr_Fetch(type, value, tb) +#endif + +/* PyObjectGetAttrStrNoError.proto (used by HasAttr) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name); + +/* HasAttr.proto (used by ImportImpl) */ +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_HasAttr(o, n) PyObject_HasAttrWithError(o, n) +#else +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *, PyObject *); +#endif + +/* ImportImpl.export */ +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level); + +/* Import.proto */ +static CYTHON_INLINE PyObject *__Pyx_Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, int level); + +/* ImportFrom.proto */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name); + +/* dict_setdefault.proto (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value); + +/* LimitedApiGetTypeDict.proto (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp); +#endif + +/* SetItemOnTypeDict.proto (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v); +#define __Pyx_SetItemOnTypeDict(tp, k, v) __Pyx__SetItemOnTypeDict((PyTypeObject*)tp, k, v) + +/* FixUpExtensionType.proto (used by FetchCommonType) */ +static CYTHON_INLINE int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type); + +/* AddModuleRef.proto (used by FetchSharedCythonModule) */ +#if ((CYTHON_COMPILING_IN_CPYTHON_FREETHREADING ) ||\ + __PYX_LIMITED_VERSION_HEX < 0x030d0000) + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name); +#else + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#endif + +/* FetchSharedCythonModule.proto (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void); + +/* FetchCommonType.proto (used by CommonTypesMetaclass) */ +static PyTypeObject* __Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases); + +/* CommonTypesMetaclass.proto (used by CythonFunctionShared) */ +static int __pyx_CommonTypesMetaclass_init(PyObject *module); +#define __Pyx_CommonTypesMetaclass_USED + +/* CallTypeTraverse.proto (used by CythonFunctionShared) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#define __Pyx_call_type_traverse(o, always_call, visit, arg) 0 +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg); +#endif + +/* PyMethodNew.proto (used by CythonFunctionShared) */ +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ); + +/* PyVectorcallFastCallDict.proto (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw); +#endif + +/* CythonFunctionShared.proto (used by CythonFunction) */ +#define __Pyx_CyFunction_USED +#define __Pyx_CYFUNCTION_STATICMETHOD 0x01 +#define __Pyx_CYFUNCTION_CLASSMETHOD 0x02 +#define __Pyx_CYFUNCTION_CCLASS 0x04 +#define __Pyx_CYFUNCTION_COROUTINE 0x08 +#define __Pyx_CyFunction_GetClosure(f)\ + (((__pyx_CyFunctionObject *) (f))->func_closure) +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + #define __Pyx_CyFunction_GetClassObj(f)\ + (((__pyx_CyFunctionObject *) (f))->func_classobj) +#else + #define __Pyx_CyFunction_GetClassObj(f)\ + ((PyObject*) ((PyCMethodObject *) (f))->mm_class) +#endif +#define __Pyx_CyFunction_SetClassObj(f, classobj)\ + __Pyx__CyFunction_SetClassObj((__pyx_CyFunctionObject *) (f), (classobj)) +#define __Pyx_CyFunction_Defaults(type, f)\ + ((type *)(((__pyx_CyFunctionObject *) (f))->defaults)) +#define __Pyx_CyFunction_SetDefaultsGetter(f, g)\ + ((__pyx_CyFunctionObject *) (f))->defaults_getter = (g) +typedef struct { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject_HEAD + PyObject *func; +#elif PY_VERSION_HEX < 0x030900B1 + PyCFunctionObject func; +#else + PyCMethodObject func; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API && CYTHON_METH_FASTCALL + __pyx_vectorcallfunc func_vectorcall; +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_weakreflist; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_dict; +#endif + PyObject *func_name; + PyObject *func_qualname; + PyObject *func_doc; + PyObject *func_globals; + PyObject *func_code; + PyObject *func_closure; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + PyObject *func_classobj; +#endif + PyObject *defaults; + int flags; + PyObject *defaults_tuple; + PyObject *defaults_kwdict; + PyObject *(*defaults_getter)(PyObject *); + PyObject *func_annotations; + PyObject *func_is_coroutine; +} __pyx_CyFunctionObject; +#undef __Pyx_CyOrPyCFunction_Check +#define __Pyx_CyFunction_Check(obj) __Pyx_TypeCheck(obj, __pyx_mstate_global->__pyx_CyFunctionType) +#define __Pyx_CyOrPyCFunction_Check(obj) __Pyx_TypeCheck2(obj, __pyx_mstate_global->__pyx_CyFunctionType, &PyCFunction_Type) +#define __Pyx_CyFunction_CheckExact(obj) __Pyx_IS_TYPE(obj, __pyx_mstate_global->__pyx_CyFunctionType) +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)); +#undef __Pyx_IsSameCFunction +#define __Pyx_IsSameCFunction(func, cfunc) __Pyx__IsSameCyOrCFunction(func, cfunc) +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject* op, PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj); +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, + PyTypeObject *defaults_type); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *m, + PyObject *tuple); +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *m, + PyObject *dict); +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *m, + PyObject *dict); +static int __pyx_CyFunction_init(PyObject *module); +#if CYTHON_METH_FASTCALL +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames); +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_func_vectorcall(f) (((__pyx_CyFunctionObject*)f)->func_vectorcall) +#else +#define __Pyx_CyFunction_func_vectorcall(f) (((PyCFunctionObject*)f)->vectorcall) +#endif +#endif + +/* CythonFunction.proto */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, + int flags, PyObject* qualname, + PyObject *closure, + PyObject *module, PyObject *globals, + PyObject* code); + +/* PyDictVersioning.proto (used by CLineInTraceback) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +#define __PYX_DICT_VERSION_INIT ((PY_UINT64_T) -1) +#define __PYX_GET_DICT_VERSION(dict) (((PyDictObject*)(dict))->ma_version_tag) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var)\ + (version_var) = __PYX_GET_DICT_VERSION(dict);\ + (cache_var) = (value); +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) {\ + static PY_UINT64_T __pyx_dict_version = 0;\ + static PyObject *__pyx_dict_cached_value = NULL;\ + if (likely(__PYX_GET_DICT_VERSION(DICT) == __pyx_dict_version)) {\ + (VAR) = __Pyx_XNewRef(__pyx_dict_cached_value);\ + } else {\ + (VAR) = __pyx_dict_cached_value = (LOOKUP);\ + __pyx_dict_version = __PYX_GET_DICT_VERSION(DICT);\ + }\ +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj); +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj); +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version); +#else +#define __PYX_GET_DICT_VERSION(dict) (0) +#define __PYX_UPDATE_DICT_CACHE(dict, value, cache_var, version_var) +#define __PYX_PY_DICT_LOOKUP_IF_MODIFIED(VAR, DICT, LOOKUP) (VAR) = (LOOKUP); +#endif + +/* CLineInTraceback.proto (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line); +#else +#define __Pyx_CLineForTraceback(tstate, c_line) (((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0) +#endif + +/* CodeObjectCache.proto (used by AddTraceback) */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject __Pyx_CachedCodeObjectType; +#else +typedef PyCodeObject __Pyx_CachedCodeObjectType; +#endif +typedef struct { + __Pyx_CachedCodeObjectType* code_object; + int code_line; +} __Pyx_CodeObjectCacheEntry; +struct __Pyx_CodeObjectCache { + int count; + int max_count; + __Pyx_CodeObjectCacheEntry* entries; + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_int_type accessor_count; + #endif +}; +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line); +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line); +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object); + +/* AddTraceback.proto */ +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename); + +/* FormatTypeName.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API +typedef PyObject *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%U" +#define __Pyx_DECREF_TypeName(obj) Py_XDECREF(obj) +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 +#define __Pyx_PyType_GetFullyQualifiedName PyType_GetFullyQualifiedName +#else +static __Pyx_TypeName __Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp); +#endif +#else // !LIMITED_API +typedef const char *__Pyx_TypeName; +#define __Pyx_FMT_TYPENAME "%.200s" +#define __Pyx_PyType_GetFullyQualifiedName(tp) ((tp)->tp_name) +#define __Pyx_DECREF_TypeName(obj) +#endif + +/* GCCDiagnostics.proto (used by CIntToPy) */ +#if !defined(__INTEL_COMPILER) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6)) +#define __Pyx_HAS_GCC_DIAGNOSTIC +#endif + +/* PyObjectVectorCallKwBuilder.proto (used by CIntToPy) */ +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#if CYTHON_VECTORCALL +#if PY_VERSION_HEX >= 0x03090000 +#define __Pyx_Object_Vectorcall_CallFromBuilder PyObject_Vectorcall +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder _PyObject_Vectorcall +#endif +#define __Pyx_MakeVectorcallBuilderKwds(n) PyTuple_New(n) +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n); +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n); +#else +#define __Pyx_Object_Vectorcall_CallFromBuilder __Pyx_PyObject_FastCallDict +#define __Pyx_MakeVectorcallBuilderKwds(n) __Pyx_PyDict_NewPresized(n) +#define __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n) PyDict_SetItem(builder, key, value) +#define __Pyx_VectorcallBuilder_AddArgStr(key, value, builder, args, n) PyDict_SetItemString(builder, key, value) +#endif + +/* CIntToPy.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value); + +/* CIntFromPy.proto */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *); + +/* CIntFromPy.proto */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *); + +/* FastTypeChecks.proto */ +#if CYTHON_COMPILING_IN_CPYTHON +#define __Pyx_TypeCheck(obj, type) __Pyx_IsSubtype(Py_TYPE(obj), (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) __Pyx_IsAnySubtype2(Py_TYPE(obj), (PyTypeObject *)type1, (PyTypeObject *)type2) +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches(PyObject *err, PyObject *type); +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2); +#else +#define __Pyx_TypeCheck(obj, type) PyObject_TypeCheck(obj, (PyTypeObject *)type) +#define __Pyx_TypeCheck2(obj, type1, type2) (PyObject_TypeCheck(obj, (PyTypeObject *)type1) || PyObject_TypeCheck(obj, (PyTypeObject *)type2)) +#define __Pyx_PyErr_GivenExceptionMatches(err, type) PyErr_GivenExceptionMatches(err, type) +static CYTHON_INLINE int __Pyx_PyErr_GivenExceptionMatches2(PyObject *err, PyObject *type1, PyObject *type2) { + return PyErr_GivenExceptionMatches(err, type1) || PyErr_GivenExceptionMatches(err, type2); +} +#endif +#define __Pyx_PyErr_ExceptionMatches2(err1, err2) __Pyx_PyErr_GivenExceptionMatches2(__Pyx_PyErr_CurrentExceptionType(), err1, err2) +#define __Pyx_PyException_Check(obj) __Pyx_TypeCheck(obj, PyExc_Exception) +#ifdef PyExceptionInstance_Check + #define __Pyx_PyBaseException_Check(obj) PyExceptionInstance_Check(obj) +#else + #define __Pyx_PyBaseException_Check(obj) __Pyx_TypeCheck(obj, PyExc_BaseException) +#endif + +/* GetRuntimeVersion.proto */ +#if __PYX_LIMITED_VERSION_HEX < 0x030b0000 +static unsigned long __Pyx_cached_runtime_version = 0; +static void __Pyx_init_runtime_version(void); +#else +#define __Pyx_init_runtime_version() +#endif +static unsigned long __Pyx_get_runtime_version(void); + +/* CheckBinaryVersion.proto */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer); + +/* DecompressString.proto */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo); + +/* MultiPhaseInitModuleState.proto */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +static PyObject *__Pyx_State_FindModule(void*); +static int __Pyx_State_AddModule(PyObject* module, void*); +static int __Pyx_State_RemoveModule(void*); +#elif CYTHON_USE_MODULE_STATE +#define __Pyx_State_FindModule PyState_FindModule +#define __Pyx_State_AddModule PyState_AddModule +#define __Pyx_State_RemoveModule PyState_RemoveModule +#endif + +/* #### Code section: module_declarations ### */ +/* CythonABIVersion.proto */ +#if CYTHON_COMPILING_IN_LIMITED_API + #if CYTHON_METH_FASTCALL + #define __PYX_FASTCALL_ABI_SUFFIX "_fastcall" + #else + #define __PYX_FASTCALL_ABI_SUFFIX + #endif + #define __PYX_LIMITED_ABI_SUFFIX "limited" __PYX_FASTCALL_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#else + #define __PYX_LIMITED_ABI_SUFFIX +#endif +#if __PYX_HAS_PY_AM_SEND == 1 + #define __PYX_AM_SEND_ABI_SUFFIX +#elif __PYX_HAS_PY_AM_SEND == 2 + #define __PYX_AM_SEND_ABI_SUFFIX "amsendbackport" +#else + #define __PYX_AM_SEND_ABI_SUFFIX "noamsend" +#endif +#ifndef __PYX_MONITORING_ABI_SUFFIX + #define __PYX_MONITORING_ABI_SUFFIX +#endif +#if CYTHON_USE_TP_FINALIZE + #define __PYX_TP_FINALIZE_ABI_SUFFIX +#else + #define __PYX_TP_FINALIZE_ABI_SUFFIX "nofinalize" +#endif +#if CYTHON_USE_FREELISTS || !defined(__Pyx_AsyncGen_USED) + #define __PYX_FREELISTS_ABI_SUFFIX +#else + #define __PYX_FREELISTS_ABI_SUFFIX "nofreelists" +#endif +#define CYTHON_ABI __PYX_ABI_VERSION __PYX_LIMITED_ABI_SUFFIX __PYX_MONITORING_ABI_SUFFIX __PYX_TP_FINALIZE_ABI_SUFFIX __PYX_FREELISTS_ABI_SUFFIX __PYX_AM_SEND_ABI_SUFFIX +#define __PYX_ABI_MODULE_NAME "_cython_" CYTHON_ABI +#define __PYX_TYPE_MODULE_PREFIX __PYX_ABI_MODULE_NAME "." + + +/* Module declarations from "app.core.tenancy" */ +/* #### Code section: typeinfo ### */ +/* #### Code section: before_global_var ### */ +#define __Pyx_MODULE_NAME "app.core.tenancy" +extern int __pyx_module_is_main_app__core__tenancy; +int __pyx_module_is_main_app__core__tenancy = 0; + +/* Implementation of "app.core.tenancy" */ +/* #### Code section: global_var ### */ +/* #### Code section: string_decls ### */ +static const char __pyx_k_PR12_organization_tenancy_scopin[] = "PR12: organization-tenancy scoping.\n\nNeither this service nor omnibioai-hpc-policy-engine had any concept of\norg_id before this PR -- authorization was scoped only per user_id. This\nadds an additive tenancy gate: if the request names which organization\nowns the resource being acted on (`context[\"resource_org_id\"]`, supplied\nby the caller -- this service has no database of its own to look\nresource ownership up in), the requester's own `org_id` must match it.\n\nOpt-in the same way app/core/permissions.py is: a caller that never\nsupplies `resource_org_id` in context (true of every caller today) gets\n\"no tenancy scoping required\" -- a no-op, not a new restriction on\nexisting traffic. It only activates once a caller (a fixture in these\ntests, or eventually the Gateway once it's taught which org owns a given\nresource) actually supplies it.\n"; +/* #### Code section: decls ### */ +static PyObject *__pyx_pf_3app_4core_7tenancy_evaluate_tenancy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_org_id, PyObject *__pyx_v_context); /* proto */ +/* #### Code section: late_includes ### */ +/* #### Code section: module_state ### */ +/* SmallCodeConfig */ +#ifndef CYTHON_SMALL_CODE +#if defined(__clang__) + #define CYTHON_SMALL_CODE +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)) + #define CYTHON_SMALL_CODE __attribute__((cold)) +#else + #define CYTHON_SMALL_CODE +#endif +#endif + +typedef struct { + PyObject *__pyx_d; + PyObject *__pyx_b; + PyObject *__pyx_cython_runtime; + PyObject *__pyx_empty_tuple; + PyObject *__pyx_empty_bytes; + PyObject *__pyx_empty_unicode; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_get; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_items; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_pop; + __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_values; + PyObject *__pyx_tuple[4]; + PyObject *__pyx_codeobj_tab[1]; + PyObject *__pyx_string_tab[37]; +/* #### Code section: module_state_contents ### */ +/* CommonTypesMetaclass.module_state_decls */ +PyTypeObject *__pyx_CommonTypesMetaclassType; + +/* CachedMethodType.module_state_decls */ +#if CYTHON_COMPILING_IN_LIMITED_API +PyObject *__Pyx_CachedMethodType; +#endif + +/* CythonFunctionShared.module_state_decls */ +PyTypeObject *__pyx_CyFunctionType; + +/* CodeObjectCache.module_state_decls */ +struct __Pyx_CodeObjectCache __pyx_code_cache; + +/* #### Code section: module_state_end ### */ +} __pyx_mstatetype; + +#if CYTHON_USE_MODULE_STATE +#ifdef __cplusplus +namespace { +extern struct PyModuleDef __pyx_moduledef; +} /* anonymous namespace */ +#else +static struct PyModuleDef __pyx_moduledef; +#endif + +#define __pyx_mstate_global (__Pyx_PyModule_GetState(__Pyx_State_FindModule(&__pyx_moduledef))) + +#define __pyx_m (__Pyx_State_FindModule(&__pyx_moduledef)) +#else +static __pyx_mstatetype __pyx_mstate_global_static = +#ifdef __cplusplus + {}; +#else + {0}; +#endif +static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_static; +#endif +/* #### Code section: constant_name_defines ### */ +#define __pyx_kp_u_ __pyx_string_tab[0] +#define __pyx_kp_u_Dict_str_Any __pyx_string_tab[1] +#define __pyx_kp_u_Note_that_Cython_is_deliberately __pyx_string_tab[2] +#define __pyx_kp_u__2 __pyx_string_tab[3] +#define __pyx_kp_u_add_note __pyx_string_tab[4] +#define __pyx_kp_u_app_core_tenancy_py __pyx_string_tab[5] +#define __pyx_kp_u_cross_tenant_access_denied __pyx_string_tab[6] +#define __pyx_kp_u_missing_organization_context __pyx_string_tab[7] +#define __pyx_kp_u_no_tenancy_scoping_required __pyx_string_tab[8] +#define __pyx_kp_u_tenancy_check_passed __pyx_string_tab[9] +#define __pyx_kp_u_tuple_bool_str __pyx_string_tab[10] +#define __pyx_n_u_Any __pyx_string_tab[11] +#define __pyx_n_u_Dict __pyx_string_tab[12] +#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[13] +#define __pyx_n_u_app_core_tenancy __pyx_string_tab[14] +#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[15] +#define __pyx_n_u_cline_in_traceback __pyx_string_tab[16] +#define __pyx_n_u_context __pyx_string_tab[17] +#define __pyx_n_u_evaluate_tenancy __pyx_string_tab[18] +#define __pyx_n_u_func __pyx_string_tab[19] +#define __pyx_n_u_get __pyx_string_tab[20] +#define __pyx_n_u_is_coroutine __pyx_string_tab[21] +#define __pyx_n_u_items __pyx_string_tab[22] +#define __pyx_n_u_main __pyx_string_tab[23] +#define __pyx_n_u_module __pyx_string_tab[24] +#define __pyx_n_u_name __pyx_string_tab[25] +#define __pyx_n_u_org_id __pyx_string_tab[26] +#define __pyx_n_u_pop __pyx_string_tab[27] +#define __pyx_n_u_qualname __pyx_string_tab[28] +#define __pyx_n_u_resource_org_id __pyx_string_tab[29] +#define __pyx_n_u_return __pyx_string_tab[30] +#define __pyx_n_u_set_name __pyx_string_tab[31] +#define __pyx_n_u_setdefault __pyx_string_tab[32] +#define __pyx_n_u_test __pyx_string_tab[33] +#define __pyx_n_u_typing __pyx_string_tab[34] +#define __pyx_n_u_values __pyx_string_tab[35] +#define __pyx_kp_b_iso88591_a_gT_s_vQ_wc_wa_s_83c_wa_6 __pyx_string_tab[36] +/* #### Code section: module_state_clear ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { + __pyx_mstatetype *clear_module_state = __Pyx_PyModule_GetState(m); + if (!clear_module_state) return 0; + Py_CLEAR(clear_module_state->__pyx_d); + Py_CLEAR(clear_module_state->__pyx_b); + Py_CLEAR(clear_module_state->__pyx_cython_runtime); + Py_CLEAR(clear_module_state->__pyx_empty_tuple); + Py_CLEAR(clear_module_state->__pyx_empty_bytes); + Py_CLEAR(clear_module_state->__pyx_empty_unicode); + #if CYTHON_PEP489_MULTI_PHASE_INIT + __Pyx_State_RemoveModule(NULL); + #endif + for (int i=0; i<4; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } + for (int i=0; i<1; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<37; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } +/* #### Code section: module_state_clear_contents ### */ +/* CommonTypesMetaclass.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CommonTypesMetaclassType); + +/* CythonFunctionShared.module_state_clear */ +Py_CLEAR(clear_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_clear_end ### */ +return 0; +} +#endif +/* #### Code section: module_state_traverse ### */ +#if CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void *arg) { + __pyx_mstatetype *traverse_module_state = __Pyx_PyModule_GetState(m); + if (!traverse_module_state) return 0; + Py_VISIT(traverse_module_state->__pyx_d); + Py_VISIT(traverse_module_state->__pyx_b); + Py_VISIT(traverse_module_state->__pyx_cython_runtime); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_tuple); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_bytes); + __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); + for (int i=0; i<4; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } + for (int i=0; i<1; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } + for (int i=0; i<37; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } +/* #### Code section: module_state_traverse_contents ### */ +/* CommonTypesMetaclass.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CommonTypesMetaclassType); + +/* CythonFunctionShared.module_state_traverse */ +Py_VISIT(traverse_module_state->__pyx_CyFunctionType); + +/* #### Code section: module_state_traverse_end ### */ +return 0; +} +#endif +/* #### Code section: module_code ### */ + +/* "app/core/tenancy.py":21 + * + * + * def evaluate_tenancy(org_id: Any, context: Dict[str, Any]) -> tuple[bool, str]: # <<<<<<<<<<<<<< + * resource_org_id = context.get("resource_org_id") + * +*/ + +/* Python wrapper */ +static PyObject *__pyx_pw_3app_4core_7tenancy_1evaluate_tenancy(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +); /*proto*/ +static PyMethodDef __pyx_mdef_3app_4core_7tenancy_1evaluate_tenancy = {"evaluate_tenancy", (PyCFunction)(void(*)(void))(__Pyx_PyCFunction_FastCallWithKeywords)__pyx_pw_3app_4core_7tenancy_1evaluate_tenancy, __Pyx_METH_FASTCALL|METH_KEYWORDS, 0}; +static PyObject *__pyx_pw_3app_4core_7tenancy_1evaluate_tenancy(PyObject *__pyx_self, +#if CYTHON_METH_FASTCALL +PyObject *const *__pyx_args, Py_ssize_t __pyx_nargs, PyObject *__pyx_kwds +#else +PyObject *__pyx_args, PyObject *__pyx_kwds +#endif +) { + PyObject *__pyx_v_org_id = 0; + PyObject *__pyx_v_context = 0; + #if !CYTHON_METH_FASTCALL + CYTHON_UNUSED Py_ssize_t __pyx_nargs; + #endif + CYTHON_UNUSED PyObject *const *__pyx_kwvalues; + PyObject* values[2] = {0,0}; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + PyObject *__pyx_r = 0; + __Pyx_RefNannyDeclarations + __Pyx_RefNannySetupContext("evaluate_tenancy (wrapper)", 0); + #if !CYTHON_METH_FASTCALL + #if CYTHON_ASSUME_SAFE_SIZE + __pyx_nargs = PyTuple_GET_SIZE(__pyx_args); + #else + __pyx_nargs = PyTuple_Size(__pyx_args); if (unlikely(__pyx_nargs < 0)) return NULL; + #endif + #endif + __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); + { + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_org_id,&__pyx_mstate_global->__pyx_n_u_context,0}; + const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; + if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 21, __pyx_L3_error) + if (__pyx_kwds_len > 0) { + switch (__pyx_nargs) { + case 2: + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 21, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 1: + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 21, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 0: break; + default: goto __pyx_L5_argtuple_error; + } + const Py_ssize_t kwd_pos_args = __pyx_nargs; + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "evaluate_tenancy", 0) < (0)) __PYX_ERR(0, 21, __pyx_L3_error) + for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("evaluate_tenancy", 1, 2, 2, i); __PYX_ERR(0, 21, __pyx_L3_error) } + } + } else if (unlikely(__pyx_nargs != 2)) { + goto __pyx_L5_argtuple_error; + } else { + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 21, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 21, __pyx_L3_error) + } + __pyx_v_org_id = values[0]; + __pyx_v_context = ((PyObject*)values[1]); + } + goto __pyx_L6_skip; + __pyx_L5_argtuple_error:; + __Pyx_RaiseArgtupleInvalid("evaluate_tenancy", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 21, __pyx_L3_error) + __pyx_L6_skip:; + goto __pyx_L4_argument_unpacking_done; + __pyx_L3_error:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __Pyx_AddTraceback("app.core.tenancy.evaluate_tenancy", __pyx_clineno, __pyx_lineno, __pyx_filename); + __Pyx_RefNannyFinishContext(); + return NULL; + __pyx_L4_argument_unpacking_done:; + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_context), (&PyDict_Type), 0, "context", 2))) __PYX_ERR(0, 21, __pyx_L1_error) + __pyx_r = __pyx_pf_3app_4core_7tenancy_evaluate_tenancy(__pyx_self, __pyx_v_org_id, __pyx_v_context); + + /* function exit code */ + goto __pyx_L0; + __pyx_L1_error:; + __pyx_r = NULL; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + goto __pyx_L7_cleaned_up; + __pyx_L0:; + for (Py_ssize_t __pyx_temp=0; __pyx_temp < (Py_ssize_t)(sizeof(values)/sizeof(values[0])); ++__pyx_temp) { + Py_XDECREF(values[__pyx_temp]); + } + __pyx_L7_cleaned_up:; + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} + +static PyObject *__pyx_pf_3app_4core_7tenancy_evaluate_tenancy(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_org_id, PyObject *__pyx_v_context) { + PyObject *__pyx_v_resource_org_id = NULL; + PyObject *__pyx_r = NULL; + __Pyx_RefNannyDeclarations + PyObject *__pyx_t_1 = NULL; + int __pyx_t_2; + PyObject *__pyx_t_3 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannySetupContext("evaluate_tenancy", 0); + + /* "app/core/tenancy.py":22 + * + * def evaluate_tenancy(org_id: Any, context: Dict[str, Any]) -> tuple[bool, str]: + * resource_org_id = context.get("resource_org_id") # <<<<<<<<<<<<<< + * + * if resource_org_id is None: +*/ + __pyx_t_1 = __Pyx_PyDict_GetItemDefault(__pyx_v_context, __pyx_mstate_global->__pyx_n_u_resource_org_id, Py_None); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 22, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_v_resource_org_id = __pyx_t_1; + __pyx_t_1 = 0; + + /* "app/core/tenancy.py":24 + * resource_org_id = context.get("resource_org_id") + * + * if resource_org_id is None: # <<<<<<<<<<<<<< + * return True, "no tenancy scoping required" + * +*/ + __pyx_t_2 = (__pyx_v_resource_org_id == Py_None); + if (__pyx_t_2) { + + /* "app/core/tenancy.py":25 + * + * if resource_org_id is None: + * return True, "no tenancy scoping required" # <<<<<<<<<<<<<< + * + * if org_id is None: +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[0]); + __pyx_r = __pyx_mstate_global->__pyx_tuple[0]; + goto __pyx_L0; + + /* "app/core/tenancy.py":24 + * resource_org_id = context.get("resource_org_id") + * + * if resource_org_id is None: # <<<<<<<<<<<<<< + * return True, "no tenancy scoping required" + * +*/ + } + + /* "app/core/tenancy.py":27 + * return True, "no tenancy scoping required" + * + * if org_id is None: # <<<<<<<<<<<<<< + * return False, "missing organization context" + * +*/ + __pyx_t_2 = (__pyx_v_org_id == Py_None); + if (__pyx_t_2) { + + /* "app/core/tenancy.py":28 + * + * if org_id is None: + * return False, "missing organization context" # <<<<<<<<<<<<<< + * + * if str(org_id) != str(resource_org_id): +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[1]); + __pyx_r = __pyx_mstate_global->__pyx_tuple[1]; + goto __pyx_L0; + + /* "app/core/tenancy.py":27 + * return True, "no tenancy scoping required" + * + * if org_id is None: # <<<<<<<<<<<<<< + * return False, "missing organization context" + * +*/ + } + + /* "app/core/tenancy.py":30 + * return False, "missing organization context" + * + * if str(org_id) != str(resource_org_id): # <<<<<<<<<<<<<< + * return False, "cross-tenant access denied" + * +*/ + __pyx_t_1 = __Pyx_PyObject_Unicode(__pyx_v_org_id); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_3 = __Pyx_PyObject_Unicode(__pyx_v_resource_org_id); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_3); + __pyx_t_2 = (__Pyx_PyUnicode_Equals(__pyx_t_1, __pyx_t_3, Py_NE)); if (unlikely((__pyx_t_2 < 0))) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; + if (__pyx_t_2) { + + /* "app/core/tenancy.py":31 + * + * if str(org_id) != str(resource_org_id): + * return False, "cross-tenant access denied" # <<<<<<<<<<<<<< + * + * return True, "tenancy check passed" +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[2]); + __pyx_r = __pyx_mstate_global->__pyx_tuple[2]; + goto __pyx_L0; + + /* "app/core/tenancy.py":30 + * return False, "missing organization context" + * + * if str(org_id) != str(resource_org_id): # <<<<<<<<<<<<<< + * return False, "cross-tenant access denied" + * +*/ + } + + /* "app/core/tenancy.py":33 + * return False, "cross-tenant access denied" + * + * return True, "tenancy check passed" # <<<<<<<<<<<<<< +*/ + __Pyx_XDECREF(__pyx_r); + __Pyx_INCREF(__pyx_mstate_global->__pyx_tuple[3]); + __pyx_r = __pyx_mstate_global->__pyx_tuple[3]; + goto __pyx_L0; + + /* "app/core/tenancy.py":21 + * + * + * def evaluate_tenancy(org_id: Any, context: Dict[str, Any]) -> tuple[bool, str]: # <<<<<<<<<<<<<< + * resource_org_id = context.get("resource_org_id") + * +*/ + + /* function exit code */ + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_1); + __Pyx_XDECREF(__pyx_t_3); + __Pyx_AddTraceback("app.core.tenancy.evaluate_tenancy", __pyx_clineno, __pyx_lineno, __pyx_filename); + __pyx_r = NULL; + __pyx_L0:; + __Pyx_XDECREF(__pyx_v_resource_org_id); + __Pyx_XGIVEREF(__pyx_r); + __Pyx_RefNannyFinishContext(); + return __pyx_r; +} +/* #### Code section: module_exttypes ### */ + +static PyMethodDef __pyx_methods[] = { + {0, 0, 0, 0} +}; +/* #### Code section: initfunc_declarations ### */ +static CYTHON_SMALL_CODE int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitGlobals(void); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate); /*proto*/ +static CYTHON_SMALL_CODE int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate); /*proto*/ +/* #### Code section: init_module ### */ + +static int __Pyx_modinit_global_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_global_init_code", 0); + /*--- Global init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_export_code", 0); + /*--- Variable export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_export_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_export_code", 0); + /*--- Function export code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_init_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_init_code", 0); + /*--- Type init code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_type_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_type_import_code", 0); + /*--- Type import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_variable_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_variable_import_code", 0); + /*--- Variable import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +static int __Pyx_modinit_function_import_code(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_modinit_function_import_code", 0); + /*--- Function import code ---*/ + __Pyx_RefNannyFinishContext(); + return 0; +} + +#if CYTHON_PEP489_MULTI_PHASE_INIT +static PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def); /*proto*/ +static int __pyx_pymod_exec_tenancy(PyObject* module); /*proto*/ +static PyModuleDef_Slot __pyx_moduledef_slots[] = { + {Py_mod_create, (void*)__pyx_pymod_create}, + {Py_mod_exec, (void*)__pyx_pymod_exec_tenancy}, + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + {Py_mod_gil, __Pyx_FREETHREADING_COMPATIBLE}, + #endif + #if PY_VERSION_HEX >= 0x030C0000 && CYTHON_USE_MODULE_STATE + {Py_mod_multiple_interpreters, Py_MOD_MULTIPLE_INTERPRETERS_NOT_SUPPORTED}, + #endif + {0, NULL} +}; +#endif + +#ifdef __cplusplus +namespace { + struct PyModuleDef __pyx_moduledef = + #else + static struct PyModuleDef __pyx_moduledef = + #endif + { + PyModuleDef_HEAD_INIT, + "tenancy", + __pyx_k_PR12_organization_tenancy_scopin, /* m_doc */ + #if CYTHON_USE_MODULE_STATE + sizeof(__pyx_mstatetype), /* m_size */ + #else + (CYTHON_PEP489_MULTI_PHASE_INIT) ? 0 : -1, /* m_size */ + #endif + __pyx_methods /* m_methods */, + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_moduledef_slots, /* m_slots */ + #else + NULL, /* m_reload */ + #endif + #if CYTHON_USE_MODULE_STATE + __pyx_m_traverse, /* m_traverse */ + __pyx_m_clear, /* m_clear */ + NULL /* m_free */ + #else + NULL, /* m_traverse */ + NULL, /* m_clear */ + NULL /* m_free */ + #endif + }; + #ifdef __cplusplus +} /* anonymous namespace */ +#endif + +/* PyModInitFuncType */ +#ifndef CYTHON_NO_PYINIT_EXPORT + #define __Pyx_PyMODINIT_FUNC PyMODINIT_FUNC +#else + #ifdef __cplusplus + #define __Pyx_PyMODINIT_FUNC extern "C" PyObject * + #else + #define __Pyx_PyMODINIT_FUNC PyObject * + #endif +#endif + +__Pyx_PyMODINIT_FUNC PyInit_tenancy(void) CYTHON_SMALL_CODE; /*proto*/ +__Pyx_PyMODINIT_FUNC PyInit_tenancy(void) +#if CYTHON_PEP489_MULTI_PHASE_INIT +{ + return PyModuleDef_Init(&__pyx_moduledef); +} +/* ModuleCreationPEP489 */ +#if CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) +static PY_INT64_T __Pyx_GetCurrentInterpreterId(void) { + { + PyObject *module = PyImport_ImportModule("_interpreters"); // 3.13+ I think + if (!module) { + PyErr_Clear(); // just try the 3.8-3.12 version + module = PyImport_ImportModule("_xxsubinterpreters"); + if (!module) goto bad; + } + PyObject *current = PyObject_CallMethod(module, "get_current", NULL); + Py_DECREF(module); + if (!current) goto bad; + if (PyTuple_Check(current)) { + PyObject *new_current = PySequence_GetItem(current, 0); + Py_DECREF(current); + current = new_current; + if (!new_current) goto bad; + } + long long as_c_int = PyLong_AsLongLong(current); + Py_DECREF(current); + return as_c_int; + } + bad: + PySys_WriteStderr("__Pyx_GetCurrentInterpreterId failed. Try setting the C define CYTHON_PEP489_MULTI_PHASE_INIT=0\n"); + return -1; +} +#endif +#if !CYTHON_USE_MODULE_STATE +static CYTHON_SMALL_CODE int __Pyx_check_single_interpreter(void) { + static PY_INT64_T main_interpreter_id = -1; +#if CYTHON_COMPILING_IN_GRAAL && defined(GRAALPY_VERSION_NUM) && GRAALPY_VERSION_NUM > 0x19000000 + PY_INT64_T current_id = GraalPyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_GRAAL + PY_INT64_T current_id = PyInterpreterState_GetIDFromThreadState(PyThreadState_Get()); +#elif CYTHON_COMPILING_IN_LIMITED_API && (__PYX_LIMITED_VERSION_HEX < 0x03090000\ + || ((defined(_WIN32) || defined(WIN32) || defined(MS_WINDOWS)) && __PYX_LIMITED_VERSION_HEX < 0x030A0000)) + PY_INT64_T current_id = __Pyx_GetCurrentInterpreterId(); +#elif CYTHON_COMPILING_IN_LIMITED_API + PY_INT64_T current_id = PyInterpreterState_GetID(PyInterpreterState_Get()); +#else + PY_INT64_T current_id = PyInterpreterState_GetID(PyThreadState_Get()->interp); +#endif + if (unlikely(current_id == -1)) { + return -1; + } + if (main_interpreter_id == -1) { + main_interpreter_id = current_id; + return 0; + } else if (unlikely(main_interpreter_id != current_id)) { + PyErr_SetString( + PyExc_ImportError, + "Interpreter change detected - this module can only be loaded into one interpreter per process."); + return -1; + } + return 0; +} +#endif +static CYTHON_SMALL_CODE int __Pyx_copy_spec_to_module(PyObject *spec, PyObject *moddict, const char* from_name, const char* to_name, int allow_none) +{ + PyObject *value = PyObject_GetAttrString(spec, from_name); + int result = 0; + if (likely(value)) { + if (allow_none || value != Py_None) { + result = PyDict_SetItemString(moddict, to_name, value); + } + Py_DECREF(value); + } else if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + } else { + result = -1; + } + return result; +} +static CYTHON_SMALL_CODE PyObject* __pyx_pymod_create(PyObject *spec, PyModuleDef *def) { + PyObject *module = NULL, *moddict, *modname; + CYTHON_UNUSED_VAR(def); + #if !CYTHON_USE_MODULE_STATE + if (__Pyx_check_single_interpreter()) + return NULL; + #endif + if (__pyx_m) + return __Pyx_NewRef(__pyx_m); + modname = PyObject_GetAttrString(spec, "name"); + if (unlikely(!modname)) goto bad; + module = PyModule_NewObject(modname); + Py_DECREF(modname); + if (unlikely(!module)) goto bad; + moddict = PyModule_GetDict(module); + if (unlikely(!moddict)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "loader", "__loader__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "origin", "__file__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "parent", "__package__", 1) < 0)) goto bad; + if (unlikely(__Pyx_copy_spec_to_module(spec, moddict, "submodule_search_locations", "__path__", 0) < 0)) goto bad; + return module; +bad: + Py_XDECREF(module); + return NULL; +} + + +static CYTHON_SMALL_CODE int __pyx_pymod_exec_tenancy(PyObject *__pyx_pyinit_module) +#endif +{ + int stringtab_initialized = 0; + #if CYTHON_USE_MODULE_STATE + int pystate_addmodule_run = 0; + #endif + __pyx_mstatetype *__pyx_mstate = NULL; + PyObject *__pyx_t_1 = NULL; + PyObject *__pyx_t_2 = NULL; + Py_ssize_t __pyx_t_3; + PyObject *__pyx_t_4 = NULL; + int __pyx_lineno = 0; + const char *__pyx_filename = NULL; + int __pyx_clineno = 0; + __Pyx_RefNannyDeclarations + #if CYTHON_PEP489_MULTI_PHASE_INIT + if (__pyx_m) { + if (__pyx_m == __pyx_pyinit_module) return 0; + PyErr_SetString(PyExc_RuntimeError, "Module 'tenancy' has already been imported. Re-initialisation is not supported."); + return -1; + } + #else + if (__pyx_m) return __Pyx_NewRef(__pyx_m); + #endif + /*--- Module creation code ---*/ + #if CYTHON_PEP489_MULTI_PHASE_INIT + __pyx_t_1 = __pyx_pyinit_module; + Py_INCREF(__pyx_t_1); + #else + __pyx_t_1 = PyModule_Create(&__pyx_moduledef); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 1, __pyx_L1_error) + #endif + #if CYTHON_USE_MODULE_STATE + { + int add_module_result = __Pyx_State_AddModule(__pyx_t_1, &__pyx_moduledef); + __pyx_t_1 = 0; /* transfer ownership from __pyx_t_1 to "tenancy" pseudovariable */ + if (unlikely((add_module_result < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + pystate_addmodule_run = 1; + } + #else + __pyx_m = __pyx_t_1; + #endif + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + PyUnstable_Module_SetGIL(__pyx_m, Py_MOD_GIL_USED); + #endif + __pyx_mstate = __pyx_mstate_global; + CYTHON_UNUSED_VAR(__pyx_t_1); + __pyx_mstate->__pyx_d = PyModule_GetDict(__pyx_m); if (unlikely(!__pyx_mstate->__pyx_d)) __PYX_ERR(0, 1, __pyx_L1_error) + Py_INCREF(__pyx_mstate->__pyx_d); + __pyx_mstate->__pyx_b = __Pyx_PyImport_AddModuleRef(__Pyx_BUILTIN_MODULE_NAME); if (unlikely(!__pyx_mstate->__pyx_b)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_cython_runtime = __Pyx_PyImport_AddModuleRef("cython_runtime"); if (unlikely(!__pyx_mstate->__pyx_cython_runtime)) __PYX_ERR(0, 1, __pyx_L1_error) + if (PyObject_SetAttrString(__pyx_m, "__builtins__", __pyx_mstate->__pyx_b) < 0) __PYX_ERR(0, 1, __pyx_L1_error) + /* ImportRefnannyAPI */ + #if CYTHON_REFNANNY + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("refnanny"); + if (!__Pyx_RefNanny) { + PyErr_Clear(); + __Pyx_RefNanny = __Pyx_RefNannyImportAPI("Cython.Runtime.refnanny"); + if (!__Pyx_RefNanny) + Py_FatalError("failed to import 'refnanny' module"); + } + #endif + +__Pyx_RefNannySetupContext("PyInit_tenancy", 0); + __Pyx_init_runtime_version(); + if (__Pyx_check_binary_version(__PYX_LIMITED_VERSION_HEX, __Pyx_get_runtime_version(), CYTHON_COMPILING_IN_LIMITED_API) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_tuple = PyTuple_New(0); if (unlikely(!__pyx_mstate->__pyx_empty_tuple)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_bytes = PyBytes_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_bytes)) __PYX_ERR(0, 1, __pyx_L1_error) + __pyx_mstate->__pyx_empty_unicode = PyUnicode_FromStringAndSize("", 0); if (unlikely(!__pyx_mstate->__pyx_empty_unicode)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Library function declarations ---*/ + /*--- Initialize various global constants etc. ---*/ + if (__Pyx_InitConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + stringtab_initialized = 1; + if (__Pyx_InitGlobals() < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__pyx_module_is_main_app__core__tenancy) { + if (PyObject_SetAttr(__pyx_m, __pyx_mstate_global->__pyx_n_u_name, __pyx_mstate_global->__pyx_n_u_main) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + } + { + PyObject *modules = PyImport_GetModuleDict(); if (unlikely(!modules)) __PYX_ERR(0, 1, __pyx_L1_error) + if (!PyDict_GetItemString(modules, "app.core.tenancy")) { + if (unlikely((PyDict_SetItemString(modules, "app.core.tenancy", __pyx_m) < 0))) __PYX_ERR(0, 1, __pyx_L1_error) + } + } + /*--- Builtin init code ---*/ + if (__Pyx_InitCachedBuiltins(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Constants init code ---*/ + if (__Pyx_InitCachedConstants(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + if (__Pyx_CreateCodeObjects(__pyx_mstate) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + /*--- Global type/function init code ---*/ + (void)__Pyx_modinit_global_init_code(__pyx_mstate); + (void)__Pyx_modinit_variable_export_code(__pyx_mstate); + (void)__Pyx_modinit_function_export_code(__pyx_mstate); + (void)__Pyx_modinit_type_init_code(__pyx_mstate); + (void)__Pyx_modinit_type_import_code(__pyx_mstate); + (void)__Pyx_modinit_variable_import_code(__pyx_mstate); + (void)__Pyx_modinit_function_import_code(__pyx_mstate); + /*--- Execution code ---*/ + + /* "app/core/tenancy.py":18 + * """ + * + * from typing import Any, Dict # <<<<<<<<<<<<<< + * + * +*/ + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_Any,__pyx_mstate_global->__pyx_n_u_Dict}; + __pyx_t_1 = __Pyx_Import(__pyx_mstate_global->__pyx_n_u_typing, __pyx_imported_names, 2, NULL, 0); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 18, __pyx_L1_error) + } + __pyx_t_2 = __pyx_t_1; + __Pyx_GOTREF(__pyx_t_2); + { + PyObject* const __pyx_imported_names[] = {__pyx_mstate_global->__pyx_n_u_Any,__pyx_mstate_global->__pyx_n_u_Dict}; + for (__pyx_t_3=0; __pyx_t_3 < 2; __pyx_t_3++) { + __pyx_t_4 = __Pyx_ImportFrom(__pyx_t_2, __pyx_imported_names[__pyx_t_3]); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 18, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_imported_names[__pyx_t_3], __pyx_t_4) < (0)) __PYX_ERR(0, 18, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + } + } + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + + /* "app/core/tenancy.py":21 + * + * + * def evaluate_tenancy(org_id: Any, context: Dict[str, Any]) -> tuple[bool, str]: # <<<<<<<<<<<<<< + * resource_org_id = context.get("resource_org_id") + * +*/ + __pyx_t_2 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_org_id, __pyx_mstate_global->__pyx_n_u_Any) < (0)) __PYX_ERR(0, 21, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_context, __pyx_mstate_global->__pyx_kp_u_Dict_str_Any) < (0)) __PYX_ERR(0, 21, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_return, __pyx_mstate_global->__pyx_kp_u_tuple_bool_str) < (0)) __PYX_ERR(0, 21, __pyx_L1_error) + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_3app_4core_7tenancy_1evaluate_tenancy, 0, __pyx_mstate_global->__pyx_n_u_evaluate_tenancy, NULL, __pyx_mstate_global->__pyx_n_u_app_core_tenancy, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[0])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 + PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); + #endif + __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_2); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_evaluate_tenancy, __pyx_t_4) < (0)) __PYX_ERR(0, 21, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /* "app/core/tenancy.py":1 + * """PR12: organization-tenancy scoping. # <<<<<<<<<<<<<< + * + * Neither this service nor omnibioai-hpc-policy-engine had any concept of +*/ + __pyx_t_4 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + if (PyDict_SetItem(__pyx_mstate_global->__pyx_d, __pyx_mstate_global->__pyx_n_u_test, __pyx_t_4) < (0)) __PYX_ERR(0, 1, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + + /*--- Wrapped vars code ---*/ + + goto __pyx_L0; + __pyx_L1_error:; + __Pyx_XDECREF(__pyx_t_2); + __Pyx_XDECREF(__pyx_t_4); + if (__pyx_m) { + if (__pyx_mstate->__pyx_d && stringtab_initialized) { + __Pyx_AddTraceback("init app.core.tenancy", __pyx_clineno, __pyx_lineno, __pyx_filename); + } + #if !CYTHON_USE_MODULE_STATE + Py_CLEAR(__pyx_m); + #else + Py_DECREF(__pyx_m); + if (pystate_addmodule_run) { + PyObject *tp, *value, *tb; + PyErr_Fetch(&tp, &value, &tb); + PyState_RemoveModule(&__pyx_moduledef); + PyErr_Restore(tp, value, tb); + } + #endif + } else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_ImportError, "init app.core.tenancy"); + } + __pyx_L0:; + __Pyx_RefNannyFinishContext(); + #if CYTHON_PEP489_MULTI_PHASE_INIT + return (__pyx_m != NULL) ? 0 : -1; + #else + return __pyx_m; + #endif +} +/* #### Code section: pystring_table ### */ +/* #### Code section: cached_builtins ### */ + +static int __Pyx_InitCachedBuiltins(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + + /* Cached unbound methods */ + __pyx_mstate->__pyx_umethod_PyDict_Type_get.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_get.method_name = &__pyx_mstate->__pyx_n_u_get; + __pyx_mstate->__pyx_umethod_PyDict_Type_items.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_items.method_name = &__pyx_mstate->__pyx_n_u_items; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_pop.method_name = &__pyx_mstate->__pyx_n_u_pop; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.type = (PyObject*)&PyDict_Type; + __pyx_mstate->__pyx_umethod_PyDict_Type_values.method_name = &__pyx_mstate->__pyx_n_u_values; + return 0; +} +/* #### Code section: cached_constants ### */ + +static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { + __Pyx_RefNannyDeclarations + CYTHON_UNUSED_VAR(__pyx_mstate); + __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); + + /* "app/core/tenancy.py":25 + * + * if resource_org_id is None: + * return True, "no tenancy scoping required" # <<<<<<<<<<<<<< + * + * if org_id is None: +*/ + __pyx_mstate_global->__pyx_tuple[0] = PyTuple_Pack(2, Py_True, __pyx_mstate_global->__pyx_kp_u_no_tenancy_scoping_required); if (unlikely(!__pyx_mstate_global->__pyx_tuple[0])) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[0]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[0]); + + /* "app/core/tenancy.py":28 + * + * if org_id is None: + * return False, "missing organization context" # <<<<<<<<<<<<<< + * + * if str(org_id) != str(resource_org_id): +*/ + __pyx_mstate_global->__pyx_tuple[1] = PyTuple_Pack(2, Py_False, __pyx_mstate_global->__pyx_kp_u_missing_organization_context); if (unlikely(!__pyx_mstate_global->__pyx_tuple[1])) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[1]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[1]); + + /* "app/core/tenancy.py":31 + * + * if str(org_id) != str(resource_org_id): + * return False, "cross-tenant access denied" # <<<<<<<<<<<<<< + * + * return True, "tenancy check passed" +*/ + __pyx_mstate_global->__pyx_tuple[2] = PyTuple_Pack(2, Py_False, __pyx_mstate_global->__pyx_kp_u_cross_tenant_access_denied); if (unlikely(!__pyx_mstate_global->__pyx_tuple[2])) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[2]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[2]); + + /* "app/core/tenancy.py":33 + * return False, "cross-tenant access denied" + * + * return True, "tenancy check passed" # <<<<<<<<<<<<<< +*/ + __pyx_mstate_global->__pyx_tuple[3] = PyTuple_Pack(2, Py_True, __pyx_mstate_global->__pyx_kp_u_tenancy_check_passed); if (unlikely(!__pyx_mstate_global->__pyx_tuple[3])) __PYX_ERR(0, 33, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[3]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[3]); + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = __pyx_mstate->__pyx_tuple; + for (Py_ssize_t i=0; i<4; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #if PY_VERSION_HEX < 0x030E0000 + if (_Py_IsOwnedByCurrentThread(table[i]) && Py_REFCNT(table[i]) == 1) + #else + if (PyUnstable_Object_IsUniquelyReferenced(table[i])) + #endif + { + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + } + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + __Pyx_RefNannyFinishContext(); + return 0; + __pyx_L1_error:; + __Pyx_RefNannyFinishContext(); + return -1; +} +/* #### Code section: init_constants ### */ + +static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { + CYTHON_UNUSED_VAR(__pyx_mstate); + { + const struct { const unsigned int length: 8; } index[] = {{1},{14},{179},{1},{8},{19},{26},{28},{27},{20},{16},{3},{4},{20},{16},{18},{18},{7},{16},{8},{3},{13},{5},{8},{10},{8},{6},{3},{12},{15},{6},{12},{10},{8},{6},{6},{85}}; + #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (543 bytes) */ +const char* const cstring = "BZh91AY&SY\315\224\335\327\000\000&\177\373D\310\241\202`\217\215A\257!t\013\277\377\377\360@@@@@\000\000@@@@\000@\001\245 A\251\241\032\t\345\031M\224\365?P\232bi\246\215\001\240\301\250\323\322~\251\342\203@\215\t\244\332MOT\336\223S h\000\001\210hcB0\346\004\304\320a2d\311\221\204\3014\323#\023\000C\001\314\t\211\240\302d\311\223#\t\202i\246F&\000\206\n\364\013@\265\017\030\346%\033\372\273\016\230\242\364\237\217\006\360GO\273\223\3701\036\244m\212\235\310\201K:\202\252\272\304\236\030\027d\342u\345m\316>\313\013\311T\222\245\005\207V\231\032Zp\356\224\0361u\003\255\355hQ]\272`\231\321\242\033\265\t\014mx\377w\3273\201\270g\034\001\231O\205\024\3003\210&/\357_,\333\034!5Da\0134#;%\031\204\320\334\275]\370mh\215A\334\244\272\353\205\201)\2014\014\032\237>]\270\2173\000\210Fa\236C\243\033&Y\223\000!\246\207\261^\276\0321\231s\250\024\243\333uV\222\353\2622PL\301\"\246\2168\236\025\216\330\370\314A\267\030\313u\206\333\211\311\023G*\230\317q;\207\325\035\214\3525X\250\243\\\266KL#T\220\304\305&\313x]\364\rD*\375Yf\022\"\306\260\264\242\n~\031\202\225\214\024\024a\204\226\341\324 \370\316+\260\361\0332B\250t\032\351\241\3336\022\025\220\202\030\327\236\261\305~\360\310\2162\030\212\010\315\211\343e\017\252qD3\311\222\231\300\222\340\214/\231\223\257\221\300n\356\010.\362z\360+\352\302\246ng\\k\345\303/\225V\375A\300\317\014\305\342O\021a3k\355\010\013\177\356\220&\242\010\364Q\001\020\217$\331\350!\314\361\244\014/)\201\306\031o\260\316R\366\007\351\252\336&r\366\370\274\035\313\365\370\351k\254EoInI_#\332s\377\213\271\"\234(Hf\312n\353\200"; + PyObject *data = __Pyx_DecompressString(cstring, 543, 2); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (459 bytes) */ +const char* const cstring = "x\332MQ=o\0241\020\245\210\024$\nt\rTHsU\n\222MA\204R\201\020\037\022Mt \272(X^{\356\316\304ko<\343K6\025\345\226[^\231\237\301\317\2702%?\205\361fA\254\264\336\361\333yo\336\314T\037\234\341s\342t\010\357Bwq\026\031\201\327\232\341}\307\353\030\300\021X\364\256\306\244\031}\007\222)\004L%)\300\342\343\342\350\344\364\004t\260\220\360\007\032&\240\\\033\257\211\220 .\241\316\316\263\013\300]\213T\301\347%t1C@\264\300\021Z\311\373\237\300k\014@\310%\200\003\035Bd\315.\006%t\027V\007`]\222\"n\203\205\375I{\302\352\255\266VI\"\352\266=61\3411c\320\301tU\333\231\024\211\216\306;\2036\006\251\264\023\034\332\306\021\211\"\304\264\322\301\335\216U\300\304\300x\303!\302$\001db),\315]e)m\377\342f\215\346r\264/Xn=\236\3271\372\3032\236\013\231c\031\252R\213\356F\3361>\023\331\257\270\024\213U\261XM:\232\272`\\,X\3142&$\343\345TN:N\332`\255\315\345d\n7\332g\331\201\232\250J-s0J\255\220\225#\365O\30116\244T\243EC\236&\332\354\261DA7\362\225~\225\263ml\225\272\312\332?\200\t)\346dp\372\233\220s\022\266,bbId\305}\366\322\025#\225s\\H\361\204\264{\364b\373}\367\362\315/}\277\367lXm\277\335\315\356\346\277\367\366w\373\317\007\332\316\357\037?\3557\303\027\001~^\367f\230\225\373\365\240\313\235\372y\177:\274\032\314v\366\2207\342O\372\327\303\354\017,\330\001\254"; + PyObject *data = __Pyx_DecompressString(cstring, 459, 1); + if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) + const char* const bytes = __Pyx_PyBytes_AsString(data); + #if !CYTHON_ASSUME_SAFE_MACROS + if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } + #endif + #else /* compression: none (665 bytes) */ +const char* const bytes = ".Dict[str, Any]Note that Cython is deliberately stricter than PEP-484 and rejects subclasses of builtin types. If you need to pass subclasses then set the 'annotation_typing' directive to False.?add_noteapp/core/tenancy.pycross-tenant access deniedmissing organization contextno tenancy scoping requiredtenancy check passedtuple[bool, str]AnyDict__Pyx_PyDict_NextRefapp.core.tenancyasyncio.coroutinescline_in_tracebackcontextevaluate_tenancy__func__get_is_coroutineitems__main____module____name__org_idpop__qualname__resource_org_idreturn__set_name__setdefault__test__typingvalues\320\000\035\230^\320+>\270a\330\004\026\220g\230T\240\021\240!\340\004\007\320\007\027\220s\230!\330\010\017\210v\220Q\340\004\007\200w\210c\220\021\330\010\017\210w\220a\340\004\007\200s\210!\2108\2203\220c\230\021\230!\330\010\017\210w\220a\340\004\013\2106\220\021"; + PyObject *data = NULL; + CYTHON_UNUSED_VAR(__Pyx_DecompressString); + #endif + PyObject **stringtab = __pyx_mstate->__pyx_string_tab; + Py_ssize_t pos = 0; + for (int i = 0; i < 36; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); + if (likely(string) && i >= 11) PyUnicode_InternInPlace(&string); + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + stringtab[i] = string; + pos += bytes_length; + } + for (int i = 36; i < 37; i++) { + Py_ssize_t bytes_length = index[i].length; + PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); + stringtab[i] = string; + pos += bytes_length; + if (unlikely(!string)) { + Py_XDECREF(data); + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + Py_XDECREF(data); + for (Py_ssize_t i = 0; i < 37; i++) { + if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { + __PYX_ERR(0, 1, __pyx_L1_error) + } + } + #if CYTHON_IMMORTAL_CONSTANTS + { + PyObject **table = stringtab + 36; + for (Py_ssize_t i=0; i<1; ++i) { + #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + #if PY_VERSION_HEX < 0x030E0000 + if (_Py_IsOwnedByCurrentThread(table[i]) && Py_REFCNT(table[i]) == 1) + #else + if (PyUnstable_Object_IsUniquelyReferenced(table[i])) + #endif + { + Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL); + } + #else + Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT); + #endif + } + } + #endif + } + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: init_codeobjects ### */ +typedef struct { + unsigned int argcount : 2; + unsigned int num_posonly_args : 1; + unsigned int num_kwonly_args : 1; + unsigned int nlocals : 2; + unsigned int flags : 10; + unsigned int first_line : 5; +} __Pyx_PyCode_New_function_description; +/* NewCodeObj.proto */ +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +); + + +static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) { + PyObject* tuple_dedup_map = PyDict_New(); + if (unlikely(!tuple_dedup_map)) return -1; + { + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 21}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_org_id, __pyx_mstate->__pyx_n_u_context, __pyx_mstate->__pyx_n_u_resource_org_id}; + __pyx_mstate_global->__pyx_codeobj_tab[0] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_core_tenancy_py, __pyx_mstate->__pyx_n_u_evaluate_tenancy, __pyx_mstate->__pyx_kp_b_iso88591_a_gT_s_vQ_wc_wa_s_83c_wa_6, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[0])) goto bad; + } + Py_DECREF(tuple_dedup_map); + return 0; + bad: + Py_DECREF(tuple_dedup_map); + return -1; +} +/* #### Code section: init_globals ### */ + +static int __Pyx_InitGlobals(void) { + /* PythonCompatibility.init */ + if (likely(__Pyx_init_co_variables() == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CommonTypesMetaclass.init */ + if (likely(__pyx_CommonTypesMetaclass_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CachedMethodType.init */ + #if CYTHON_COMPILING_IN_LIMITED_API + { + PyObject *typesModule=NULL; + typesModule = PyImport_ImportModule("types"); + if (typesModule) { + __pyx_mstate_global->__Pyx_CachedMethodType = PyObject_GetAttrString(typesModule, "MethodType"); + Py_DECREF(typesModule); + } + } // error handling follows + #endif + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + /* CythonFunctionShared.init */ + if (likely(__pyx_CyFunction_init(__pyx_m) == 0)); else + + if (unlikely(PyErr_Occurred())) __PYX_ERR(0, 1, __pyx_L1_error) + + return 0; + __pyx_L1_error:; + return -1; +} +/* #### Code section: cleanup_globals ### */ +/* #### Code section: cleanup_module ### */ +/* #### Code section: main_method ### */ +/* #### Code section: utility_code_pragmas ### */ +#ifdef _MSC_VER +#pragma warning( push ) +/* Warning 4127: conditional expression is constant + * Cython uses constant conditional expressions to allow in inline functions to be optimized at + * compile-time, so this warning is not useful + */ +#pragma warning( disable : 4127 ) +#endif + + + +/* #### Code section: utility_code_def ### */ + +/* --- Runtime support code --- */ +/* Refnanny */ +#if CYTHON_REFNANNY +static __Pyx_RefNannyAPIStruct *__Pyx_RefNannyImportAPI(const char *modname) { + PyObject *m = NULL, *p = NULL; + void *r = NULL; + m = PyImport_ImportModule(modname); + if (!m) goto end; + p = PyObject_GetAttrString(m, "RefNannyAPI"); + if (!p) goto end; + r = PyLong_AsVoidPtr(p); +end: + Py_XDECREF(p); + Py_XDECREF(m); + return (__Pyx_RefNannyAPIStruct *)r; +} +#endif + +/* TupleAndListFromArray (used by fastcall) */ +#if !CYTHON_COMPILING_IN_CPYTHON && CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + Py_ssize_t i; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + for (i = 0; i < n; i++) { + Py_INCREF(src[i]); + if (unlikely(__Pyx_PyTuple_SET_ITEM(res, i, src[i]) < (0))) { + Py_DECREF(res); + return NULL; + } + } + return res; +} +#elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE void __Pyx_copy_object_array(PyObject *const *CYTHON_RESTRICT src, PyObject** CYTHON_RESTRICT dest, Py_ssize_t length) { + PyObject *v; + Py_ssize_t i; + for (i = 0; i < length; i++) { + v = dest[i] = src[i]; + Py_INCREF(v); + } +} +static CYTHON_INLINE PyObject * +__Pyx_PyTuple_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return __Pyx_NewRef(__pyx_mstate_global->__pyx_empty_tuple); + } + res = PyTuple_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyTupleObject*)res)->ob_item, n); + return res; +} +static CYTHON_INLINE PyObject * +__Pyx_PyList_FromArray(PyObject *const *src, Py_ssize_t n) +{ + PyObject *res; + if (n <= 0) { + return PyList_New(0); + } + res = PyList_New(n); + if (unlikely(res == NULL)) return NULL; + __Pyx_copy_object_array(src, ((PyListObject*)res)->ob_item, n); + return res; +} +#endif + +/* BytesEquals (used by UnicodeEquals) */ +static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL ||\ + !(CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) + return PyObject_RichCompareBool(s1, s2, equals); +#else + if (s1 == s2) { + return (equals == Py_EQ); + } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) { + const char *ps1, *ps2; + Py_ssize_t length = PyBytes_GET_SIZE(s1); + if (length != PyBytes_GET_SIZE(s2)) + return (equals == Py_NE); + ps1 = PyBytes_AS_STRING(s1); + ps2 = PyBytes_AS_STRING(s2); + if (ps1[0] != ps2[0]) { + return (equals == Py_NE); + } else if (length == 1) { + return (equals == Py_EQ); + } else { + int result; +#if CYTHON_USE_UNICODE_INTERNALS && (PY_VERSION_HEX < 0x030B0000) + Py_hash_t hash1, hash2; + hash1 = ((PyBytesObject*)s1)->ob_shash; + hash2 = ((PyBytesObject*)s2)->ob_shash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + return (equals == Py_NE); + } +#endif + result = memcmp(ps1, ps2, (size_t)length); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) { + return (equals == Py_NE); + } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) { + return (equals == Py_NE); + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +#endif +} + +/* UnicodeEquals (used by fastcall) */ +static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) { +#if CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_GRAAL + return PyObject_RichCompareBool(s1, s2, equals); +#else + int s1_is_unicode, s2_is_unicode; + if (s1 == s2) { + goto return_eq; + } + s1_is_unicode = PyUnicode_CheckExact(s1); + s2_is_unicode = PyUnicode_CheckExact(s2); + if (s1_is_unicode & s2_is_unicode) { + Py_ssize_t length, length2; + int kind; + void *data1, *data2; + #if !CYTHON_COMPILING_IN_LIMITED_API + if (unlikely(__Pyx_PyUnicode_READY(s1) < 0) || unlikely(__Pyx_PyUnicode_READY(s2) < 0)) + return -1; + #endif + length = __Pyx_PyUnicode_GET_LENGTH(s1); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length < 0)) return -1; + #endif + length2 = __Pyx_PyUnicode_GET_LENGTH(s2); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(length2 < 0)) return -1; + #endif + if (length != length2) { + goto return_ne; + } +#if CYTHON_USE_UNICODE_INTERNALS + { + Py_hash_t hash1, hash2; + hash1 = ((PyASCIIObject*)s1)->hash; + hash2 = ((PyASCIIObject*)s2)->hash; + if (hash1 != hash2 && hash1 != -1 && hash2 != -1) { + goto return_ne; + } + } +#endif + kind = __Pyx_PyUnicode_KIND(s1); + if (kind != __Pyx_PyUnicode_KIND(s2)) { + goto return_ne; + } + data1 = __Pyx_PyUnicode_DATA(s1); + data2 = __Pyx_PyUnicode_DATA(s2); + if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) { + goto return_ne; + } else if (length == 1) { + goto return_eq; + } else { + int result = memcmp(data1, data2, (size_t)(length * kind)); + return (equals == Py_EQ) ? (result == 0) : (result != 0); + } + } else if ((s1 == Py_None) & s2_is_unicode) { + goto return_ne; + } else if ((s2 == Py_None) & s1_is_unicode) { + goto return_ne; + } else { + int result; + PyObject* py_result = PyObject_RichCompare(s1, s2, equals); + if (!py_result) + return -1; + result = __Pyx_PyObject_IsTrue(py_result); + Py_DECREF(py_result); + return result; + } +return_eq: + return (equals == Py_EQ); +return_ne: + return (equals == Py_NE); +#endif +} + +/* fastcall */ +#if CYTHON_METH_FASTCALL +static CYTHON_INLINE PyObject * __Pyx_GetKwValue_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues, PyObject *s) +{ + Py_ssize_t i, n = __Pyx_PyTuple_GET_SIZE(kwnames); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(n == -1)) return NULL; + #endif + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + if (s == namei) return kwvalues[i]; + } + for (i = 0; i < n; i++) + { + PyObject *namei = __Pyx_PyTuple_GET_ITEM(kwnames, i); + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!namei)) return NULL; + #endif + int eq = __Pyx_PyUnicode_Equals(s, namei, Py_EQ); + if (unlikely(eq != 0)) { + if (unlikely(eq < 0)) return NULL; + return kwvalues[i]; + } + } + return NULL; +} +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030d0000 || CYTHON_COMPILING_IN_LIMITED_API +CYTHON_UNUSED static PyObject *__Pyx_KwargsAsDict_FASTCALL(PyObject *kwnames, PyObject *const *kwvalues) { + Py_ssize_t i, nkwargs; + PyObject *dict; +#if !CYTHON_ASSUME_SAFE_SIZE + nkwargs = PyTuple_Size(kwnames); + if (unlikely(nkwargs < 0)) return NULL; +#else + nkwargs = PyTuple_GET_SIZE(kwnames); +#endif + dict = PyDict_New(); + if (unlikely(!dict)) + return NULL; + for (i=0; itp_call; + if (unlikely(!call)) + return PyObject_Call(func, arg, kw); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = (*call)(func, arg, kw); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectCallMethO (used by PyObjectFastCall) */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallMethO(PyObject *func, PyObject *arg) { + PyObject *self, *result; + PyCFunction cfunc; + cfunc = __Pyx_CyOrPyCFunction_GET_FUNCTION(func); + self = __Pyx_CyOrPyCFunction_GET_SELF(func); + if (unlikely(Py_EnterRecursiveCall(" while calling a Python object"))) + return NULL; + result = cfunc(self, arg); + Py_LeaveRecursiveCall(); + if (unlikely(!result) && unlikely(!PyErr_Occurred())) { + PyErr_SetString( + PyExc_SystemError, + "NULL result without error in PyObject_Call"); + } + return result; +} +#endif + +/* PyObjectFastCall (used by PyObjectCallOneArg) */ +#if PY_VERSION_HEX < 0x03090000 || CYTHON_COMPILING_IN_LIMITED_API +static PyObject* __Pyx_PyObject_FastCall_fallback(PyObject *func, PyObject * const*args, size_t nargs, PyObject *kwargs) { + PyObject *argstuple; + PyObject *result = 0; + size_t i; + argstuple = PyTuple_New((Py_ssize_t)nargs); + if (unlikely(!argstuple)) return NULL; + for (i = 0; i < nargs; i++) { + Py_INCREF(args[i]); + if (__Pyx_PyTuple_SET_ITEM(argstuple, (Py_ssize_t)i, args[i]) != (0)) goto bad; + } + result = __Pyx_PyObject_Call(func, argstuple, kwargs); + bad: + Py_DECREF(argstuple); + return result; +} +#endif +#if CYTHON_VECTORCALL && !CYTHON_COMPILING_IN_LIMITED_API + #if PY_VERSION_HEX < 0x03090000 + #define __Pyx_PyVectorcall_Function(callable) _PyVectorcall_Function(callable) + #elif CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE vectorcallfunc __Pyx_PyVectorcall_Function(PyObject *callable) { + PyTypeObject *tp = Py_TYPE(callable); + #if defined(__Pyx_CyFunction_USED) + if (__Pyx_CyFunction_CheckExact(callable)) { + return __Pyx_CyFunction_func_vectorcall(callable); + } + #endif + if (!PyType_HasFeature(tp, Py_TPFLAGS_HAVE_VECTORCALL)) { + return NULL; + } + assert(PyCallable_Check(callable)); + Py_ssize_t offset = tp->tp_vectorcall_offset; + assert(offset > 0); + vectorcallfunc ptr; + memcpy(&ptr, (char *) callable + offset, sizeof(ptr)); + return ptr; +} + #else + #define __Pyx_PyVectorcall_Function(callable) PyVectorcall_Function(callable) + #endif +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_FastCallDict(PyObject *func, PyObject *const *args, size_t _nargs, PyObject *kwargs) { + Py_ssize_t nargs = __Pyx_PyVectorcall_NARGS(_nargs); +#if CYTHON_COMPILING_IN_CPYTHON + if (nargs == 0 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_NOARGS)) + return __Pyx_PyObject_CallMethO(func, NULL); + } + else if (nargs == 1 && kwargs == NULL) { + if (__Pyx_CyOrPyCFunction_Check(func) && likely( __Pyx_CyOrPyCFunction_GET_FLAGS(func) & METH_O)) + return __Pyx_PyObject_CallMethO(func, args[0]); + } +#endif + if (kwargs == NULL) { + #if CYTHON_VECTORCALL + #if CYTHON_COMPILING_IN_LIMITED_API + return PyObject_Vectorcall(func, args, _nargs, NULL); + #else + vectorcallfunc f = __Pyx_PyVectorcall_Function(func); + if (f) { + return f(func, args, _nargs, NULL); + } + #endif + #endif + } + if (nargs == 0) { + return __Pyx_PyObject_Call(func, __pyx_mstate_global->__pyx_empty_tuple, kwargs); + } + #if PY_VERSION_HEX >= 0x03090000 && !CYTHON_COMPILING_IN_LIMITED_API + return PyObject_VectorcallDict(func, args, (size_t)nargs, kwargs); + #else + return __Pyx_PyObject_FastCall_fallback(func, args, (size_t)nargs, kwargs); + #endif +} + +/* PyObjectCallOneArg (used by CallUnboundCMethod0) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_CallOneArg(PyObject *func, PyObject *arg) { + PyObject *args[2] = {NULL, arg}; + return __Pyx_PyObject_FastCall(func, args+1, 1 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* PyObjectGetAttrStr (used by UnpackUnboundCMethod) */ +#if CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStr(PyObject* obj, PyObject* attr_name) { + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro)) + return tp->tp_getattro(obj, attr_name); + return PyObject_GetAttr(obj, attr_name); +} +#endif + +/* UnpackUnboundCMethod (used by CallUnboundCMethod0) */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *args, PyObject *kwargs) { + PyObject *result; + PyObject *selfless_args = PyTuple_GetSlice(args, 1, PyTuple_Size(args)); + if (unlikely(!selfless_args)) return NULL; + result = PyObject_Call(method, selfless_args, kwargs); + Py_DECREF(selfless_args); + return result; +} +#elif CYTHON_COMPILING_IN_PYPY && PY_VERSION_HEX < 0x03090000 +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) { + return _PyObject_Vectorcall + (method, args ? args+1 : NULL, nargs ? nargs-1 : 0, kwnames); +} +#else +static PyObject *__Pyx_SelflessCall(PyObject *method, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { + return +#if PY_VERSION_HEX < 0x03090000 + _PyObject_Vectorcall +#else + PyObject_Vectorcall +#endif + (method, args ? args+1 : NULL, nargs ? (size_t) nargs-1 : 0, kwnames); +} +#endif +static PyMethodDef __Pyx_UnboundCMethod_Def = { + "CythonUnboundCMethod", + __PYX_REINTERPRET_FUNCION(PyCFunction, __Pyx_SelflessCall), +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030C0000 + METH_VARARGS | METH_KEYWORDS, +#else + METH_FASTCALL | METH_KEYWORDS, +#endif + NULL +}; +static int __Pyx_TryUnpackUnboundCMethod(__Pyx_CachedCFunction* target) { + PyObject *method, *result=NULL; + method = __Pyx_PyObject_GetAttrStr(target->type, *target->method_name); + if (unlikely(!method)) + return -1; + result = method; +#if CYTHON_COMPILING_IN_CPYTHON + if (likely(__Pyx_TypeCheck(method, &PyMethodDescr_Type))) + { + PyMethodDescrObject *descr = (PyMethodDescrObject*) method; + target->func = descr->d_method->ml_meth; + target->flag = descr->d_method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST | METH_STACKLESS); + } else +#endif +#if CYTHON_COMPILING_IN_PYPY +#else + if (PyCFunction_Check(method)) +#endif + { + PyObject *self; + int self_found; +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + self = PyObject_GetAttrString(method, "__self__"); + if (!self) { + PyErr_Clear(); + } +#else + self = PyCFunction_GET_SELF(method); +#endif + self_found = (self && self != Py_None); +#if CYTHON_COMPILING_IN_LIMITED_API || CYTHON_COMPILING_IN_PYPY + Py_XDECREF(self); +#endif + if (self_found) { + PyObject *unbound_method = PyCFunction_New(&__Pyx_UnboundCMethod_Def, method); + if (unlikely(!unbound_method)) return -1; + Py_DECREF(method); + result = unbound_method; + } + } +#if !CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + if (unlikely(target->method)) { + Py_DECREF(result); + } else +#endif + target->method = result; + return 0; +} + +/* CallUnboundCMethod0 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + if (likely(cfunc->flag == METH_NOARGS)) + return __Pyx_CallCFunction(cfunc, self, NULL); + if (likely(cfunc->flag == METH_FASTCALL)) + return __Pyx_CallCFunctionFast(cfunc, self, NULL, 0); + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, NULL, 0, NULL); + if (likely(cfunc->flag == (METH_VARARGS | METH_KEYWORDS))) + return __Pyx_CallCFunctionWithKeywords(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple, NULL); + if (cfunc->flag == METH_VARARGS) + return __Pyx_CallCFunction(cfunc, self, __pyx_mstate_global->__pyx_empty_tuple); + return __Pyx__CallUnboundCMethod0(cfunc, self); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod0(&tmp_cfunc, self); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod0(cfunc, self); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod0(__Pyx_CachedCFunction* cfunc, PyObject* self) { + PyObject *result; + if (unlikely(!cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; + result = __Pyx_PyObject_CallOneArg(cfunc->method, self); + return result; +} + +/* py_dict_items (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Items(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_items, d); +} + +/* py_dict_values (used by OwnedDictNext) */ +static CYTHON_INLINE PyObject* __Pyx_PyDict_Values(PyObject* d) { + return __Pyx_CallUnboundCMethod0(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_values, d); +} + +/* OwnedDictNext (used by ParseKeywordsImpl) */ +#if CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, PyObject **ppos, PyObject **pkey, PyObject **pvalue) { + PyObject *next = NULL; + if (!*ppos) { + if (pvalue) { + PyObject *dictview = pkey ? __Pyx_PyDict_Items(p) : __Pyx_PyDict_Values(p); + if (unlikely(!dictview)) goto bad; + *ppos = PyObject_GetIter(dictview); + Py_DECREF(dictview); + } else { + *ppos = PyObject_GetIter(p); + } + if (unlikely(!*ppos)) goto bad; + } + next = PyIter_Next(*ppos); + if (!next) { + if (PyErr_Occurred()) goto bad; + return 0; + } + if (pkey && pvalue) { + *pkey = __Pyx_PySequence_ITEM(next, 0); + if (unlikely(*pkey)) goto bad; + *pvalue = __Pyx_PySequence_ITEM(next, 1); + if (unlikely(*pvalue)) goto bad; + Py_DECREF(next); + } else if (pkey) { + *pkey = next; + } else { + assert(pvalue); + *pvalue = next; + } + return 1; + bad: + Py_XDECREF(next); +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 + PyErr_FormatUnraisable("Exception ignored in __Pyx_PyDict_NextRef"); +#else + PyErr_WriteUnraisable(__pyx_mstate_global->__pyx_n_u_Pyx_PyDict_NextRef); +#endif + if (pkey) *pkey = NULL; + if (pvalue) *pvalue = NULL; + return 0; +} +#else // !CYTHON_AVOID_BORROWED_REFS +static int __Pyx_PyDict_NextRef(PyObject *p, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue) { + int result = PyDict_Next(p, ppos, pkey, pvalue); + if (likely(result == 1)) { + if (pkey) Py_INCREF(*pkey); + if (pvalue) Py_INCREF(*pvalue); + } + return result; +} +#endif + +/* RaiseDoubleKeywords (used by ParseKeywordsImpl) */ +static void __Pyx_RaiseDoubleKeywordsError( + const char* func_name, + PyObject* kw_name) +{ + PyErr_Format(PyExc_TypeError, + "%s() got multiple values for keyword argument '%U'", func_name, kw_name); +} + +/* CallUnboundCMethod2 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject *__Pyx_CallUnboundCMethod2(__Pyx_CachedCFunction *cfunc, PyObject *self, PyObject *arg1, PyObject *arg2) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + PyObject *args[2] = {arg1, arg2}; + if (cfunc->flag == METH_FASTCALL) { + return __Pyx_CallCFunctionFast(cfunc, self, args, 2); + } + if (cfunc->flag == (METH_FASTCALL | METH_KEYWORDS)) + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, args, 2, NULL); + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod2(&tmp_cfunc, self, arg1, arg2); + } +#endif + PyObject *result = __Pyx__CallUnboundCMethod2(cfunc, self, arg1, arg2); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod2(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg1, PyObject* arg2){ + if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_COMPILING_IN_CPYTHON + if (cfunc->func && (cfunc->flag & METH_VARARGS)) { + PyObject *result = NULL; + PyObject *args = PyTuple_New(2); + if (unlikely(!args)) return NULL; + Py_INCREF(arg1); + PyTuple_SET_ITEM(args, 0, arg1); + Py_INCREF(arg2); + PyTuple_SET_ITEM(args, 1, arg2); + if (cfunc->flag & METH_KEYWORDS) + result = __Pyx_CallCFunctionWithKeywords(cfunc, self, args, NULL); + else + result = __Pyx_CallCFunction(cfunc, self, args); + Py_DECREF(args); + return result; + } +#endif + { + PyObject *args[4] = {NULL, self, arg1, arg2}; + return __Pyx_PyObject_FastCall(cfunc->method, args+1, 3 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); + } +} + +/* ParseKeywordsImpl (used by ParseKeywords) */ +static int __Pyx_ValidateDuplicatePosArgs( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char* function_name) +{ + PyObject ** const *name = argnames; + while (name != first_kw_arg) { + PyObject *key = **name; + int found = PyDict_Contains(kwds, key); + if (unlikely(found)) { + if (found == 1) __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; + } + name++; + } + return 0; +bad: + return -1; +} +#if CYTHON_USE_UNICODE_INTERNALS +static CYTHON_INLINE int __Pyx_UnicodeKeywordsEqual(PyObject *s1, PyObject *s2) { + int kind; + Py_ssize_t len = PyUnicode_GET_LENGTH(s1); + if (len != PyUnicode_GET_LENGTH(s2)) return 0; + kind = PyUnicode_KIND(s1); + if (kind != PyUnicode_KIND(s2)) return 0; + const void *data1 = PyUnicode_DATA(s1); + const void *data2 = PyUnicode_DATA(s2); + return (memcmp(data1, data2, (size_t) len * (size_t) kind) == 0); +} +#endif +static int __Pyx_MatchKeywordArg_str( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + #if CYTHON_USE_UNICODE_INTERNALS + Py_hash_t key_hash = ((PyASCIIObject*)key)->hash; + if (unlikely(key_hash == -1)) { + key_hash = PyObject_Hash(key); + if (unlikely(key_hash == -1)) + goto bad; + } + #endif + name = first_kw_arg; + while (*name) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (key_hash == ((PyASCIIObject*)name_str)->hash && __Pyx_UnicodeKeywordsEqual(name_str, key)) { + *index_found = (size_t) (name - argnames); + return 1; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) { + *index_found = (size_t) (name - argnames); + return 1; + } + } + #endif + name++; + } + name = argnames; + while (name != first_kw_arg) { + PyObject *name_str = **name; + #if CYTHON_USE_UNICODE_INTERNALS + if (unlikely(key_hash == ((PyASCIIObject*)name_str)->hash)) { + if (__Pyx_UnicodeKeywordsEqual(name_str, key)) + goto arg_passed_twice; + } + #else + #if CYTHON_ASSUME_SAFE_SIZE + if (PyUnicode_GET_LENGTH(name_str) == PyUnicode_GET_LENGTH(key)) + #endif + { + if (unlikely(name_str == key)) goto arg_passed_twice; + int cmp = PyUnicode_Compare(name_str, key); + if (cmp < 0 && unlikely(PyErr_Occurred())) goto bad; + if (cmp == 0) goto arg_passed_twice; + } + #endif + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +bad: + return -1; +} +static int __Pyx_MatchKeywordArg_nostr( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + PyObject ** const *name; + if (unlikely(!PyUnicode_Check(key))) goto invalid_keyword_type; + name = first_kw_arg; + while (*name) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (cmp == 1) { + *index_found = (size_t) (name - argnames); + return 1; + } + if (unlikely(cmp == -1)) goto bad; + name++; + } + name = argnames; + while (name != first_kw_arg) { + int cmp = PyObject_RichCompareBool(**name, key, Py_EQ); + if (unlikely(cmp != 0)) { + if (cmp == 1) goto arg_passed_twice; + else goto bad; + } + name++; + } + return 0; +arg_passed_twice: + __Pyx_RaiseDoubleKeywordsError(function_name, key); + goto bad; +invalid_keyword_type: + PyErr_Format(PyExc_TypeError, + "%.200s() keywords must be strings", function_name); + goto bad; +bad: + return -1; +} +static CYTHON_INLINE int __Pyx_MatchKeywordArg( + PyObject *key, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + size_t *index_found, + const char *function_name) +{ + return likely(PyUnicode_CheckExact(key)) ? + __Pyx_MatchKeywordArg_str(key, argnames, first_kw_arg, index_found, function_name) : + __Pyx_MatchKeywordArg_nostr(key, argnames, first_kw_arg, index_found, function_name); +} +static void __Pyx_RejectUnknownKeyword( + PyObject *kwds, + PyObject ** const argnames[], + PyObject ** const *first_kw_arg, + const char *function_name) +{ + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos = NULL; + #else + Py_ssize_t pos = 0; + #endif + PyObject *key = NULL; + __Pyx_BEGIN_CRITICAL_SECTION(kwds); + while ( + #if CYTHON_AVOID_BORROWED_REFS + __Pyx_PyDict_NextRef(kwds, &pos, &key, NULL) + #else + PyDict_Next(kwds, &pos, &key, NULL) + #endif + ) { + PyObject** const *name = first_kw_arg; + while (*name && (**name != key)) name++; + if (!*name) { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp != 1) { + if (cmp == 0) { + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + break; + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + #endif + } + __Pyx_END_CRITICAL_SECTION(); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(pos); + #endif + assert(PyErr_Occurred()); +} +static int __Pyx_ParseKeywordDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t extracted = 0; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + name = first_kw_arg; + while (*name && num_kwargs > extracted) { + PyObject * key = **name; + PyObject *value; + int found = 0; + #if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + found = PyDict_GetItemRef(kwds, key, &value); + #else + value = PyDict_GetItemWithError(kwds, key); + if (value) { + Py_INCREF(value); + found = 1; + } else { + if (unlikely(PyErr_Occurred())) goto bad; + } + #endif + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + extracted++; + } + name++; + } + if (num_kwargs > extracted) { + if (ignore_unknown_kwargs) { + if (unlikely(__Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name) == -1)) + goto bad; + } else { + __Pyx_RejectUnknownKeyword(kwds, argnames, first_kw_arg, function_name); + goto bad; + } + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordDictToDict( + PyObject *kwds, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + const char* function_name) +{ + PyObject** const *name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + Py_ssize_t len; +#if !CYTHON_COMPILING_IN_PYPY || defined(PyArg_ValidateKeywordArguments) + if (unlikely(!PyArg_ValidateKeywordArguments(kwds))) return -1; +#endif + if (PyDict_Update(kwds2, kwds) < 0) goto bad; + name = first_kw_arg; + while (*name) { + PyObject *key = **name; + PyObject *value; +#if !CYTHON_COMPILING_IN_LIMITED_API && (PY_VERSION_HEX >= 0x030d00A2 || defined(PyDict_Pop)) + int found = PyDict_Pop(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + int found = PyDict_GetItemRef(kwds2, key, &value); + if (found) { + if (unlikely(found < 0)) goto bad; + values[name-argnames] = value; + if (unlikely(PyDict_DelItem(kwds2, key) < 0)) goto bad; + } +#else + #if CYTHON_COMPILING_IN_CPYTHON + value = _PyDict_Pop(kwds2, key, kwds2); + #else + value = __Pyx_CallUnboundCMethod2(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_pop, kwds2, key, kwds2); + #endif + if (value == kwds2) { + Py_DECREF(value); + } else { + if (unlikely(!value)) goto bad; + values[name-argnames] = value; + } +#endif + name++; + } + len = PyDict_Size(kwds2); + if (len > 0) { + return __Pyx_ValidateDuplicatePosArgs(kwds, argnames, first_kw_arg, function_name); + } else if (unlikely(len == -1)) { + goto bad; + } + return 0; +bad: + return -1; +} +static int __Pyx_ParseKeywordsTuple( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + PyObject *key = NULL; + PyObject** const * name; + PyObject** const *first_kw_arg = argnames + num_pos_args; + for (Py_ssize_t pos = 0; pos < num_kwargs; pos++) { +#if CYTHON_AVOID_BORROWED_REFS + key = __Pyx_PySequence_ITEM(kwds, pos); +#else + key = __Pyx_PyTuple_GET_ITEM(kwds, pos); +#endif +#if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(!key)) goto bad; +#endif + name = first_kw_arg; + while (*name && (**name != key)) name++; + if (*name) { + PyObject *value = kwvalues[pos]; + values[name-argnames] = __Pyx_NewRef(value); + } else { + size_t index_found = 0; + int cmp = __Pyx_MatchKeywordArg(key, argnames, first_kw_arg, &index_found, function_name); + if (cmp == 1) { + PyObject *value = kwvalues[pos]; + values[index_found] = __Pyx_NewRef(value); + } else { + if (unlikely(cmp == -1)) goto bad; + if (kwds2) { + PyObject *value = kwvalues[pos]; + if (unlikely(PyDict_SetItem(kwds2, key, value))) goto bad; + } else if (!ignore_unknown_kwargs) { + goto invalid_keyword; + } + } + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(key); + key = NULL; + #endif + } + return 0; +invalid_keyword: + PyErr_Format(PyExc_TypeError, + "%s() got an unexpected keyword argument '%U'", + function_name, key); + goto bad; +bad: + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(key); + #endif + return -1; +} + +/* ParseKeywords */ +static int __Pyx_ParseKeywords( + PyObject *kwds, + PyObject * const *kwvalues, + PyObject ** const argnames[], + PyObject *kwds2, + PyObject *values[], + Py_ssize_t num_pos_args, + Py_ssize_t num_kwargs, + const char* function_name, + int ignore_unknown_kwargs) +{ + if (CYTHON_METH_FASTCALL && likely(PyTuple_Check(kwds))) + return __Pyx_ParseKeywordsTuple(kwds, kwvalues, argnames, kwds2, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); + else if (kwds2) + return __Pyx_ParseKeywordDictToDict(kwds, argnames, kwds2, values, num_pos_args, function_name); + else + return __Pyx_ParseKeywordDict(kwds, argnames, values, num_pos_args, num_kwargs, function_name, ignore_unknown_kwargs); +} + +/* RaiseArgTupleInvalid */ +static void __Pyx_RaiseArgtupleInvalid( + const char* func_name, + int exact, + Py_ssize_t num_min, + Py_ssize_t num_max, + Py_ssize_t num_found) +{ + Py_ssize_t num_expected; + const char *more_or_less; + if (num_found < num_min) { + num_expected = num_min; + more_or_less = "at least"; + } else { + num_expected = num_max; + more_or_less = "at most"; + } + if (exact) { + more_or_less = "exactly"; + } + PyErr_Format(PyExc_TypeError, + "%.200s() takes %.8s %" CYTHON_FORMAT_SSIZE_T "d positional argument%.1s (%" CYTHON_FORMAT_SSIZE_T "d given)", + func_name, more_or_less, num_expected, + (num_expected == 1) ? "" : "s", num_found); +} + +/* ArgTypeTestFunc (used by ArgTypeTest) */ +static int __Pyx__ArgTypeTest(PyObject *obj, PyTypeObject *type, const char *name, int exact) +{ + __Pyx_TypeName type_name; + __Pyx_TypeName obj_type_name; + PyObject *extra_info = __pyx_mstate_global->__pyx_empty_unicode; + int from_annotation_subclass = 0; + if (unlikely(!type)) { + PyErr_SetString(PyExc_SystemError, "Missing type object"); + return 0; + } + else if (!exact) { + if (likely(__Pyx_TypeCheck(obj, type))) return 1; + } else if (exact == 2) { + if (__Pyx_TypeCheck(obj, type)) { + from_annotation_subclass = 1; + extra_info = __pyx_mstate_global->__pyx_kp_u_Note_that_Cython_is_deliberately; + } + } + type_name = __Pyx_PyType_GetFullyQualifiedName(type); + obj_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(obj)); + PyErr_Format(PyExc_TypeError, + "Argument '%.200s' has incorrect type (expected " __Pyx_FMT_TYPENAME + ", got " __Pyx_FMT_TYPENAME ")" +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 + "%s%U" +#endif + , name, type_name, obj_type_name +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 + , (from_annotation_subclass ? ". " : ""), extra_info +#endif + ); +#if __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + if (exact == 2 && from_annotation_subclass) { + PyObject *res; + PyObject *vargs[2]; + vargs[0] = PyErr_GetRaisedException(); + vargs[1] = extra_info; + res = PyObject_VectorcallMethod(__pyx_mstate_global->__pyx_kp_u_add_note, vargs, 2, NULL); + Py_XDECREF(res); + PyErr_SetRaisedException(vargs[0]); + } +#endif + __Pyx_DECREF_TypeName(type_name); + __Pyx_DECREF_TypeName(obj_type_name); + return 0; +} + +/* PyObjectCall2Args (used by CallUnboundCMethod1) */ +static CYTHON_INLINE PyObject* __Pyx_PyObject_Call2Args(PyObject* function, PyObject* arg1, PyObject* arg2) { + PyObject *args[3] = {NULL, arg1, arg2}; + return __Pyx_PyObject_FastCall(function, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET); +} + +/* CallUnboundCMethod1 */ +#if CYTHON_COMPILING_IN_CPYTHON +static CYTHON_INLINE PyObject* __Pyx_CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg) { + int was_initialized = __Pyx_CachedCFunction_GetAndSetInitializing(cfunc); + if (likely(was_initialized == 2 && cfunc->func)) { + int flag = cfunc->flag; + if (flag == METH_O) { + return __Pyx_CallCFunction(cfunc, self, arg); + } else if (flag == METH_FASTCALL) { + return __Pyx_CallCFunctionFast(cfunc, self, &arg, 1); + } else if (flag == (METH_FASTCALL | METH_KEYWORDS)) { + return __Pyx_CallCFunctionFastWithKeywords(cfunc, self, &arg, 1, NULL); + } + } +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + else if (unlikely(was_initialized == 1)) { + __Pyx_CachedCFunction tmp_cfunc = { +#ifndef __cplusplus + 0 +#endif + }; + tmp_cfunc.type = cfunc->type; + tmp_cfunc.method_name = cfunc->method_name; + return __Pyx__CallUnboundCMethod1(&tmp_cfunc, self, arg); + } +#endif + PyObject* result = __Pyx__CallUnboundCMethod1(cfunc, self, arg); + __Pyx_CachedCFunction_SetFinishedInitializing(cfunc); + return result; +} +#endif +static PyObject* __Pyx__CallUnboundCMethod1(__Pyx_CachedCFunction* cfunc, PyObject* self, PyObject* arg){ + PyObject *result = NULL; + if (unlikely(!cfunc->func && !cfunc->method) && unlikely(__Pyx_TryUnpackUnboundCMethod(cfunc) < 0)) return NULL; +#if CYTHON_COMPILING_IN_CPYTHON + if (cfunc->func && (cfunc->flag & METH_VARARGS)) { + PyObject *args = PyTuple_New(1); + if (unlikely(!args)) return NULL; + Py_INCREF(arg); + PyTuple_SET_ITEM(args, 0, arg); + if (cfunc->flag & METH_KEYWORDS) + result = __Pyx_CallCFunctionWithKeywords(cfunc, self, args, NULL); + else + result = __Pyx_CallCFunction(cfunc, self, args); + Py_DECREF(args); + } else +#endif + { + result = __Pyx_PyObject_Call2Args(cfunc->method, self, arg); + } + return result; +} + +/* dict_getitem_default */ +static PyObject* __Pyx_PyDict_GetItemDefault(PyObject* d, PyObject* key, PyObject* default_value) { + PyObject* value; +#if !CYTHON_COMPILING_IN_PYPY || PYPY_VERSION_NUM >= 0x07020000 + value = PyDict_GetItemWithError(d, key); + if (unlikely(!value)) { + if (unlikely(PyErr_Occurred())) + return NULL; + value = default_value; + } + Py_INCREF(value); + if ((1)); +#else + if (PyBytes_CheckExact(key) || PyUnicode_CheckExact(key) || PyLong_CheckExact(key)) { + value = PyDict_GetItem(d, key); + if (unlikely(!value)) { + value = default_value; + } + Py_INCREF(value); + } +#endif + else { + if (default_value == Py_None) + value = __Pyx_CallUnboundCMethod1(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_get, d, key); + else + value = __Pyx_CallUnboundCMethod2(&__pyx_mstate_global->__pyx_umethod_PyDict_Type_get, d, key, default_value); + } + return value; +} + +/* PyErrExceptionMatches (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static int __Pyx_PyErr_ExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(tuple); + for (i=0; i= 0x030C00A6 + PyObject *current_exception = tstate->current_exception; + if (unlikely(!current_exception)) return 0; + exc_type = (PyObject*) Py_TYPE(current_exception); + if (exc_type == err) return 1; +#else + exc_type = tstate->curexc_type; + if (exc_type == err) return 1; + if (unlikely(!exc_type)) return 0; +#endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(exc_type); + #endif + if (unlikely(PyTuple_Check(err))) { + result = __Pyx_PyErr_ExceptionMatchesTuple(exc_type, err); + } else { + result = __Pyx_PyErr_GivenExceptionMatches(exc_type, err); + } + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(exc_type); + #endif + return result; +} +#endif + +/* PyErrFetchRestore (used by PyObjectGetAttrStrNoError) */ +#if CYTHON_FAST_THREAD_STATE +static CYTHON_INLINE void __Pyx_ErrRestoreInState(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject *tmp_value; + assert(type == NULL || (value != NULL && type == (PyObject*) Py_TYPE(value))); + if (value) { + #if CYTHON_COMPILING_IN_CPYTHON + if (unlikely(((PyBaseExceptionObject*) value)->traceback != tb)) + #endif + PyException_SetTraceback(value, tb); + } + tmp_value = tstate->current_exception; + tstate->current_exception = value; + Py_XDECREF(tmp_value); + Py_XDECREF(type); + Py_XDECREF(tb); +#else + PyObject *tmp_type, *tmp_value, *tmp_tb; + tmp_type = tstate->curexc_type; + tmp_value = tstate->curexc_value; + tmp_tb = tstate->curexc_traceback; + tstate->curexc_type = type; + tstate->curexc_value = value; + tstate->curexc_traceback = tb; + Py_XDECREF(tmp_type); + Py_XDECREF(tmp_value); + Py_XDECREF(tmp_tb); +#endif +} +static CYTHON_INLINE void __Pyx_ErrFetchInState(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { +#if PY_VERSION_HEX >= 0x030C00A6 + PyObject* exc_value; + exc_value = tstate->current_exception; + tstate->current_exception = 0; + *value = exc_value; + *type = NULL; + *tb = NULL; + if (exc_value) { + *type = (PyObject*) Py_TYPE(exc_value); + Py_INCREF(*type); + #if CYTHON_COMPILING_IN_CPYTHON + *tb = ((PyBaseExceptionObject*) exc_value)->traceback; + Py_XINCREF(*tb); + #else + *tb = PyException_GetTraceback(exc_value); + #endif + } +#else + *type = tstate->curexc_type; + *value = tstate->curexc_value; + *tb = tstate->curexc_traceback; + tstate->curexc_type = 0; + tstate->curexc_value = 0; + tstate->curexc_traceback = 0; +#endif +} +#endif + +/* PyObjectGetAttrStrNoError (used by HasAttr) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static void __Pyx_PyObject_GetAttrStr_ClearAttributeError(void) { + __Pyx_PyThreadState_declare + __Pyx_PyThreadState_assign + if (likely(__Pyx_PyErr_ExceptionMatches(PyExc_AttributeError))) + __Pyx_PyErr_Clear(); +} +#endif +static CYTHON_INLINE PyObject* __Pyx_PyObject_GetAttrStrNoError(PyObject* obj, PyObject* attr_name) { + PyObject *result; +#if __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + (void) PyObject_GetOptionalAttr(obj, attr_name, &result); + return result; +#else +#if CYTHON_COMPILING_IN_CPYTHON && CYTHON_USE_TYPE_SLOTS + PyTypeObject* tp = Py_TYPE(obj); + if (likely(tp->tp_getattro == PyObject_GenericGetAttr)) { + return _PyObject_GenericGetAttrWithDict(obj, attr_name, NULL, 1); + } +#endif + result = __Pyx_PyObject_GetAttrStr(obj, attr_name); + if (unlikely(!result)) { + __Pyx_PyObject_GetAttrStr_ClearAttributeError(); + } + return result; +#endif +} + +/* HasAttr (used by ImportImpl) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static CYTHON_INLINE int __Pyx_HasAttr(PyObject *o, PyObject *n) { + PyObject *r; + if (unlikely(!PyUnicode_Check(n))) { + PyErr_SetString(PyExc_TypeError, + "hasattr(): attribute name must be string"); + return -1; + } + r = __Pyx_PyObject_GetAttrStrNoError(o, n); + if (!r) { + return (unlikely(PyErr_Occurred())) ? -1 : 0; + } else { + Py_DECREF(r); + return 1; + } +} +#endif + +/* ImportImpl (used by Import) */ +static int __Pyx__Import_GetModule(PyObject *qualname, PyObject **module) { + PyObject *imported_module = PyImport_GetModule(qualname); + if (unlikely(!imported_module)) { + *module = NULL; + if (PyErr_Occurred()) { + return -1; + } + return 0; + } + *module = imported_module; + return 1; +} +static int __Pyx__Import_Lookup(PyObject *qualname, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject **module) { + PyObject *imported_module; + PyObject *top_level_package_name; + Py_ssize_t i; + int status, module_found; + Py_ssize_t dot_index; + module_found = __Pyx__Import_GetModule(qualname, &imported_module); + if (unlikely(!module_found || module_found == -1)) { + *module = NULL; + return module_found; + } + if (imported_names) { + for (i = 0; i < len_imported_names; i++) { + PyObject *imported_name = imported_names[i]; +#if __PYX_LIMITED_VERSION_HEX < 0x030d0000 + int has_imported_attribute = PyObject_HasAttr(imported_module, imported_name); +#else + int has_imported_attribute = PyObject_HasAttrWithError(imported_module, imported_name); + if (unlikely(has_imported_attribute == -1)) goto error; +#endif + if (!has_imported_attribute) { + goto not_found; + } + } + *module = imported_module; + return 1; + } + dot_index = PyUnicode_FindChar(qualname, '.', 0, PY_SSIZE_T_MAX, 1); + if (dot_index == -1) { + *module = imported_module; + return 1; + } + if (unlikely(dot_index == -2)) goto error; + top_level_package_name = PyUnicode_Substring(qualname, 0, dot_index); + if (unlikely(!top_level_package_name)) goto error; + Py_DECREF(imported_module); + status = __Pyx__Import_GetModule(top_level_package_name, module); + Py_DECREF(top_level_package_name); + return status; +error: + Py_DECREF(imported_module); + *module = NULL; + return -1; +not_found: + Py_DECREF(imported_module); + *module = NULL; + return 0; +} +static PyObject *__Pyx__Import(PyObject *name, PyObject *const *imported_names, Py_ssize_t len_imported_names, PyObject *qualname, PyObject *moddict, int level) { + PyObject *module = 0; + PyObject *empty_dict = 0; + PyObject *from_list = 0; + int module_found; + if (!qualname) { + qualname = name; + } + module_found = __Pyx__Import_Lookup(qualname, imported_names, len_imported_names, &module); + if (likely(module_found == 1)) { + return module; + } else if (unlikely(module_found == -1)) { + return NULL; + } + empty_dict = PyDict_New(); + if (unlikely(!empty_dict)) + goto bad; + if (imported_names) { +#if CYTHON_COMPILING_IN_CPYTHON + from_list = __Pyx_PyList_FromArray(imported_names, len_imported_names); + if (unlikely(!from_list)) + goto bad; +#else + from_list = PyList_New(len_imported_names); + if (unlikely(!from_list)) goto bad; + for (Py_ssize_t i=0; i__pyx_d, level); +} + +/* ImportFrom */ +static PyObject* __Pyx_ImportFrom(PyObject* module, PyObject* name) { + PyObject* value = __Pyx_PyObject_GetAttrStr(module, name); + if (unlikely(!value) && PyErr_ExceptionMatches(PyExc_AttributeError)) { + const char* module_name_str = 0; + PyObject* module_name = 0; + PyObject* module_dot = 0; + PyObject* full_name = 0; + PyErr_Clear(); + module_name_str = PyModule_GetName(module); + if (unlikely(!module_name_str)) { goto modbad; } + module_name = PyUnicode_FromString(module_name_str); + if (unlikely(!module_name)) { goto modbad; } + module_dot = PyUnicode_Concat(module_name, __pyx_mstate_global->__pyx_kp_u_); + if (unlikely(!module_dot)) { goto modbad; } + full_name = PyUnicode_Concat(module_dot, name); + if (unlikely(!full_name)) { goto modbad; } + #if (CYTHON_COMPILING_IN_PYPY && PYPY_VERSION_NUM < 0x07030400) ||\ + CYTHON_COMPILING_IN_GRAAL + { + PyObject *modules = PyImport_GetModuleDict(); + if (unlikely(!modules)) + goto modbad; + value = PyObject_GetItem(modules, full_name); + } + #else + value = PyImport_GetModule(full_name); + #endif + modbad: + Py_XDECREF(full_name); + Py_XDECREF(module_dot); + Py_XDECREF(module_name); + } + if (unlikely(!value)) { + PyErr_Format(PyExc_ImportError, "cannot import name %S", name); + } + return value; +} + +/* dict_setdefault (used by FetchCommonType) */ +static CYTHON_INLINE PyObject *__Pyx_PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *default_value) { + PyObject* value; +#if __PYX_LIMITED_VERSION_HEX >= 0x030F0000 || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4) + PyDict_SetDefaultRef(d, key, default_value, &value); +#elif CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + PyObject *args[] = {d, key, default_value}; + value = PyObject_VectorcallMethod(__pyx_mstate_global->__pyx_n_u_setdefault, args, 3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); +#elif CYTHON_COMPILING_IN_LIMITED_API + value = PyObject_CallMethodObjArgs(d, __pyx_mstate_global->__pyx_n_u_setdefault, key, default_value, NULL); +#else + value = PyDict_SetDefault(d, key, default_value); + if (unlikely(!value)) return NULL; + Py_INCREF(value); +#endif + return value; +} + +/* LimitedApiGetTypeDict (used by SetItemOnTypeDict) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static Py_ssize_t __Pyx_GetTypeDictOffset(void) { + PyObject *tp_dictoffset_o; + Py_ssize_t tp_dictoffset; + tp_dictoffset_o = PyObject_GetAttrString((PyObject*)(&PyType_Type), "__dictoffset__"); + if (unlikely(!tp_dictoffset_o)) return -1; + tp_dictoffset = PyLong_AsSsize_t(tp_dictoffset_o); + Py_DECREF(tp_dictoffset_o); + if (unlikely(tp_dictoffset == 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' doesn't have a dictoffset"); + return -1; + } else if (unlikely(tp_dictoffset < 0)) { + PyErr_SetString( + PyExc_TypeError, + "'type' has an unexpected negative dictoffset. " + "Please report this as Cython bug"); + return -1; + } + return tp_dictoffset; +} +static PyObject *__Pyx_GetTypeDict(PyTypeObject *tp) { + static Py_ssize_t tp_dictoffset = 0; + if (unlikely(tp_dictoffset == 0)) { + tp_dictoffset = __Pyx_GetTypeDictOffset(); + if (unlikely(tp_dictoffset == -1 && PyErr_Occurred())) { + tp_dictoffset = 0; // try again next time? + return NULL; + } + } + return *(PyObject**)((char*)tp + tp_dictoffset); +} +#endif + +/* SetItemOnTypeDict (used by FixUpExtensionType) */ +static int __Pyx__SetItemOnTypeDict(PyTypeObject *tp, PyObject *k, PyObject *v) { + int result; + PyObject *tp_dict; +#if CYTHON_COMPILING_IN_LIMITED_API + tp_dict = __Pyx_GetTypeDict(tp); + if (unlikely(!tp_dict)) return -1; +#else + tp_dict = tp->tp_dict; +#endif + result = PyDict_SetItem(tp_dict, k, v); + if (likely(!result)) { + PyType_Modified(tp); + if (unlikely(PyObject_HasAttr(v, __pyx_mstate_global->__pyx_n_u_set_name))) { + PyObject *setNameResult = PyObject_CallMethodObjArgs(v, __pyx_mstate_global->__pyx_n_u_set_name, (PyObject *) tp, k, NULL); + if (!setNameResult) return -1; + Py_DECREF(setNameResult); + } + } + return result; +} + +/* FixUpExtensionType (used by FetchCommonType) */ +static int __Pyx_fix_up_extension_type_from_spec(PyType_Spec *spec, PyTypeObject *type) { +#if __PYX_LIMITED_VERSION_HEX > 0x030900B1 + CYTHON_UNUSED_VAR(spec); + CYTHON_UNUSED_VAR(type); + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#else + const PyType_Slot *slot = spec->slots; + int changed = 0; +#if !CYTHON_COMPILING_IN_LIMITED_API + while (slot && slot->slot && slot->slot != Py_tp_members) + slot++; + if (slot && slot->slot == Py_tp_members) { +#if !CYTHON_COMPILING_IN_CPYTHON + const +#endif // !CYTHON_COMPILING_IN_CPYTHON) + PyMemberDef *memb = (PyMemberDef*) slot->pfunc; + while (memb && memb->name) { + if (memb->name[0] == '_' && memb->name[1] == '_') { + if (strcmp(memb->name, "__weaklistoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_weaklistoffset = memb->offset; + changed = 1; + } + else if (strcmp(memb->name, "__dictoffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_dictoffset = memb->offset; + changed = 1; + } +#if CYTHON_METH_FASTCALL + else if (strcmp(memb->name, "__vectorcalloffset__") == 0) { + assert(memb->type == T_PYSSIZET); + assert(memb->flags == READONLY); + type->tp_vectorcall_offset = memb->offset; + changed = 1; + } +#endif // CYTHON_METH_FASTCALL +#if !CYTHON_COMPILING_IN_PYPY + else if (strcmp(memb->name, "__module__") == 0) { + PyObject *descr; + assert(memb->type == T_OBJECT); + assert(memb->flags == 0 || memb->flags == READONLY); + descr = PyDescr_NewMember(type, memb); + if (unlikely(!descr)) + return -1; + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } +#endif // !CYTHON_COMPILING_IN_PYPY + } + memb++; + } + } +#endif // !CYTHON_COMPILING_IN_LIMITED_API +#if !CYTHON_COMPILING_IN_PYPY + slot = spec->slots; + while (slot && slot->slot && slot->slot != Py_tp_getset) + slot++; + if (slot && slot->slot == Py_tp_getset) { + PyGetSetDef *getset = (PyGetSetDef*) slot->pfunc; + while (getset && getset->name) { + if (getset->name[0] == '_' && getset->name[1] == '_' && strcmp(getset->name, "__module__") == 0) { + PyObject *descr = PyDescr_NewGetSet(type, getset); + if (unlikely(!descr)) + return -1; + #if CYTHON_COMPILING_IN_LIMITED_API + PyObject *pyname = PyUnicode_FromString(getset->name); + if (unlikely(!pyname)) { + Py_DECREF(descr); + return -1; + } + int set_item_result = __Pyx_SetItemOnTypeDict(type, pyname, descr); + Py_DECREF(pyname); + #else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); + int set_item_result = PyDict_SetItem(type->tp_dict, PyDescr_NAME(descr), descr); + #endif + Py_DECREF(descr); + if (unlikely(set_item_result < 0)) { + return -1; + } + changed = 1; + } + ++getset; + } + } +#else + CYTHON_UNUSED_VAR(__Pyx__SetItemOnTypeDict); +#endif // !CYTHON_COMPILING_IN_PYPY + if (changed) + PyType_Modified(type); +#endif // PY_VERSION_HEX > 0x030900B1 + return 0; +} + +/* AddModuleRef (used by FetchSharedCythonModule) */ +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + static PyObject *__Pyx_PyImport_AddModuleObjectRef(PyObject *name) { + PyObject *module_dict = PyImport_GetModuleDict(); + PyObject *m; + if (PyMapping_GetOptionalItem(module_dict, name, &m) < 0) { + return NULL; + } + if (m != NULL && PyModule_Check(m)) { + return m; + } + Py_XDECREF(m); + m = PyModule_NewObject(name); + if (m == NULL) + return NULL; + if (PyDict_CheckExact(module_dict)) { + PyObject *new_m; + (void)PyDict_SetDefaultRef(module_dict, name, m, &new_m); + Py_DECREF(m); + return new_m; + } else { + if (PyObject_SetItem(module_dict, name, m) != 0) { + Py_DECREF(m); + return NULL; + } + return m; + } + } + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *py_name = PyUnicode_FromString(name); + if (!py_name) return NULL; + PyObject *module = __Pyx_PyImport_AddModuleObjectRef(py_name); + Py_DECREF(py_name); + return module; + } +#elif __PYX_LIMITED_VERSION_HEX >= 0x030d0000 + #define __Pyx_PyImport_AddModuleRef(name) PyImport_AddModuleRef(name) +#else + static PyObject *__Pyx_PyImport_AddModuleRef(const char *name) { + PyObject *module = PyImport_AddModule(name); + Py_XINCREF(module); + return module; + } +#endif + +/* FetchSharedCythonModule (used by FetchCommonType) */ +static PyObject *__Pyx_FetchSharedCythonABIModule(void) { + return __Pyx_PyImport_AddModuleRef(__PYX_ABI_MODULE_NAME); +} + +/* FetchCommonType (used by CommonTypesMetaclass) */ +#if __PYX_LIMITED_VERSION_HEX < 0x030C0000 +static PyObject* __Pyx_PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *result = __Pyx_PyType_FromModuleAndSpec(module, spec, bases); + if (result && metaclass) { + PyObject *old_tp = (PyObject*)Py_TYPE(result); + Py_INCREF((PyObject*)metaclass); +#if __PYX_LIMITED_VERSION_HEX >= 0x03090000 + Py_SET_TYPE(result, metaclass); +#else + result->ob_type = metaclass; +#endif + Py_DECREF(old_tp); + } + return result; +} +#else +#define __Pyx_PyType_FromMetaclass(me, mo, s, b) PyType_FromMetaclass(me, mo, s, b) +#endif +static int __Pyx_VerifyCachedType(PyObject *cached_type, + const char *name, + Py_ssize_t expected_basicsize) { + Py_ssize_t basicsize; + if (!PyType_Check(cached_type)) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s is not a type object", name); + return -1; + } + if (expected_basicsize == 0) { + return 0; // size is inherited, nothing useful to check + } +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_basicsize; + py_basicsize = PyObject_GetAttrString(cached_type, "__basicsize__"); + if (unlikely(!py_basicsize)) return -1; + basicsize = PyLong_AsSsize_t(py_basicsize); + Py_DECREF(py_basicsize); + py_basicsize = NULL; + if (unlikely(basicsize == (Py_ssize_t)-1) && PyErr_Occurred()) return -1; +#else + basicsize = ((PyTypeObject*) cached_type)->tp_basicsize; +#endif + if (basicsize != expected_basicsize) { + PyErr_Format(PyExc_TypeError, + "Shared Cython type %.200s has the wrong size, try recompiling", + name); + return -1; + } + return 0; +} +static PyTypeObject *__Pyx_FetchCommonTypeFromSpec(PyTypeObject *metaclass, PyObject *module, PyType_Spec *spec, PyObject *bases) { + PyObject *abi_module = NULL, *cached_type = NULL, *abi_module_dict, *new_cached_type, *py_object_name; + int get_item_ref_result; + const char* object_name = strrchr(spec->name, '.'); + object_name = object_name ? object_name+1 : spec->name; + py_object_name = PyUnicode_FromString(object_name); + if (!py_object_name) return NULL; + abi_module = __Pyx_FetchSharedCythonABIModule(); + if (!abi_module) goto done; + abi_module_dict = PyModule_GetDict(abi_module); + if (!abi_module_dict) goto done; + get_item_ref_result = __Pyx_PyDict_GetItemRef(abi_module_dict, py_object_name, &cached_type); + if (get_item_ref_result == 1) { + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else if (unlikely(get_item_ref_result == -1)) { + goto bad; + } + cached_type = __Pyx_PyType_FromMetaclass( + metaclass, + CYTHON_USE_MODULE_STATE ? module : abi_module, + spec, bases); + if (unlikely(!cached_type)) goto bad; + if (unlikely(__Pyx_fix_up_extension_type_from_spec(spec, (PyTypeObject *) cached_type) < 0)) goto bad; + new_cached_type = __Pyx_PyDict_SetDefault(abi_module_dict, py_object_name, cached_type); + if (unlikely(new_cached_type != cached_type)) { + if (unlikely(!new_cached_type)) goto bad; + Py_DECREF(cached_type); + cached_type = new_cached_type; + if (__Pyx_VerifyCachedType( + cached_type, + object_name, + spec->basicsize) < 0) { + goto bad; + } + goto done; + } else { + Py_DECREF(new_cached_type); + } +done: + Py_XDECREF(abi_module); + Py_DECREF(py_object_name); + assert(cached_type == NULL || PyType_Check(cached_type)); + return (PyTypeObject *) cached_type; +bad: + Py_XDECREF(cached_type); + cached_type = NULL; + goto done; +} + +/* CommonTypesMetaclass (used by CythonFunctionShared) */ +static PyObject* __pyx_CommonTypesMetaclass_get_module(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED void* context) { + return PyUnicode_FromString(__PYX_ABI_MODULE_NAME); +} +#if __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject* __pyx_CommonTypesMetaclass_call(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *args, CYTHON_UNUSED PyObject *kwds) { + PyErr_SetString(PyExc_TypeError, "Cannot instantiate Cython internal types"); + return NULL; +} +static int __pyx_CommonTypesMetaclass_setattr(CYTHON_UNUSED PyObject *self, CYTHON_UNUSED PyObject *attr, CYTHON_UNUSED PyObject *value) { + PyErr_SetString(PyExc_TypeError, "Cython internal types are immutable"); + return -1; +} +#endif +static PyGetSetDef __pyx_CommonTypesMetaclass_getset[] = { + {"__module__", __pyx_CommonTypesMetaclass_get_module, NULL, NULL, NULL}, + {0, 0, 0, 0, 0} +}; +static PyType_Slot __pyx_CommonTypesMetaclass_slots[] = { + {Py_tp_getset, (void *)__pyx_CommonTypesMetaclass_getset}, + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {Py_tp_call, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_new, (void*)__pyx_CommonTypesMetaclass_call}, + {Py_tp_setattro, (void*)__pyx_CommonTypesMetaclass_setattr}, + #endif + {0, 0} +}; +static PyType_Spec __pyx_CommonTypesMetaclass_spec = { + __PYX_TYPE_MODULE_PREFIX "_common_types_metatype", + 0, + 0, + Py_TPFLAGS_IMMUTABLETYPE | + Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT, + __pyx_CommonTypesMetaclass_slots +}; +static int __pyx_CommonTypesMetaclass_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + PyObject *bases = PyTuple_Pack(1, &PyType_Type); + if (unlikely(!bases)) { + return -1; + } + mstate->__pyx_CommonTypesMetaclassType = __Pyx_FetchCommonTypeFromSpec(NULL, module, &__pyx_CommonTypesMetaclass_spec, bases); + Py_DECREF(bases); + if (unlikely(mstate->__pyx_CommonTypesMetaclassType == NULL)) { + return -1; + } + return 0; +} + +/* CallTypeTraverse (used by CythonFunctionShared) */ +#if !CYTHON_USE_TYPE_SPECS || (!CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x03090000) +#else +static int __Pyx_call_type_traverse(PyObject *o, int always_call, visitproc visit, void *arg) { + #if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x03090000 + if (__Pyx_get_runtime_version() < 0x03090000) return 0; + #endif + if (!always_call) { + PyTypeObject *base = __Pyx_PyObject_GetSlot(o, tp_base, PyTypeObject*); + unsigned long flags = PyType_GetFlags(base); + if (flags & Py_TPFLAGS_HEAPTYPE) { + return 0; + } + } + Py_VISIT((PyObject*)Py_TYPE(o)); + return 0; +} +#endif + +/* PyMethodNew (used by CythonFunctionShared) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + PyObject *result; + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + #if __PYX_LIMITED_VERSION_HEX >= 0x030C0000 + { + PyObject *args[] = {func, self}; + result = PyObject_Vectorcall(__pyx_mstate_global->__Pyx_CachedMethodType, args, 2, NULL); + } + #else + result = PyObject_CallFunctionObjArgs(__pyx_mstate_global->__Pyx_CachedMethodType, func, self, NULL); + #endif + return result; +} +#else +static PyObject *__Pyx_PyMethod_New(PyObject *func, PyObject *self, PyObject *typ) { + CYTHON_UNUSED_VAR(typ); + if (!self) + return __Pyx_NewRef(func); + return PyMethod_New(func, self); +} +#endif + +/* PyVectorcallFastCallDict (used by CythonFunctionShared) */ +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static PyObject *__Pyx_PyVectorcall_FastCallDict_kw(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + PyObject *res = NULL; + PyObject *kwnames; + PyObject **newargs; + PyObject **kwvalues; + Py_ssize_t i; + #if CYTHON_AVOID_BORROWED_REFS + PyObject *pos; + #else + Py_ssize_t pos; + #endif + size_t j; + PyObject *key, *value; + unsigned long keys_are_strings; + #if !CYTHON_ASSUME_SAFE_SIZE + Py_ssize_t nkw = PyDict_Size(kw); + if (unlikely(nkw == -1)) return NULL; + #else + Py_ssize_t nkw = PyDict_GET_SIZE(kw); + #endif + newargs = (PyObject **)PyMem_Malloc((nargs + (size_t)nkw) * sizeof(args[0])); + if (unlikely(newargs == NULL)) { + PyErr_NoMemory(); + return NULL; + } + for (j = 0; j < nargs; j++) newargs[j] = args[j]; + kwnames = PyTuple_New(nkw); + if (unlikely(kwnames == NULL)) { + PyMem_Free(newargs); + return NULL; + } + kwvalues = newargs + nargs; + pos = 0; + i = 0; + keys_are_strings = Py_TPFLAGS_UNICODE_SUBCLASS; + while (__Pyx_PyDict_NextRef(kw, &pos, &key, &value)) { + keys_are_strings &= + #if CYTHON_COMPILING_IN_LIMITED_API + PyType_GetFlags(Py_TYPE(key)); + #else + Py_TYPE(key)->tp_flags; + #endif + #if !CYTHON_ASSUME_SAFE_MACROS + if (unlikely(PyTuple_SetItem(kwnames, i, key) < 0)) goto cleanup; + #else + PyTuple_SET_ITEM(kwnames, i, key); + #endif + kwvalues[i] = value; + i++; + } + if (unlikely(!keys_are_strings)) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + goto cleanup; + } + res = vc(func, newargs, nargs, kwnames); +cleanup: + #if CYTHON_AVOID_BORROWED_REFS + Py_DECREF(pos); + #endif + Py_DECREF(kwnames); + for (i = 0; i < nkw; i++) + Py_DECREF(kwvalues[i]); + PyMem_Free(newargs); + return res; +} +static CYTHON_INLINE PyObject *__Pyx_PyVectorcall_FastCallDict(PyObject *func, __pyx_vectorcallfunc vc, PyObject *const *args, size_t nargs, PyObject *kw) +{ + Py_ssize_t kw_size = + likely(kw == NULL) ? + 0 : +#if !CYTHON_ASSUME_SAFE_SIZE + PyDict_Size(kw); +#else + PyDict_GET_SIZE(kw); +#endif + if (kw_size == 0) { + return vc(func, args, nargs, NULL); + } +#if !CYTHON_ASSUME_SAFE_SIZE + else if (unlikely(kw_size == -1)) { + return NULL; + } +#endif + return __Pyx_PyVectorcall_FastCallDict_kw(func, vc, args, nargs, kw); +} +#endif + +/* CythonFunctionShared (used by CythonFunction) */ +#if CYTHON_COMPILING_IN_LIMITED_API +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunctionNoMethod(PyObject *func, void (*cfunc)(void)) { + if (__Pyx_CyFunction_Check(func)) { + return PyCFunction_GetFunction(((__pyx_CyFunctionObject*)func)->func) == (PyCFunction) cfunc; + } else if (PyCFunction_Check(func)) { + return PyCFunction_GetFunction(func) == (PyCFunction) cfunc; + } + return 0; +} +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if ((PyObject*)Py_TYPE(func) == __pyx_mstate_global->__Pyx_CachedMethodType) { + int result; + PyObject *newFunc = PyObject_GetAttr(func, __pyx_mstate_global->__pyx_n_u_func); + if (unlikely(!newFunc)) { + PyErr_Clear(); // It's only an optimization, so don't throw an error + return 0; + } + result = __Pyx__IsSameCyOrCFunctionNoMethod(newFunc, cfunc); + Py_DECREF(newFunc); + return result; + } + return __Pyx__IsSameCyOrCFunctionNoMethod(func, cfunc); +} +#else +static CYTHON_INLINE int __Pyx__IsSameCyOrCFunction(PyObject *func, void (*cfunc)(void)) { + if (PyMethod_Check(func)) { + func = PyMethod_GET_FUNCTION(func); + } + return __Pyx_CyOrPyCFunction_Check(func) && __Pyx_CyOrPyCFunction_GET_FUNCTION(func) == (PyCFunction) cfunc; +} +#endif +static CYTHON_INLINE void __Pyx__CyFunction_SetClassObj(__pyx_CyFunctionObject* f, PyObject* classobj) { +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + __Pyx_Py_XDECREF_SET( + __Pyx_CyFunction_GetClassObj(f), + ((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#else + __Pyx_Py_XDECREF_SET( + ((PyCMethodObject *) (f))->mm_class, + (PyTypeObject*)((classobj) ? __Pyx_NewRef(classobj) : NULL)); +#endif +} +static PyObject * +__Pyx_CyFunction_get_doc_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_doc == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_doc = PyObject_GetAttrString(op->func, "__doc__"); + if (unlikely(!op->func_doc)) return NULL; +#else + if (((PyCFunctionObject*)op)->m_ml->ml_doc) { + op->func_doc = PyUnicode_FromString(((PyCFunctionObject*)op)->m_ml->ml_doc); + if (unlikely(op->func_doc == NULL)) + return NULL; + } else { + Py_INCREF(Py_None); + return Py_None; + } +#endif + } + Py_INCREF(op->func_doc); + return op->func_doc; +} +static PyObject * +__Pyx_CyFunction_get_doc(__pyx_CyFunctionObject *op, void *closure) { + PyObject *result; + CYTHON_UNUSED_VAR(closure); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_doc_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_doc(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (value == NULL) { + value = Py_None; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_doc, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_name_locked(__pyx_CyFunctionObject *op) +{ + if (unlikely(op->func_name == NULL)) { +#if CYTHON_COMPILING_IN_LIMITED_API + op->func_name = PyObject_GetAttrString(op->func, "__name__"); +#else + op->func_name = PyUnicode_InternFromString(((PyCFunctionObject*)op)->m_ml->ml_name); +#endif + if (unlikely(op->func_name == NULL)) + return NULL; + } + Py_INCREF(op->func_name); + return op->func_name; +} +static PyObject * +__Pyx_CyFunction_get_name(__pyx_CyFunctionObject *op, void *context) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_name_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_name(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__name__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_name, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_qualname(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + PyObject *result; + __Pyx_BEGIN_CRITICAL_SECTION(op); + Py_INCREF(op->func_qualname); + result = op->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_qualname(__pyx_CyFunctionObject *op, PyObject *value, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(value == NULL || !PyUnicode_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__qualname__ must be set to a string object"); + return -1; + } + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_qualname, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +static PyObject * +__Pyx_CyFunction_get_dict(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + if (unlikely(op->func_dict == NULL)) { + op->func_dict = PyDict_New(); + if (unlikely(op->func_dict == NULL)) + return NULL; + } + Py_INCREF(op->func_dict); + return op->func_dict; +} +#endif +static PyObject * +__Pyx_CyFunction_get_globals(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(context); + Py_INCREF(op->func_globals); + return op->func_globals; +} +static PyObject * +__Pyx_CyFunction_get_closure(__pyx_CyFunctionObject *op, void *context) +{ + CYTHON_UNUSED_VAR(op); + CYTHON_UNUSED_VAR(context); + Py_INCREF(Py_None); + return Py_None; +} +static PyObject * +__Pyx_CyFunction_get_code(__pyx_CyFunctionObject *op, void *context) +{ + PyObject* result = (op->func_code) ? op->func_code : Py_None; + CYTHON_UNUSED_VAR(context); + Py_INCREF(result); + return result; +} +static int +__Pyx_CyFunction_init_defaults(__pyx_CyFunctionObject *op) { + int result = 0; + PyObject *res = op->defaults_getter((PyObject *) op); + if (unlikely(!res)) + return -1; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + op->defaults_tuple = PyTuple_GET_ITEM(res, 0); + Py_INCREF(op->defaults_tuple); + op->defaults_kwdict = PyTuple_GET_ITEM(res, 1); + Py_INCREF(op->defaults_kwdict); + #else + op->defaults_tuple = __Pyx_PySequence_ITEM(res, 0); + if (unlikely(!op->defaults_tuple)) result = -1; + else { + op->defaults_kwdict = __Pyx_PySequence_ITEM(res, 1); + if (unlikely(!op->defaults_kwdict)) result = -1; + } + #endif + Py_DECREF(res); + return result; +} +static int +__Pyx_CyFunction_set_defaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyTuple_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__defaults__ must be set to a tuple object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__defaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_tuple, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_defaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_tuple; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_tuple; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_defaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result = NULL; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_defaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_kwdefaults(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value) { + value = Py_None; + } else if (unlikely(value != Py_None && !PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__kwdefaults__ must be set to a dict object"); + return -1; + } + PyErr_WarnEx(PyExc_RuntimeWarning, "changes to cyfunction.__kwdefaults__ will not " + "currently affect the values used in function calls", 1); + Py_INCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->defaults_kwdict, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->defaults_kwdict; + if (unlikely(!result)) { + if (op->defaults_getter) { + if (unlikely(__Pyx_CyFunction_init_defaults(op) < 0)) return NULL; + result = op->defaults_kwdict; + } else { + result = Py_None; + } + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_kwdefaults(__pyx_CyFunctionObject *op, void *context) { + PyObject* result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_kwdefaults_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static int +__Pyx_CyFunction_set_annotations(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + if (!value || value == Py_None) { + value = NULL; + } else if (unlikely(!PyDict_Check(value))) { + PyErr_SetString(PyExc_TypeError, + "__annotations__ must be set to a dict object"); + return -1; + } + Py_XINCREF(value); + __Pyx_BEGIN_CRITICAL_SECTION(op); + __Pyx_Py_XDECREF_SET(op->func_annotations, value); + __Pyx_END_CRITICAL_SECTION(); + return 0; +} +static PyObject * +__Pyx_CyFunction_get_annotations_locked(__pyx_CyFunctionObject *op) { + PyObject* result = op->func_annotations; + if (unlikely(!result)) { + result = PyDict_New(); + if (unlikely(!result)) return NULL; + op->func_annotations = result; + } + Py_INCREF(result); + return result; +} +static PyObject * +__Pyx_CyFunction_get_annotations(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + __Pyx_BEGIN_CRITICAL_SECTION(op); + result = __Pyx_CyFunction_get_annotations_locked(op); + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine_value(__pyx_CyFunctionObject *op) { + int is_coroutine = op->flags & __Pyx_CYFUNCTION_COROUTINE; + if (is_coroutine) { + PyObject *is_coroutine_value, *module, *fromlist, *marker = __pyx_mstate_global->__pyx_n_u_is_coroutine; + fromlist = PyList_New(1); + if (unlikely(!fromlist)) return NULL; + Py_INCREF(marker); +#if CYTHON_ASSUME_SAFE_MACROS + PyList_SET_ITEM(fromlist, 0, marker); +#else + if (unlikely(PyList_SetItem(fromlist, 0, marker) < 0)) { + Py_DECREF(fromlist); + return NULL; + } +#endif + module = PyImport_ImportModuleLevelObject(__pyx_mstate_global->__pyx_n_u_asyncio_coroutines, NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + if (unlikely(!module)) goto ignore; + is_coroutine_value = __Pyx_PyObject_GetAttrStr(module, marker); + Py_DECREF(module); + if (likely(is_coroutine_value)) { + return is_coroutine_value; + } +ignore: + PyErr_Clear(); + } + return __Pyx_PyBool_FromLong(is_coroutine); +} +static PyObject * +__Pyx_CyFunction_get_is_coroutine(__pyx_CyFunctionObject *op, void *context) { + PyObject *result; + CYTHON_UNUSED_VAR(context); + if (op->func_is_coroutine) { + return __Pyx_NewRef(op->func_is_coroutine); + } + result = __Pyx_CyFunction_get_is_coroutine_value(op); + if (unlikely(!result)) + return NULL; + __Pyx_BEGIN_CRITICAL_SECTION(op); + if (op->func_is_coroutine) { + Py_DECREF(result); + result = __Pyx_NewRef(op->func_is_coroutine); + } else { + op->func_is_coroutine = __Pyx_NewRef(result); + } + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static void __Pyx_CyFunction_raise_argument_count_error(__pyx_CyFunctionObject *func, const char* message, Py_ssize_t size) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + py_name, message, size); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s (%" CYTHON_FORMAT_SSIZE_T "d given)", + name, message, size); +#endif +} +static void __Pyx_CyFunction_raise_type_error(__pyx_CyFunctionObject *func, const char* message) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *py_name = __Pyx_CyFunction_get_name(func, NULL); + if (!py_name) return; + PyErr_Format(PyExc_TypeError, + "%.200S() %s", + py_name, message); + Py_DECREF(py_name); +#else + const char* name = ((PyCFunctionObject*)func)->m_ml->ml_name; + PyErr_Format(PyExc_TypeError, + "%.200s() %s", + name, message); +#endif +} +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject * +__Pyx_CyFunction_get_module(__pyx_CyFunctionObject *op, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_GetAttrString(op->func, "__module__"); +} +static int +__Pyx_CyFunction_set_module(__pyx_CyFunctionObject *op, PyObject* value, void *context) { + CYTHON_UNUSED_VAR(context); + return PyObject_SetAttrString(op->func, "__module__", value); +} +#endif +static PyGetSetDef __pyx_CyFunction_getsets[] = { + {"func_doc", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"__doc__", (getter)__Pyx_CyFunction_get_doc, (setter)__Pyx_CyFunction_set_doc, 0, 0}, + {"func_name", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__name__", (getter)__Pyx_CyFunction_get_name, (setter)__Pyx_CyFunction_set_name, 0, 0}, + {"__qualname__", (getter)__Pyx_CyFunction_get_qualname, (setter)__Pyx_CyFunction_set_qualname, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 + {"func_dict", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)__Pyx_CyFunction_get_dict, (setter)PyObject_GenericSetDict, 0, 0}, +#else + {"func_dict", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, + {"__dict__", (getter)PyObject_GenericGetDict, (setter)PyObject_GenericSetDict, 0, 0}, +#endif + {"func_globals", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"__globals__", (getter)__Pyx_CyFunction_get_globals, 0, 0, 0}, + {"func_closure", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"__closure__", (getter)__Pyx_CyFunction_get_closure, 0, 0, 0}, + {"func_code", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"__code__", (getter)__Pyx_CyFunction_get_code, 0, 0, 0}, + {"func_defaults", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__defaults__", (getter)__Pyx_CyFunction_get_defaults, (setter)__Pyx_CyFunction_set_defaults, 0, 0}, + {"__kwdefaults__", (getter)__Pyx_CyFunction_get_kwdefaults, (setter)__Pyx_CyFunction_set_kwdefaults, 0, 0}, + {"__annotations__", (getter)__Pyx_CyFunction_get_annotations, (setter)__Pyx_CyFunction_set_annotations, 0, 0}, + {"_is_coroutine", (getter)__Pyx_CyFunction_get_is_coroutine, 0, 0, 0}, +#if CYTHON_COMPILING_IN_LIMITED_API + {"__module__", (getter)__Pyx_CyFunction_get_module, (setter)__Pyx_CyFunction_set_module, 0, 0}, +#endif + {0, 0, 0, 0, 0} +}; +static PyMemberDef __pyx_CyFunction_members[] = { +#if !CYTHON_COMPILING_IN_LIMITED_API + {"__module__", T_OBJECT, offsetof(PyCFunctionObject, m_module), 0, 0}, +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + {"__dictoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_dict), READONLY, 0}, +#endif +#if CYTHON_METH_FASTCALL +#if CYTHON_COMPILING_IN_LIMITED_API + {"__vectorcalloffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_vectorcall), READONLY, 0}, +#else + {"__vectorcalloffset__", T_PYSSIZET, offsetof(PyCFunctionObject, vectorcall), READONLY, 0}, +#endif +#if CYTHON_COMPILING_IN_LIMITED_API + {"__weaklistoffset__", T_PYSSIZET, offsetof(__pyx_CyFunctionObject, func_weakreflist), READONLY, 0}, +#else + {"__weaklistoffset__", T_PYSSIZET, offsetof(PyCFunctionObject, m_weakreflist), READONLY, 0}, +#endif +#endif + {0, 0, 0, 0, 0} +}; +static PyObject * +__Pyx_CyFunction_reduce(__pyx_CyFunctionObject *m, PyObject *args) +{ + PyObject *result = NULL; + CYTHON_UNUSED_VAR(args); + __Pyx_BEGIN_CRITICAL_SECTION(m); + Py_INCREF(m->func_qualname); + result = m->func_qualname; + __Pyx_END_CRITICAL_SECTION(); + return result; +} +static PyMethodDef __pyx_CyFunction_methods[] = { + {"__reduce__", (PyCFunction)__Pyx_CyFunction_reduce, METH_VARARGS, 0}, + {0, 0, 0, 0} +}; +#if CYTHON_COMPILING_IN_LIMITED_API +#define __Pyx_CyFunction_weakreflist(cyfunc) ((cyfunc)->func_weakreflist) +#else +#define __Pyx_CyFunction_weakreflist(cyfunc) (((PyCFunctionObject*)cyfunc)->m_weakreflist) +#endif +static PyObject *__Pyx_CyFunction_Init(__pyx_CyFunctionObject *op, PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { +#if !CYTHON_COMPILING_IN_LIMITED_API + PyCFunctionObject *cf = (PyCFunctionObject*) op; +#endif + if (unlikely(op == NULL)) + return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + op->func = PyCFunction_NewEx(ml, (PyObject*)op, module); + if (unlikely(!op->func)) return NULL; +#endif + op->flags = flags; + __Pyx_CyFunction_weakreflist(op) = NULL; +#if !CYTHON_COMPILING_IN_LIMITED_API + cf->m_ml = ml; + cf->m_self = (PyObject *) op; +#endif + Py_XINCREF(closure); + op->func_closure = closure; +#if !CYTHON_COMPILING_IN_LIMITED_API + Py_XINCREF(module); + cf->m_module = module; +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + op->func_dict = NULL; +#endif + op->func_name = NULL; + Py_INCREF(qualname); + op->func_qualname = qualname; + op->func_doc = NULL; +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + op->func_classobj = NULL; +#else + ((PyCMethodObject*)op)->mm_class = NULL; +#endif + op->func_globals = globals; + Py_INCREF(op->func_globals); + Py_XINCREF(code); + op->func_code = code; + op->defaults = NULL; + op->defaults_tuple = NULL; + op->defaults_kwdict = NULL; + op->defaults_getter = NULL; + op->func_annotations = NULL; + op->func_is_coroutine = NULL; +#if CYTHON_METH_FASTCALL + switch (ml->ml_flags & (METH_VARARGS | METH_FASTCALL | METH_NOARGS | METH_O | METH_KEYWORDS | METH_METHOD)) { + case METH_NOARGS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_NOARGS; + break; + case METH_O: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_O; + break; + case METH_METHOD | METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD; + break; + case METH_FASTCALL | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS; + break; + case METH_VARARGS | METH_KEYWORDS: + __Pyx_CyFunction_func_vectorcall(op) = NULL; + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + Py_DECREF(op); + return NULL; + } +#endif + return (PyObject *) op; +} +static int +__Pyx_CyFunction_clear(__pyx_CyFunctionObject *m) +{ + Py_CLEAR(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func); +#else + Py_CLEAR(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(m->func_dict); +#elif PY_VERSION_HEX < 0x030d0000 + _PyObject_ClearManagedDict((PyObject*)m); +#else + PyObject_ClearManagedDict((PyObject*)m); +#endif + Py_CLEAR(m->func_name); + Py_CLEAR(m->func_qualname); + Py_CLEAR(m->func_doc); + Py_CLEAR(m->func_globals); + Py_CLEAR(m->func_code); +#if PY_VERSION_HEX < 0x030900B1 || CYTHON_COMPILING_IN_LIMITED_API + Py_CLEAR(__Pyx_CyFunction_GetClassObj(m)); +#else + { + PyObject *cls = (PyObject*) ((PyCMethodObject *) (m))->mm_class; + ((PyCMethodObject *) (m))->mm_class = NULL; + Py_XDECREF(cls); + } +#endif + Py_CLEAR(m->defaults_tuple); + Py_CLEAR(m->defaults_kwdict); + Py_CLEAR(m->func_annotations); + Py_CLEAR(m->func_is_coroutine); + Py_CLEAR(m->defaults); + return 0; +} +static void __Pyx__CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + if (__Pyx_CyFunction_weakreflist(m) != NULL) + PyObject_ClearWeakRefs((PyObject *) m); + __Pyx_CyFunction_clear(m); + __Pyx_PyHeapTypeObject_GC_Del(m); +} +static void __Pyx_CyFunction_dealloc(__pyx_CyFunctionObject *m) +{ + PyObject_GC_UnTrack(m); + __Pyx__CyFunction_dealloc(m); +} +static int __Pyx_CyFunction_traverse(__pyx_CyFunctionObject *m, visitproc visit, void *arg) +{ + { + int e = __Pyx_call_type_traverse((PyObject*)m, 1, visit, arg); + if (e) return e; + } + Py_VISIT(m->func_closure); +#if CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func); +#else + Py_VISIT(((PyCFunctionObject*)m)->m_module); +#endif +#if PY_VERSION_HEX < 0x030C0000 || CYTHON_COMPILING_IN_LIMITED_API + Py_VISIT(m->func_dict); +#else + { + int e = +#if PY_VERSION_HEX < 0x030d0000 + _PyObject_VisitManagedDict +#else + PyObject_VisitManagedDict +#endif + ((PyObject*)m, visit, arg); + if (e != 0) return e; + } +#endif + __Pyx_VISIT_CONST(m->func_name); + __Pyx_VISIT_CONST(m->func_qualname); + Py_VISIT(m->func_doc); + Py_VISIT(m->func_globals); + __Pyx_VISIT_CONST(m->func_code); + Py_VISIT(__Pyx_CyFunction_GetClassObj(m)); + Py_VISIT(m->defaults_tuple); + Py_VISIT(m->defaults_kwdict); + Py_VISIT(m->func_annotations); + Py_VISIT(m->func_is_coroutine); + Py_VISIT(m->defaults); + return 0; +} +static PyObject* +__Pyx_CyFunction_repr(__pyx_CyFunctionObject *op) +{ + PyObject *repr; + __Pyx_BEGIN_CRITICAL_SECTION(op); + repr = PyUnicode_FromFormat("", + op->func_qualname, (void *)op); + __Pyx_END_CRITICAL_SECTION(); + return repr; +} +static PyObject * __Pyx_CyFunction_CallMethod(PyObject *func, PyObject *self, PyObject *arg, PyObject *kw) { +#if CYTHON_COMPILING_IN_LIMITED_API + PyObject *f = ((__pyx_CyFunctionObject*)func)->func; + PyCFunction meth; + int flags; + meth = PyCFunction_GetFunction(f); + if (unlikely(!meth)) return NULL; + flags = PyCFunction_GetFlags(f); + if (unlikely(flags < 0)) return NULL; +#else + PyCFunctionObject* f = (PyCFunctionObject*)func; + PyCFunction meth = f->m_ml->ml_meth; + int flags = f->m_ml->ml_flags; +#endif + Py_ssize_t size; + switch (flags & (METH_VARARGS | METH_KEYWORDS | METH_NOARGS | METH_O)) { + case METH_VARARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) + return (*meth)(self, arg); + break; + case METH_VARARGS | METH_KEYWORDS: + return (*(PyCFunctionWithKeywords)(void(*)(void))meth)(self, arg, kw); + case METH_NOARGS: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 0)) + return (*meth)(self, NULL); + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes no arguments", size); + return NULL; + } + break; + case METH_O: + if (likely(kw == NULL || PyDict_Size(kw) == 0)) { +#if CYTHON_ASSUME_SAFE_SIZE + size = PyTuple_GET_SIZE(arg); +#else + size = PyTuple_Size(arg); + if (unlikely(size < 0)) return NULL; +#endif + if (likely(size == 1)) { + PyObject *result, *arg0; + #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS + arg0 = PyTuple_GET_ITEM(arg, 0); + #else + arg0 = __Pyx_PySequence_ITEM(arg, 0); if (unlikely(!arg0)) return NULL; + #endif + result = (*meth)(self, arg0); + #if !(CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS) + Py_DECREF(arg0); + #endif + return result; + } + __Pyx_CyFunction_raise_argument_count_error( + (__pyx_CyFunctionObject*)func, + "takes exactly one argument", size); + return NULL; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "Bad call flags for CyFunction"); + return NULL; + } + __Pyx_CyFunction_raise_type_error( + (__pyx_CyFunctionObject*)func, "takes no keyword arguments"); + return NULL; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) { + PyObject *self, *result; +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)func)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)func)->m_self; +#endif + result = __Pyx_CyFunction_CallMethod(func, self, arg, kw); + return result; +} +static PyObject *__Pyx_CyFunction_CallAsMethod(PyObject *func, PyObject *args, PyObject *kw) { + PyObject *result; + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *) func; +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL + __pyx_vectorcallfunc vc = __Pyx_CyFunction_func_vectorcall(cyfunc); + if (vc) { +#if CYTHON_ASSUME_SAFE_MACROS && CYTHON_ASSUME_SAFE_SIZE + return __Pyx_PyVectorcall_FastCallDict(func, vc, &PyTuple_GET_ITEM(args, 0), (size_t)PyTuple_GET_SIZE(args), kw); +#else + (void) &__Pyx_PyVectorcall_FastCallDict; + return PyVectorcall_Call(func, args, kw); +#endif + } +#endif + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + Py_ssize_t argc; + PyObject *new_args; + PyObject *self; +#if CYTHON_ASSUME_SAFE_SIZE + argc = PyTuple_GET_SIZE(args); +#else + argc = PyTuple_Size(args); + if (unlikely(argc < 0)) return NULL; +#endif + new_args = PyTuple_GetSlice(args, 1, argc); + if (unlikely(!new_args)) + return NULL; + self = PyTuple_GetItem(args, 0); + if (unlikely(!self)) { + Py_DECREF(new_args); + PyErr_Format(PyExc_TypeError, + "unbound method %.200S() needs an argument", + cyfunc->func_qualname); + return NULL; + } + result = __Pyx_CyFunction_CallMethod(func, self, new_args, kw); + Py_DECREF(new_args); + } else { + result = __Pyx_CyFunction_Call(func, args, kw); + } + return result; +} +#if CYTHON_METH_FASTCALL && CYTHON_VECTORCALL +static CYTHON_INLINE int __Pyx_CyFunction_Vectorcall_CheckArgs(__pyx_CyFunctionObject *cyfunc, Py_ssize_t nargs, PyObject *kwnames) +{ + int ret = 0; + if ((cyfunc->flags & __Pyx_CYFUNCTION_CCLASS) && !(cyfunc->flags & __Pyx_CYFUNCTION_STATICMETHOD)) { + if (unlikely(nargs < 1)) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "needs an argument"); + return -1; + } + ret = 1; + } + if (unlikely(kwnames) && unlikely(__Pyx_PyTuple_GET_SIZE(kwnames))) { + __Pyx_CyFunction_raise_type_error( + cyfunc, "takes no keyword arguments"); + return -1; + } + return ret; +} +static PyObject * __Pyx_CyFunction_Vectorcall_NOARGS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 0)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes no arguments", nargs); + return NULL; + } + return meth(self, NULL); +} +static PyObject * __Pyx_CyFunction_Vectorcall_O(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, kwnames)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + if (unlikely(nargs != 1)) { + __Pyx_CyFunction_raise_argument_count_error( + cyfunc, "takes exactly one argument", nargs); + return NULL; + } + return meth(self, args[0]); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + return ((__Pyx_PyCFunctionFastWithKeywords)(void(*)(void))meth)(self, args, nargs, kwnames); +} +static PyObject * __Pyx_CyFunction_Vectorcall_FASTCALL_KEYWORDS_METHOD(PyObject *func, PyObject *const *args, size_t nargsf, PyObject *kwnames) +{ + __pyx_CyFunctionObject *cyfunc = (__pyx_CyFunctionObject *)func; + PyTypeObject *cls = (PyTypeObject *) __Pyx_CyFunction_GetClassObj(cyfunc); + Py_ssize_t nargs = PyVectorcall_NARGS(nargsf); + PyObject *self; +#if CYTHON_COMPILING_IN_LIMITED_API + PyCFunction meth = PyCFunction_GetFunction(cyfunc->func); + if (unlikely(!meth)) return NULL; +#else + PyCFunction meth = ((PyCFunctionObject*)cyfunc)->m_ml->ml_meth; +#endif + switch (__Pyx_CyFunction_Vectorcall_CheckArgs(cyfunc, nargs, NULL)) { + case 1: + self = args[0]; + args += 1; + nargs -= 1; + break; + case 0: +#if CYTHON_COMPILING_IN_LIMITED_API + self = PyCFunction_GetSelf(((__pyx_CyFunctionObject*)cyfunc)->func); + if (unlikely(!self) && PyErr_Occurred()) return NULL; +#else + self = ((PyCFunctionObject*)cyfunc)->m_self; +#endif + break; + default: + return NULL; + } + #if PY_VERSION_HEX < 0x030e00A6 + size_t nargs_value = (size_t) nargs; + #else + Py_ssize_t nargs_value = nargs; + #endif + return ((__Pyx_PyCMethod)(void(*)(void))meth)(self, cls, args, nargs_value, kwnames); +} +#endif +static PyType_Slot __pyx_CyFunctionType_slots[] = { + {Py_tp_dealloc, (void *)__Pyx_CyFunction_dealloc}, + {Py_tp_repr, (void *)__Pyx_CyFunction_repr}, + {Py_tp_call, (void *)__Pyx_CyFunction_CallAsMethod}, + {Py_tp_traverse, (void *)__Pyx_CyFunction_traverse}, + {Py_tp_clear, (void *)__Pyx_CyFunction_clear}, + {Py_tp_methods, (void *)__pyx_CyFunction_methods}, + {Py_tp_members, (void *)__pyx_CyFunction_members}, + {Py_tp_getset, (void *)__pyx_CyFunction_getsets}, + {Py_tp_descr_get, (void *)__Pyx_PyMethod_New}, + {0, 0}, +}; +static PyType_Spec __pyx_CyFunctionType_spec = { + __PYX_TYPE_MODULE_PREFIX "cython_function_or_method", + sizeof(__pyx_CyFunctionObject), + 0, +#ifdef Py_TPFLAGS_METHOD_DESCRIPTOR + Py_TPFLAGS_METHOD_DESCRIPTOR | +#endif +#if CYTHON_METH_FASTCALL +#if defined(Py_TPFLAGS_HAVE_VECTORCALL) + Py_TPFLAGS_HAVE_VECTORCALL | +#elif defined(_Py_TPFLAGS_HAVE_VECTORCALL) + _Py_TPFLAGS_HAVE_VECTORCALL | +#endif +#endif // CYTHON_METH_FASTCALL +#if PY_VERSION_HEX >= 0x030C0000 && !CYTHON_COMPILING_IN_LIMITED_API + Py_TPFLAGS_MANAGED_DICT | +#endif + Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION | + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, + __pyx_CyFunctionType_slots +}; +static int __pyx_CyFunction_init(PyObject *module) { + __pyx_mstatetype *mstate = __Pyx_PyModule_GetState(module); + mstate->__pyx_CyFunctionType = __Pyx_FetchCommonTypeFromSpec( + mstate->__pyx_CommonTypesMetaclassType, module, &__pyx_CyFunctionType_spec, NULL); + if (unlikely(mstate->__pyx_CyFunctionType == NULL)) { + return -1; + } + return 0; +} +static CYTHON_INLINE PyObject *__Pyx_CyFunction_InitDefaults(PyObject *func, PyTypeObject *defaults_type) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults = PyObject_CallObject((PyObject*)defaults_type, NULL); // _PyObject_New(defaults_type); + if (unlikely(!m->defaults)) + return NULL; + return m->defaults; +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsTuple(PyObject *func, PyObject *tuple) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_tuple = tuple; + Py_INCREF(tuple); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetDefaultsKwDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->defaults_kwdict = dict; + Py_INCREF(dict); +} +static CYTHON_INLINE void __Pyx_CyFunction_SetAnnotationsDict(PyObject *func, PyObject *dict) { + __pyx_CyFunctionObject *m = (__pyx_CyFunctionObject *) func; + m->func_annotations = dict; + Py_INCREF(dict); +} + +/* CythonFunction */ +static PyObject *__Pyx_CyFunction_New(PyMethodDef *ml, int flags, PyObject* qualname, + PyObject *closure, PyObject *module, PyObject* globals, PyObject* code) { + PyObject *op = __Pyx_CyFunction_Init( + PyObject_GC_New(__pyx_CyFunctionObject, __pyx_mstate_global->__pyx_CyFunctionType), + ml, flags, qualname, closure, module, globals, code + ); + if (likely(op)) { + PyObject_GC_Track(op); + } + return op; +} + +/* PyDictVersioning (used by CLineInTraceback) */ +#if CYTHON_USE_DICT_VERSIONS && CYTHON_USE_TYPE_SLOTS +static CYTHON_INLINE PY_UINT64_T __Pyx_get_tp_dict_version(PyObject *obj) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + return likely(dict) ? __PYX_GET_DICT_VERSION(dict) : 0; +} +static CYTHON_INLINE PY_UINT64_T __Pyx_get_object_dict_version(PyObject *obj) { + PyObject **dictptr = NULL; + Py_ssize_t offset = Py_TYPE(obj)->tp_dictoffset; + if (offset) { +#if CYTHON_COMPILING_IN_CPYTHON + dictptr = (likely(offset > 0)) ? (PyObject **) ((char *)obj + offset) : _PyObject_GetDictPtr(obj); +#else + dictptr = _PyObject_GetDictPtr(obj); +#endif + } + return (dictptr && *dictptr) ? __PYX_GET_DICT_VERSION(*dictptr) : 0; +} +static CYTHON_INLINE int __Pyx_object_dict_version_matches(PyObject* obj, PY_UINT64_T tp_dict_version, PY_UINT64_T obj_dict_version) { + PyObject *dict = Py_TYPE(obj)->tp_dict; + if (unlikely(!dict) || unlikely(tp_dict_version != __PYX_GET_DICT_VERSION(dict))) + return 0; + return obj_dict_version == __Pyx_get_object_dict_version(obj); +} +#endif + +/* CLineInTraceback (used by AddTraceback) */ +#if CYTHON_CLINE_IN_TRACEBACK && CYTHON_CLINE_IN_TRACEBACK_RUNTIME +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030A0000 +#define __Pyx_PyProbablyModule_GetDict(o) __Pyx_XNewRef(PyModule_GetDict(o)) +#elif !CYTHON_COMPILING_IN_CPYTHON || CYTHON_COMPILING_IN_CPYTHON_FREETHREADING +#define __Pyx_PyProbablyModule_GetDict(o) PyObject_GenericGetDict(o, NULL); +#else +PyObject* __Pyx_PyProbablyModule_GetDict(PyObject *o) { + PyObject **dict_ptr = _PyObject_GetDictPtr(o); + return dict_ptr ? __Pyx_XNewRef(*dict_ptr) : NULL; +} +#endif +static int __Pyx_CLineForTraceback(PyThreadState *tstate, int c_line) { + PyObject *use_cline = NULL; + PyObject *ptype, *pvalue, *ptraceback; + PyObject *cython_runtime_dict; + CYTHON_MAYBE_UNUSED_VAR(tstate); + if (unlikely(!__pyx_mstate_global->__pyx_cython_runtime)) { + return c_line; + } + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + cython_runtime_dict = __Pyx_PyProbablyModule_GetDict(__pyx_mstate_global->__pyx_cython_runtime); + if (likely(cython_runtime_dict)) { + __PYX_PY_DICT_LOOKUP_IF_MODIFIED( + use_cline, cython_runtime_dict, + __Pyx_PyDict_SetDefault(cython_runtime_dict, __pyx_mstate_global->__pyx_n_u_cline_in_traceback, Py_False)) + } + if (use_cline == NULL || use_cline == Py_False || (use_cline != Py_True && PyObject_Not(use_cline) != 0)) { + c_line = 0; + } + Py_XDECREF(use_cline); + Py_XDECREF(cython_runtime_dict); + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + return c_line; +} +#endif + +/* CodeObjectCache (used by AddTraceback) */ +static int __pyx_bisect_code_objects(__Pyx_CodeObjectCacheEntry* entries, int count, int code_line) { + int start = 0, mid = 0, end = count - 1; + if (end >= 0 && code_line > entries[end].code_line) { + return count; + } + while (start < end) { + mid = start + (end - start) / 2; + if (code_line < entries[mid].code_line) { + end = mid; + } else if (code_line > entries[mid].code_line) { + start = mid + 1; + } else { + return mid; + } + } + if (code_line <= entries[mid].code_line) { + return mid; + } else { + return mid + 1; + } +} +static __Pyx_CachedCodeObjectType *__pyx__find_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line) { + __Pyx_CachedCodeObjectType* code_object; + int pos; + if (unlikely(!code_line) || unlikely(!code_cache->entries)) { + return NULL; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if (unlikely(pos >= code_cache->count) || unlikely(code_cache->entries[pos].code_line != code_line)) { + return NULL; + } + code_object = code_cache->entries[pos].code_object; + Py_INCREF(code_object); + return code_object; +} +static __Pyx_CachedCodeObjectType *__pyx_find_code_object(int code_line) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__find_code_object; + return NULL; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just miss. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type old_count = __pyx_atomic_incr_acq_rel(&code_cache->accessor_count); + if (old_count < 0) { + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); + return NULL; + } +#endif + __Pyx_CachedCodeObjectType *result = __pyx__find_code_object(code_cache, code_line); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_decr_acq_rel(&code_cache->accessor_count); +#endif + return result; +#endif +} +static void __pyx__insert_code_object(struct __Pyx_CodeObjectCache *code_cache, int code_line, __Pyx_CachedCodeObjectType* code_object) +{ + int pos, i; + __Pyx_CodeObjectCacheEntry* entries = code_cache->entries; + if (unlikely(!code_line)) { + return; + } + if (unlikely(!entries)) { + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Malloc(64*sizeof(__Pyx_CodeObjectCacheEntry)); + if (likely(entries)) { + code_cache->entries = entries; + code_cache->max_count = 64; + code_cache->count = 1; + entries[0].code_line = code_line; + entries[0].code_object = code_object; + Py_INCREF(code_object); + } + return; + } + pos = __pyx_bisect_code_objects(code_cache->entries, code_cache->count, code_line); + if ((pos < code_cache->count) && unlikely(code_cache->entries[pos].code_line == code_line)) { + __Pyx_CachedCodeObjectType* tmp = entries[pos].code_object; + entries[pos].code_object = code_object; + Py_INCREF(code_object); + Py_DECREF(tmp); + return; + } + if (code_cache->count == code_cache->max_count) { + int new_max = code_cache->max_count + 64; + entries = (__Pyx_CodeObjectCacheEntry*)PyMem_Realloc( + code_cache->entries, ((size_t)new_max) * sizeof(__Pyx_CodeObjectCacheEntry)); + if (unlikely(!entries)) { + return; + } + code_cache->entries = entries; + code_cache->max_count = new_max; + } + for (i=code_cache->count; i>pos; i--) { + entries[i] = entries[i-1]; + } + entries[pos].code_line = code_line; + entries[pos].code_object = code_object; + code_cache->count++; + Py_INCREF(code_object); +} +static void __pyx_insert_code_object(int code_line, __Pyx_CachedCodeObjectType* code_object) { +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING && !CYTHON_ATOMICS + (void)__pyx__insert_code_object; + return; // Most implementation should have atomics. But otherwise, don't make it thread-safe, just fail. +#else + struct __Pyx_CodeObjectCache *code_cache = &__pyx_mstate_global->__pyx_code_cache; +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_nonatomic_int_type expected = 0; + if (!__pyx_atomic_int_cmp_exchange(&code_cache->accessor_count, &expected, INT_MIN)) { + return; + } +#endif + __pyx__insert_code_object(code_cache, code_line, code_object); +#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING + __pyx_atomic_sub(&code_cache->accessor_count, INT_MIN); +#endif +#endif +} + +/* AddTraceback */ +#include "compile.h" +#include "frameobject.h" +#include "traceback.h" +#if PY_VERSION_HEX >= 0x030b00a6 && !CYTHON_COMPILING_IN_LIMITED_API && !defined(PYPY_VERSION) + #ifndef Py_BUILD_CORE + #define Py_BUILD_CORE 1 + #endif + #include "internal/pycore_frame.h" +#endif +#if CYTHON_COMPILING_IN_LIMITED_API +static PyObject *__Pyx_PyCode_Replace_For_AddTraceback(PyObject *code, PyObject *scratch_dict, + PyObject *firstlineno, PyObject *name) { + PyObject *replace = NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_firstlineno", firstlineno))) return NULL; + if (unlikely(PyDict_SetItemString(scratch_dict, "co_name", name))) return NULL; + replace = PyObject_GetAttrString(code, "replace"); + if (likely(replace)) { + PyObject *result = PyObject_Call(replace, __pyx_mstate_global->__pyx_empty_tuple, scratch_dict); + Py_DECREF(replace); + return result; + } + PyErr_Clear(); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyObject *code_object = NULL, *py_py_line = NULL, *py_funcname = NULL, *dict = NULL; + PyObject *replace = NULL, *getframe = NULL, *frame = NULL; + PyObject *exc_type, *exc_value, *exc_traceback; + int success = 0; + if (c_line) { + c_line = __Pyx_CLineForTraceback(__Pyx_PyThreadState_Current, c_line); + } + PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); + code_object = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!code_object) { + code_object = Py_CompileString("_getframe()", filename, Py_eval_input); + if (unlikely(!code_object)) goto bad; + py_py_line = PyLong_FromLong(py_line); + if (unlikely(!py_py_line)) goto bad; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + } else { + py_funcname = PyUnicode_FromString(funcname); + } + if (unlikely(!py_funcname)) goto bad; + dict = PyDict_New(); + if (unlikely(!dict)) goto bad; + { + PyObject *old_code_object = code_object; + code_object = __Pyx_PyCode_Replace_For_AddTraceback(code_object, dict, py_py_line, py_funcname); + Py_DECREF(old_code_object); + } + if (unlikely(!code_object)) goto bad; + __pyx_insert_code_object(c_line ? -c_line : py_line, code_object); + } else { + dict = PyDict_New(); + } + getframe = PySys_GetObject("_getframe"); + if (unlikely(!getframe)) goto bad; + if (unlikely(PyDict_SetItemString(dict, "_getframe", getframe))) goto bad; + frame = PyEval_EvalCode(code_object, dict, dict); + if (unlikely(!frame) || frame == Py_None) goto bad; + success = 1; + bad: + PyErr_Restore(exc_type, exc_value, exc_traceback); + Py_XDECREF(code_object); + Py_XDECREF(py_py_line); + Py_XDECREF(py_funcname); + Py_XDECREF(dict); + Py_XDECREF(replace); + if (success) { + PyTraceBack_Here( + (struct _frame*)frame); + } + Py_XDECREF(frame); +} +#else +static PyCodeObject* __Pyx_CreateCodeObjectForTraceback( + const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = NULL; + PyObject *py_funcname = NULL; + if (c_line) { + py_funcname = PyUnicode_FromFormat( "%s (%s:%d)", funcname, __pyx_cfilenm, c_line); + if (!py_funcname) goto bad; + funcname = PyUnicode_AsUTF8(py_funcname); + if (!funcname) goto bad; + } + py_code = PyCode_NewEmpty(filename, funcname, py_line); + Py_XDECREF(py_funcname); + return py_code; +bad: + Py_XDECREF(py_funcname); + return NULL; +} +static void __Pyx_AddTraceback(const char *funcname, int c_line, + int py_line, const char *filename) { + PyCodeObject *py_code = 0; + PyFrameObject *py_frame = 0; + PyThreadState *tstate = __Pyx_PyThreadState_Current; + PyObject *ptype, *pvalue, *ptraceback; + if (c_line) { + c_line = __Pyx_CLineForTraceback(tstate, c_line); + } + py_code = __pyx_find_code_object(c_line ? -c_line : py_line); + if (!py_code) { + __Pyx_ErrFetchInState(tstate, &ptype, &pvalue, &ptraceback); + py_code = __Pyx_CreateCodeObjectForTraceback( + funcname, c_line, py_line, filename); + if (!py_code) { + /* If the code object creation fails, then we should clear the + fetched exception references and propagate the new exception */ + Py_XDECREF(ptype); + Py_XDECREF(pvalue); + Py_XDECREF(ptraceback); + goto bad; + } + __Pyx_ErrRestoreInState(tstate, ptype, pvalue, ptraceback); + __pyx_insert_code_object(c_line ? -c_line : py_line, py_code); + } + py_frame = PyFrame_New( + tstate, /*PyThreadState *tstate,*/ + py_code, /*PyCodeObject *code,*/ + __pyx_mstate_global->__pyx_d, /*PyObject *globals,*/ + 0 /*PyObject *locals*/ + ); + if (!py_frame) goto bad; + __Pyx_PyFrame_SetLineNumber(py_frame, py_line); + PyTraceBack_Here(py_frame); +bad: + Py_XDECREF(py_code); + Py_XDECREF(py_frame); +} +#endif + +/* FormatTypeName */ +#if CYTHON_COMPILING_IN_LIMITED_API && __PYX_LIMITED_VERSION_HEX < 0x030d0000 +static __Pyx_TypeName +__Pyx_PyType_GetFullyQualifiedName(PyTypeObject* tp) +{ + PyObject *module = NULL, *name = NULL, *result = NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + name = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_qualname); + #else + name = PyType_GetQualName(tp); + #endif + if (unlikely(name == NULL) || unlikely(!PyUnicode_Check(name))) goto bad; + module = __Pyx_PyObject_GetAttrStr((PyObject *)tp, + __pyx_mstate_global->__pyx_n_u_module); + if (unlikely(module == NULL) || unlikely(!PyUnicode_Check(module))) goto bad; + if (PyUnicode_CompareWithASCIIString(module, "builtins") == 0) { + result = name; + name = NULL; + goto done; + } + result = PyUnicode_FromFormat("%U.%U", module, name); + if (unlikely(result == NULL)) goto bad; + done: + Py_XDECREF(name); + Py_XDECREF(module); + return result; + bad: + PyErr_Clear(); + if (name) { + result = name; + name = NULL; + } else { + result = __Pyx_NewRef(__pyx_mstate_global->__pyx_kp_u__2); + } + goto done; +} +#endif + +/* PyObjectVectorCallKwBuilder (used by CIntToPy) */ +#if CYTHON_VECTORCALL +static int __Pyx_VectorcallBuilder_AddArg(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_PyObject_FastCallDict; + Py_INCREF(key); + if (__Pyx_PyTuple_SET_ITEM(builder, n, key) != (0)) return -1; + args[n] = value; + return 0; +} +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + (void)__Pyx_VectorcallBuilder_AddArgStr; + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return __Pyx_VectorcallBuilder_AddArg(key, value, builder, args, n); +} +static int __Pyx_VectorcallBuilder_AddArgStr(const char *key, PyObject *value, PyObject *builder, PyObject **args, int n) { + PyObject *pyKey = PyUnicode_FromString(key); + if (!pyKey) return -1; + return __Pyx_VectorcallBuilder_AddArg(pyKey, value, builder, args, n); +} +#else // CYTHON_VECTORCALL +CYTHON_UNUSED static int __Pyx_VectorcallBuilder_AddArg_Check(PyObject *key, PyObject *value, PyObject *builder, CYTHON_UNUSED PyObject **args, CYTHON_UNUSED int n) { + if (unlikely(!PyUnicode_Check(key))) { + PyErr_SetString(PyExc_TypeError, "keywords must be strings"); + return -1; + } + return PyDict_SetItem(builder, key, value); +} +#endif + +/* CIntToPy */ +static CYTHON_INLINE PyObject* __Pyx_PyLong_From_long(long value) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (is_unsigned) { + if (sizeof(long) < sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(unsigned long)) { + return PyLong_FromUnsignedLong((unsigned long) value); +#if !CYTHON_COMPILING_IN_PYPY + } else if (sizeof(long) <= sizeof(unsigned PY_LONG_LONG)) { + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG) value); +#endif + } + } else { + if (sizeof(long) <= sizeof(long)) { + return PyLong_FromLong((long) value); + } else if (sizeof(long) <= sizeof(PY_LONG_LONG)) { + return PyLong_FromLongLong((PY_LONG_LONG) value); + } + } + { + unsigned char *bytes = (unsigned char *)&value; +#if !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d00A4 + if (is_unsigned) { + return PyLong_FromUnsignedNativeBytes(bytes, sizeof(value), -1); + } else { + return PyLong_FromNativeBytes(bytes, sizeof(value), -1); + } +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX < 0x030d0000 + int one = 1; int little = (int)*(unsigned char *)&one; + return _PyLong_FromByteArray(bytes, sizeof(long), + little, !is_unsigned); +#else + int one = 1; int little = (int)*(unsigned char *)&one; + PyObject *from_bytes, *result = NULL, *kwds = NULL; + PyObject *py_bytes = NULL, *order_str = NULL; + from_bytes = PyObject_GetAttrString((PyObject*)&PyLong_Type, "from_bytes"); + if (!from_bytes) return NULL; + py_bytes = PyBytes_FromStringAndSize((char*)bytes, sizeof(long)); + if (!py_bytes) goto limited_bad; + order_str = PyUnicode_FromString(little ? "little" : "big"); + if (!order_str) goto limited_bad; + { + PyObject *args[3+(CYTHON_VECTORCALL ? 1 : 0)] = { NULL, py_bytes, order_str }; + if (!is_unsigned) { + kwds = __Pyx_MakeVectorcallBuilderKwds(1); + if (!kwds) goto limited_bad; + if (__Pyx_VectorcallBuilder_AddArgStr("signed", __Pyx_NewRef(Py_True), kwds, args+3, 0) < 0) goto limited_bad; + } + result = __Pyx_Object_Vectorcall_CallFromBuilder(from_bytes, args+1, 2 | __Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET, kwds); + } + limited_bad: + Py_XDECREF(kwds); + Py_XDECREF(order_str); + Py_XDECREF(py_bytes); + Py_XDECREF(from_bytes); + return result; +#endif + } +} + +/* CIntFromPyVerify (used by CIntFromPy) */ +#define __PYX_VERIFY_RETURN_INT(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 0) +#define __PYX_VERIFY_RETURN_INT_EXC(target_type, func_type, func_value)\ + __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, 1) +#define __PYX__VERIFY_RETURN_INT(target_type, func_type, func_value, exc)\ + {\ + func_type value = func_value;\ + if (sizeof(target_type) < sizeof(func_type)) {\ + if (unlikely(value != (func_type) (target_type) value)) {\ + func_type zero = 0;\ + if (exc && unlikely(value == (func_type)-1 && PyErr_Occurred()))\ + return (target_type) -1;\ + if (is_unsigned && unlikely(value < zero))\ + goto raise_neg_overflow;\ + else\ + goto raise_overflow;\ + }\ + }\ + return (target_type) value;\ + } + +/* CIntFromPy */ +static CYTHON_INLINE long __Pyx_PyLong_As_long(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const long neg_one = (long) -1, const_zero = (long) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + long val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (long) -1; + val = __Pyx_PyLong_As_long(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 2 * PyLong_SHIFT)) { + return (long) (((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 3 * PyLong_SHIFT)) { + return (long) (((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) >= 4 * PyLong_SHIFT)) { + return (long) (((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (long) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(long) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(long) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(long, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(long) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(long) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + return (long) ((((((long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(long) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(long) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + return (long) ((((((((long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(long) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) (((long)-1)*(((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(long) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(long, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(long) - 1 > 4 * PyLong_SHIFT)) { + return (long) ((((((((((long)digits[3]) << PyLong_SHIFT) | (long)digits[2]) << PyLong_SHIFT) | (long)digits[1]) << PyLong_SHIFT) | (long)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(long) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(long, long, PyLong_AsLong(x)) + } else if ((sizeof(long) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(long, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + long val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (long) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (long) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (long) -1; + } else { + stepval = v; + } + v = NULL; + val = (long) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(long) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((long) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(long) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((long) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((long) 1) << (sizeof(long) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (long) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to long"); + return (long) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to long"); + return (long) -1; +} + +/* CIntFromPy */ +static CYTHON_INLINE int __Pyx_PyLong_As_int(PyObject *x) { +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + const int neg_one = (int) -1, const_zero = (int) 0; +#ifdef __Pyx_HAS_GCC_DIAGNOSTIC +#pragma GCC diagnostic pop +#endif + const int is_unsigned = neg_one > const_zero; + if (unlikely(!PyLong_Check(x))) { + int val; + PyObject *tmp = __Pyx_PyNumber_Long(x); + if (!tmp) return (int) -1; + val = __Pyx_PyLong_As_int(tmp); + Py_DECREF(tmp); + return val; + } + if (is_unsigned) { +#if CYTHON_USE_PYLONG_INTERNALS + if (unlikely(__Pyx_PyLong_IsNeg(x))) { + goto raise_neg_overflow; + } else if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_upylong, __Pyx_PyLong_CompactValueUnsigned(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_DigitCount(x)) { + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 2 * PyLong_SHIFT)) { + return (int) (((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 3 * PyLong_SHIFT)) { + return (int) (((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) >= 4 * PyLong_SHIFT)) { + return (int) (((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0])); + } + } + break; + } + } +#endif +#if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX < 0x030C00A7 + if (unlikely(Py_SIZE(x) < 0)) { + goto raise_neg_overflow; + } +#else + { + int result = PyObject_RichCompareBool(x, Py_False, Py_LT); + if (unlikely(result < 0)) + return (int) -1; + if (unlikely(result == 1)) + goto raise_neg_overflow; + } +#endif + if ((sizeof(int) <= sizeof(unsigned long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned long, PyLong_AsUnsignedLong(x)) + } else if ((sizeof(int) <= sizeof(unsigned PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, unsigned PY_LONG_LONG, PyLong_AsUnsignedLongLong(x)) + } + } else { +#if CYTHON_USE_PYLONG_INTERNALS + if (__Pyx_PyLong_IsCompact(x)) { + __PYX_VERIFY_RETURN_INT(int, __Pyx_compact_pylong, __Pyx_PyLong_CompactValue(x)) + } else { + const digit* digits = __Pyx_PyLong_Digits(x); + assert(__Pyx_PyLong_DigitCount(x) > 1); + switch (__Pyx_PyLong_SignedDigitCount(x)) { + case -2: + if ((8 * sizeof(int) - 1 > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 2: + if ((8 * sizeof(int) > 1 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 2 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + return (int) ((((((int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -3: + if ((8 * sizeof(int) - 1 > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 3: + if ((8 * sizeof(int) > 2 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 3 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + return (int) ((((((((int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case -4: + if ((8 * sizeof(int) - 1 > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, long, -(long) (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) (((int)-1)*(((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + case 4: + if ((8 * sizeof(int) > 3 * PyLong_SHIFT)) { + if ((8 * sizeof(unsigned long) > 4 * PyLong_SHIFT)) { + __PYX_VERIFY_RETURN_INT(int, unsigned long, (((((((((unsigned long)digits[3]) << PyLong_SHIFT) | (unsigned long)digits[2]) << PyLong_SHIFT) | (unsigned long)digits[1]) << PyLong_SHIFT) | (unsigned long)digits[0]))) + } else if ((8 * sizeof(int) - 1 > 4 * PyLong_SHIFT)) { + return (int) ((((((((((int)digits[3]) << PyLong_SHIFT) | (int)digits[2]) << PyLong_SHIFT) | (int)digits[1]) << PyLong_SHIFT) | (int)digits[0]))); + } + } + break; + } + } +#endif + if ((sizeof(int) <= sizeof(long))) { + __PYX_VERIFY_RETURN_INT_EXC(int, long, PyLong_AsLong(x)) + } else if ((sizeof(int) <= sizeof(PY_LONG_LONG))) { + __PYX_VERIFY_RETURN_INT_EXC(int, PY_LONG_LONG, PyLong_AsLongLong(x)) + } + } + { + int val; + int ret = -1; +#if PY_VERSION_HEX >= 0x030d00A6 && !CYTHON_COMPILING_IN_LIMITED_API + Py_ssize_t bytes_copied = PyLong_AsNativeBytes( + x, &val, sizeof(val), Py_ASNATIVEBYTES_NATIVE_ENDIAN | (is_unsigned ? Py_ASNATIVEBYTES_UNSIGNED_BUFFER | Py_ASNATIVEBYTES_REJECT_NEGATIVE : 0)); + if (unlikely(bytes_copied == -1)) { + } else if (unlikely(bytes_copied > (Py_ssize_t) sizeof(val))) { + goto raise_overflow; + } else { + ret = 0; + } +#elif PY_VERSION_HEX < 0x030d0000 && !(CYTHON_COMPILING_IN_PYPY || CYTHON_COMPILING_IN_LIMITED_API) || defined(_PyLong_AsByteArray) + int one = 1; int is_little = (int)*(unsigned char *)&one; + unsigned char *bytes = (unsigned char *)&val; + ret = _PyLong_AsByteArray((PyLongObject *)x, + bytes, sizeof(val), + is_little, !is_unsigned); +#else + PyObject *v; + PyObject *stepval = NULL, *mask = NULL, *shift = NULL; + int bits, remaining_bits, is_negative = 0; + int chunk_size = (sizeof(long) < 8) ? 30 : 62; + if (likely(PyLong_CheckExact(x))) { + v = __Pyx_NewRef(x); + } else { + v = PyNumber_Long(x); + if (unlikely(!v)) return (int) -1; + assert(PyLong_CheckExact(v)); + } + { + int result = PyObject_RichCompareBool(v, Py_False, Py_LT); + if (unlikely(result < 0)) { + Py_DECREF(v); + return (int) -1; + } + is_negative = result == 1; + } + if (is_unsigned && unlikely(is_negative)) { + Py_DECREF(v); + goto raise_neg_overflow; + } else if (is_negative) { + stepval = PyNumber_Invert(v); + Py_DECREF(v); + if (unlikely(!stepval)) + return (int) -1; + } else { + stepval = v; + } + v = NULL; + val = (int) 0; + mask = PyLong_FromLong((1L << chunk_size) - 1); if (unlikely(!mask)) goto done; + shift = PyLong_FromLong(chunk_size); if (unlikely(!shift)) goto done; + for (bits = 0; bits < (int) sizeof(int) * 8 - chunk_size; bits += chunk_size) { + PyObject *tmp, *digit; + long idigit; + digit = PyNumber_And(stepval, mask); + if (unlikely(!digit)) goto done; + idigit = PyLong_AsLong(digit); + Py_DECREF(digit); + if (unlikely(idigit < 0)) goto done; + val |= ((int) idigit) << bits; + tmp = PyNumber_Rshift(stepval, shift); + if (unlikely(!tmp)) goto done; + Py_DECREF(stepval); stepval = tmp; + } + Py_DECREF(shift); shift = NULL; + Py_DECREF(mask); mask = NULL; + { + long idigit = PyLong_AsLong(stepval); + if (unlikely(idigit < 0)) goto done; + remaining_bits = ((int) sizeof(int) * 8) - bits - (is_unsigned ? 0 : 1); + if (unlikely(idigit >= (1L << remaining_bits))) + goto raise_overflow; + val |= ((int) idigit) << bits; + } + if (!is_unsigned) { + if (unlikely(val & (((int) 1) << (sizeof(int) * 8 - 1)))) + goto raise_overflow; + if (is_negative) + val = ~val; + } + ret = 0; + done: + Py_XDECREF(shift); + Py_XDECREF(mask); + Py_XDECREF(stepval); +#endif + if (unlikely(ret)) + return (int) -1; + return val; + } +raise_overflow: + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to int"); + return (int) -1; +raise_neg_overflow: + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to int"); + return (int) -1; +} + +/* FastTypeChecks */ +#if CYTHON_COMPILING_IN_CPYTHON +static int __Pyx_InBases(PyTypeObject *a, PyTypeObject *b) { + while (a) { + a = __Pyx_PyType_GetSlot(a, tp_base, PyTypeObject*); + if (a == b) + return 1; + } + return b == &PyBaseObject_Type; +} +static CYTHON_INLINE int __Pyx_IsSubtype(PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (a == b) return 1; + mro = a->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + if (PyTuple_GET_ITEM(mro, i) == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(a, b); +} +static CYTHON_INLINE int __Pyx_IsAnySubtype2(PyTypeObject *cls, PyTypeObject *a, PyTypeObject *b) { + PyObject *mro; + if (cls == a || cls == b) return 1; + mro = cls->tp_mro; + if (likely(mro)) { + Py_ssize_t i, n; + n = PyTuple_GET_SIZE(mro); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(mro, i); + if (base == (PyObject *)a || base == (PyObject *)b) + return 1; + } + return 0; + } + return __Pyx_InBases(cls, a) || __Pyx_InBases(cls, b); +} +static CYTHON_INLINE int __Pyx_inner_PyErr_GivenExceptionMatches2(PyObject *err, PyObject* exc_type1, PyObject *exc_type2) { + if (exc_type1) { + return __Pyx_IsAnySubtype2((PyTypeObject*)err, (PyTypeObject*)exc_type1, (PyTypeObject*)exc_type2); + } else { + return __Pyx_IsSubtype((PyTypeObject*)err, (PyTypeObject*)exc_type2); + } +} +static int __Pyx_PyErr_GivenExceptionMatchesTuple(PyObject *exc_type, PyObject *tuple) { + Py_ssize_t i, n; + assert(PyExceptionClass_Check(exc_type)); + n = PyTuple_GET_SIZE(tuple); + for (i=0; i>= 8; + ++i; + } + __Pyx_cached_runtime_version = version; + } +} +#endif +static unsigned long __Pyx_get_runtime_version(void) { +#if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + return Py_Version & ~0xFFUL; +#else + return __Pyx_cached_runtime_version; +#endif +} + +/* CheckBinaryVersion */ +static int __Pyx_check_binary_version(unsigned long ct_version, unsigned long rt_version, int allow_newer) { + const unsigned long MAJOR_MINOR = 0xFFFF0000UL; + if ((rt_version & MAJOR_MINOR) == (ct_version & MAJOR_MINOR)) + return 0; + if (likely(allow_newer && (rt_version & MAJOR_MINOR) > (ct_version & MAJOR_MINOR))) + return 1; + { + char message[200]; + PyOS_snprintf(message, sizeof(message), + "compile time Python version %d.%d " + "of module '%.100s' " + "%s " + "runtime version %d.%d", + (int) (ct_version >> 24), (int) ((ct_version >> 16) & 0xFF), + __Pyx_MODULE_NAME, + (allow_newer) ? "was newer than" : "does not match", + (int) (rt_version >> 24), (int) ((rt_version >> 16) & 0xFF) + ); + return PyErr_WarnEx(NULL, message, 1); + } +} + +/* NewCodeObj */ +#if CYTHON_COMPILING_IN_LIMITED_API + static PyObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyObject *exception_table = NULL; + PyObject *types_module=NULL, *code_type=NULL, *result=NULL; + #if __PYX_LIMITED_VERSION_HEX < 0x030b0000 + PyObject *version_info; + PyObject *py_minor_version = NULL; + #endif + long minor_version = 0; + PyObject *type, *value, *traceback; + PyErr_Fetch(&type, &value, &traceback); + #if __PYX_LIMITED_VERSION_HEX >= 0x030b0000 + minor_version = 11; + #else + if (!(version_info = PySys_GetObject("version_info"))) goto end; + if (!(py_minor_version = PySequence_GetItem(version_info, 1))) goto end; + minor_version = PyLong_AsLong(py_minor_version); + Py_DECREF(py_minor_version); + if (minor_version == -1 && PyErr_Occurred()) goto end; + #endif + if (!(types_module = PyImport_ImportModule("types"))) goto end; + if (!(code_type = PyObject_GetAttrString(types_module, "CodeType"))) goto end; + if (minor_version <= 7) { + (void)p; + result = PyObject_CallFunction(code_type, "iiiiiOOOOOOiOOO", a, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else if (minor_version <= 10) { + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOiOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, fline, lnos, fv, cell); + } else { + if (!(exception_table = PyBytes_FromStringAndSize(NULL, 0))) goto end; + result = PyObject_CallFunction(code_type, "iiiiiiOOOOOOOiOOOO", a,p, k, l, s, f, code, + c, n, v, fn, name, name, fline, lnos, exception_table, fv, cell); + } + end: + Py_XDECREF(code_type); + Py_XDECREF(exception_table); + Py_XDECREF(types_module); + if (type) { + PyErr_Restore(type, value, traceback); + } + return result; + } +#elif PY_VERSION_HEX >= 0x030B0000 + static PyCodeObject* __Pyx__PyCode_New(int a, int p, int k, int l, int s, int f, + PyObject *code, PyObject *c, PyObject* n, PyObject *v, + PyObject *fv, PyObject *cell, PyObject* fn, + PyObject *name, int fline, PyObject *lnos) { + PyCodeObject *result; + result = + #if PY_VERSION_HEX >= 0x030C0000 + PyUnstable_Code_NewWithPosOnlyArgs + #else + PyCode_NewWithPosOnlyArgs + #endif + (a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, name, fline, lnos, __pyx_mstate_global->__pyx_empty_bytes); + #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030c00A1 + if (likely(result)) + result->_co_firsttraceable = 0; + #endif + return result; + } +#elif !CYTHON_COMPILING_IN_PYPY + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_NewWithPosOnlyArgs(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#else + #define __Pyx__PyCode_New(a, p, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos)\ + PyCode_New(a, k, l, s, f, code, c, n, v, fv, cell, fn, name, fline, lnos) +#endif +static PyObject* __Pyx_PyCode_New( + const __Pyx_PyCode_New_function_description descr, + PyObject * const *varnames, + PyObject *filename, + PyObject *funcname, + PyObject *line_table, + PyObject *tuple_dedup_map +) { + PyObject *code_obj = NULL, *varnames_tuple_dedup = NULL, *code_bytes = NULL; + Py_ssize_t var_count = (Py_ssize_t) descr.nlocals; + PyObject *varnames_tuple = PyTuple_New(var_count); + if (unlikely(!varnames_tuple)) return NULL; + for (Py_ssize_t i=0; i < var_count; i++) { + Py_INCREF(varnames[i]); + if (__Pyx_PyTuple_SET_ITEM(varnames_tuple, i, varnames[i]) != (0)) goto done; + } + #if CYTHON_COMPILING_IN_LIMITED_API + varnames_tuple_dedup = PyDict_GetItem(tuple_dedup_map, varnames_tuple); + if (!varnames_tuple_dedup) { + if (unlikely(PyDict_SetItem(tuple_dedup_map, varnames_tuple, varnames_tuple) < 0)) goto done; + varnames_tuple_dedup = varnames_tuple; + } + #else + varnames_tuple_dedup = PyDict_SetDefault(tuple_dedup_map, varnames_tuple, varnames_tuple); + if (unlikely(!varnames_tuple_dedup)) goto done; + #endif + #if CYTHON_AVOID_BORROWED_REFS + Py_INCREF(varnames_tuple_dedup); + #endif + if (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table != NULL && !CYTHON_COMPILING_IN_GRAAL) { + Py_ssize_t line_table_length = __Pyx_PyBytes_GET_SIZE(line_table); + #if !CYTHON_ASSUME_SAFE_SIZE + if (unlikely(line_table_length == -1)) goto done; + #endif + Py_ssize_t code_len = (line_table_length * 2 + 4) & ~3LL; + code_bytes = PyBytes_FromStringAndSize(NULL, code_len); + if (unlikely(!code_bytes)) goto done; + char* c_code_bytes = PyBytes_AsString(code_bytes); + if (unlikely(!c_code_bytes)) goto done; + memset(c_code_bytes, 0, (size_t) code_len); + } + code_obj = (PyObject*) __Pyx__PyCode_New( + (int) descr.argcount, + (int) descr.num_posonly_args, + (int) descr.num_kwonly_args, + (int) descr.nlocals, + 0, + (int) descr.flags, + code_bytes ? code_bytes : __pyx_mstate_global->__pyx_empty_bytes, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + varnames_tuple_dedup, + __pyx_mstate_global->__pyx_empty_tuple, + __pyx_mstate_global->__pyx_empty_tuple, + filename, + funcname, + (int) descr.first_line, + (__PYX_LIMITED_VERSION_HEX >= (0x030b0000) && line_table) ? line_table : __pyx_mstate_global->__pyx_empty_bytes + ); +done: + Py_XDECREF(code_bytes); + #if CYTHON_AVOID_BORROWED_REFS + Py_XDECREF(varnames_tuple_dedup); + #endif + Py_DECREF(varnames_tuple); + return code_obj; +} + +/* DecompressString */ +static PyObject *__Pyx_DecompressString(const char *s, Py_ssize_t length, int algo) { + PyObject *module = NULL, *decompress, *compressed_bytes, *decompressed; + const char* module_name = algo == 3 ? "compression.zstd" : algo == 2 ? "bz2" : "zlib"; + PyObject *methodname = PyUnicode_FromString("decompress"); + if (unlikely(!methodname)) return NULL; + #if __PYX_LIMITED_VERSION_HEX >= 0x030e0000 + if (algo == 3) { + PyObject *fromlist = Py_BuildValue("[O]", methodname); + if (unlikely(!fromlist)) goto bad; + module = PyImport_ImportModuleLevel("compression.zstd", NULL, NULL, fromlist, 0); + Py_DECREF(fromlist); + } else + #endif + module = PyImport_ImportModule(module_name); + if (unlikely(!module)) goto import_failed; + decompress = PyObject_GetAttr(module, methodname); + if (unlikely(!decompress)) goto import_failed; + { + #ifdef __cplusplus + char *memview_bytes = const_cast(s); + #else + #if defined(__clang__) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wcast-qual" + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-qual" + #endif + char *memview_bytes = (char*) s; + #if defined(__clang__) + #pragma clang diagnostic pop + #elif !defined(__INTEL_COMPILER) && defined(__GNUC__) + #pragma GCC diagnostic pop + #endif + #endif + #if CYTHON_COMPILING_IN_LIMITED_API && !defined(PyBUF_READ) + int memview_flags = 0x100; + #else + int memview_flags = PyBUF_READ; + #endif + compressed_bytes = PyMemoryView_FromMemory(memview_bytes, length, memview_flags); + } + if (unlikely(!compressed_bytes)) { + Py_DECREF(decompress); + goto bad; + } + decompressed = PyObject_CallFunctionObjArgs(decompress, compressed_bytes, NULL); + Py_DECREF(compressed_bytes); + Py_DECREF(decompress); + Py_DECREF(module); + Py_DECREF(methodname); + return decompressed; +import_failed: + PyErr_Format(PyExc_ImportError, + "Failed to import '%.20s.decompress' - cannot initialise module strings. " + "String compression was configured with the C macro 'CYTHON_COMPRESS_STRINGS=%d'.", + module_name, algo); +bad: + Py_XDECREF(module); + Py_DECREF(methodname); + return NULL; +} + +#include +static CYTHON_INLINE Py_ssize_t __Pyx_ssize_strlen(const char *s) { + size_t len = strlen(s); + if (unlikely(len > (size_t) PY_SSIZE_T_MAX)) { + PyErr_SetString(PyExc_OverflowError, "byte string is too long"); + return -1; + } + return (Py_ssize_t) len; +} +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return __Pyx_PyUnicode_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE PyObject* __Pyx_PyByteArray_FromString(const char* c_str) { + Py_ssize_t len = __Pyx_ssize_strlen(c_str); + if (unlikely(len < 0)) return NULL; + return PyByteArray_FromStringAndSize(c_str, len); +} +static CYTHON_INLINE const char* __Pyx_PyObject_AsString(PyObject* o) { + Py_ssize_t ignore; + return __Pyx_PyObject_AsStringAndSize(o, &ignore); +} +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 +static CYTHON_INLINE const char* __Pyx_PyUnicode_AsStringAndSize(PyObject* o, Py_ssize_t *length) { + if (unlikely(__Pyx_PyUnicode_READY(o) == -1)) return NULL; +#if CYTHON_COMPILING_IN_LIMITED_API + { + const char* result; + Py_ssize_t unicode_length; + CYTHON_MAYBE_UNUSED_VAR(unicode_length); // only for __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + #if __PYX_LIMITED_VERSION_HEX < 0x030A0000 + if (unlikely(PyArg_Parse(o, "s#", &result, length) < 0)) return NULL; + #else + result = PyUnicode_AsUTF8AndSize(o, length); + #endif + #if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + unicode_length = PyUnicode_GetLength(o); + if (unlikely(unicode_length < 0)) return NULL; + if (unlikely(unicode_length != *length)) { + PyUnicode_AsASCIIString(o); + return NULL; + } + #endif + return result; + } +#else +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII + if (likely(PyUnicode_IS_ASCII(o))) { + *length = PyUnicode_GET_LENGTH(o); + return PyUnicode_AsUTF8(o); + } else { + PyUnicode_AsASCIIString(o); + return NULL; + } +#else + return PyUnicode_AsUTF8AndSize(o, length); +#endif +#endif +} +#endif +static CYTHON_INLINE const char* __Pyx_PyObject_AsStringAndSize(PyObject* o, Py_ssize_t *length) { +#if __PYX_DEFAULT_STRING_ENCODING_IS_ASCII || __PYX_DEFAULT_STRING_ENCODING_IS_UTF8 + if (PyUnicode_Check(o)) { + return __Pyx_PyUnicode_AsStringAndSize(o, length); + } else +#endif + if (PyByteArray_Check(o)) { +#if (CYTHON_ASSUME_SAFE_SIZE && CYTHON_ASSUME_SAFE_MACROS) || (CYTHON_COMPILING_IN_PYPY && (defined(PyByteArray_AS_STRING) && defined(PyByteArray_GET_SIZE))) + *length = PyByteArray_GET_SIZE(o); + return PyByteArray_AS_STRING(o); +#else + *length = PyByteArray_Size(o); + if (*length == -1) return NULL; + return PyByteArray_AsString(o); +#endif + } else + { + char* result; + int r = PyBytes_AsStringAndSize(o, &result, length); + if (unlikely(r < 0)) { + return NULL; + } else { + return result; + } + } +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject* x) { + int is_true = x == Py_True; + if (is_true | (x == Py_False) | (x == Py_None)) return is_true; + else return PyObject_IsTrue(x); +} +static CYTHON_INLINE int __Pyx_PyObject_IsTrueAndDecref(PyObject* x) { + int retval; + if (unlikely(!x)) return -1; + retval = __Pyx_PyObject_IsTrue(x); + Py_DECREF(x); + return retval; +} +static PyObject* __Pyx_PyNumber_LongWrongResultType(PyObject* result) { + __Pyx_TypeName result_type_name = __Pyx_PyType_GetFullyQualifiedName(Py_TYPE(result)); + if (PyLong_Check(result)) { + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME "). " + "The ability to return an instance of a strict subclass of int is deprecated, " + "and may be removed in a future version of Python.", + result_type_name)) { + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; + } + __Pyx_DECREF_TypeName(result_type_name); + return result; + } + PyErr_Format(PyExc_TypeError, + "__int__ returned non-int (type " __Pyx_FMT_TYPENAME ")", + result_type_name); + __Pyx_DECREF_TypeName(result_type_name); + Py_DECREF(result); + return NULL; +} +static CYTHON_INLINE PyObject* __Pyx_PyNumber_Long(PyObject* x) { +#if CYTHON_USE_TYPE_SLOTS + PyNumberMethods *m; +#endif + PyObject *res = NULL; + if (likely(PyLong_Check(x))) + return __Pyx_NewRef(x); +#if CYTHON_USE_TYPE_SLOTS + m = Py_TYPE(x)->tp_as_number; + if (likely(m && m->nb_int)) { + res = m->nb_int(x); + } +#else + if (!PyBytes_CheckExact(x) && !PyUnicode_CheckExact(x)) { + res = PyNumber_Long(x); + } +#endif + if (likely(res)) { + if (unlikely(!PyLong_CheckExact(res))) { + return __Pyx_PyNumber_LongWrongResultType(res); + } + } + else if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_TypeError, + "an integer is required"); + } + return res; +} +static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { + Py_ssize_t ival; + PyObject *x; + if (likely(PyLong_CheckExact(b))) { + #if CYTHON_USE_PYLONG_INTERNALS + if (likely(__Pyx_PyLong_IsCompact(b))) { + return __Pyx_PyLong_CompactValue(b); + } else { + const digit* digits = __Pyx_PyLong_Digits(b); + const Py_ssize_t size = __Pyx_PyLong_SignedDigitCount(b); + switch (size) { + case 2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return (Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -2: + if (8 * sizeof(Py_ssize_t) > 2 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -3: + if (8 * sizeof(Py_ssize_t) > 3 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case 4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return (Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + case -4: + if (8 * sizeof(Py_ssize_t) > 4 * PyLong_SHIFT) { + return -(Py_ssize_t) (((((((((size_t)digits[3]) << PyLong_SHIFT) | (size_t)digits[2]) << PyLong_SHIFT) | (size_t)digits[1]) << PyLong_SHIFT) | (size_t)digits[0])); + } + break; + } + } + #endif + return PyLong_AsSsize_t(b); + } + x = PyNumber_Index(b); + if (!x) return -1; + ival = PyLong_AsSsize_t(x); + Py_DECREF(x); + return ival; +} +static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) { + if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) { + return (Py_hash_t) __Pyx_PyIndex_AsSsize_t(o); + } else { + Py_ssize_t ival; + PyObject *x; + x = PyNumber_Index(o); + if (!x) return -1; + ival = PyLong_AsLong(x); + Py_DECREF(x); + return ival; + } +} +static CYTHON_INLINE PyObject *__Pyx_Owned_Py_None(int b) { + CYTHON_UNUSED_VAR(b); + return __Pyx_NewRef(Py_None); +} +static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { + return __Pyx_NewRef(b ? Py_True: Py_False); +} +static CYTHON_INLINE PyObject * __Pyx_PyLong_FromSize_t(size_t ival) { + return PyLong_FromSize_t(ival); +} + + +/* MultiPhaseInitModuleState */ +#if CYTHON_PEP489_MULTI_PHASE_INIT && CYTHON_USE_MODULE_STATE +#ifndef CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#if (CYTHON_COMPILING_IN_LIMITED_API || PY_VERSION_HEX >= 0x030C0000) + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 1 +#else + #define CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE 0 +#endif +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE && !CYTHON_ATOMICS +#error "Module state with PEP489 requires atomics. Currently that's one of\ + C11, C++11, gcc atomic intrinsics or MSVC atomic intrinsics" +#endif +#if !CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +#define __Pyx_ModuleStateLookup_Lock() +#define __Pyx_ModuleStateLookup_Unlock() +#elif !CYTHON_COMPILING_IN_LIMITED_API && PY_VERSION_HEX >= 0x030d0000 +static PyMutex __Pyx_ModuleStateLookup_mutex = {0}; +#define __Pyx_ModuleStateLookup_Lock() PyMutex_Lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() PyMutex_Unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(__cplusplus) && __cplusplus >= 201103L +#include +static std::mutex __Pyx_ModuleStateLookup_mutex; +#define __Pyx_ModuleStateLookup_Lock() __Pyx_ModuleStateLookup_mutex.lock() +#define __Pyx_ModuleStateLookup_Unlock() __Pyx_ModuleStateLookup_mutex.unlock() +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ > 201112L) && !defined(__STDC_NO_THREADS__) +#include +static mtx_t __Pyx_ModuleStateLookup_mutex; +static once_flag __Pyx_ModuleStateLookup_mutex_once_flag = ONCE_FLAG_INIT; +static void __Pyx_ModuleStateLookup_initialize_mutex(void) { + mtx_init(&__Pyx_ModuleStateLookup_mutex, mtx_plain); +} +#define __Pyx_ModuleStateLookup_Lock()\ + call_once(&__Pyx_ModuleStateLookup_mutex_once_flag, __Pyx_ModuleStateLookup_initialize_mutex);\ + mtx_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() mtx_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(HAVE_PTHREAD_H) +#include +static pthread_mutex_t __Pyx_ModuleStateLookup_mutex = PTHREAD_MUTEX_INITIALIZER; +#define __Pyx_ModuleStateLookup_Lock() pthread_mutex_lock(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() pthread_mutex_unlock(&__Pyx_ModuleStateLookup_mutex) +#elif defined(_WIN32) +#include // synchapi.h on its own doesn't work +static SRWLOCK __Pyx_ModuleStateLookup_mutex = SRWLOCK_INIT; +#define __Pyx_ModuleStateLookup_Lock() AcquireSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#define __Pyx_ModuleStateLookup_Unlock() ReleaseSRWLockExclusive(&__Pyx_ModuleStateLookup_mutex) +#else +#error "No suitable lock available for CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE.\ + Requires C standard >= C11, or C++ standard >= C++11,\ + or pthreads, or the Windows 32 API, or Python >= 3.13." +#endif +typedef struct { + int64_t id; + PyObject *module; +} __Pyx_InterpreterIdAndModule; +typedef struct { + char interpreter_id_as_index; + Py_ssize_t count; + Py_ssize_t allocated; + __Pyx_InterpreterIdAndModule table[1]; +} __Pyx_ModuleStateLookupData; +#define __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE 32 +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_int_type __Pyx_ModuleStateLookup_read_counter = 0; +#endif +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static __pyx_atomic_ptr_type __Pyx_ModuleStateLookup_data = 0; +#else +static __Pyx_ModuleStateLookupData* __Pyx_ModuleStateLookup_data = NULL; +#endif +static __Pyx_InterpreterIdAndModule* __Pyx_State_FindModuleStateLookupTableLowerBound( + __Pyx_InterpreterIdAndModule* table, + Py_ssize_t count, + int64_t interpreterId) { + __Pyx_InterpreterIdAndModule* begin = table; + __Pyx_InterpreterIdAndModule* end = begin + count; + if (begin->id == interpreterId) { + return begin; + } + while ((end - begin) > __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + __Pyx_InterpreterIdAndModule* halfway = begin + (end - begin)/2; + if (halfway->id == interpreterId) { + return halfway; + } + if (halfway->id < interpreterId) { + begin = halfway; + } else { + end = halfway; + } + } + for (; begin < end; ++begin) { + if (begin->id >= interpreterId) return begin; + } + return begin; +} +static PyObject *__Pyx_State_FindModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return NULL; +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData* data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + { + __pyx_atomic_incr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + if (likely(data)) { + __Pyx_ModuleStateLookupData* new_data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_acquire(&__Pyx_ModuleStateLookup_data); + if (likely(data == new_data)) { + goto read_finished; + } + } + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); + __Pyx_ModuleStateLookup_Lock(); + __pyx_atomic_incr_relaxed(&__Pyx_ModuleStateLookup_read_counter); + data = (__Pyx_ModuleStateLookupData*)__pyx_atomic_pointer_load_relaxed(&__Pyx_ModuleStateLookup_data); + __Pyx_ModuleStateLookup_Unlock(); + } + read_finished:; +#else + __Pyx_ModuleStateLookupData* data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_InterpreterIdAndModule* found = NULL; + if (unlikely(!data)) goto end; + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + found = data->table+interpreter_id; + } + } else { + found = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + } + end: + { + PyObject *result=NULL; + if (found && found->id == interpreter_id) { + result = found->module; + } +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_decr_acq_rel(&__Pyx_ModuleStateLookup_read_counter); +#endif + return result; + } +} +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE +static void __Pyx_ModuleStateLookup_wait_until_no_readers(void) { + while (__pyx_atomic_load(&__Pyx_ModuleStateLookup_read_counter) != 0); +} +#else +#define __Pyx_ModuleStateLookup_wait_until_no_readers() +#endif +static int __Pyx_State_AddModuleInterpIdAsIndex(__Pyx_ModuleStateLookupData **old_data, PyObject* module, int64_t interpreter_id) { + Py_ssize_t to_allocate = (*old_data)->allocated; + while (to_allocate <= interpreter_id) { + if (to_allocate == 0) to_allocate = 1; + else to_allocate *= 2; + } + __Pyx_ModuleStateLookupData *new_data = *old_data; + if (to_allocate != (*old_data)->allocated) { + new_data = (__Pyx_ModuleStateLookupData *)realloc( + *old_data, + sizeof(__Pyx_ModuleStateLookupData)+(to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + PyErr_NoMemory(); + return -1; + } + for (Py_ssize_t i = new_data->allocated; i < to_allocate; ++i) { + new_data->table[i].id = i; + new_data->table[i].module = NULL; + } + new_data->allocated = to_allocate; + } + new_data->table[interpreter_id].module = module; + if (new_data->count < interpreter_id+1) { + new_data->count = interpreter_id+1; + } + *old_data = new_data; + return 0; +} +static void __Pyx_State_ConvertFromInterpIdAsIndex(__Pyx_ModuleStateLookupData *data) { + __Pyx_InterpreterIdAndModule *read = data->table; + __Pyx_InterpreterIdAndModule *write = data->table; + __Pyx_InterpreterIdAndModule *end = read + data->count; + for (; readmodule) { + write->id = read->id; + write->module = read->module; + ++write; + } + } + data->count = write - data->table; + for (; writeid = 0; + write->module = NULL; + } + data->interpreter_id_as_index = 0; +} +static int __Pyx_State_AddModule(PyObject* module, CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + int result = 0; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *old_data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *old_data = __Pyx_ModuleStateLookup_data; +#endif + __Pyx_ModuleStateLookupData *new_data = old_data; + if (!new_data) { + new_data = (__Pyx_ModuleStateLookupData *)calloc(1, sizeof(__Pyx_ModuleStateLookupData)); + if (!new_data) { + result = -1; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = 1; + new_data->interpreter_id_as_index = 1; + } + __Pyx_ModuleStateLookup_wait_until_no_readers(); + if (new_data->interpreter_id_as_index) { + if (interpreter_id < __PYX_MODULE_STATE_LOOKUP_SMALL_SIZE) { + result = __Pyx_State_AddModuleInterpIdAsIndex(&new_data, module, interpreter_id); + goto end; + } + __Pyx_State_ConvertFromInterpIdAsIndex(new_data); + } + { + Py_ssize_t insert_at = 0; + { + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + new_data->table, new_data->count, interpreter_id); + assert(lower_bound); + insert_at = lower_bound - new_data->table; + if (unlikely(insert_at < new_data->count && lower_bound->id == interpreter_id)) { + lower_bound->module = module; + goto end; // already in table, nothing more to do + } + } + if (new_data->count+1 >= new_data->allocated) { + Py_ssize_t to_allocate = (new_data->count+1)*2; + new_data = + (__Pyx_ModuleStateLookupData*)realloc( + new_data, + sizeof(__Pyx_ModuleStateLookupData) + + (to_allocate-1)*sizeof(__Pyx_InterpreterIdAndModule)); + if (!new_data) { + result = -1; + new_data = old_data; + PyErr_NoMemory(); + goto end; + } + new_data->allocated = to_allocate; + } + ++new_data->count; + int64_t last_id = interpreter_id; + PyObject *last_module = module; + for (Py_ssize_t i=insert_at; icount; ++i) { + int64_t current_id = new_data->table[i].id; + new_data->table[i].id = last_id; + last_id = current_id; + PyObject *current_module = new_data->table[i].module; + new_data->table[i].module = last_module; + last_module = current_module; + } + } + end: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, new_data); +#else + __Pyx_ModuleStateLookup_data = new_data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return result; +} +static int __Pyx_State_RemoveModule(CYTHON_UNUSED void* dummy) { + int64_t interpreter_id = PyInterpreterState_GetID(__Pyx_PyInterpreterState_Get()); + if (interpreter_id == -1) return -1; + __Pyx_ModuleStateLookup_Lock(); +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __Pyx_ModuleStateLookupData *data = (__Pyx_ModuleStateLookupData *) + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, 0); +#else + __Pyx_ModuleStateLookupData *data = __Pyx_ModuleStateLookup_data; +#endif + if (data->interpreter_id_as_index) { + if (interpreter_id < data->count) { + data->table[interpreter_id].module = NULL; + } + goto done; + } + { + __Pyx_ModuleStateLookup_wait_until_no_readers(); + __Pyx_InterpreterIdAndModule* lower_bound = __Pyx_State_FindModuleStateLookupTableLowerBound( + data->table, data->count, interpreter_id); + if (!lower_bound) goto done; + if (lower_bound->id != interpreter_id) goto done; + __Pyx_InterpreterIdAndModule *end = data->table+data->count; + for (;lower_boundid = (lower_bound+1)->id; + lower_bound->module = (lower_bound+1)->module; + } + } + --data->count; + if (data->count == 0) { + free(data); + data = NULL; + } + done: +#if CYTHON_MODULE_STATE_LOOKUP_THREAD_SAFE + __pyx_atomic_pointer_exchange(&__Pyx_ModuleStateLookup_data, data); +#else + __Pyx_ModuleStateLookup_data = data; +#endif + __Pyx_ModuleStateLookup_Unlock(); + return 0; +} +#endif + +/* #### Code section: utility_code_pragmas_end ### */ +#ifdef _MSC_VER +#pragma warning( pop ) +#endif + + + +/* #### Code section: end ### */ +#endif /* Py_PYTHON_H */ diff --git a/app/core/tenancy.cpython-313-aarch64-linux-gnu.so b/app/core/tenancy.cpython-313-aarch64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..13e8fcd4167ef73489dc6cecf190ceb87c11372b GIT binary patch literal 79344 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

B!U=hBGoAi;>lqw0=fJr+-$^7Ukdwm$ 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 literal 0 HcmV?d00001 diff --git a/app/core/tenancy.py b/app/core/tenancy.py new file mode 100644 index 0000000..7d5d91f --- /dev/null +++ b/app/core/tenancy.py @@ -0,0 +1,33 @@ +"""PR12: organization-tenancy scoping. + +Neither this service nor omnibioai-hpc-policy-engine had any concept of +org_id before this PR -- authorization was scoped only per user_id. This +adds an additive tenancy gate: if the request names which organization +owns the resource being acted on (`context["resource_org_id"]`, supplied +by the caller -- this service has no database of its own to look +resource ownership up in), the requester's own `org_id` must match it. + +Opt-in the same way app/core/permissions.py is: a caller that never +supplies `resource_org_id` in context (true of every caller today) gets +"no tenancy scoping required" -- a no-op, not a new restriction on +existing traffic. It only activates once a caller (a fixture in these +tests, or eventually the Gateway once it's taught which org owns a given +resource) actually supplies it. +""" + +from typing import Any, Dict + + +def evaluate_tenancy(org_id: Any, context: Dict[str, Any]) -> tuple[bool, str]: + resource_org_id = context.get("resource_org_id") + + if resource_org_id is None: + return True, "no tenancy scoping required" + + if org_id is None: + return False, "missing organization context" + + if str(org_id) != str(resource_org_id): + return False, "cross-tenant access denied" + + return True, "tenancy check passed" diff --git a/app/models/request.py b/app/models/request.py index 50685d8..b60681a 100644 --- a/app/models/request.py +++ b/app/models/request.py @@ -7,6 +7,8 @@ class PolicyRequest(BaseModel): email: Optional[str] = None roles: list[str] = [] permissions: list[str] = [] + # PR12: requester's organization, for tenancy scoping (app/core/tenancy.py). + org_id: Optional[str] = None action: str resource: str diff --git a/app/services/cache.c b/app/services/cache.c index 4ef8969..6a332d9 100644 --- a/app/services/cache.c +++ b/app/services/cache.c @@ -1961,6 +1961,9 @@ static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr PyObject_Format(s, f)) #endif +/* PyUnicode_Unicode.proto */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj); + /* JoinPyUnicode.export */ static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count, Py_ssize_t result_ulength, Py_UCS4 max_char); @@ -2341,7 +2344,7 @@ int __pyx_module_is_main_app__services__cache = 0; /* #### Code section: string_decls ### */ /* #### Code section: decls ### */ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache___init__(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_redis_url); /* proto */ -static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_user_id, PyObject *__pyx_v_action, PyObject *__pyx_v_resource, PyObject *__pyx_v_context); /* proto */ +static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_user_id, PyObject *__pyx_v_action, PyObject *__pyx_v_resource, PyObject *__pyx_v_context, PyObject *__pyx_v_org_id, PyObject *__pyx_v_permissions); /* proto */ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_4get(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_key); /* proto */ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_6set(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_key, PyObject *__pyx_v_value, PyObject *__pyx_v_ttl); /* proto */ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_self, PyObject *__pyx_v_user_id); /* proto */ @@ -2368,9 +2371,9 @@ typedef struct { __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_items; __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_pop; __Pyx_CachedCFunction __pyx_umethod_PyDict_Type_values; - PyObject *__pyx_tuple[1]; + PyObject *__pyx_tuple[2]; PyObject *__pyx_codeobj_tab[5]; - PyObject *__pyx_string_tab[76]; + PyObject *__pyx_string_tab[81]; PyObject *__pyx_number_tab[1]; /* #### Code section: module_state_contents ### */ /* CommonTypesMetaclass.module_state_decls */ @@ -2413,81 +2416,86 @@ static __pyx_mstatetype * const __pyx_mstate_global = &__pyx_mstate_global_stati #endif /* #### Code section: constant_name_defines ### */ #define __pyx_kp_u_ __pyx_string_tab[0] -#define __pyx_kp_u_Note_that_Cython_is_deliberately __pyx_string_tab[1] -#define __pyx_kp_u_Optional_dict __pyx_string_tab[2] -#define __pyx_kp_u__2 __pyx_string_tab[3] -#define __pyx_kp_u__3 __pyx_string_tab[4] -#define __pyx_kp_u_add_note __pyx_string_tab[5] -#define __pyx_kp_u_app_services_cache_py __pyx_string_tab[6] -#define __pyx_kp_u_policy __pyx_string_tab[7] -#define __pyx_kp_u_policy_2 __pyx_string_tab[8] -#define __pyx_n_u_Any __pyx_string_tab[9] -#define __pyx_n_u_Optional __pyx_string_tab[10] -#define __pyx_n_u_PolicyCache __pyx_string_tab[11] -#define __pyx_n_u_PolicyCache___init __pyx_string_tab[12] -#define __pyx_n_u_PolicyCache_build_key __pyx_string_tab[13] -#define __pyx_n_u_PolicyCache_get __pyx_string_tab[14] -#define __pyx_n_u_PolicyCache_invalidate_user __pyx_string_tab[15] -#define __pyx_n_u_PolicyCache_set __pyx_string_tab[16] -#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[17] -#define __pyx_n_u_action __pyx_string_tab[18] -#define __pyx_n_u_app_services_cache __pyx_string_tab[19] -#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[20] -#define __pyx_n_u_build_key __pyx_string_tab[21] -#define __pyx_n_u_cline_in_traceback __pyx_string_tab[22] -#define __pyx_n_u_context __pyx_string_tab[23] -#define __pyx_n_u_decode_responses __pyx_string_tab[24] -#define __pyx_n_u_delete __pyx_string_tab[25] -#define __pyx_n_u_dict __pyx_string_tab[26] -#define __pyx_n_u_digest __pyx_string_tab[27] -#define __pyx_n_u_doc __pyx_string_tab[28] -#define __pyx_n_u_dumps __pyx_string_tab[29] -#define __pyx_n_u_from_url __pyx_string_tab[30] -#define __pyx_n_u_func __pyx_string_tab[31] -#define __pyx_n_u_get __pyx_string_tab[32] -#define __pyx_n_u_hashlib __pyx_string_tab[33] -#define __pyx_n_u_hexdigest __pyx_string_tab[34] -#define __pyx_n_u_init __pyx_string_tab[35] -#define __pyx_n_u_int __pyx_string_tab[36] -#define __pyx_n_u_invalidate_user __pyx_string_tab[37] -#define __pyx_n_u_is_coroutine __pyx_string_tab[38] -#define __pyx_n_u_items __pyx_string_tab[39] -#define __pyx_n_u_json __pyx_string_tab[40] -#define __pyx_n_u_key __pyx_string_tab[41] -#define __pyx_n_u_loads __pyx_string_tab[42] -#define __pyx_n_u_main __pyx_string_tab[43] -#define __pyx_n_u_metaclass __pyx_string_tab[44] -#define __pyx_n_u_module __pyx_string_tab[45] -#define __pyx_n_u_name __pyx_string_tab[46] -#define __pyx_n_u_pop __pyx_string_tab[47] -#define __pyx_n_u_prepare __pyx_string_tab[48] -#define __pyx_n_u_qualname __pyx_string_tab[49] -#define __pyx_n_u_raw __pyx_string_tab[50] -#define __pyx_n_u_redis __pyx_string_tab[51] -#define __pyx_n_u_redis_url __pyx_string_tab[52] -#define __pyx_n_u_resource __pyx_string_tab[53] -#define __pyx_n_u_return __pyx_string_tab[54] -#define __pyx_n_u_scan_iter __pyx_string_tab[55] -#define __pyx_n_u_self __pyx_string_tab[56] -#define __pyx_n_u_set __pyx_string_tab[57] -#define __pyx_n_u_set_name __pyx_string_tab[58] -#define __pyx_n_u_setdefault __pyx_string_tab[59] -#define __pyx_n_u_setex __pyx_string_tab[60] -#define __pyx_n_u_sha256 __pyx_string_tab[61] -#define __pyx_n_u_sort_keys __pyx_string_tab[62] -#define __pyx_n_u_str __pyx_string_tab[63] -#define __pyx_n_u_test __pyx_string_tab[64] -#define __pyx_n_u_ttl __pyx_string_tab[65] -#define __pyx_n_u_typing __pyx_string_tab[66] -#define __pyx_n_u_user_id __pyx_string_tab[67] -#define __pyx_n_u_val __pyx_string_tab[68] -#define __pyx_n_u_value __pyx_string_tab[69] -#define __pyx_n_u_values __pyx_string_tab[70] -#define __pyx_kp_b_iso88591_6_a_F_e4vQa __pyx_string_tab[71] -#define __pyx_kp_b_iso88591_IU_1K __pyx_string_tab[72] -#define __pyx_kp_b_iso88591_o_9TU_c_9Jat6_Q_q_7_Zq_y __pyx_string_tab[73] -#define __pyx_kp_b_iso88591_q_G4vZq_xs_F __pyx_string_tab[74] -#define __pyx_kp_b_iso88591_xq_d_AQ_1_4vQa_q __pyx_string_tab[75] +#define __pyx_kp_u_None __pyx_string_tab[1] +#define __pyx_kp_u_Note_that_Cython_is_deliberately __pyx_string_tab[2] +#define __pyx_kp_u_Optional_dict __pyx_string_tab[3] +#define __pyx_kp_u_Optional_list __pyx_string_tab[4] +#define __pyx_kp_u_Optional_str __pyx_string_tab[5] +#define __pyx_kp_u__2 __pyx_string_tab[6] +#define __pyx_kp_u__3 __pyx_string_tab[7] +#define __pyx_kp_u_add_note __pyx_string_tab[8] +#define __pyx_kp_u_app_services_cache_py __pyx_string_tab[9] +#define __pyx_kp_u_policy __pyx_string_tab[10] +#define __pyx_kp_u_policy_2 __pyx_string_tab[11] +#define __pyx_n_u_Any __pyx_string_tab[12] +#define __pyx_n_u_Optional __pyx_string_tab[13] +#define __pyx_n_u_PolicyCache __pyx_string_tab[14] +#define __pyx_n_u_PolicyCache___init __pyx_string_tab[15] +#define __pyx_n_u_PolicyCache_build_key __pyx_string_tab[16] +#define __pyx_n_u_PolicyCache_get __pyx_string_tab[17] +#define __pyx_n_u_PolicyCache_invalidate_user __pyx_string_tab[18] +#define __pyx_n_u_PolicyCache_set __pyx_string_tab[19] +#define __pyx_n_u_Pyx_PyDict_NextRef __pyx_string_tab[20] +#define __pyx_n_u_action __pyx_string_tab[21] +#define __pyx_n_u_app_services_cache __pyx_string_tab[22] +#define __pyx_n_u_asyncio_coroutines __pyx_string_tab[23] +#define __pyx_n_u_build_key __pyx_string_tab[24] +#define __pyx_n_u_cline_in_traceback __pyx_string_tab[25] +#define __pyx_n_u_context __pyx_string_tab[26] +#define __pyx_n_u_decode_responses __pyx_string_tab[27] +#define __pyx_n_u_delete __pyx_string_tab[28] +#define __pyx_n_u_dict __pyx_string_tab[29] +#define __pyx_n_u_digest __pyx_string_tab[30] +#define __pyx_n_u_doc __pyx_string_tab[31] +#define __pyx_n_u_dumps __pyx_string_tab[32] +#define __pyx_n_u_from_url __pyx_string_tab[33] +#define __pyx_n_u_func __pyx_string_tab[34] +#define __pyx_n_u_get __pyx_string_tab[35] +#define __pyx_n_u_hashlib __pyx_string_tab[36] +#define __pyx_n_u_hexdigest __pyx_string_tab[37] +#define __pyx_n_u_init __pyx_string_tab[38] +#define __pyx_n_u_int __pyx_string_tab[39] +#define __pyx_n_u_invalidate_user __pyx_string_tab[40] +#define __pyx_n_u_is_coroutine __pyx_string_tab[41] +#define __pyx_n_u_items __pyx_string_tab[42] +#define __pyx_n_u_json __pyx_string_tab[43] +#define __pyx_n_u_key __pyx_string_tab[44] +#define __pyx_n_u_loads __pyx_string_tab[45] +#define __pyx_n_u_main __pyx_string_tab[46] +#define __pyx_n_u_metaclass __pyx_string_tab[47] +#define __pyx_n_u_module __pyx_string_tab[48] +#define __pyx_n_u_name __pyx_string_tab[49] +#define __pyx_n_u_org_id __pyx_string_tab[50] +#define __pyx_n_u_permissions __pyx_string_tab[51] +#define __pyx_n_u_pop __pyx_string_tab[52] +#define __pyx_n_u_prepare __pyx_string_tab[53] +#define __pyx_n_u_qualname __pyx_string_tab[54] +#define __pyx_n_u_raw __pyx_string_tab[55] +#define __pyx_n_u_redis __pyx_string_tab[56] +#define __pyx_n_u_redis_url __pyx_string_tab[57] +#define __pyx_n_u_resource __pyx_string_tab[58] +#define __pyx_n_u_return __pyx_string_tab[59] +#define __pyx_n_u_scan_iter __pyx_string_tab[60] +#define __pyx_n_u_self __pyx_string_tab[61] +#define __pyx_n_u_set __pyx_string_tab[62] +#define __pyx_n_u_set_name __pyx_string_tab[63] +#define __pyx_n_u_setdefault __pyx_string_tab[64] +#define __pyx_n_u_setex __pyx_string_tab[65] +#define __pyx_n_u_sha256 __pyx_string_tab[66] +#define __pyx_n_u_sort_keys __pyx_string_tab[67] +#define __pyx_n_u_str __pyx_string_tab[68] +#define __pyx_n_u_test __pyx_string_tab[69] +#define __pyx_n_u_ttl __pyx_string_tab[70] +#define __pyx_n_u_typing __pyx_string_tab[71] +#define __pyx_n_u_user_id __pyx_string_tab[72] +#define __pyx_n_u_val __pyx_string_tab[73] +#define __pyx_n_u_value __pyx_string_tab[74] +#define __pyx_n_u_values __pyx_string_tab[75] +#define __pyx_kp_b_iso88591_6_a_F_e4vQa __pyx_string_tab[76] +#define __pyx_kp_b_iso88591_A_Q_z_AT_q_1_axq_F_c_q_7_Zq_y __pyx_string_tab[77] +#define __pyx_kp_b_iso88591_IU_1K __pyx_string_tab[78] +#define __pyx_kp_b_iso88591_q_G4vZq_xs_F __pyx_string_tab[79] +#define __pyx_kp_b_iso88591_xq_d_AQ_1_4vQa_q __pyx_string_tab[80] #define __pyx_int_300 __pyx_number_tab[0] /* #### Code section: module_state_clear ### */ #if CYTHON_USE_MODULE_STATE @@ -2503,9 +2511,9 @@ static CYTHON_SMALL_CODE int __pyx_m_clear(PyObject *m) { #if CYTHON_PEP489_MULTI_PHASE_INIT __Pyx_State_RemoveModule(NULL); #endif - for (int i=0; i<1; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } + for (int i=0; i<2; ++i) { Py_CLEAR(clear_module_state->__pyx_tuple[i]); } for (int i=0; i<5; ++i) { Py_CLEAR(clear_module_state->__pyx_codeobj_tab[i]); } - for (int i=0; i<76; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } + for (int i=0; i<81; ++i) { Py_CLEAR(clear_module_state->__pyx_string_tab[i]); } for (int i=0; i<1; ++i) { Py_CLEAR(clear_module_state->__pyx_number_tab[i]); } /* #### Code section: module_state_clear_contents ### */ /* CommonTypesMetaclass.module_state_clear */ @@ -2529,9 +2537,9 @@ static CYTHON_SMALL_CODE int __pyx_m_traverse(PyObject *m, visitproc visit, void __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_tuple); __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_bytes); __Pyx_VISIT_CONST(traverse_module_state->__pyx_empty_unicode); - for (int i=0; i<1; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } + for (int i=0; i<2; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_tuple[i]); } for (int i=0; i<5; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_codeobj_tab[i]); } - for (int i=0; i<76; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } + for (int i=0; i<81; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_string_tab[i]); } for (int i=0; i<1; ++i) { __Pyx_VISIT_CONST(traverse_module_state->__pyx_number_tab[i]); } /* #### Code section: module_state_traverse_contents ### */ /* CommonTypesMetaclass.module_state_traverse */ @@ -2737,9 +2745,9 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache___init__(CYTHON_UN /* "app/services/cache.py":14 * # deterministic cache key * # ---------------------------- - * def build_key(self, user_id: str, action: str, resource: str, context: dict) -> str: # <<<<<<<<<<<<<< - * raw = f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}" - * digest = hashlib.sha256(raw.encode()).hexdigest() + * def build_key( # <<<<<<<<<<<<<< + * self, + * user_id: str, */ /* Python wrapper */ @@ -2763,11 +2771,13 @@ PyObject *__pyx_args, PyObject *__pyx_kwds PyObject *__pyx_v_action = 0; PyObject *__pyx_v_resource = 0; PyObject *__pyx_v_context = 0; + PyObject *__pyx_v_org_id = 0; + PyObject *__pyx_v_permissions = 0; #if !CYTHON_METH_FASTCALL CYTHON_UNUSED Py_ssize_t __pyx_nargs; #endif CYTHON_UNUSED PyObject *const *__pyx_kwvalues; - PyObject* values[5] = {0,0,0,0,0}; + PyObject* values[7] = {0,0,0,0,0,0,0}; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; @@ -2783,11 +2793,19 @@ PyObject *__pyx_args, PyObject *__pyx_kwds #endif __pyx_kwvalues = __Pyx_KwValues_FASTCALL(__pyx_args, __pyx_nargs); { - PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_user_id,&__pyx_mstate_global->__pyx_n_u_action,&__pyx_mstate_global->__pyx_n_u_resource,&__pyx_mstate_global->__pyx_n_u_context,0}; + PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_user_id,&__pyx_mstate_global->__pyx_n_u_action,&__pyx_mstate_global->__pyx_n_u_resource,&__pyx_mstate_global->__pyx_n_u_context,&__pyx_mstate_global->__pyx_n_u_org_id,&__pyx_mstate_global->__pyx_n_u_permissions,0}; const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 14, __pyx_L3_error) if (__pyx_kwds_len > 0) { switch (__pyx_nargs) { + case 7: + values[6] = __Pyx_ArgRef_FASTCALL(__pyx_args, 6); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[6])) __PYX_ERR(0, 14, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 6: + values[5] = __Pyx_ArgRef_FASTCALL(__pyx_args, 5); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[5])) __PYX_ERR(0, 14, __pyx_L3_error) + CYTHON_FALLTHROUGH; case 5: values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 14, __pyx_L3_error) @@ -2813,32 +2831,81 @@ PyObject *__pyx_args, PyObject *__pyx_kwds } const Py_ssize_t kwd_pos_args = __pyx_nargs; if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "build_key", 0) < (0)) __PYX_ERR(0, 14, __pyx_L3_error) + + /* "app/services/cache.py":20 + * resource: str, + * context: dict, + * org_id: Optional[str] = None, # <<<<<<<<<<<<<< + * permissions: Optional[list] = None, + * ) -> str: +*/ + if (!values[5]) values[5] = __Pyx_NewRef(((PyObject*)Py_None)); + + /* "app/services/cache.py":21 + * context: dict, + * org_id: Optional[str] = None, + * permissions: Optional[list] = None, # <<<<<<<<<<<<<< + * ) -> str: + * # PR12: org_id/permissions now affect the decision (tenancy.py, +*/ + if (!values[6]) values[6] = __Pyx_NewRef(((PyObject*)Py_None)); for (Py_ssize_t i = __pyx_nargs; i < 5; i++) { - if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("build_key", 1, 5, 5, i); __PYX_ERR(0, 14, __pyx_L3_error) } + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("build_key", 0, 5, 7, i); __PYX_ERR(0, 14, __pyx_L3_error) } } - } else if (unlikely(__pyx_nargs != 5)) { - goto __pyx_L5_argtuple_error; } else { - values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 14, __pyx_L3_error) - values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 14, __pyx_L3_error) - values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 14, __pyx_L3_error) - values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 14, __pyx_L3_error) - values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 14, __pyx_L3_error) + switch (__pyx_nargs) { + case 7: + values[6] = __Pyx_ArgRef_FASTCALL(__pyx_args, 6); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[6])) __PYX_ERR(0, 14, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 6: + values[5] = __Pyx_ArgRef_FASTCALL(__pyx_args, 5); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[5])) __PYX_ERR(0, 14, __pyx_L3_error) + CYTHON_FALLTHROUGH; + case 5: + values[4] = __Pyx_ArgRef_FASTCALL(__pyx_args, 4); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[4])) __PYX_ERR(0, 14, __pyx_L3_error) + values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 14, __pyx_L3_error) + values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 14, __pyx_L3_error) + values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 14, __pyx_L3_error) + values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 14, __pyx_L3_error) + break; + default: goto __pyx_L5_argtuple_error; + } + + /* "app/services/cache.py":20 + * resource: str, + * context: dict, + * org_id: Optional[str] = None, # <<<<<<<<<<<<<< + * permissions: Optional[list] = None, + * ) -> str: +*/ + if (!values[5]) values[5] = __Pyx_NewRef(((PyObject*)Py_None)); + + /* "app/services/cache.py":21 + * context: dict, + * org_id: Optional[str] = None, + * permissions: Optional[list] = None, # <<<<<<<<<<<<<< + * ) -> str: + * # PR12: org_id/permissions now affect the decision (tenancy.py, +*/ + if (!values[6]) values[6] = __Pyx_NewRef(((PyObject*)Py_None)); } __pyx_v_self = values[0]; __pyx_v_user_id = ((PyObject*)values[1]); __pyx_v_action = ((PyObject*)values[2]); __pyx_v_resource = ((PyObject*)values[3]); __pyx_v_context = ((PyObject*)values[4]); + __pyx_v_org_id = ((PyObject*)values[5]); + __pyx_v_permissions = ((PyObject*)values[6]); } goto __pyx_L6_skip; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("build_key", 1, 5, 5, __pyx_nargs); __PYX_ERR(0, 14, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("build_key", 0, 5, 7, __pyx_nargs); __PYX_ERR(0, 14, __pyx_L3_error) __pyx_L6_skip:; goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; @@ -2849,11 +2916,21 @@ PyObject *__pyx_args, PyObject *__pyx_kwds __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_id), (&PyUnicode_Type), 0, "user_id", 2))) __PYX_ERR(0, 14, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_action), (&PyUnicode_Type), 0, "action", 2))) __PYX_ERR(0, 14, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_resource), (&PyUnicode_Type), 0, "resource", 2))) __PYX_ERR(0, 14, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_context), (&PyDict_Type), 0, "context", 2))) __PYX_ERR(0, 14, __pyx_L1_error) - __pyx_r = __pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(__pyx_self, __pyx_v_self, __pyx_v_user_id, __pyx_v_action, __pyx_v_resource, __pyx_v_context); + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_id), (&PyUnicode_Type), 0, "user_id", 2))) __PYX_ERR(0, 16, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_action), (&PyUnicode_Type), 0, "action", 2))) __PYX_ERR(0, 17, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_resource), (&PyUnicode_Type), 0, "resource", 2))) __PYX_ERR(0, 18, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_context), (&PyDict_Type), 0, "context", 2))) __PYX_ERR(0, 19, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_org_id), (&PyUnicode_Type), 1, "org_id", 2))) __PYX_ERR(0, 20, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_permissions), (&PyList_Type), 1, "permissions", 2))) __PYX_ERR(0, 21, __pyx_L1_error) + __pyx_r = __pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(__pyx_self, __pyx_v_self, __pyx_v_user_id, __pyx_v_action, __pyx_v_resource, __pyx_v_context, __pyx_v_org_id, __pyx_v_permissions); + + /* "app/services/cache.py":14 + * # deterministic cache key + * # ---------------------------- + * def build_key( # <<<<<<<<<<<<<< + * self, + * user_id: str, +*/ /* function exit code */ goto __pyx_L0; @@ -2872,7 +2949,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds return __pyx_r; } -static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_user_id, PyObject *__pyx_v_action, PyObject *__pyx_v_resource, PyObject *__pyx_v_context) { +static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self, PyObject *__pyx_v_user_id, PyObject *__pyx_v_action, PyObject *__pyx_v_resource, PyObject *__pyx_v_context, PyObject *__pyx_v_org_id, PyObject *__pyx_v_permissions) { PyObject *__pyx_v_raw = NULL; PyObject *__pyx_v_digest = NULL; PyObject *__pyx_r = NULL; @@ -2881,130 +2958,184 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(CYTHON_ PyObject *__pyx_t_2 = NULL; PyObject *__pyx_t_3 = NULL; PyObject *__pyx_t_4 = NULL; - PyObject *__pyx_t_5[7]; + int __pyx_t_5; PyObject *__pyx_t_6 = NULL; - PyObject *__pyx_t_7 = NULL; - size_t __pyx_t_8; + PyObject *__pyx_t_7[11]; + PyObject *__pyx_t_8 = NULL; + size_t __pyx_t_9; int __pyx_lineno = 0; const char *__pyx_filename = NULL; int __pyx_clineno = 0; __Pyx_RefNannySetupContext("build_key", 0); - /* "app/services/cache.py":15 - * # ---------------------------- - * def build_key(self, user_id: str, action: str, resource: str, context: dict) -> str: - * raw = f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}" # <<<<<<<<<<<<<< - * digest = hashlib.sha256(raw.encode()).hexdigest() - * return f"policy:{digest}" + /* "app/services/cache.py":27 + * # cache hit for one org/permission-set could be served to another. + * raw = ( + * f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}:" # <<<<<<<<<<<<<< + * f"{org_id}:{json.dumps(sorted(permissions or []))}" + * ) */ - __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_json); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_json); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 27, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_dumps); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 15, __pyx_L1_error) + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_dumps); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 27, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 15, __pyx_L1_error) + __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 27, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); __Pyx_INCREF(__pyx_v_context); __Pyx_GIVEREF(__pyx_v_context); - if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_context) != (0)) __PYX_ERR(0, 15, __pyx_L1_error); - __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 15, __pyx_L1_error) + if (__Pyx_PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_v_context) != (0)) __PYX_ERR(0, 27, __pyx_L1_error); + __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 27, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - if (PyDict_SetItem(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_sort_keys, Py_True) < (0)) __PYX_ERR(0, 15, __pyx_L1_error) - __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 15, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_3, __pyx_mstate_global->__pyx_n_u_sort_keys, Py_True) < (0)) __PYX_ERR(0, 27, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_1, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 27, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 15, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_FormatSimple(__pyx_t_4, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 27, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_t_5[0] = __pyx_v_user_id; - __pyx_t_5[1] = __pyx_mstate_global->__pyx_kp_u_; - __pyx_t_5[2] = __pyx_v_action; - __pyx_t_5[3] = __pyx_mstate_global->__pyx_kp_u_; - __pyx_t_5[4] = __pyx_v_resource; - __pyx_t_5[5] = __pyx_mstate_global->__pyx_kp_u_; - __pyx_t_5[6] = __pyx_t_3; - __pyx_t_4 = __Pyx_PyUnicode_Join(__pyx_t_5, 7, __Pyx_PyUnicode_GET_LENGTH(__pyx_v_user_id) + 1 * 3 + __Pyx_PyUnicode_GET_LENGTH(__pyx_v_action) + __Pyx_PyUnicode_GET_LENGTH(__pyx_v_resource) + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3), 127 | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_user_id) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_action) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_resource) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3)); - if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 15, __pyx_L1_error) + + /* "app/services/cache.py":28 + * raw = ( + * f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}:" + * f"{org_id}:{json.dumps(sorted(permissions or []))}" # <<<<<<<<<<<<<< + * ) + * digest = hashlib.sha256(raw.encode()).hexdigest() +*/ + __pyx_t_4 = __Pyx_PyUnicode_Unicode(__pyx_v_org_id); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 28, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); + __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_json); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_t_1, __pyx_mstate_global->__pyx_n_u_dumps); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_permissions); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 28, __pyx_L1_error) + if (!__pyx_t_5) { + } else { + __Pyx_INCREF(__pyx_v_permissions); + __pyx_t_1 = __pyx_v_permissions; + goto __pyx_L3_bool_binop_done; + } + __pyx_t_6 = PyList_New(0); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_INCREF(__pyx_t_6); + __pyx_t_1 = __pyx_t_6; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_L3_bool_binop_done:; + __pyx_t_6 = PySequence_List(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + if (unlikely((PyList_Sort(__pyx_t_6) < 0))) __PYX_ERR(0, 28, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_6); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_t_6 = __Pyx_PyObject_FormatSimple(__pyx_t_1, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 28, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_6); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_t_7[0] = __pyx_v_user_id; + __pyx_t_7[1] = __pyx_mstate_global->__pyx_kp_u_; + __pyx_t_7[2] = __pyx_v_action; + __pyx_t_7[3] = __pyx_mstate_global->__pyx_kp_u_; + __pyx_t_7[4] = __pyx_v_resource; + __pyx_t_7[5] = __pyx_mstate_global->__pyx_kp_u_; + __pyx_t_7[6] = __pyx_t_3; + __pyx_t_7[7] = __pyx_mstate_global->__pyx_kp_u_; + __pyx_t_7[8] = __pyx_t_4; + __pyx_t_7[9] = __pyx_mstate_global->__pyx_kp_u_; + __pyx_t_7[10] = __pyx_t_6; + + /* "app/services/cache.py":27 + * # cache hit for one org/permission-set could be served to another. + * raw = ( + * f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}:" # <<<<<<<<<<<<<< + * f"{org_id}:{json.dumps(sorted(permissions or []))}" + * ) +*/ + __pyx_t_1 = __Pyx_PyUnicode_Join(__pyx_t_7, 11, __Pyx_PyUnicode_GET_LENGTH(__pyx_v_user_id) + 1 * 5 + __Pyx_PyUnicode_GET_LENGTH(__pyx_v_action) + __Pyx_PyUnicode_GET_LENGTH(__pyx_v_resource) + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_3) + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_4) + __Pyx_PyUnicode_GET_LENGTH(__pyx_t_6), 127 | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_user_id) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_action) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_v_resource) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_3) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_4) | __Pyx_PyUnicode_MAX_CHAR_VALUE(__pyx_t_6)); + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 27, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - __pyx_v_raw = ((PyObject*)__pyx_t_4); - __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; + __pyx_v_raw = ((PyObject*)__pyx_t_1); + __pyx_t_1 = 0; - /* "app/services/cache.py":16 - * def build_key(self, user_id: str, action: str, resource: str, context: dict) -> str: - * raw = f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}" + /* "app/services/cache.py":30 + * f"{org_id}:{json.dumps(sorted(permissions or []))}" + * ) * digest = hashlib.sha256(raw.encode()).hexdigest() # <<<<<<<<<<<<<< * return f"policy:{digest}" * */ - __pyx_t_2 = NULL; - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_hashlib); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 16, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_sha256); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 16, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_7); - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __pyx_t_6 = PyUnicode_AsEncodedString(__pyx_v_raw, NULL, NULL); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 16, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_6); - __pyx_t_8 = 1; + __pyx_t_3 = NULL; + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_hashlib); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_sha256); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_8); + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __pyx_t_2 = PyUnicode_AsEncodedString(__pyx_v_raw, NULL, NULL); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_2); + __pyx_t_9 = 1; #if CYTHON_UNPACK_METHODS - if (unlikely(PyMethod_Check(__pyx_t_7))) { - __pyx_t_2 = PyMethod_GET_SELF(__pyx_t_7); - assert(__pyx_t_2); - PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_7); - __Pyx_INCREF(__pyx_t_2); + if (unlikely(PyMethod_Check(__pyx_t_8))) { + __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_8); + assert(__pyx_t_3); + PyObject* __pyx__function = PyMethod_GET_FUNCTION(__pyx_t_8); + __Pyx_INCREF(__pyx_t_3); __Pyx_INCREF(__pyx__function); - __Pyx_DECREF_SET(__pyx_t_7, __pyx__function); - __pyx_t_8 = 0; + __Pyx_DECREF_SET(__pyx_t_8, __pyx__function); + __pyx_t_9 = 0; } #endif { - PyObject *__pyx_callargs[2] = {__pyx_t_2, __pyx_t_6}; - __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); - __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; - __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 16, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_1); - } - __pyx_t_3 = __pyx_t_1; - __Pyx_INCREF(__pyx_t_3); - __pyx_t_8 = 0; - { - PyObject *__pyx_callargs[2] = {__pyx_t_3, NULL}; - __pyx_t_4 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_hexdigest, __pyx_callargs+__pyx_t_8, (1-__pyx_t_8) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + PyObject *__pyx_callargs[2] = {__pyx_t_3, __pyx_t_2}; + __pyx_t_4 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_8, __pyx_callargs+__pyx_t_9, (2-__pyx_t_9) | (__pyx_t_9*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; - __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 16, __pyx_L1_error) + __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; + __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 30, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); } - __pyx_v_digest = __pyx_t_4; - __pyx_t_4 = 0; + __pyx_t_6 = __pyx_t_4; + __Pyx_INCREF(__pyx_t_6); + __pyx_t_9 = 0; + { + PyObject *__pyx_callargs[2] = {__pyx_t_6, NULL}; + __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_hexdigest, __pyx_callargs+__pyx_t_9, (1-__pyx_t_9) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); + __Pyx_XDECREF(__pyx_t_6); __pyx_t_6 = 0; + __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_1); + } + __pyx_v_digest = __pyx_t_1; + __pyx_t_1 = 0; - /* "app/services/cache.py":17 - * raw = f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}" + /* "app/services/cache.py":31 + * ) * digest = hashlib.sha256(raw.encode()).hexdigest() * return f"policy:{digest}" # <<<<<<<<<<<<<< * * # ---------------------------- */ __Pyx_XDECREF(__pyx_r); - __pyx_t_4 = __Pyx_PyObject_FormatSimple(__pyx_v_digest, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 17, __pyx_L1_error) - __Pyx_GOTREF(__pyx_t_4); - __pyx_t_1 = __Pyx_PyUnicode_Concat(__pyx_mstate_global->__pyx_kp_u_policy, __pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 17, __pyx_L1_error) + __pyx_t_1 = __Pyx_PyObject_FormatSimple(__pyx_v_digest, __pyx_mstate_global->__pyx_empty_unicode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 31, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); - __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - __pyx_r = ((PyObject*)__pyx_t_1); - __pyx_t_1 = 0; + __pyx_t_4 = __Pyx_PyUnicode_Concat(__pyx_mstate_global->__pyx_kp_u_policy, __pyx_t_1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 31, __pyx_L1_error) + __Pyx_GOTREF(__pyx_t_4); + __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; + __pyx_r = ((PyObject*)__pyx_t_4); + __pyx_t_4 = 0; goto __pyx_L0; /* "app/services/cache.py":14 * # deterministic cache key * # ---------------------------- - * def build_key(self, user_id: str, action: str, resource: str, context: dict) -> str: # <<<<<<<<<<<<<< - * raw = f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}" - * digest = hashlib.sha256(raw.encode()).hexdigest() + * def build_key( # <<<<<<<<<<<<<< + * self, + * user_id: str, */ /* function exit code */ @@ -3014,7 +3145,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(CYTHON_ __Pyx_XDECREF(__pyx_t_3); __Pyx_XDECREF(__pyx_t_4); __Pyx_XDECREF(__pyx_t_6); - __Pyx_XDECREF(__pyx_t_7); + __Pyx_XDECREF(__pyx_t_8); __Pyx_AddTraceback("app.services.cache.PolicyCache.build_key", __pyx_clineno, __pyx_lineno, __pyx_filename); __pyx_r = NULL; __pyx_L0:; @@ -3025,7 +3156,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_2build_key(CYTHON_ return __pyx_r; } -/* "app/services/cache.py":22 +/* "app/services/cache.py":36 * # get cached decision * # ---------------------------- * def get(self, key: str) -> Optional[dict]: # <<<<<<<<<<<<<< @@ -3073,39 +3204,39 @@ PyObject *__pyx_args, PyObject *__pyx_kwds { PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_key,0}; const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; - if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 22, __pyx_L3_error) + if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 36, __pyx_L3_error) if (__pyx_kwds_len > 0) { switch (__pyx_nargs) { case 2: values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 22, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 36, __pyx_L3_error) CYTHON_FALLTHROUGH; case 1: values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 22, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 36, __pyx_L3_error) CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "get", 0) < (0)) __PYX_ERR(0, 22, __pyx_L3_error) + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "get", 0) < (0)) __PYX_ERR(0, 36, __pyx_L3_error) for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { - if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("get", 1, 2, 2, i); __PYX_ERR(0, 22, __pyx_L3_error) } + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("get", 1, 2, 2, i); __PYX_ERR(0, 36, __pyx_L3_error) } } } else if (unlikely(__pyx_nargs != 2)) { goto __pyx_L5_argtuple_error; } else { values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 22, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 36, __pyx_L3_error) values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 22, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 36, __pyx_L3_error) } __pyx_v_self = values[0]; __pyx_v_key = ((PyObject*)values[1]); } goto __pyx_L6_skip; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("get", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 22, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("get", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 36, __pyx_L3_error) __pyx_L6_skip:; goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; @@ -3116,7 +3247,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_key), (&PyUnicode_Type), 0, "key", 2))) __PYX_ERR(0, 22, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_key), (&PyUnicode_Type), 0, "key", 2))) __PYX_ERR(0, 36, __pyx_L1_error) __pyx_r = __pyx_pf_3app_8services_5cache_11PolicyCache_4get(__pyx_self, __pyx_v_self, __pyx_v_key); /* function exit code */ @@ -3151,14 +3282,14 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_4get(CYTHON_UNUSED int __pyx_clineno = 0; __Pyx_RefNannySetupContext("get", 0); - /* "app/services/cache.py":23 + /* "app/services/cache.py":37 * # ---------------------------- * def get(self, key: str) -> Optional[dict]: * val = self.redis.get(key) # <<<<<<<<<<<<<< * if val: * return json.loads(val) */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_redis); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 23, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_redis); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_2 = __pyx_t_3; __Pyx_INCREF(__pyx_t_2); @@ -3168,23 +3299,23 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_4get(CYTHON_UNUSED __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_get, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 23, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 37, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } __pyx_v_val = __pyx_t_1; __pyx_t_1 = 0; - /* "app/services/cache.py":24 + /* "app/services/cache.py":38 * def get(self, key: str) -> Optional[dict]: * val = self.redis.get(key) * if val: # <<<<<<<<<<<<<< * return json.loads(val) * return None */ - __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_val); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 24, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyObject_IsTrue(__pyx_v_val); if (unlikely((__pyx_t_5 < 0))) __PYX_ERR(0, 38, __pyx_L1_error) if (__pyx_t_5) { - /* "app/services/cache.py":25 + /* "app/services/cache.py":39 * val = self.redis.get(key) * if val: * return json.loads(val) # <<<<<<<<<<<<<< @@ -3193,9 +3324,9 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_4get(CYTHON_UNUSED */ __Pyx_XDECREF(__pyx_r); __pyx_t_3 = NULL; - __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_json); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_json); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_2); - __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_loads); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 25, __pyx_L1_error) + __pyx_t_6 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_loads); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0; __pyx_t_4 = 1; @@ -3215,15 +3346,15 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_4get(CYTHON_UNUSED __pyx_t_1 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_6, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (__pyx_t_4*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0; __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 25, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } - if (!(likely(PyDict_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None) || __Pyx_RaiseUnexpectedTypeError("dict", __pyx_t_1))) __PYX_ERR(0, 25, __pyx_L1_error) + if (!(likely(PyDict_CheckExact(__pyx_t_1))||((__pyx_t_1) == Py_None) || __Pyx_RaiseUnexpectedTypeError("dict", __pyx_t_1))) __PYX_ERR(0, 39, __pyx_L1_error) __pyx_r = ((PyObject*)__pyx_t_1); __pyx_t_1 = 0; goto __pyx_L0; - /* "app/services/cache.py":24 + /* "app/services/cache.py":38 * def get(self, key: str) -> Optional[dict]: * val = self.redis.get(key) * if val: # <<<<<<<<<<<<<< @@ -3232,7 +3363,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_4get(CYTHON_UNUSED */ } - /* "app/services/cache.py":26 + /* "app/services/cache.py":40 * if val: * return json.loads(val) * return None # <<<<<<<<<<<<<< @@ -3243,7 +3374,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_4get(CYTHON_UNUSED __pyx_r = ((PyObject*)Py_None); __Pyx_INCREF(Py_None); goto __pyx_L0; - /* "app/services/cache.py":22 + /* "app/services/cache.py":36 * # get cached decision * # ---------------------------- * def get(self, key: str) -> Optional[dict]: # <<<<<<<<<<<<<< @@ -3266,7 +3397,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_4get(CYTHON_UNUSED return __pyx_r; } -/* "app/services/cache.py":31 +/* "app/services/cache.py":45 * # set cache with TTL * # ---------------------------- * def set(self, key: str, value: dict, ttl: int = 300): # <<<<<<<<<<<<<< @@ -3316,47 +3447,47 @@ PyObject *__pyx_args, PyObject *__pyx_kwds { PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_key,&__pyx_mstate_global->__pyx_n_u_value,&__pyx_mstate_global->__pyx_n_u_ttl,0}; const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; - if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 31, __pyx_L3_error) + if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 45, __pyx_L3_error) if (__pyx_kwds_len > 0) { switch (__pyx_nargs) { case 4: values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 31, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 45, __pyx_L3_error) CYTHON_FALLTHROUGH; case 3: values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 31, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 45, __pyx_L3_error) CYTHON_FALLTHROUGH; case 2: values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 31, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 45, __pyx_L3_error) CYTHON_FALLTHROUGH; case 1: values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 31, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 45, __pyx_L3_error) CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "set", 0) < (0)) __PYX_ERR(0, 31, __pyx_L3_error) + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "set", 0) < (0)) __PYX_ERR(0, 45, __pyx_L3_error) if (!values[3]) values[3] = __Pyx_NewRef(((PyObject*)((PyObject*)__pyx_mstate_global->__pyx_int_300))); for (Py_ssize_t i = __pyx_nargs; i < 3; i++) { - if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("set", 0, 3, 4, i); __PYX_ERR(0, 31, __pyx_L3_error) } + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("set", 0, 3, 4, i); __PYX_ERR(0, 45, __pyx_L3_error) } } } else { switch (__pyx_nargs) { case 4: values[3] = __Pyx_ArgRef_FASTCALL(__pyx_args, 3); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 31, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[3])) __PYX_ERR(0, 45, __pyx_L3_error) CYTHON_FALLTHROUGH; case 3: values[2] = __Pyx_ArgRef_FASTCALL(__pyx_args, 2); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 31, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[2])) __PYX_ERR(0, 45, __pyx_L3_error) values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 31, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 45, __pyx_L3_error) values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 31, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 45, __pyx_L3_error) break; default: goto __pyx_L5_argtuple_error; } @@ -3365,12 +3496,12 @@ PyObject *__pyx_args, PyObject *__pyx_kwds __pyx_v_self = values[0]; __pyx_v_key = ((PyObject*)values[1]); __pyx_v_value = ((PyObject*)values[2]); - if (__Pyx_PyInt_FromNumber(&values[3], "ttl", 0) < (0)) __PYX_ERR(0, 31, __pyx_L3_error) + if (__Pyx_PyInt_FromNumber(&values[3], "ttl", 0) < (0)) __PYX_ERR(0, 45, __pyx_L3_error) __pyx_v_ttl = ((PyObject*)values[3]); } goto __pyx_L6_skip; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("set", 0, 3, 4, __pyx_nargs); __PYX_ERR(0, 31, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("set", 0, 3, 4, __pyx_nargs); __PYX_ERR(0, 45, __pyx_L3_error) __pyx_L6_skip:; goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; @@ -3381,9 +3512,9 @@ PyObject *__pyx_args, PyObject *__pyx_kwds __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_key), (&PyUnicode_Type), 0, "key", 2))) __PYX_ERR(0, 31, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_value), (&PyDict_Type), 0, "value", 2))) __PYX_ERR(0, 31, __pyx_L1_error) - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ttl), (&PyLong_Type), 0, "ttl", 2))) __PYX_ERR(0, 31, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_key), (&PyUnicode_Type), 0, "key", 2))) __PYX_ERR(0, 45, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_value), (&PyDict_Type), 0, "value", 2))) __PYX_ERR(0, 45, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_ttl), (&PyLong_Type), 0, "ttl", 2))) __PYX_ERR(0, 45, __pyx_L1_error) __pyx_r = __pyx_pf_3app_8services_5cache_11PolicyCache_6set(__pyx_self, __pyx_v_self, __pyx_v_key, __pyx_v_value, __pyx_v_ttl); /* function exit code */ @@ -3419,21 +3550,21 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_6set(CYTHON_UNUSED int __pyx_clineno = 0; __Pyx_RefNannySetupContext("set", 0); - /* "app/services/cache.py":32 + /* "app/services/cache.py":46 * # ---------------------------- * def set(self, key: str, value: dict, ttl: int = 300): * self.redis.setex(key, ttl, json.dumps(value)) # <<<<<<<<<<<<<< * * # ---------------------------- */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_redis); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 32, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_redis); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 46, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_2 = __pyx_t_3; __Pyx_INCREF(__pyx_t_2); __pyx_t_5 = NULL; - __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_json); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 32, __pyx_L1_error) + __Pyx_GetModuleGlobalName(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_json); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 46, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_6); - __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_dumps); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 32, __pyx_L1_error) + __pyx_t_7 = __Pyx_PyObject_GetAttrStr(__pyx_t_6, __pyx_mstate_global->__pyx_n_u_dumps); if (unlikely(!__pyx_t_7)) __PYX_ERR(0, 46, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_7); __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0; __pyx_t_8 = 1; @@ -3453,7 +3584,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_6set(CYTHON_UNUSED __pyx_t_4 = __Pyx_PyObject_FastCall((PyObject*)__pyx_t_7, __pyx_callargs+__pyx_t_8, (2-__pyx_t_8) | (__pyx_t_8*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0; __Pyx_DECREF(__pyx_t_7); __pyx_t_7 = 0; - if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 32, __pyx_L1_error) + if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 46, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); } __pyx_t_8 = 0; @@ -3463,12 +3594,12 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_6set(CYTHON_UNUSED __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 32, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 46, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "app/services/cache.py":31 + /* "app/services/cache.py":45 * # set cache with TTL * # ---------------------------- * def set(self, key: str, value: dict, ttl: int = 300): # <<<<<<<<<<<<<< @@ -3495,7 +3626,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_6set(CYTHON_UNUSED return __pyx_r; } -/* "app/services/cache.py":37 +/* "app/services/cache.py":51 * # invalidation (important for IAM sync) * # ---------------------------- * def invalidate_user(self, user_id: str): # <<<<<<<<<<<<<< @@ -3543,39 +3674,39 @@ PyObject *__pyx_args, PyObject *__pyx_kwds { PyObject ** const __pyx_pyargnames[] = {&__pyx_mstate_global->__pyx_n_u_self,&__pyx_mstate_global->__pyx_n_u_user_id,0}; const Py_ssize_t __pyx_kwds_len = (__pyx_kwds) ? __Pyx_NumKwargs_FASTCALL(__pyx_kwds) : 0; - if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 37, __pyx_L3_error) + if (unlikely(__pyx_kwds_len < 0)) __PYX_ERR(0, 51, __pyx_L3_error) if (__pyx_kwds_len > 0) { switch (__pyx_nargs) { case 2: values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 37, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 51, __pyx_L3_error) CYTHON_FALLTHROUGH; case 1: values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 37, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 51, __pyx_L3_error) CYTHON_FALLTHROUGH; case 0: break; default: goto __pyx_L5_argtuple_error; } const Py_ssize_t kwd_pos_args = __pyx_nargs; - if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "invalidate_user", 0) < (0)) __PYX_ERR(0, 37, __pyx_L3_error) + if (__Pyx_ParseKeywords(__pyx_kwds, __pyx_kwvalues, __pyx_pyargnames, 0, values, kwd_pos_args, __pyx_kwds_len, "invalidate_user", 0) < (0)) __PYX_ERR(0, 51, __pyx_L3_error) for (Py_ssize_t i = __pyx_nargs; i < 2; i++) { - if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("invalidate_user", 1, 2, 2, i); __PYX_ERR(0, 37, __pyx_L3_error) } + if (unlikely(!values[i])) { __Pyx_RaiseArgtupleInvalid("invalidate_user", 1, 2, 2, i); __PYX_ERR(0, 51, __pyx_L3_error) } } } else if (unlikely(__pyx_nargs != 2)) { goto __pyx_L5_argtuple_error; } else { values[0] = __Pyx_ArgRef_FASTCALL(__pyx_args, 0); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 37, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[0])) __PYX_ERR(0, 51, __pyx_L3_error) values[1] = __Pyx_ArgRef_FASTCALL(__pyx_args, 1); - if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 37, __pyx_L3_error) + if (!CYTHON_ASSUME_SAFE_MACROS && unlikely(!values[1])) __PYX_ERR(0, 51, __pyx_L3_error) } __pyx_v_self = values[0]; __pyx_v_user_id = ((PyObject*)values[1]); } goto __pyx_L6_skip; __pyx_L5_argtuple_error:; - __Pyx_RaiseArgtupleInvalid("invalidate_user", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 37, __pyx_L3_error) + __Pyx_RaiseArgtupleInvalid("invalidate_user", 1, 2, 2, __pyx_nargs); __PYX_ERR(0, 51, __pyx_L3_error) __pyx_L6_skip:; goto __pyx_L4_argument_unpacking_done; __pyx_L3_error:; @@ -3586,7 +3717,7 @@ PyObject *__pyx_args, PyObject *__pyx_kwds __Pyx_RefNannyFinishContext(); return NULL; __pyx_L4_argument_unpacking_done:; - if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_id), (&PyUnicode_Type), 0, "user_id", 2))) __PYX_ERR(0, 37, __pyx_L1_error) + if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_user_id), (&PyUnicode_Type), 0, "user_id", 2))) __PYX_ERR(0, 51, __pyx_L1_error) __pyx_r = __pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(__pyx_self, __pyx_v_self, __pyx_v_user_id); /* function exit code */ @@ -3623,14 +3754,14 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C int __pyx_clineno = 0; __Pyx_RefNannySetupContext("invalidate_user", 0); - /* "app/services/cache.py":39 + /* "app/services/cache.py":53 * def invalidate_user(self, user_id: str): * # simple pattern-based invalidation (can be improved later with redis SCAN) * for key in self.redis.scan_iter(f"policy:*"): # <<<<<<<<<<<<<< * if user_id in key: * self.redis.delete(key) */ - __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_redis); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) + __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_redis); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 53, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); __pyx_t_2 = __pyx_t_3; __Pyx_INCREF(__pyx_t_2); @@ -3640,7 +3771,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_scan_iter, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) { @@ -3648,9 +3779,9 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C __pyx_t_5 = 0; __pyx_t_6 = NULL; } else { - __pyx_t_5 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 39, __pyx_L1_error) + __pyx_t_5 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 53, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_3); - __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 39, __pyx_L1_error) + __pyx_t_6 = (CYTHON_COMPILING_IN_LIMITED_API) ? PyIter_Next : __Pyx_PyObject_GetIterNextFunc(__pyx_t_3); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 53, __pyx_L1_error) } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; for (;;) { @@ -3659,7 +3790,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C { Py_ssize_t __pyx_temp = __Pyx_PyList_GET_SIZE(__pyx_t_3); #if !CYTHON_ASSUME_SAFE_SIZE - if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 39, __pyx_L1_error) + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 53, __pyx_L1_error) #endif if (__pyx_t_5 >= __pyx_temp) break; } @@ -3669,7 +3800,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C { Py_ssize_t __pyx_temp = __Pyx_PyTuple_GET_SIZE(__pyx_t_3); #if !CYTHON_ASSUME_SAFE_SIZE - if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 39, __pyx_L1_error) + if (unlikely((__pyx_temp < 0))) __PYX_ERR(0, 53, __pyx_L1_error) #endif if (__pyx_t_5 >= __pyx_temp) break; } @@ -3680,13 +3811,13 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C #endif ++__pyx_t_5; } - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 53, __pyx_L1_error) } else { __pyx_t_1 = __pyx_t_6(__pyx_t_3); if (unlikely(!__pyx_t_1)) { PyObject* exc_type = PyErr_Occurred(); if (exc_type) { - if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 39, __pyx_L1_error) + if (unlikely(!__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) __PYX_ERR(0, 53, __pyx_L1_error) PyErr_Clear(); } break; @@ -3696,21 +3827,21 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C __Pyx_XDECREF_SET(__pyx_v_key, __pyx_t_1); __pyx_t_1 = 0; - /* "app/services/cache.py":40 + /* "app/services/cache.py":54 * # simple pattern-based invalidation (can be improved later with redis SCAN) * for key in self.redis.scan_iter(f"policy:*"): * if user_id in key: # <<<<<<<<<<<<<< * self.redis.delete(key) */ - __pyx_t_7 = (__Pyx_PySequence_ContainsTF(__pyx_v_user_id, __pyx_v_key, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 40, __pyx_L1_error) + __pyx_t_7 = (__Pyx_PySequence_ContainsTF(__pyx_v_user_id, __pyx_v_key, Py_EQ)); if (unlikely((__pyx_t_7 < 0))) __PYX_ERR(0, 54, __pyx_L1_error) if (__pyx_t_7) { - /* "app/services/cache.py":41 + /* "app/services/cache.py":55 * for key in self.redis.scan_iter(f"policy:*"): * if user_id in key: * self.redis.delete(key) # <<<<<<<<<<<<<< */ - __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_redis); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 41, __pyx_L1_error) + __pyx_t_8 = __Pyx_PyObject_GetAttrStr(__pyx_v_self, __pyx_mstate_global->__pyx_n_u_redis); if (unlikely(!__pyx_t_8)) __PYX_ERR(0, 55, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_8); __pyx_t_2 = __pyx_t_8; __Pyx_INCREF(__pyx_t_2); @@ -3720,12 +3851,12 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C __pyx_t_1 = __Pyx_PyObject_FastCallMethod((PyObject*)__pyx_mstate_global->__pyx_n_u_delete, __pyx_callargs+__pyx_t_4, (2-__pyx_t_4) | (1*__Pyx_PY_VECTORCALL_ARGUMENTS_OFFSET)); __Pyx_XDECREF(__pyx_t_2); __pyx_t_2 = 0; __Pyx_DECREF(__pyx_t_8); __pyx_t_8 = 0; - if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 41, __pyx_L1_error) + if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 55, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_1); } __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0; - /* "app/services/cache.py":40 + /* "app/services/cache.py":54 * # simple pattern-based invalidation (can be improved later with redis SCAN) * for key in self.redis.scan_iter(f"policy:*"): * if user_id in key: # <<<<<<<<<<<<<< @@ -3733,7 +3864,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C */ } - /* "app/services/cache.py":39 + /* "app/services/cache.py":53 * def invalidate_user(self, user_id: str): * # simple pattern-based invalidation (can be improved later with redis SCAN) * for key in self.redis.scan_iter(f"policy:*"): # <<<<<<<<<<<<<< @@ -3743,7 +3874,7 @@ static PyObject *__pyx_pf_3app_8services_5cache_11PolicyCache_8invalidate_user(C } __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0; - /* "app/services/cache.py":37 + /* "app/services/cache.py":51 * # invalidation (important for IAM sync) * # ---------------------------- * def invalidate_user(self, user_id: str): # <<<<<<<<<<<<<< @@ -4212,89 +4343,92 @@ __Pyx_RefNannySetupContext("PyInit_cache", 0); /* "app/services/cache.py":14 * # deterministic cache key * # ---------------------------- - * def build_key(self, user_id: str, action: str, resource: str, context: dict) -> str: # <<<<<<<<<<<<<< - * raw = f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}" - * digest = hashlib.sha256(raw.encode()).hexdigest() + * def build_key( # <<<<<<<<<<<<<< + * self, + * user_id: str, */ - __pyx_t_5 = __Pyx_PyDict_NewPresized(5); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 14, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyDict_NewPresized(7); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_user_id, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_action, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_resource, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_context, __pyx_mstate_global->__pyx_n_u_dict) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_org_id, __pyx_mstate_global->__pyx_kp_u_Optional_str) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_permissions, __pyx_mstate_global->__pyx_kp_u_Optional_list) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_return, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_3app_8services_5cache_11PolicyCache_3build_key, 0, __pyx_mstate_global->__pyx_n_u_PolicyCache_build_key, NULL, __pyx_mstate_global->__pyx_n_u_app_services_cache, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[1])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 14, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); #endif + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_mstate_global->__pyx_tuple[0]); __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_5); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_build_key, __pyx_t_4) < (0)) __PYX_ERR(0, 14, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - /* "app/services/cache.py":22 + /* "app/services/cache.py":36 * # get cached decision * # ---------------------------- * def get(self, key: str) -> Optional[dict]: # <<<<<<<<<<<<<< * val = self.redis.get(key) * if val: */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 22, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 36, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_key, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 22, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_return, __pyx_mstate_global->__pyx_kp_u_Optional_dict) < (0)) __PYX_ERR(0, 22, __pyx_L1_error) - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_3app_8services_5cache_11PolicyCache_5get, 0, __pyx_mstate_global->__pyx_n_u_PolicyCache_get, NULL, __pyx_mstate_global->__pyx_n_u_app_services_cache, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[2])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 22, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_key, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 36, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_return, __pyx_mstate_global->__pyx_kp_u_Optional_dict) < (0)) __PYX_ERR(0, 36, __pyx_L1_error) + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_3app_8services_5cache_11PolicyCache_5get, 0, __pyx_mstate_global->__pyx_n_u_PolicyCache_get, NULL, __pyx_mstate_global->__pyx_n_u_app_services_cache, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[2])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 36, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 PyUnstable_Object_EnableDeferredRefcount(__pyx_t_5); #endif __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_4); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_get, __pyx_t_5) < (0)) __PYX_ERR(0, 22, __pyx_L1_error) + if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_get, __pyx_t_5) < (0)) __PYX_ERR(0, 36, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - /* "app/services/cache.py":31 + /* "app/services/cache.py":45 * # set cache with TTL * # ---------------------------- * def set(self, key: str, value: dict, ttl: int = 300): # <<<<<<<<<<<<<< * self.redis.setex(key, ttl, json.dumps(value)) * */ - __pyx_t_5 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 31, __pyx_L1_error) + __pyx_t_5 = __Pyx_PyDict_NewPresized(3); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); - if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_key, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 31, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_value, __pyx_mstate_global->__pyx_n_u_dict) < (0)) __PYX_ERR(0, 31, __pyx_L1_error) - if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_ttl, __pyx_mstate_global->__pyx_n_u_int) < (0)) __PYX_ERR(0, 31, __pyx_L1_error) - __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_3app_8services_5cache_11PolicyCache_7set, 0, __pyx_mstate_global->__pyx_n_u_PolicyCache_set, NULL, __pyx_mstate_global->__pyx_n_u_app_services_cache, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[3])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 31, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_key, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 45, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_value, __pyx_mstate_global->__pyx_n_u_dict) < (0)) __PYX_ERR(0, 45, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_5, __pyx_mstate_global->__pyx_n_u_ttl, __pyx_mstate_global->__pyx_n_u_int) < (0)) __PYX_ERR(0, 45, __pyx_L1_error) + __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_3app_8services_5cache_11PolicyCache_7set, 0, __pyx_mstate_global->__pyx_n_u_PolicyCache_set, NULL, __pyx_mstate_global->__pyx_n_u_app_services_cache, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[3])); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 PyUnstable_Object_EnableDeferredRefcount(__pyx_t_4); #endif - __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_mstate_global->__pyx_tuple[0]); + __Pyx_CyFunction_SetDefaultsTuple(__pyx_t_4, __pyx_mstate_global->__pyx_tuple[1]); __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_4, __pyx_t_5); __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; - if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_set, __pyx_t_4) < (0)) __PYX_ERR(0, 31, __pyx_L1_error) + if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_set, __pyx_t_4) < (0)) __PYX_ERR(0, 45, __pyx_L1_error) __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - /* "app/services/cache.py":37 + /* "app/services/cache.py":51 * # invalidation (important for IAM sync) * # ---------------------------- * def invalidate_user(self, user_id: str): # <<<<<<<<<<<<<< * # simple pattern-based invalidation (can be improved later with redis SCAN) * for key in self.redis.scan_iter(f"policy:*"): */ - __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 37, __pyx_L1_error) + __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 51, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_4); - if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_user_id, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 37, __pyx_L1_error) - __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_3app_8services_5cache_11PolicyCache_9invalidate_user, 0, __pyx_mstate_global->__pyx_n_u_PolicyCache_invalidate_user, NULL, __pyx_mstate_global->__pyx_n_u_app_services_cache, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[4])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 37, __pyx_L1_error) + if (PyDict_SetItem(__pyx_t_4, __pyx_mstate_global->__pyx_n_u_user_id, __pyx_mstate_global->__pyx_n_u_str) < (0)) __PYX_ERR(0, 51, __pyx_L1_error) + __pyx_t_5 = __Pyx_CyFunction_New(&__pyx_mdef_3app_8services_5cache_11PolicyCache_9invalidate_user, 0, __pyx_mstate_global->__pyx_n_u_PolicyCache_invalidate_user, NULL, __pyx_mstate_global->__pyx_n_u_app_services_cache, __pyx_mstate_global->__pyx_d, ((PyObject *)__pyx_mstate_global->__pyx_codeobj_tab[4])); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 51, __pyx_L1_error) __Pyx_GOTREF(__pyx_t_5); #if CYTHON_COMPILING_IN_CPYTHON && PY_VERSION_HEX >= 0x030E0000 PyUnstable_Object_EnableDeferredRefcount(__pyx_t_5); #endif __Pyx_CyFunction_SetAnnotationsDict(__pyx_t_5, __pyx_t_4); __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0; - if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_invalidate_user, __pyx_t_5) < (0)) __PYX_ERR(0, 37, __pyx_L1_error) + if (__Pyx_SetNameInClass(__pyx_t_2, __pyx_mstate_global->__pyx_n_u_invalidate_user, __pyx_t_5) < (0)) __PYX_ERR(0, 51, __pyx_L1_error) __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0; /* "app/services/cache.py":7 @@ -4378,20 +4512,31 @@ static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { CYTHON_UNUSED_VAR(__pyx_mstate); __Pyx_RefNannySetupContext("__Pyx_InitCachedConstants", 0); - /* "app/services/cache.py":31 + /* "app/services/cache.py":14 + * # deterministic cache key + * # ---------------------------- + * def build_key( # <<<<<<<<<<<<<< + * self, + * user_id: str, +*/ + __pyx_mstate_global->__pyx_tuple[0] = PyTuple_Pack(2, Py_None, Py_None); if (unlikely(!__pyx_mstate_global->__pyx_tuple[0])) __PYX_ERR(0, 14, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[0]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[0]); + + /* "app/services/cache.py":45 * # set cache with TTL * # ---------------------------- * def set(self, key: str, value: dict, ttl: int = 300): # <<<<<<<<<<<<<< * self.redis.setex(key, ttl, json.dumps(value)) * */ - __pyx_mstate_global->__pyx_tuple[0] = PyTuple_Pack(1, ((PyObject*)__pyx_mstate_global->__pyx_int_300)); if (unlikely(!__pyx_mstate_global->__pyx_tuple[0])) __PYX_ERR(0, 31, __pyx_L1_error) - __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[0]); - __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[0]); + __pyx_mstate_global->__pyx_tuple[1] = PyTuple_Pack(1, ((PyObject*)__pyx_mstate_global->__pyx_int_300)); if (unlikely(!__pyx_mstate_global->__pyx_tuple[1])) __PYX_ERR(0, 45, __pyx_L1_error) + __Pyx_GOTREF(__pyx_mstate_global->__pyx_tuple[1]); + __Pyx_GIVEREF(__pyx_mstate_global->__pyx_tuple[1]); #if CYTHON_IMMORTAL_CONSTANTS { PyObject **table = __pyx_mstate->__pyx_tuple; - for (Py_ssize_t i=0; i<1; ++i) { + for (Py_ssize_t i=0; i<2; ++i) { #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING #if PY_VERSION_HEX < 0x030E0000 if (_Py_IsOwnedByCurrentThread(table[i]) && Py_REFCNT(table[i]) == 1) @@ -4418,34 +4563,34 @@ static int __Pyx_InitCachedConstants(__pyx_mstatetype *__pyx_mstate) { static int __Pyx_InitConstants(__pyx_mstatetype *__pyx_mstate) { CYTHON_UNUSED_VAR(__pyx_mstate); { - const struct { const unsigned int length: 8; } index[] = {{1},{179},{14},{1},{1},{8},{21},{7},{8},{3},{8},{11},{20},{21},{15},{27},{15},{20},{6},{18},{18},{9},{18},{7},{16},{6},{4},{6},{7},{5},{8},{8},{3},{7},{9},{8},{3},{15},{13},{5},{4},{3},{5},{8},{13},{10},{8},{3},{11},{12},{3},{5},{9},{8},{6},{9},{4},{3},{12},{10},{5},{6},{9},{3},{8},{3},{6},{7},{3},{5},{6},{32},{23},{67},{40},{41}}; - #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (764 bytes) */ -const char* const cstring = "BZh91AY&SY\265\036\220\221\000\000>\177\377l\315\356\222y\263\267\360\357\271\366\033\277\377\377\344\000@@@@@@@@@@@@\000@\002Ms\235\226\326\270D\322\247\350\3253\024\365\033MOS\332\220\017(h\003F\206\230\232\032\006\236\246\236\210b=M\246\032\240\324M4d\233M53Jx\247\2444\r4\006\232\000\000\000\000\000\032\001\023\021\222\nxMG\250\006\200\000\000\031\000\000\0004\006\201\2405=A\0324\231OF\246j4\332\206@\000\000\000\000\000\000\032\r\026\300\"\t#\216b\001\202pH\201\030\020\020#\"QVuTh\264\031\t\200\360E\216\256>8b\337m\223^\366\375\264>#\214\311\022\031d\t\312y\302\306[\2344\354\363\311\335+\n\202e\221\252\323\226\325\215\333\024\201KV\3138\3544\235y\006\253\327.\035@&\250\272V\264D\242\300p\324:\327\216\205T\177s1\203A\3433\324]x\261\346\275f\000\022n\024\004\202\006-\231\002\376\032j(1\226\212\214\251\\\000)iB`\307\017,\245(aB\311\374}b\333z\300\210\203m\331}Y.\210~\214\356\364\241H\244\352.\273\034\257\026b\030\315\0221\216PJ_\214^\024O\033c\264s\334\205\001\300\003\305\024\0148\177,@\200\0378p\001i&\2304\341\345\264-\227\222\356\023\246\021!\016%S\246\250LBE.\001\030\307\261/\315-L\206\013\364\204e\020\270 i5\227P\231\200U0y\240l\002_4\305\222\014\245O1\317\374\232\340Q[\336\240tS\3118\260\2451\300S\000\031\224\226\211\305_c2\302\004*\023!\372\353b\204\341H\215T\210\r\276bD\202U12>\260\302\341Ih\224F\324V\230\000( \340<\236\370\315\220>\023f\370#\215\304\240bluE5\205Va\0068\344X\332\016OU\007+1uC(\317\004\255\"@\224\350)C\213\250\265\314\201\212\370d\312|\227\n\211Z\014\266\305\345\253\333\375\003\252\230\305r\t\206\304S\307r\234\326\033\0040\243\"\250Y!\305\216H\006\205\203RX)\200\215\311H}n\252 \245\333\257E\277F\n\347\002\243\021q\021\333\256\270Q\005\220\203>\010\212\334\202\345\t\r@L\225\2433h\210\205\221\323H:\n\201\010P\360\226!l\007\023\210\360b\325@td\022\225\026w\322\024\\\242\230F\"\201\0224L,*d\001d\351h\003\036\027\211$\324\210\341\253\035e\257]'\260@Ovz\\\277\226\032\357\370\006\020F@, \205\345\373\277j\310\313\213\023<\227r;\371\023\351\375\315""\034\364j/fF\244\231\266\345\257Y\212-\330\233M0#m\345\350%\335#\035\3473\204\331\350T\337\342\356H\247\n\022\026\243\322\022 "; - PyObject *data = __Pyx_DecompressString(cstring, 764, 2); + const struct { const unsigned int length: 8; } index[] = {{1},{4},{179},{14},{14},{13},{1},{1},{8},{21},{7},{8},{3},{8},{11},{20},{21},{15},{27},{15},{20},{6},{18},{18},{9},{18},{7},{16},{6},{4},{6},{7},{5},{8},{8},{3},{7},{9},{8},{3},{15},{13},{5},{4},{3},{5},{8},{13},{10},{8},{6},{11},{3},{11},{12},{3},{5},{9},{8},{6},{9},{4},{3},{12},{10},{5},{6},{9},{3},{8},{3},{6},{7},{3},{5},{6},{32},{106},{23},{40},{41}}; + #if (CYTHON_COMPRESS_STRINGS) == 2 /* compression: bz2 (824 bytes) */ +const char* const cstring = "BZh91AY&SY\266g\222\000\000\000I\377\377\354\375\377\260y\267\267\320\357\251\366\032\277\377\377\364@@@@@@@@@@@@@\000@\000@\002\2359\335l\266\265\270E6\246\231\nzd\3116I\352\032\003@\017P\304\003F\217H\000\032h\323OS\321\036\214\324\032\211\351S\364\312zjz\023!=F\200\003\324\032\000\000\000\000\000\006\215\r\000\324\302\023E=5\032\r4\320\310h\000\000\003@\000\000\000\000\000J\232\t2z)\247\243MO)\251\344\t\204\036\243F4\000\021\210h\003 \036S\324\303#\270\002\371\327\203\016\036\320r\261\3421\242\204G\246)I\030\010\251\220DE\213H\027U\365^X\364\201l\245\026:\263Q\006\312\347\244w\240\275Z\334p\026\372g\270Y\n\030\030a11\227|\032n\203\201wuE\0146D\376s\2562\220\270)_%B\246\252\021\367\331f\200\032\033B\024\363?\311\237j\032O \300\226YQ9\363<\320\245\311\245F\023\251\016X5\356\273\274\370Q-\201L\34446\261\315\016\000\213\360\230\014\020\025i\310\027\326\"\257@\326\324$(\315`\005Uj0\343\276\017R3cI\212E\364\244\013*\354\001\247\007\262\311\372\347d\000Z\031\036\017\030\214\326\\WD2\244\365\014E(\245\024O[\336\245\250e:\313T\313<\272Nu\331!\026\004\010e\231\261\366\334\253\010Tp\2605\242fQ;\202]L:/\265\242\371\004(\255k\"\251n\272\320\0203\216\351n\314\210\224d\335\022mB\222\017\374\244\320\344&\210)\253(\307MT\003A\0228U\016\270T&N)\211\034\331\037\354V\340S\241\202\300\370\350\255%\005\306\266\010\302\270\t3\027\021A=\364\215\242\212\243\t\225R\323\\\302\201\212\310d\210*8\274\020,\246,\222\273\241\\14rF\031\rUr\264*\242\310\025\010..\244\016\020\225\031\034$FmDOr\270\342\010H\300\331\242G\306\364|\362\0144\231\362+\032\313\r\0172\2244\240\224W\006d\213\006\255M$\267\234\360D)O\207\251_\023\344\324W\257\232\365\037f\236\354d>6\232HG\004(\331\005\313<\250\2148o%\367`C\222&\007\037\016^\254\277Y'L\013b\341\024\270w\304\245]\256\230s\340\210\351\221n*\225\227\232\370,\001\027\221\275\036\311LJ4\200 \336\220\004\363\346\013|\014\2328\360\301!\035\246\265\361\314K\243)\226K}\322!BZ\034\"\207\020\252w\231r\020}IB\006S\337\005\002\373\021\275eBP\254\003\226$\253\016\354Prp\253\234\361\030\242$K\214\222<\333\372\367{\276\255\263\353\362\203:\264\023\362\346\334\210R\251\245\247t>\0268\tz\006\331|\360\004\374\374R\352!SR\240h4E\024\363[\310\017\373e#\374\336#d\272\017#\377\025z\214\327@\222$\272F\035\325\250\231\3134\227&\342\306\232\024\245\004w3\237+\\\"@\352-\343\320e\374\214\033\355\261\235\000n\004P\013.1\032\205\305#\004\017A !O\300\341|a8\232\264\237\270\2365}\232ZEi/\325\030D\"1s1\236y\014\243\353\364\231\010R\373\377xQ\351\350\r0\351\241\357N\235\321\010M\031&\034\245}\206\350\360\351\203g\365!\327\013#R\005\301\323\254\217\377\304$h,$\314\326\321A\312\324l\307\262_\026a\273\332\004\220\310\310\244\226\203\005\237Z\3558\323\024\247Z\007\252W\313\032\314\254\024=\201\242\246\312\243\007#\027\263\227\2576\234\261>\010\347\360\032S\352kj\336\253\331\355\232\361\021\310\017\337\024j\343&\215\207\371\357r\243Z\256\330\264\2718\336\315\237\025\013\305r\001\345z9\254\016+6i<)\333ag/?*V\312\265\362\363d\365\335\345\302\244\321.\037W\346\342\347\325\346\344\333\321\264yw\314\363G\305f\371\251b\225?\337\270h]\254\\n]\035N\233\255\374aq\273\030\224\267\312\327\325\323\352\370|0m.\2153\234\321\2324:\345\340\017v\376\230\257\347\303\342\270\034T\013\323\305\245\361(wE{z\357A\276[t\312V\331\016\010G\305 \314\020\210\256Ql\027\330\367\316xm\272x\277\256<,Xh:\370\013\365\264\210\032"; - PyObject *data = __Pyx_DecompressString(cstring, 667, 1); + #elif (CYTHON_COMPRESS_STRINGS) != 0 /* compression: zlib (726 bytes) */ +const char* const cstring = "x\332]R\277o\0231\024\246\"\022i\251\240)\024\004\223\013\022\021\010R\201JA,P\001E\010\251\264\010\026Pe9\366K\343\326\261/~\276\220C\014\214\031o\274\361\306\033;222v\274\261\177\002\177\002\357.\264\2128\335\331\357\275{?\276\357\263\237m;\013\333.\000\013}\021\330\313$\364\235e\032\231\002\243\273\340E\000\2230\014^\313\000\276J\262l\347\365\316\203\365\247\353LX\305<\034\200\014\3100\356J#\020\001\231\353\261n\254M\320\226\205$\002\354\260\267=\226\270\230Y\000\305\202c\021\345\315\026\204>X\206\020*\203\265\205\265.\210\240\235\345T\256\355~\233)\355i\210\036AU\275%\014B\347}Te\010\363E\021\260\2753\317h\234\361\010\366^\347\271P\212SK\020Q\264\206\340GZ\002\256I!\373\320\211\222\310\031-\223g\377\266{\23369\255\336\251C/\253\274\031\263\303\271\266:p>\033\253\350*~\010\311lp\037\302\254\253\355H\030\255HO\036\023\212\331_D\235\372%c\372^\021\033\276\r\343\360\001zB\326@\242\250s\212\272S\243\026\230X\251]G:\357bR\031\360l\2764\344\022@\036\274\220\320\025\362P:\033\250\235\002\351\024p\017\0309K\232\323\351B\200J;\245\367\001i\276r\222\226x\020a\317\273\001\217\275\341\274\027[\n\022\221\276\300>]\207>\214O\323\247\"h\033\376\343\3055\3623`:\300\000\017\320Y\202f\234P\310\371@\020:z\006\020D}\376\265\343Tl\240\262\254\030\320\356\374>\327*\002?\320\210\244\001\201\2168\217\036];\032\376\234\377u\363\367\303r\361\322DL\306\3510kd[y\273h\025\367\217\344\317\326I\263\225^\317.d\303\374|\376\244\270]|>\032\226\315\313\223\204f\266\216\033\267\362\325\n\303\333\364Sv7\177\230\277;^{\361k\356\270\321\316\207'\024~\223\256\247\243\354s>,\346\252\241\343\024\263\325r""\351j\272\225\265\363V\276Z\021\031g\324\356\322D\021\211F\266\231\355\226\315\213\023\202r\245\256\334\315D5k\370\027\256\216\247\354"; + PyObject *data = __Pyx_DecompressString(cstring, 726, 1); if (unlikely(!data)) __PYX_ERR(0, 1, __pyx_L1_error) const char* const bytes = __Pyx_PyBytes_AsString(data); #if !CYTHON_ASSUME_SAFE_MACROS if (likely(bytes)); else { Py_DECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) } #endif - #else /* compression: none (989 bytes) */ -const char* const bytes = ":Note that Cython is deliberately stricter than PEP-484 and rejects subclasses of builtin types. If you need to pass subclasses then set the 'annotation_typing' directive to False.Optional[dict].?add_noteapp/services/cache.pypolicy:policy:*AnyOptionalPolicyCachePolicyCache.__init__PolicyCache.build_keyPolicyCache.getPolicyCache.invalidate_userPolicyCache.set__Pyx_PyDict_NextRefactionapp.services.cacheasyncio.coroutinesbuild_keycline_in_tracebackcontextdecode_responsesdeletedictdigest__doc__dumpsfrom_url__func__gethashlibhexdigest__init__intinvalidate_user_is_coroutineitemsjsonkeyloads__main____metaclass____module____name__pop__prepare____qualname__rawredisredis_urlresourcereturnscan_iterselfset__set_name__setdefaultsetexsha256sort_keysstr__test__ttltypinguser_idvalvaluevalues\320\004\027\220|\2406\250\025\250a\330\010\014\210F\220&\230\001\230\025\230e\2404\240v\250Q\250a\320\004\"\240!\330\010\014\210I\220U\230)\2401\240K\320/@\300\001\320\004!\240\035\250o\270^\3109\320TU\330\010\016\210c\220\032\2309\240J\250a\250t\2606\270\021\270)\300:\310Q\330\010\021\220\027\230\007\230q\240\003\2407\250#\250Z\260q\330\010\017\210y\230\001\230\021\320\004'\240q\340\010\014\210G\2204\220v\230Z\240q\250\001\330\014\017\210x\220s\230!\330\020\024\220F\230'\240\021\240!\320\004\027\220x\230q\330\010\016\210d\220&\230\004\230A\230Q\330\010\013\2101\330\014\023\2204\220v\230Q\230a\330\010\017\210q"; + #else /* compression: none (1076 bytes) */ +const char* const bytes = ":NoneNote that Cython is deliberately stricter than PEP-484 and rejects subclasses of builtin types. If you need to pass subclasses then set the 'annotation_typing' directive to False.Optional[dict]Optional[list]Optional[str].?add_noteapp/services/cache.pypolicy:policy:*AnyOptionalPolicyCachePolicyCache.__init__PolicyCache.build_keyPolicyCache.getPolicyCache.invalidate_userPolicyCache.set__Pyx_PyDict_NextRefactionapp.services.cacheasyncio.coroutinesbuild_keycline_in_tracebackcontextdecode_responsesdeletedictdigest__doc__dumpsfrom_url__func__gethashlibhexdigest__init__intinvalidate_user_is_coroutineitemsjsonkeyloads__main____metaclass____module____name__org_idpermissionspop__prepare____qualname__rawredisredis_urlresourcereturnscan_iterselfset__set_name__setdefaultsetexsha256sort_keysstr__test__ttltypinguser_idvalvaluevalues\320\004\027\220|\2406\250\025\250a\330\010\014\210F\220&\230\001\230\025\230e\2404\240v\250Q\250a\200A\340\021\022\330\020\021\330\022\023\330\021\022\330\010\020\220\001\330\010\025\220Q\330\t\n\360\010\000\t\n\330\014\017\210z\230\031\240*\250A\250T\260\026\260q\270\t\300\032\3101\330\014\016\210a\210x\220q\230\004\230F\240'\250\021\250,\260c\270\021\340\010\021\220\027\230\007\230q\240\003\2407\250#\250Z\260q\330\010\017\210y\230\001\230\021\320\004\"\240!\330\010\014\210I\220U\230)\2401\240K\320/@\300\001\320\004'\240q\340\010\014\210G\2204\220v\230Z\240q\250\001\330\014\017\210x\220s\230!\330\020\024\220F\230'\240\021\240!\320\004\027\220x\230q\330\010\016\210d\220&\230\004\230A\230Q\330\010\013\2101\330\014\023\2204\220v\230Q\230a\330\010\017\210q"; PyObject *data = NULL; CYTHON_UNUSED_VAR(__Pyx_DecompressString); #endif PyObject **stringtab = __pyx_mstate->__pyx_string_tab; Py_ssize_t pos = 0; - for (int i = 0; i < 71; i++) { + for (int i = 0; i < 76; i++) { Py_ssize_t bytes_length = index[i].length; PyObject *string = PyUnicode_DecodeUTF8(bytes + pos, bytes_length, NULL); - if (likely(string) && i >= 9) PyUnicode_InternInPlace(&string); + if (likely(string) && i >= 12) PyUnicode_InternInPlace(&string); if (unlikely(!string)) { Py_XDECREF(data); __PYX_ERR(0, 1, __pyx_L1_error) @@ -4453,7 +4598,7 @@ const char* const bytes = ":Note that Cython is deliberately stricter than PEP-4 stringtab[i] = string; pos += bytes_length; } - for (int i = 71; i < 76; i++) { + for (int i = 76; i < 81; i++) { Py_ssize_t bytes_length = index[i].length; PyObject *string = PyBytes_FromStringAndSize(bytes + pos, bytes_length); stringtab[i] = string; @@ -4464,14 +4609,14 @@ const char* const bytes = ":Note that Cython is deliberately stricter than PEP-4 } } Py_XDECREF(data); - for (Py_ssize_t i = 0; i < 76; i++) { + for (Py_ssize_t i = 0; i < 81; i++) { if (unlikely(PyObject_Hash(stringtab[i]) == -1)) { __PYX_ERR(0, 1, __pyx_L1_error) } } #if CYTHON_IMMORTAL_CONSTANTS { - PyObject **table = stringtab + 71; + PyObject **table = stringtab + 76; for (Py_ssize_t i=0; i<5; ++i) { #if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING #if PY_VERSION_HEX < 0x030E0000 @@ -4525,7 +4670,7 @@ typedef struct { unsigned int argcount : 3; unsigned int num_posonly_args : 1; unsigned int num_kwonly_args : 1; - unsigned int nlocals : 3; + unsigned int nlocals : 4; unsigned int flags : 10; unsigned int first_line : 6; } __Pyx_PyCode_New_function_description; @@ -4549,22 +4694,22 @@ static int __Pyx_CreateCodeObjects(__pyx_mstatetype *__pyx_mstate) { __pyx_mstate_global->__pyx_codeobj_tab[0] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_services_cache_py, __pyx_mstate->__pyx_n_u_init, __pyx_mstate->__pyx_kp_b_iso88591_IU_1K, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[0])) goto bad; } { - const __Pyx_PyCode_New_function_description descr = {5, 0, 0, 7, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 14}; - PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_user_id, __pyx_mstate->__pyx_n_u_action, __pyx_mstate->__pyx_n_u_resource, __pyx_mstate->__pyx_n_u_context, __pyx_mstate->__pyx_n_u_raw, __pyx_mstate->__pyx_n_u_digest}; - __pyx_mstate_global->__pyx_codeobj_tab[1] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_services_cache_py, __pyx_mstate->__pyx_n_u_build_key, __pyx_mstate->__pyx_kp_b_iso88591_o_9TU_c_9Jat6_Q_q_7_Zq_y, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[1])) goto bad; + const __Pyx_PyCode_New_function_description descr = {7, 0, 0, 9, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 14}; + PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_user_id, __pyx_mstate->__pyx_n_u_action, __pyx_mstate->__pyx_n_u_resource, __pyx_mstate->__pyx_n_u_context, __pyx_mstate->__pyx_n_u_org_id, __pyx_mstate->__pyx_n_u_permissions, __pyx_mstate->__pyx_n_u_raw, __pyx_mstate->__pyx_n_u_digest}; + __pyx_mstate_global->__pyx_codeobj_tab[1] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_services_cache_py, __pyx_mstate->__pyx_n_u_build_key, __pyx_mstate->__pyx_kp_b_iso88591_A_Q_z_AT_q_1_axq_F_c_q_7_Zq_y, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[1])) goto bad; } { - const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 22}; + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 36}; PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_key, __pyx_mstate->__pyx_n_u_val}; __pyx_mstate_global->__pyx_codeobj_tab[2] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_services_cache_py, __pyx_mstate->__pyx_n_u_get, __pyx_mstate->__pyx_kp_b_iso88591_xq_d_AQ_1_4vQa_q, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[2])) goto bad; } { - const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 31}; + const __Pyx_PyCode_New_function_description descr = {4, 0, 0, 4, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 45}; PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_key, __pyx_mstate->__pyx_n_u_value, __pyx_mstate->__pyx_n_u_ttl}; __pyx_mstate_global->__pyx_codeobj_tab[3] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_services_cache_py, __pyx_mstate->__pyx_n_u_set, __pyx_mstate->__pyx_kp_b_iso88591_6_a_F_e4vQa, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[3])) goto bad; } { - const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 37}; + const __Pyx_PyCode_New_function_description descr = {2, 0, 0, 3, (unsigned int)(CO_OPTIMIZED|CO_NEWLOCALS), 51}; PyObject* const varnames[] = {__pyx_mstate->__pyx_n_u_self, __pyx_mstate->__pyx_n_u_user_id, __pyx_mstate->__pyx_n_u_key}; __pyx_mstate_global->__pyx_codeobj_tab[4] = __Pyx_PyCode_New(descr, varnames, __pyx_mstate->__pyx_kp_u_app_services_cache_py, __pyx_mstate->__pyx_n_u_invalidate_user, __pyx_mstate->__pyx_kp_b_iso88591_q_G4vZq_xs_F, tuple_dedup_map); if (unlikely(!__pyx_mstate_global->__pyx_codeobj_tab[4])) goto bad; } @@ -5975,6 +6120,13 @@ static CYTHON_INLINE int __Pyx_PyObject_SetAttrStr(PyObject* obj, PyObject* attr } #endif +/* PyUnicode_Unicode */ +static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Unicode(PyObject *obj) { + if (unlikely(obj == Py_None)) + obj = __pyx_mstate_global->__pyx_kp_u_None; + return __Pyx_NewRef(obj); +} + /* JoinPyUnicode */ static PyObject* __Pyx_PyUnicode_Join(PyObject** values, Py_ssize_t value_count, Py_ssize_t result_ulength, Py_UCS4 max_char) { diff --git a/app/services/cache.cpython-313-aarch64-linux-gnu.so b/app/services/cache.cpython-313-aarch64-linux-gnu.so index 32b05ab9a6038d30b54079ab3e5c571c31c1a9f0..d3b4fb03b70cc8cf0ba9501217ff63f8a4af3513 100755 GIT binary patch delta 27719 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 str: - raw = f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}" + def build_key( + self, + user_id: str, + action: str, + resource: str, + context: dict, + org_id: Optional[str] = None, + permissions: Optional[list] = None, + ) -> str: + # PR12: org_id/permissions now affect the decision (tenancy.py, + # permissions.py), so they must be part of the key -- otherwise a + # cache hit for one org/permission-set could be served to another. + raw = ( + f"{user_id}:{action}:{resource}:{json.dumps(context, sort_keys=True)}:" + f"{org_id}:{json.dumps(sorted(permissions or []))}" + ) digest = hashlib.sha256(raw.encode()).hexdigest() return f"policy:{digest}" diff --git a/build/lib.linux-aarch64-cpython-313/app/core/engine.cpython-313-aarch64-linux-gnu.so b/build/lib.linux-aarch64-cpython-313/app/core/engine.cpython-313-aarch64-linux-gnu.so index 02700d120408fc954fcc535fd6d6a1b22ae29523..24186c9af23115eeb8fd84d8183d5b299375e7a3 100755 GIT binary patch delta 28164 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 diff --git a/build/lib.linux-aarch64-cpython-313/app/core/permissions.cpython-313-aarch64-linux-gnu.so b/build/lib.linux-aarch64-cpython-313/app/core/permissions.cpython-313-aarch64-linux-gnu.so new file mode 100755 index 0000000000000000000000000000000000000000..8266bae5ad9cef75c4aae604c06f039180357ada GIT binary patch literal 80872 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 IuI=*w7sV!8Jpcdz literal 0 HcmV?d00001 diff --git a/build/lib.linux-aarch64-cpython-313/app/core/rbac.cpython-313-aarch64-linux-gnu.so b/build/lib.linux-aarch64-cpython-313/app/core/rbac.cpython-313-aarch64-linux-gnu.so index cf67bde0c4ec159345348dc32ef07019dd4f9d8c..d5479f416775787148209fdd95d72adfbd3d700d 100755 GIT binary patch delta 13486 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 O>Jg=HDaZ0?>i+}Y&1kLw delta 12689 zcmc&)d3+Q_+OF!!F*(58lMs^33?ZDk2>}G@36O9~0s#RLCW3&1LI5F%YX+BHqavHJ z&}MaaO;}`;thjMAEZ{le^I%tmfFP_K4v30~8stigVZNujt1*oGzy165JYCQG)?05? zy>;|-`OXKq&Ii@@rLwzUVfd0&M7x%(azBt2HY7q%)wt`Qh`F#>PyCE*82wAZs1H1j z>IYx>I{jaBO#Z{kz7uyf=5a*{_X6A$cL;8)Ok@D3$pY3*8bFsR^_Wr!GuJU z1hTh9jWC6>=-4zS$8KgvW6M}+Tz57kZprQ3A4(R%0MBH_t+=0udnWQ2IDT>Y93kgv zT`rNw*y%V+wRafj2r2F4^+LWN4ahRVS4mn0Z}LXECV*cSuItqX@O#5_zAk__KcJOU zO&S6O@^IaO<^X=#Se@S+z$fa4NLv7J*f|!!8+O_?zWV1HTZN&HfD9ht5Ha1_63ut& z4kZTgIl_)LfH&;)?aHHkVi=OU3c$<4(AWUJ&FHcKe$Zsyp+y0FsjyQUz&pY7^2x3M z!7`D-8^E`Vf_(wJOX!~q;0=9q(5)?3EA*p+B(40L!4-vY=2uQYhB}d9NC0o>&j{d~ zg}yU@A0+I%Zt{Bh#49q?+!W}J7#SJ@_%@;69Ke^3)bs5M;Ju=2+5&iAwJ>xnKwud1 z1@MNUjsU)0*df8UHg)?Qx*97oUVib%GH@3CXv~0P zg+oIE_y#f4$pL(+Suc1|0AD**w_g>&=kTuK@mCWdaE;e9Y!2Yb2%T>T;7iMNepdib zM9b|B;AO!d1FyxuQDb9{J{ORoSwyvA(9qu{y1*<98oXln%cm?0?a~g@Ht`%pAo?C8(`5rT@)bb%V^KLsg2#!(~{I%SJ8eK z`Sn$jVwD`kp6O{}8+t}|tLnlIW^W;nm?*V8HC?1d>|01jcd@v+i*zhYNwFkN=pt?C zBAvu0K`Met)7jNUI*t7%#ljv$>tS(^6lOsGVK0me7or5w^*c7O-dR7Fx(&wwKV`*|+w;C5dp* za(k&hN+h)47`DAv35!gR?B?sjj%VG{Eo?a0_AcyXHX_|ZOWCya5?apw42^xzu!^;s zTbs!~g2pWN1vKWc%-$9{myPNDTh`G#GA=ooZ0cOw+Tb8kH`soa`>@KBVDeLX>w|OeAC(>vMH9hn15gj{Ub}sOry`R5t->BzF>Ee zHH0n9w1>zc?jlzR`$J}GNF5%1A*>}cBZP#yi{w!DS>}UuJDZecmFi4vX_k#znLF!t zdXasUl}z*4*I9jNB8$#0q~UB_b}xzEU=L*vrc>F=*`?U4Ud^_}G?Q0E671V7E{hxc;P#ij78aVDnnM!ZpLY6{)27%aJM_5j zQ%Kikb`*Z$_gmtjx3%%Mbx8f3LYmZ+hg<|ak(1m5 z;MOHHc3pqsNdV`4Jjwk7dxtX%J8k&Boj%YCNgrUfi1zh~yN zyFE;e?>-;g_-=P|(F`Dk@J3m^P^_#h;I(%OMF z4Yt#M?4!ZSm}I{moL+(2CGIpcR1DV#M(ZnOqV-FQhrSsUH!u&{#G;a?Ay9rGl zj1IAOL*ZwTum+(^cCoA>eS*O-Ho&N^n1W^EuW12kqH)=oy16?ZFNVjZc~fyBj%& zSob2<{T8hTyGjrZ#Pbr; ze2q!7nvQ@+gxh)0HQNY#by%OUpHruXmGqPD9V$~&sO4`cQC<4zXePrQ>Q6uVm7`c^ ztf-AsYPs|FCn#p^mZQUM6mg)A@R@xkw<8_>%TC{sMtd?kas~CXhev*xbO|xO;y)$o z_i&lJaRy_>0n^{HnetLh>i?EY=mi$-NDsjPu+^E_?T%vYk(k*NjuG?&_MT%hZDH|6 z4SXtw2ZsiGvD&eJ7g>`)@HzE!Ojbc~jSq6nmTKLrOd7Q<^M?+64 zgqwdGbEvy7Qi}#o+gxGniQGl}3?+?DKPi8V0O^|ANU-?ID0d5rk1Vz%+aV^E46;mh6QVa!WhIzGNf#5Jr| zX&C(1{T}=?gNfPHbS90c!PnSd#wVwv^jmVd!rT{;^S4cS zjjm*^6Jlu^J2K&%@FKw`MJ&DId?*=9M(6i^n!D z7uU6E| z*tpWH{_SLMiF(OIoA9#oO+EHxntMKNW@)o?_pDKx(Pma(I*R_4HI}7Vjut|zjfWg6 z(QI?xrfIy+lFCM#oiSRX8tQRuO<6Wwjw}Psb3*Z*u=RiI+od&)N{0!&;o&>%QJPz~%{|kH{coet~cm#L|_%ZMp zkdNxlwQo0eng}Z_Poj0KtlUEPv-``}_rw6@p~q|UZY1Ab#kp55m(_V_zSmjUw8Cy1 zU__gpun2UrNz;}jLWO7H>iJOn93@ z$2i{uSvU>xooL(bYFqC}}qdA?2UgS&td1^i?)= zM*ghUOWaRKBX@*PGM#JRYj_hJ-$=cF37ZMj!xve!JB^aXr^88kBB9Z|KwAAM`wsFi z;jEPsj~9jhyRGnPb5zmp#5iepNF;lIMj!6^_cIE@7&M=RB{$2QIk#wyW7R;KGu-Hb*t-+*xZV#+U8i^HLDn0v0Tn9#_(e{KZ1SaIE7 zo{ygAP0pKH#!k{Hk==u^ykAPjw!I7Q0)H8EmJ?mw%BSD<5|zK)w5E}Am%*LYxW(U8 z^d#k1?lw2#Rjd67s?WP*2e$L|TVyp6wRXTUUt&ig-kvIb7E)gSEZ?ZaH9eqeZ&bOQ za|M$E-gKNFgjiYkn5^C_2w0Gwp0<$9+{mg)!W$%v(utKA(bCSv;WL4mb~#S=AMjRCxVDa8w94F2;z7IF^RKokUP){*xAc!wM5w6_w*Y_ zLP`0hM^<)xi|*kSIu2a-Pu+5Zu>AKVQcf@X%h{ZtThfMfJ#-gC=gQq<8@ID@b9x1@ z>rToUtDMs}kuPa3eXr94?ZH)e#}u;H<_wVPud-8f`d43?I;znS6v38POjKW*dNkp6 zs2M&tzl=cOLBM_HvBrnJ2nhFR^mw}{pBwL{)j=;P9M3J&fA-gL-d{ciTs@B%*g&*| zAL60&8g{i4nR{+p&Vvwlhq-aUNZ^k*{FZQ_AIOX5{ZwSlaF0O_`E!2(i@G~;x+4M` zeyn_Tr~KN6u;P?od!c}zDm~@j!K3o>MZZ!Aqq>pUrXpu=cQ%apKJyox2cL<(0pGCk z-t2^~tAp7q`gea1kGx~iEQ3D0%4St$WNg3aFTeU*;=VSIxcz?G$hWHc240`0R>EE9 zWwxy%x4O-SSe=XbJ)=!yiA@v>#@8rG3(24S<=%_hZlswn4e+e?^H^EsEz4UP-q-T( ztAstHhw!qF4?eCbe6IK_T-yfZ5p#V-M57<+&#w}VQW6Uqt`$lbfvis=O!)CTz?YXf1 z)2A1{d16(+f4rIZMd$iW{nW6#ww?W3PWPJh0ozx|pFZ5#c{0mPe zckFWI#@CGQp6>X^t`|-J+-jaUC1SI4!?@B%pDO;~H$M%dU$vy332pi~Ehneo+@H#N z)_-&PPlHPLpNhWPSwHEI-B&#Qudhp#^&|$JbS<+-+g87{Zq$H zdhT#}kF&Y6UONAW@HYtK#Xc^HUB!dc(0}dDB}#Wpm$en3=mR=f0`E zPB*QuTK$!Cb^8yGj`ZLA{ST))KR)t8;pFVJ;j?agaq>G4k9=j}!qo?^?)<~fOP8K3 z@?2W++oON(b3FTvg&$bh+@sr{_~xz`-x~RBo4T2hmVJvRnpn>zRn^lmfM~Mm_8Npq z4xT-4`~4dbLOJjF{bw;~eZZ(7LRPl={bMnZhyS17FXN5q!bg7pBL1HdwqSM0I~s^V zL)HWL0uKY*foFmI&;OtUet#k`9XJp;7AW&SbXVe`97G3j5pXp2Vy^(pfnMNV;8|eY zLBHP&hel&>Ap>Us%YjwEMZlns{r*kB`M@`U?*fOz@pHgZU?O&?UZ4l~6L1q=SX{yQ zL)U|cO{m$X|N8yMfN`Jt{T;vtU?Mian=p;a!1X6k5bzwZhV!TV{(ZpoGk*Uvyn(+9 ztObt6mSh+3Fwh6wd=`%5J#aoYs5!u`c+YSG&jQy+<6$gDng_V|TNn;wH(_0pivIi8na+!G%-^8xl{Wq)bW z0XA%TD$7}Jmg@LphBW#OcJK23(%v`N#^wDJTnHqiLQ9Z!FM_A`0NcO(A*r;D-LYbr z)ZE4%SutKpf0MnxVsJtv0?2468TyeysO%vYv$9C?e9We=OqJpevsHka!|eH$8Pdcf z>}^2YC+tg*Gd^J<4;M+^qip=cTclS$W#2uVDh)i&y06NRYB<5B5m~TvfjF&n~*!5Y)j`H+cEq< z#xK-QyZET*7bXksdYRd7WYa~g>_%F&IaTL`Wm3!5K~~CMyOBm8YdMJL>RM6CuY}d) zS1MSPiwWvibpYl6st)k-e>DeidZbVbP`|j0VKB)ZL=va-7c>rhbt6^(lkZM0DD@^98)CxBQ}v*d7fv_QDy20Xp1F7n#3~oU>7d+m z;`Eten=d;OPNf;Vv8BKYh>Lq$7J+f(bSe)-&@65W$>=3cO?>kwO`#Dqt-=_52A_ck zZrtFF4Fh&R8s9EHp&NXK;Ef|c#)jlE!4Fa#ktpTr zmo28(?UyZ&zcMsCMvw3fA-}%G&Fza52FlS$8a>XKomOfp*p*-$awX#g*hIk>3*HzW zeZ_cn3O+~4?M5x*M&F_9TSc~YLOfsaHG;1byfJso7Q9#RrHUKos(XsaZWiJWAvPj@ z6Vm*OKC_y@JL-RN9Y#|KFFc-n{*&c1TRkhRFe}T!$u)+X6l;!Er(w% zf;UFB5dt3?hDPanKB0fn&>y4oRXUI~ytMENkYb(C9m4v@-*UKMlMq}G8CDD4CFZSm z!9OQ>Rj_+ElH zPWBnRL-59Fuy=(%{wmZew!Ty+48B_MeBM>I-bUlb88i5Bk@Fuyqiw2A%okPJFZe;z zbl!zDzrGcGUxh|tLNm@#y`s&xKM$``B^P2kg9ASp>ryI^9_JFrHuTX(ND`hD-Z&+eBlxL; zC(3DFnz8cL3Gwf4ilbvN*S0^X^pBxgNu=umBdGopYFel(l~7B{2@o4Ku2Sl`cv*n> zq*h1*dgovaEs?y#lpe9PIBCO!!U+LJZ@82-u{68KqE)wwZ^t_a#R{`%m9i%mK02MZ z$|q}b9FA7P;%Ih~aq8MosuE%>BM{>(^}0AzxVHDs7vkuv68(=-nSe+-p~Dp&%!=DW zEsEDd6KSIMO#A6DREH@#EYM+<4(oMzQCXJ=i`(_o8#?UM;j9jwI)o|FNzhDD92|z~ zFi|IGE0rLF7h{@<#(p4{*692u9k%K4jt(E{a6*S~Gzg}6{fp7E#wxizP(Zp44h@vr z9;jS}{_N$?zthFrbnxhKK!;O0wCiwPhfrl*GR(&6&|8NQ8YJC?cg_EG@_e4IRiy*d z;a@uJ)#0cP7j)>(;2cop5pfcTbNYNozgPoBnOA&@`}3p*b`=tW<1+N|m8Gv@onzBx{v5 zNZx$^HgI zo=XQu8@oOOS1L4*W``RC?80JYSRNf5QzeG8ftSrYAJ3zAP;56_^Wmd$vcF1E^WmdQ t%(*VJz7&)yjzOreksP3`^7@KdPwcu2Na|erRuZZ}w-|75BvyS#NfISp-FVPm3?y%f1vrX;94bJ#)>ZleCw* zzvuoupXZN+Pnc`IbLPyMGiT16nd{2c4f7Y3n@uJrKNj{I)|+F@Dhj4f=|!z<4$DT# zrECq;{=^diIzTmebT!HKbgvUH=!QM`At80g0M=oXQY=s zqyT(mDw^kg%Li`3w_?e1=DPaZXK#Js_K(+`ere*=;vqx+v?=ri)uZZb@TGda^5w*k z<@g_V9(p+R{&Nc{Z}hRS3t0E%eM>EDINNO&0*c~a!Z?QZC1po}$v&&a8&JJJJZ6CZ z&VbKM1NtH8cz^sqF`&N^1KJ-wVVWwqxc(&upg;O8+5O|)2J~eHc#(meXVHFt?Un;C z>POB-j7xv?3k>j(fjol@`gPJkp4|reUuwYr5d;2zG@xH-pq~p2`ZdA;Uu!V#8!&15 z)7xqTIqx&zbG1RcI}G&mk^#QLpxuCh{_70*Tx6inZyCrx$AHf(&`*E!{SJfveqqq= za05NRY0&O?13fG?puZh<(x03?2JL1U&<70c4b3tQ-}KKXD7ZKsME)uRJ=|&_|8oZ8 zGTA_WzX5*CfX`lo@p{of4__MS;kW^xhYaL#7|_#V)!)2Z4&C*K#|`>*uYsJ04e-|u z#^pZ@=>Nk&PLF|{Wd?H2F=+Q=1NvVX*#FNB=vFK z{>bij65emD4VTXe`7TOm( zJl>#pwJ#L*2JMSWYXg3--Bn%d)yw)Xakv{@j#WOttJb#;gq2N>C8)M69BgohS!Gk1 z&mDFw@vgnINf>QLF|U#)-({Se5X zQna-C4lg*b@P&Ng#V)^Vwbw&UDV2y^uqUa?ysp~XfExs&YK1p!3x|Wr#<--*yy1mm zZ?6O-Gg0}f8^S4qqrh7q_67WlU14{PHw3=apVC^di~44-33^?gWnov?>p(+5cpvJ6 zUi2ghFD#>KXkuYqeIOWC6$3$%k}VE+8fv|yMO}1M5)fF6UN82BYXTmjY0<+fpSz|s zP*?8?dP@R-kPS6PHL`P@< z`5>V|m%G*#qMl3Dm3ddW8fwEtskXJs0RjXXSkk^xJ4F!UF1!j97=*Dp9mM*G5n!Z(t*HX8;AsFP{E^&pt zf=j9d3qxd7y=`E^A!7@!cC3Im^I-1Y=xtgX2zmfD)Or13KFfQDRrXIXhb$=$#j(O0 z48cQC1IrvCe?7cfm}XT;Q`j3)Je|$&S*F{h)KssllVx=<@p>AUex?dg-Rf5Oylche z6hWXZw%uB9!xxIXj0_r|@p}(>gh60>Ve4#&mGE|ZUI2`p& zjgC6qL-|6EI+xGyaMjm49PU8S>u`jwpAh%6%l&Y2ShF0`pve*|1EHniG=!@0>avk-F2U>p zsnl9&!0+Zumz0gW4Y(@7tD-d38zV2L@Ug>&yA*qY9wbJ zCv}j@YJJu2;!vP?7OVA4uJ!pF8YjD4aO<;X5;~1lELvDn>X=?UZ8n=y6R7h}sdM># zp_(amK3a4A9@mU1U?HLfGtQg7>fhIu_g6Qy4&`*jlGaixU4NYZ&oI4fRQHI8{WL%i zH`C6>!u}f=eW?6TN^Gc?o0H}8ywf5AtCo3sy_MozQ{t5Zm*;B|m-%PJxtqkd$mgWtH8py>d1?5z+jP7#4eyqENW)u#I(`ue;#CScEhTE6u^as=MnD9%-((r9`K!wkVG<<5duCJanyk6ir zB9-%6`s;!;e4DUy$xqTd#kkB#qyJ#OE{|+S($@?69clCt>95l89Re>9dX;>pio8rE zF8R+%qt6q1+mePqHCdN)M;e|pO~)4`O#H%xb(8LA$xo$%VWQSfaFew~8vP;fDXytGBZD-`bx|j;4X!}MXYypYx+_JKWKpOR&e18 zd96bRxPB)T|HFQ8B$oW-@H?bBj-uozPr-3?m;4kcxCr@pnWo_K9yAq9Q1AFWlq^v2Aqt;L1;0qaS1Nd(f;$!bVg;{J@SzG`ui)xDYE*E# zKP^8I1s^U!q+1kxgo1BV@R16>L%|CayhXt;QSjXgK1#v&DEMdve@4N-rQlHozf8do zD)<-$KcwKAf*(`xLIsa0c#(piQ1Gz|-mT!{6}(5mFIRA8($^od|0@(cN5Lm5c%Fh! zQt$!=zf!?91*bD}`I(^L!o~BVsR~{!iIL7x@F@yzRq&|_zCgjnQo&0r6@0ovzf!?x zD7aI>XDWD&f?uuR^$I>q!5bA^_5TqCpR3SsQSfgo_%;Q5~DxHyXEr7a3BLV1qw zR&cArXODv06#N+lFH!KQf{RdzmmXB`GKKz-f{W0TmmX8_1qyvk!PSRRPAK>d3VpYN z->Bd{3cgsunb^0I{fm%}m*yyVr9z*l;9{%EOA8cSZY`)lQ*aRia{37hzJeqAe^V8F zrGn2<@b4(NRl&cj;0qM|b_K6gaEF4gRB)$)I~BZI!D|%Ut>ED`fTx=nD=?(?=DfBH0eusjO(JZf@U;kX|c?)YkJ%DXLzrJI4)Z#cQNxD(i zjmN7l{<0#T*EO$MGmkk+b>tUihb}f-<9TMr%Xoeu@+Qu0N}n@zp#Uygi{lAnZpiIOiyzFNsoM}Cu%pN0G`B|jJW{Yw6N zR%hQt~U1-=*ZggZzFae>?JBO1>I-v!%EF zRmc}9`8$v=QSyG|tCf5Z`AtgxF64J9`E|(eSMuLSzDvn(Lf)L!+x`!cFH-XNB4489 ze~f&!lD{AMO-lYDewUJe7Ww^3{tw7^Df#`#n+Nu`{{r$wO8(EtmnivHkgrzqhmqf;9`apEz6*JCc5nM1Az!5A|B8HxlK%(t)k^*ofQt~5^-=*Y7A-`YAUxs{_k}pEud_iyfmm^=K z9tqU4K_uU7KYk>8}`XCc2!$3Qh9cs{79>(7eg66Nzt`7+Wv15C zmaIvi-fC|B6mon989E`;zAqCGN6oDLjD@v5&DhnP_o0gTPBS|hWz61b8POKA42SIb zZ9fL>X$zYaF-qK1^EFD9mt-P&HL8PGrJJF=zuOD z6L^nkYeM4#> zlXRNaT;kMVKf^I5I_(zFM!!tVPSQj`6HTSr0GgKby)?4EI|f>1CGIv+e<{J?PJGpo91f7LUWO zG>m!dB1U$5xMM)1DrOnkmdIxDC!i1Luzh3}Lw`rMof7)fE@15%bipFuY90+)XdGGw zvi1SECOfd=x@#=WondV`r~^B=6EfIi+17X``0UD!?7JMaY(UQ}?0xc4J`K;)*}I^t z(-GqKTA;#6j zSlotj%>o^@N9|JmGvJqvwl!1FtYK(70zE`gN6rf;w}t$+&!}z4fale=I~5uy>_w*; z*7kSMoJOB;{*q69dla;!w@>u>w2eXMT^Cv7Bv%P+-30wwp@&k)bbh@YyHd=lGK|ao z*7yu-9OKta@!$FN&vIV?y=~LS&ICI61B~Tax1}|{Cad-H(16y&^VzTNy1gtu7Hu3q z%iU-rtke{G=&T<%TXymqZTJ zT!Am^E{V=;{xjMq`z!)q;vGajQrt89LyX-_=zP1GY(Bq@#>|Z}=TP{}$+`^^R!(w^ zfE-t`_CgvXmeagxXyh>F6Y5>kHj4U(wiuh$JQlR%cOqA^cAOz~M@wcke}wY0z@nHd zBu5Eoj+G})x?iX(WKb&{uldm#EK9Zg0 zkI7<<)BKeF&Sa7PuAuEYloP-H?0*)@VoDkGE$n_|+Z2>JNe+uH2hE8n#)I@b0cA9= zV&os-(`n52qrZhM*ENsDI53RwY2uCf_=-i$t)gB&&LW-92+-tVd_OB>?KJ+!HnC{`VhXmXTYjzjN2P=5$&{wLM9^=dpMT{MOD%>=gE3_L$|;wiO)5 z+Kjp38j`}n`Q4D~6t0Q)6Sjhwz9je@n*C^Yo2v9vxmTc!$a&;VIpDYHh!=ouA$yB&~RIT zpK;-u-N^P{jJC+ffo>1kVxcy&nbvO?bQ~FKO0HEd=-I{n)3CNzAX5v?i+o!=iZyEq zc#-`?7O=gfue0FQSv0blbW<3?+(b-A>zi|wDUPve=i~EaMf@|~rgb0mb@d>~aV_{b z%h}!@%!3Z_Db!eV6mz!dm=*KZ8lOt#^Lu7f`_vCMpS9zhv%A1O6aK!S&5H6C#3;|B zt`%*606W-xtRfx)pX$f0@zs%m&0HU^Rm4|C2R3`1+0AZePP6ASORMM60j-`9Ijx=_ z=eGWs+PMR3QVDCvId=Yj$Uywb#%@O2R$I^Pk0E0<_9oO0=lQ#ec!cWtS=?%c&%r)M zEo-8(AnbS^%62JbkcH;I^DfNs>skAixaRW>*VX&2u=~hi7h?L(K{>51#Oj?lvUv6V z)_B)!j0g4_ol{tR9b)QtrA~4Y2Ra$|Sw-ueJvPO^+TdTS8?_#WHFeBjcFF|%=t7^! z2hh5ggSKN>mm?VGOVRFVe5a!S>*lidTL$si^6)i-So1ZXZ#Z(z+3(-q319PVwEH=Y z{g;XM0@TNE7}}gz54%tnhwZ~(Rox4kF03z6j7t~RD2Iie>Y9x{48!_51?#3cQk9dB z{74q}g8n1a%SJ5wonc!ZjUh((7=Gj9F($;u113=n61$YeVOv$5-)8%uDF+Yr$H2>v00m>jx%mCDFJQdu_2uqNb_pP;!q3v$6qi;qTJf5}sbebCprNL{E$Hf_cDkzP-I&gb(qEtlD&xojr+7qY*T0(V}3yY9f> z22aH2%}$DWU<=$95lhq9q2_g+7|+<)$aPMvft}E`c>%RKtZh!?-92Q}n+CCVE1P%J znFskXM&u($K^8pDe05Ct(Js&x(mDg#seBj8X>Omv*sQ?V%|`!-XA|^HzJD#!CopHo zN7yhQ8TuN9zJG(bUIQP*SCd$THSf-5+i6YKKw|>m=dkW~K&OS!sfoe9q0^_)-wU9- ztI;Op*^4jt?OY!4AbF00hWLzO>{RElo!_|1!-5ztdzCwy6~h+?kDVJYux7;D0v zg*~&DfR@iW$N_sgTm^o|F%~W4uLsjwW8HTRF*0kVYXVt?Q%ky#!yQ1y1E!B7Oc)5VnUxs$5Jkp(*ZH2z&nhjlub=lmu5N+R$eq4)o zyh68<&S{o(!`kM7?h|~ut;6rv+Xp_H z!bbyk7HxLkgjgesEq!x3_|0YUSQU8Oz~#t|7DcX$Zu-%+V{&rujADOUix_iEj`>c+ zulB)otucQ66xx7~=GSBL^fX4czgxu8k@4L2N20$`*fGn}eNhy;Zn2Or8qxN_xx~Yx zFrMU#el6zd2#gKm>+Zzn=qShrx-UWJ#J=^&lHR^!%=Q6`GfU5`)1Y@@oVq}(VJ;UQ zw8kGnyD@XmtTVvK<|Y3xzm)v1Xg-l_Yf3Z4whVN~C02Q5GtCF+=~c3i*cWsrFs$u2 zkmUp5)F){_)F&s+eYEwTD6dA_6mQVJEX3u4y}}M$IC~1A4Ew9u5!83SpGfYl*!#pk zzilV#e+n7NFO%G7;fr2Hz7uN!`C{^Qw8k8VFP#Hk$Kf-{RtGDxM&8q9y$`&wFHQD= zy{qFt1pc9DgLF@AP+PwNMr#1g@k_DZeH-~0jVbnO$IrqyGo1A>^GTYkR*e5K@WCDn zv7Tv?JpVZBF2(+<4EwM7*mu9c&qBas4@2C>BBthf=LFAa1=(r)5#(u4H%7C(&gr69 zFF;?2bRPC-QM7~nw!)_>D86g&hL2!4=chX9^zgYa7Jaedh;8u3t%YCM9_Rpl7wVRD zSH!D%U30Q7wKs1p-Cy{Fey%i##mSDG`>U_9n%Hdc-p2MIWIq)HQ9OEpnzm0Jq-t=YT`2IF!Zz%i9%dh(Ca^7#8VQGkwV28SI zM~oCjOv!)~FE*9VYp{1kehk(ZmbdXytX2KC`629NEY2J7du4mpp|M+O+&1P|_swJG zHP|TF?=iEP6sM4H#-pcpQx>}zXLW1tz`S=d(~XGZ2WeT6K~Emiwr)nfov8QnmkB%8 zqDe$|64wrvwT8VG8AY-^2^t1|68jvwNzpgWkwuupSRc}5mbxWAKZf2TSYw=+|DUP) z#rYSVv)m6GB7OGZJ>lzlJ99xZ*vj`r5wzo+ggENU#NM-LN9xr`|NrQ(KiW5J6LYDC z+AD%TM0>QSNIx@VGp+I7b53(x3v7|jI$O;1j$+PF(z4mrk)gWmbS5Nm`0A_47s~Uo z8{&LDo76G@^pmhoay~kJEDKn1DrP0@vQ!K{`|3zZD#i#aPsQLXuZ}E9#iAx)RjHUp z*j!y#*@n566NfKB-^fpGLM&YZ z-;H}UbXrHz;tz;Du=2M>+SJBq%vn_&kw%$@2I7B3X@&4&4AMy${A@>Co) z8{ep$sXc*q$ZpBz$uCfwS3>t>_W~a(@f3T-nf9z|NY0#ddwy)~`2c!} zfVLCsV+nLy44u-sDfDEg^U+TD9kP?NmvY_nv-tDt4{-fIXC84f2D%okw^V;G&L)Tl z930UmOP=?BoX^l1n>BtP=w&+}LB}rh@E0jR1I1Fx1-!--5F{nmfsIC(1$7uA!gQUj{pgp|7NGjoYW3 zSGt}E{}uX6^X+={?_GY4dndT2vlJ@-jVPZ5jN1Hf{r&oh>OtQPU!3m&I>JAvo~U{xR5Vo*7#V|-N1&Qbm0tTY!2oH{L%)*Q#4mJ z__M5Gi0AUm%YK0Gb6Cd<$^Nq^%+^L*buQ9xmC!@$Ar)2f_~@nBcKD{p?@LWvr$2< zg*6w(7}@xv<9epd+6l~b9B1l31I{)-`ul$9I)PDpWY2WAx$$(uPCTClo?ibLumRA` zzhf?BU5k4jJ=XjGZ}`H^Y~Z~+^Vq2fbVYGUwXJkd_~ zKfg&|5f|BiCi=QFi=Dzev&;U{97*Xf#)A4wF>y88ss0B2ef#X!^p}n2{e==!#_8+& z`$y3C?QieePd@Jq`C-UOF>F?zb>F8rU)?;I4IPfL#vHh_1?%*E=s)^>rxoW7J8{17 z1o}_=Vu}sP7j(f+KZWliKR~+JiSvk!q%+*>83*2^GgA(;7s6Jk9@XJ-rBa9YML(y& zd>PN};qRZpFYCVMu;fqi%W>Eh@g-hlZ<}#H!G%2o*^|@>*+>z_M%oP7%SPzqZy1;3 z7<)Qv>l(x2VYJZ+ze@H%XRs3Y3!I(nhd1msg*WE+9pFu|gRFnMs2@fBZs2|7!#TntSw)?5Sz+zbIXk3UN?RPwgS39tl zklZr1!2H3v3;Y)OC&<(VnM{yL-g7R@*JaXeWj^jBmvebY78?Jv?(9}qHEV8!Oq*Z} zk`MLGtn|$^ROdtIGsHvk>&CgwS$75eb>uMhllXFfsl+N#$jB}fGGfglJKA(P*2IYJ z*Z+b3(m4&SRdmKQ0{NG4eKYJ5n~V0CxnL{w5og`sJ7U4O%Jaoe+$SJk+XKH%{=cZv z*|UG0xW8gyCpRKCpnHvXfge5N;KbQ}?0MX~!@el?Go-i|61#`)KV?(@S!dx#z{O?>px2JmD+@9}b z<9?0BbZ_S%D|Ciu91y2G1bMKY-swaf0H1L6B^bZsXrFXS`la|VVwrc8#<>$X`F$A| zY7FO}SPzDy-w882Mdy_Ctju2Ab4-|rpCte4T-VS;Hh|bDd6sX&Ge6N!p*x}D$8b&K z7GJZV^-h631MFeC-dfW73dc-sPXnW~!+nCD#);0CX`Jo@MteWl%puxWU|jc5c_Gus z^$^Mrp`2`t^qGZz?+0xO&T{7AET=GU)1#O_JeIVgA4Slgc>?r2fyF`B4&5eWXy}%o zk72y4^nKTJ(5IO{r*$vdAv`@Ep!JB_k!{lYJ1(!}oD*}nh}K_>(=PLgS$$+!1Q{0f zFGC09QrjXwLF)p^QUf{Yc`8*Oh1M&$|NS>z#-X&&BwM8~$wxAEAdZ*vRGVXcJ}!l90+(ZrkVER~8_S?U2JM^6Fup$-qPh$>q{+~$4{=tBJps3U z*g4lF?1lU_#`5G7INRgc3Ekd`$lkO`yl)JAo#xc@g-D4t{y+(fqYl5vCH*FB70(Ol zV@d0xJhwP|M%NwA8V=D}1KGX?TcJI@^@}%V^R|Vp7dj{Mc1MW*q@0)it9@`@#d-Y& z?f2;e&OaU~|K@#o;Vb*_&(uD&T*=%05OrYJL#Ypa#zUMV(Rp1==yAg=mYkcU%Z>2w z&Y?>A(A4sd!L*hQYui9$RHV=qrP1NOkrQh}vYpFQ%S}{1NhzO{T5f}ncjCM+S-&{7 zd?TJ;b52*vr>B;8U>$biY;eP6{p;IA<*=zFf7q64Q?_iBW4w~(7&o*L3 z-AJ!S`b(rUkhUY8hLrYwQ;_=d2 zgp6bh-KX_?u&WT)P@ZI@d02Et*8gqtY)!=1lj!W=S+sE!@y>pn!_eNeT(iYjK`#|^ zO7@j#w4M*dI+{PJ(~>>ubDT#c@Uz@H#NL*>?|vZ4EL#zy@58f$YdYXdj?}n&oM}FT z?upV`P0wXeT(f_mHU2VWrM6;2SbP2iwvY6OddYPeYYII_+1{dHEx=kpPyU7W_vhFD zakn0GSz4dL7{8wuurkE!*;`|k+KVNqi+jggJuLgh&CI-YbH26JlmFcA zF?hZjv5lRcQF1~zI9HD63}6?}ynyku)VzI#-e77#|D!gAQqYSBf!> zoJ#B^dj+p}%P0ChOVGrvcxHgcjoT()BmTHMa9TgJq55)6?*K+LHQyaKYYuF-;9B#(fto2k#x!!xePv>2wAx$554StO&wt%z8 zcocHJLC-{!P2;&_jM1xP3)=a_Ub1P5t>w8D>6PsJ3a*QSw()4^6mNTETM@3M?NF@A zB9X%vqYtqj{=CB>8b|9F*7F*4pp7=2cVSG2F&59yVLY~Oflj18To}6o@F3lhuJvbo z3)(cI<(hzB)<1EkCv%8@6EcTS~HMyu#$>g|a#=jF!P07h@BchB2zyUU+j{J6HsCp|E3d#A;s9oMU|+9c|LDj;dL`o1 zZxQW{t+-dY2Qu*Z8hi3RW_(TfeuU?dejd@!+TGfeW`2%uozh%}HXnt)W7wOZUf-B! z68s7FcKwx^P{zRf2|TO7BGa02-;VFg{tf#JlEpEIo!a<$!afuIizq%R0{v2qbO!f0 zpy#CCA?Lmr?WIwMJ@_H_F^c;wCvE8Sr?=*`z7E~exqIOmYy2_DOg=1z=WH2xzy}>V zi}(vRH_eK@0p{aAI!{HpeJ4`u)yy7&Up@x9f`8Jz;ewMc!qVh&f<~4(l``V@8RqOx z+&_sFG5bc)Me&^nKAj_Xj-om-r1KcNGpoS54$o@XH(`%FhxQ*x9f(D3SW_anAJBm> z{hnc5f$iBWd^ciUq5GB{_|m!XIDB{F{&5HP9qif(v+3TW3uy<%8FZiLI%eOHgZ<#O zxNnWVkH?qVd5&eRDa3xR0M}$6QRqRQ1Czavfowh5J4d0I4gji7}(Ipk;XRk1md4hZ(Yy|Sr75^2t2<*b5EW}m}b*C zf;>N{!2DT=z2Ob5m}~qzg6snOF+4lb8^>E=M_sTj8p{=@zjx#d^N6iH9-nY%)~D;% z^~_=;wxYc~>~9tEMx159*!Xk8w7(y=KHSrQeFV*CeN7+D?(JJ z3Z7pV?kQv=Uvw&MJJB{hFFbZlVb2Cj{z=?pwi8eN-ce5L+wc{CJw^A;7PLN(YmyNj zF5Zdt{P@op*2vLqWE;Al!n2+lv;P5WB<=rW7+a*%VpyxV{Mc8}JtfTXZJ0aT_?&hY z^Z5Md7;kEW=HUfsrvtKfp`XXG-fN1ynvmDlIF`$cb6UG2o1MA}ZPD3>sc~J84St=@ zC1^gQe|83}1-{~pg?^8qw=oQDNSVmjzz=PM|Jg=9hx`rcEk#b@d)6y*zK`c?B)@lX z-M+5Z?p%LM*xhJ@Y&bIX=5vt|%uaKS&oAVi|BYv-amGMrBGs_}UqHw7ES_~3Yu}Ht zF2Vh%4y1IyZw#K<>7hAm!CYmwb6I&epEF&I*aI>ae%$NxJ3dP6-2gr_(Jt+`$=0lj z?yO{I@K;Wh(|R5T?L1rukB}~({ry3&jABJX+@l{31?Rh5!Xn)(;jpj))RWhO6uE< ze2H}`?myz0A?MWQ@V(afWzhMZX!`?-0q>{tXS!b&Ib4G82g|ZrzeE{$_FW4u!92#g z{cDsP&2^k<>g&Z{5_-$)J0jtw(6CT23;=11)r(g?j9r z3Vz?u`5C{z&3~Uqc1e08J(1o>SEM)6*AdA0N67jZQrvHxREU^I#>It*c{U=>-SK*2 zRz&fKkTD*k^GgMb5{5l3m)D}Nmn82I$omV(OLqJyQr_oaZ=audEn)vT?+?!WyY=Vj zVt-ETrG59`akhDmmkn$CZ)MzZU1u)8V&F@IgJ8_jF!J^MTHhiT(-D)7*>Vnc$OMxMyk^`68VmcG5ZL z8m&kBU)CO!pYjY_er^%&oo=uUKl$>z3HxXF;J0ONoHZs)INz4f;OP4#Cv+N#C1%EO zFM^&$Am8^I?5+^)k`Ii4j}3lzBgW2*`A7bd&tdp&2g-?_Y}W>V*ns;>+(&+aGu(F* zS3}O^*d7Oe@{MwA3*jTbi?*e&={Qe18PT>GecZwIli#)x*V}MS_d+-CV$G2*nunVo z#c#<*&I5J;SO+k=7kVi$tiw%MhnuJz*Vo|s8o~qMGXs3;kj~}2FKN4j+WALfHqnw# zp&0K^z?v|g{Qj$Q)+f*1U^i@84c=Sq(Mp@}Vq?D+#w%vE@x{}pP7P_kkme7BHJ1(s z_?w`=ioV7b(!w=fZEY~%U#*4ks@1EsaIi@W;=QMJ^*+2Zlipw8aPyWNGaS<$S0jI| zyJ?kpWvVuQx#kLMnuDr-ubJw{1tG${BZ*_KuA?#$d1L^eFp=xfIUkl*1qgu6B zs|~n3Aix`71Him=;SK7qgVyT3L9IR*aC<``yimnYuNftI9K22tujb|-JxBN|A6{=N zP{sm5-)f(q@Or$E6)(aTMfBQde^|%EHNEtqhH70tN672KYeLbC+eI&i4e9N8?{d{P z(0i-pt6O!L>B^rlQCp+G6c^oW2!*L{c#AYtD5|sZA<(SG_|)N5&_29lStEwtkhUri zlyxoDbmNv?f08SAQdIC{0|4QntGm*&CCT{UUlG>&&RxN6Bd`XkoIKp_YHH=}jn zrSJT;-J$;YhUqQYDqE)8JZ4lt>zyIRDO}e2phlXa{2k1G(zk2XDohbR4TU*0g!p{W zl9P;-k1=#O)~x+1iPF?!C{GHP|5p;}_JNlgPoZ}jPZ9H?7_VcdPtx8o#0`FLW4-PQ zgt;U~J!$E}0(<9^ZkXeX=Y%ve*ZKfnX^-jXs!i4%Upy_8V$0MnUfmm}caYn9rxJIM zS7_w#e16CZ2M3jt=bVs~OP?NB@foULPb6-Pp?}5Hzhc=x14p30tysH4km=32YUzFV zn`F5{HFJRXy^;P69{f*q(cu(oD6pKr+@mm9v&z96(b_x{DU%~c!o z#tdB?)}EcP^7i%rc;&#Fz_rJ3oHhKzhi<+7k)0iXd1m_fc|SO{%Jx+Id#B!R3cUA{ zeaufgLtWvVf0nGhbHpVZ-*~k1d;fK^AbRo2GrxS{$xFVMegDL)MdK$%yN-9A_~1-d zc+a-(>`|Au+;-`I{%D(4{KPA-JUuA--L3YHkH?3nm0H`Q7k}qZpYM#W8Eic`K4SS+ ziRb0wf#bs?S7bZCdw-Gto*$fFxPJd%fAQ-T3yc2x>+5Ds>zw93)Dd3(_9OW}`tb|j zzGv3J*7jke-+JNV9~B*FKiu)|kC#UeL>r$k+&|9bsh)V%%ir}*tV?vQ`nQjQ?Ne6z zuY3HBY3H7w{`jCr+?TXfZT(02d(*BT_U3;+lfQNOuU0Oe`{=XI+pb#q()7#69skh2 zWbTr;oWFSaLr?DPw^qNo@zLEkOb$)G;TPK;9Q*0gj%l-=wEt{=>EoBb^|xP@*=B$8 z;P)SVx~}%YXaD@xyvPL;Kl0R{`^mP@&|hCwUA@rr$M1c1c=*@{L$@tBwYh!$nd;BK zclMK)r+n|Zv$ZSho_qJ@e|+@Z+0WK~{+H~xUis&kd4He%{7BRHZ$G2{2Xi+L3)?j8Rtu+C#` zCkL0bZm%>Yu^1L>`isdmGD9*N%xG;bCMKrsD&Oh`3T@Wn&E(u8mco|Z!GLx}=`HpJ zOP4rGmoBcXn!jwBW0}2b;gX7F*NyjFk$lyfY?)6ojeNW|ei`H@QMB|)3_K;SDHgL! zI$cK~=+GA|%rnT;;FjS7@*+$Sk%q%@7u<>d4*tNZRe0OFJ|7*9wfJiUnBZX*WsI6| zc<>iD#0M)xz>O*#mq8B6C)TN6y54n;Fr5#*=v@DR4>G;+3@=|@8>q$~mmmuKSra`Y zNO-xsHV}f&^>UF(DaQ-&b@r&w{}4$szS7$lOC;ytyE^Io)Rl(XPg&QQ18>ELUkxIHPO^@JWW=E}Dmq!F=9uL;3yTD8Tg9X}Zgurt(-zq*qgWfw4 z!G`&43u$X>@P}1WdYT(p>(}=fnCgLsAUaj;MUOQEo4jppf>W&5w-!kf%suKv(RZC! zX|x{J`n;ap>L%VG#X^u39ZJy@t?Y=1Judu-1N>DBTETqbkcQUDU)2TzYjP!b0Owg6@RKj8V2P1hS|7&R&Fh57$E8V6Ny@NOMZ5M4z1yh=!8_7;OUnRuJzB)xjw1T@MF5 zt|n|Gyx~x85&A60Mc5MWhz}mCh>tq7GC5Fx6%RUHXnifp$rJOxc!9Cc^)|vm(TIeD z2t|GFVr?M|i8f~#BHvvYZ0G~#)!UB=E^U>sF$}Lk!a{c;Z!W09p{p?T8f5i{5s!lb zskH(ONJE^3FAU{|T@9;i!o9Xa^cEQXZ+jupdAH4W)Fq%)CLB3*#=HKey8)m}^_T98gf+K%)|q{onU zBmIKP@j&}b$Tbt`0;G1Nw;_!o-GbEmN+PibX$#V+koN%6GNfm40Pr`Yd3X?t98veH ziNqqLhmIr?+mKeihI&XpKzfL9JowmyG

B!U=hBGoAi;>lqw0=fJr+-$^7Ukdwm$ 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 literal 0 HcmV?d00001 diff --git a/build/lib.linux-aarch64-cpython-313/app/services/cache.cpython-313-aarch64-linux-gnu.so b/build/lib.linux-aarch64-cpython-313/app/services/cache.cpython-313-aarch64-linux-gnu.so index 32b05ab9a6038d30b54079ab3e5c571c31c1a9f0..d3b4fb03b70cc8cf0ba9501217ff63f8a4af3513 100755 GIT binary patch delta 27719 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 literal 77736 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 LUy_-FZH)gfZu4(q literal 0 HcmV?d00001 diff --git a/build/temp.linux-aarch64-cpython-313/app/core/rbac.o b/build/temp.linux-aarch64-cpython-313/app/core/rbac.o index cac6fcd9ef2b513f44b47444a830752006efb695..66cf3ac8f6a51fef172a89b7d9a90536e3e93643 100644 GIT binary patch delta 4626 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 NaLk(QjAKT0{V!sp^SS^4 delta 3864 zcmZ`)dstM}7T@PEFf&Ip9wWm`W&n8zH3BLFRB{Fc#ViFUGPN8Op{#tM1$r&OyoHYp zSPG_O441q*2?A$S9^xJRdhqoUE6Xc>G?*pQt$3)-!HaYEnR8A}bHDZ?b5 zwb$Nrd4fFl8(9%WMxAbneqKsgpj!G6(ZqZyEt(9UD^@^*Vg_U?RxnXh-*cBw*0K5S z$UNVZ`6gfu;g8h_Z)Eb}SIFrA~M$#&4+*Yw)010-=f!?59G+ zPu(h{FLl9kgOL9A3fXaAY5Wx1 zYjsnY*0J^)490O-sXLm}?Qm9@X5(g*y-KsI1>O=4chm{wfUl#HTnZM31e3;4SQn!5 zy26F>F>(8-5Zd&q7aR)7AT3kjT1Z6LRS7by)NYroZb7C2x2YyKgcRz%v<+8pM!2F9 z5u@UeNXH)Z_x3qp zRr%%UCLyy`MYDDNb~AxHklSz9hDgvwe8w!%Z$Bk$vtNsY@?1Kz@1$q9Y>6#u3Pl2qg`-;N^%^Z^8}fZ(@6V%$uzLwd*Y-@JWQ` zfqghff+)@2CFFh-ORn*EH%~gwHS@dQ>@_zrX2%OWGlH15$WS-vkB)%L(eX@tOf^|j zeC3I(M>Z(pJl*B;>6BtusQd2MhjvN=L(*mM8LescyQa)5N`8vD6I3vKWlzD`t1r(u zc{cusiJkjru<|F5UjJw8l=A5@jYVh2eq_6DXd^RadArCB^Pf5@JJOvs{NP#z71o@$ z;qQg+=?BlfdoFR?D-yqHdE*&5er@Ii^{lvt5_j{5(h;w`|Lh91wUx$AEuS}Ky6$A# zVYk)>*`n-82Mv2Omu%mi@$oDFO(t$I!PlgwuT-(Ia|Ua(f{Z`is-3;$i+-;=6UN8h zp0at*>6`Q4*s<`cYrd^WC(ius?Srv>?|H|3dmz8CetpBO zviuhp4s89rWbOLTwyeB)_i>;2NORQ%Gri*Ws^^wwK6c=1eZcj&2pq?cY;^v1&a#WgGC`uEGHr8pZa~FbC zJ1$10P7AxW=gIRVJf2uYXyBv7NTLdUNerO6DaV!BZx{#fq*+8YWF)1L_Ymw!3MLSk zk|O1#j@^3CUQ_1*SCX{uAJA;bXW*Nh=B4(i6d%2{bsm*#EU+$FJ8d`3()bpN440r~ zIbvxQGM|4P&LszeFMoy{VpzCH*c*%}~e9(#+Dt;?94#;IMScRlIYp6#w9L z!UNVXd4YHg`j(_c8V<;+rH9E{f=vJBlJ07sj?+^weUnx#Js{K75{F3zcG(VDS&`5j zDPfAUWD-IKWlvlnah&X&ql6!@IVpsiNqSN#CukHeq&|i?7HUz*wa$+3(^j9#XA~mx%WWI9K&@r>cAZ z0>AthxRuAFk=U9f6xNd);l!{L%cbfmc-frr7UA0=a7o}| z3bvipkg*h)u%Icpg2fUFsAdgmpdcBGjTEfIqLhL|%^C6vVT(jCHY=-IqR2W5qFXY^ zW(o?iuu#y^f)9d%AuMP)1hhWmZxej#9GmmobMvKUDqE!l`K%lcF`D>dp`E=>NpeM% z3%Jb%uam<#qalmsOtd*iLXZZZAci5XGey3viuWIct({sT5n4J^pt(~0;J^)EwTJm}Z9wuKX?~0NS3Pc68V`4!IjCReH7cb_m adm!nYR!$putsJ&u?b%bj)&c(WRsREah7$n* diff --git a/build/temp.linux-aarch64-cpython-313/app/core/tenancy.o b/build/temp.linux-aarch64-cpython-313/app/core/tenancy.o new file mode 100644 index 0000000000000000000000000000000000000000..29281281b0f6eb495589580f10b6c070756308c2 GIT binary patch literal 51496 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 literal 0 HcmV?d00001 diff --git a/build/temp.linux-aarch64-cpython-313/app/services/cache.o b/build/temp.linux-aarch64-cpython-313/app/services/cache.o index 286e5a57ddb52e06854f5c4b23c3c1ced932c105..9db0b94336a206a74dff17d50d00acd3204e05da 100644 GIT binary patch delta 28259 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 diff --git a/setup.py b/setup.py index bb21cb3..4eb5e69 100644 --- a/setup.py +++ b/setup.py @@ -15,6 +15,8 @@ "app/core/rbac.py", "app/core/abac.py", "app/core/rules.py", + "app/core/permissions.py", + "app/core/tenancy.py", "app/services/policy_service.py", "app/services/cache.py", "app/api/routes_policy.py", diff --git a/tests/test_engine_permission_tenancy.py b/tests/test_engine_permission_tenancy.py new file mode 100644 index 0000000..bcb9863 --- /dev/null +++ b/tests/test_engine_permission_tenancy.py @@ -0,0 +1,153 @@ +import json +from unittest.mock import MagicMock, patch + +from app.core.engine import PolicyEngine +from app.models.request import PolicyRequest +from app.services.cache import PolicyCache + + +def make_engine(): + mock_redis = MagicMock() + mock_redis.get.return_value = None + with patch("app.services.cache.redis") as mock_redis_module: + mock_redis_module.from_url.return_value = mock_redis + cache = PolicyCache(redis_url="redis://localhost") + cache.redis = mock_redis + return PolicyEngine(cache=cache), mock_redis + + +def basic_request(**kwargs): + defaults = { + "user_id": "u1", + "email": "u1@test.com", + "roles": [], + "permissions": [], + "org_id": None, + "action": "tes.submit", + "resource": "job_queue", + "context": {}, + } + defaults.update(kwargs) + return PolicyRequest(**defaults) + + +# --------------------------------------------------------------------------- +# PERMISSION gate runs after RBAC, before ABAC/RULES +# --------------------------------------------------------------------------- + +def test_permission_deny_stops_before_abac(): + engine, _ = make_engine() + req = basic_request( + roles=["researcher"], # passes RBAC + permissions=["dataset.read"], # populated, but missing workflow.execute + action="tes.submit", + context={"gpu_required": True}, # would also fail ABAC if reached + ) + + decision = engine._evaluate_core(req) + + assert decision.allowed is False + assert decision.policy_source == "PERMISSION" + assert "workflow.execute" in decision.reason + + +def test_permission_allow_falls_through_to_all_passed(): + engine, _ = make_engine() + req = basic_request( + roles=["researcher"], + permissions=["workflow.execute"], + action="tes.submit", + ) + + decision = engine._evaluate_core(req) + + assert decision.allowed is True + assert decision.policy_source == "ALL_PASSED" + + +def test_permission_check_is_noop_for_legacy_role_only_traffic(): + """No permissions supplied at all (today's real production shape) must + behave exactly as it did before this PR.""" + engine, _ = make_engine() + req = basic_request(roles=["researcher"], permissions=[], action="tes.submit") + + decision = engine._evaluate_core(req) + + assert decision.allowed is True + assert decision.policy_source == "ALL_PASSED" + + +# --------------------------------------------------------------------------- +# TENANCY gate runs after PERMISSION, before ABAC/RULES +# --------------------------------------------------------------------------- + +def test_tenancy_deny_cross_org_access(): + engine, _ = make_engine() + req = basic_request( + roles=["researcher"], + permissions=["workflow.execute"], + org_id="org-1", + action="tes.submit", + context={"resource_org_id": "org-2"}, + ) + + decision = engine._evaluate_core(req) + + assert decision.allowed is False + assert decision.policy_source == "TENANCY" + assert decision.reason == "cross-tenant access denied" + + +def test_tenancy_allow_same_org(): + engine, _ = make_engine() + req = basic_request( + roles=["researcher"], + permissions=["workflow.execute"], + org_id="org-1", + action="tes.submit", + context={"resource_org_id": "org-1"}, + ) + + decision = engine._evaluate_core(req) + + assert decision.allowed is True + assert decision.policy_source == "ALL_PASSED" + + +def test_admin_bypasses_permission_but_not_tenancy(): + """Admin override in rbac/permissions is a role-scope bypass, not a + tenancy bypass -- an admin acting cross-org must still be scoped, + since tenancy is about *which organization's data*, not *how + privileged this user is*.""" + engine, _ = make_engine() + req = basic_request( + roles=["admin"], + permissions=[], + org_id="org-1", + action="tes.submit", + context={"resource_org_id": "org-2"}, + ) + + decision = engine._evaluate_core(req) + + assert decision.allowed is False + assert decision.policy_source == "TENANCY" + + +# --------------------------------------------------------------------------- +# Cache key incorporates org_id/permissions +# --------------------------------------------------------------------------- + +def test_cache_key_differs_by_org_id(): + _, mock_redis = make_engine() + cache = PolicyCache(redis_url="redis://localhost") + key_org1 = cache.build_key("u1", "tes.submit", "job", {}, org_id="org-1", permissions=[]) + key_org2 = cache.build_key("u1", "tes.submit", "job", {}, org_id="org-2", permissions=[]) + assert key_org1 != key_org2 + + +def test_cache_key_differs_by_permissions(): + cache = PolicyCache(redis_url="redis://localhost") + key_a = cache.build_key("u1", "tes.submit", "job", {}, org_id=None, permissions=["workflow.execute"]) + key_b = cache.build_key("u1", "tes.submit", "job", {}, org_id=None, permissions=[]) + assert key_a != key_b diff --git a/tests/test_permissions.py b/tests/test_permissions.py new file mode 100644 index 0000000..870d957 --- /dev/null +++ b/tests/test_permissions.py @@ -0,0 +1,80 @@ +import pytest +from app.core.permissions import evaluate_permission, required_permission + + +# --------------------------------------------------------------------------- +# Backward compatibility: no permissions supplied -> no-op (PR12 requirement +# that existing role-only callers see zero behavior change) +# --------------------------------------------------------------------------- + +def test_no_permissions_supplied_is_noop(): + allowed, reason = evaluate_permission(["researcher"], [], "tes.submit", "job") + assert allowed is True + assert "no permissions supplied" in reason + + +def test_admin_role_always_overrides_even_with_permissions_supplied(): + allowed, reason = evaluate_permission(["admin"], ["something.else"], "tes.submit", "job") + assert allowed is True + assert reason == "admin override" + + +# --------------------------------------------------------------------------- +# required_permission mapping +# --------------------------------------------------------------------------- + +def test_required_permission_for_tes_prefix(): + assert required_permission("tes.submit", "job") == "workflow.execute" + + +def test_required_permission_for_dataset_read(): + assert required_permission("dataset.read", "human_genome") == "dataset.read" + + +def test_required_permission_for_model_registry_delete(): + assert required_permission("delete", "model_registry") == "workflow.manage" + + +def test_required_permission_none_for_unrelated_action(): + assert required_permission("profile.read", "profile") is None + + +# --------------------------------------------------------------------------- +# Allow: permission present +# --------------------------------------------------------------------------- + +def test_scientist_with_workflow_execute_allowed_tes_submit(): + allowed, reason = evaluate_permission( + [], ["workflow.execute", "dataset.read"], "tes.submit", "job" + ) + assert allowed is True + assert reason == "permission granted" + + +def test_viewer_with_dataset_read_allowed_dataset_read(): + allowed, reason = evaluate_permission([], ["dataset.read"], "dataset.read", "human_genome") + assert allowed is True + + +# --------------------------------------------------------------------------- +# Deny: permissions supplied but missing the required one +# --------------------------------------------------------------------------- + +def test_viewer_without_workflow_execute_denied_tes_submit(): + allowed, reason = evaluate_permission([], ["dataset.read"], "tes.submit", "job") + assert allowed is False + assert "workflow.execute" in reason + + +def test_scientist_without_workflow_manage_denied_model_registry_delete(): + allowed, reason = evaluate_permission( + [], ["workflow.execute", "dataset.read"], "delete", "model_registry" + ) + assert allowed is False + assert "workflow.manage" in reason + + +def test_unrelated_action_allowed_even_with_permissions_supplied(): + allowed, reason = evaluate_permission([], ["dataset.read"], "profile.read", "profile") + assert allowed is True + assert reason == "no permission required" diff --git a/tests/test_role_hierarchy_fixtures.py b/tests/test_role_hierarchy_fixtures.py new file mode 100644 index 0000000..4236798 --- /dev/null +++ b/tests/test_role_hierarchy_fixtures.py @@ -0,0 +1,134 @@ +"""PR12 SS2 RBAC Permission Validation. + +The PR12 spec describes a conceptual Platform Owner -> Organization Admin +-> Scientist -> Viewer hierarchy. omnibioai-auth has no roles by those +names (see this PR's architecture report) -- it has global admin/ +platform_admin and org-scoped org_admin/org_member, plus a permission +registry with entries (workflow.execute, dataset.read, workflow.manage, +manage_all_orgs, manage_org, billing.manage, ...) that are reserved but +not yet granted to any role. Per this PR's scope decision, these fixtures +map the spec's conceptual tiers onto that real vocabulary *for testing +this engine* -- no new role or DB change is introduced anywhere. + +Composition note: RBAC (legacy, app/core/rbac.py -- role-name/action- +prefix matching) and PERMISSION (new, app/core/permissions.py -- +registry-permission matching) are both independent, additive gates over +the same actions, not alternatives -- see this PR's report for why (a +permission alone cannot substitute for the legacy role check without +either changing rbac.py's existing behavior, which several of its own +unit tests lock in, or silently loosening enforcement for the ~100% of +today's real traffic that has permissions=[]). So a tier that needs to +pass an action gated by rbac.py (tes.* requires "researcher") must carry +both the legacy role AND the registry permission. The one deliberate +exception is dataset.read, narrowed in rbac.py by this same PR to be +governed by the permission gate alone -- see that change's comment -- +which is what makes a genuine read-only Viewer tier possible at all. +""" + +import pytest + +from app.core.engine import PolicyEngine +from app.models.request import PolicyRequest +from app.services.cache import PolicyCache +from unittest.mock import MagicMock, patch + + +def make_engine(): + mock_redis = MagicMock() + mock_redis.get.return_value = None + with patch("app.services.cache.redis") as mock_redis_module: + mock_redis_module.from_url.return_value = mock_redis + cache = PolicyCache(redis_url="redis://localhost") + cache.redis = mock_redis + return PolicyEngine(cache=cache) + + +# Conceptual tier -> (roles, permissions), mirroring PR12 SS2's fixture list. +PLATFORM_OWNER = (["admin"], ["manage_all_orgs", "manage_roles", "billing.manage", "workflow.execute"]) +ORG_ADMIN = (["researcher"], ["manage_org", "manage_teams", "workflow.execute", "workflow.manage", "dataset.read"]) +SCIENTIST = (["researcher"], ["workflow.execute", "dataset.read"]) +VIEWER = ([], ["dataset.read"]) + + +def request_for(tier, action, resource="job_queue", org_id="org-1", context=None): + roles, perms = tier + return PolicyRequest( + user_id="u1", + email="u1@test.com", + roles=roles, + permissions=perms, + org_id=org_id, + action=action, + resource=resource, + context=context or {}, + ) + + +# --------------------------------------------------------------------------- +# Allowed: user with permission -> success +# --------------------------------------------------------------------------- + +@pytest.mark.parametrize("tier", [PLATFORM_OWNER, ORG_ADMIN, SCIENTIST]) +def test_execute_workflows_allowed_for_tiers_holding_workflow_execute(tier): + engine = make_engine() + decision = engine._evaluate_core(request_for(tier, "tes.submit")) + assert decision.allowed is True + + +@pytest.mark.parametrize("tier", [PLATFORM_OWNER, ORG_ADMIN, SCIENTIST, VIEWER]) +def test_dataset_read_allowed_for_every_tier(tier): + engine = make_engine() + decision = engine._evaluate_core(request_for(tier, "dataset.read")) + assert decision.allowed is True + + +def test_org_admin_workflow_manage_permission_passes_but_immutable_rule_still_blocks(): + """"Manage resources" for Org Admin passes RBAC and the new PERMISSION + gate (workflow.manage present) -- but model_registry deletion is an + absolute RULES-layer restriction that applies to every tier, including + admin (see test_rules_deny_model_registry_delete in test_engine.py). + A registry permission is not a way around that -- defense in depth.""" + engine = make_engine() + decision = engine._evaluate_core( + request_for(ORG_ADMIN, "delete", resource="model_registry") + ) + assert decision.allowed is False + assert decision.policy_source == "RULES" + + +# --------------------------------------------------------------------------- +# Denied: missing permission -> 403-equivalent (allowed=False) +# --------------------------------------------------------------------------- + +def test_viewer_denied_execute_workflows(): + engine = make_engine() + decision = engine._evaluate_core(request_for(VIEWER, "tes.submit")) + assert decision.allowed is False + + +def test_scientist_denied_model_registry_delete(): + engine = make_engine() + decision = engine._evaluate_core( + request_for(SCIENTIST, "delete", resource="model_registry") + ) + assert decision.allowed is False + assert decision.policy_source == "PERMISSION" + assert "workflow.manage" in decision.reason + + +# --------------------------------------------------------------------------- +# Tenancy still applies regardless of tier +# --------------------------------------------------------------------------- + +def test_org_admin_denied_cross_org_even_with_manage_org(): + engine = make_engine() + decision = engine._evaluate_core( + request_for( + ORG_ADMIN, + "tes.submit", + org_id="org-1", + context={"resource_org_id": "org-2"}, + ) + ) + assert decision.allowed is False + assert decision.policy_source == "TENANCY" diff --git a/tests/test_tenancy.py b/tests/test_tenancy.py new file mode 100644 index 0000000..1d56ef7 --- /dev/null +++ b/tests/test_tenancy.py @@ -0,0 +1,32 @@ +from app.core.tenancy import evaluate_tenancy + + +def test_no_resource_org_id_is_noop(): + allowed, reason = evaluate_tenancy("org-1", {}) + assert allowed is True + assert reason == "no tenancy scoping required" + + +def test_matching_org_allowed(): + allowed, reason = evaluate_tenancy("org-1", {"resource_org_id": "org-1"}) + assert allowed is True + assert reason == "tenancy check passed" + + +def test_mismatched_org_denied(): + allowed, reason = evaluate_tenancy("org-1", {"resource_org_id": "org-2"}) + assert allowed is False + assert reason == "cross-tenant access denied" + + +def test_missing_requester_org_denied_when_resource_scoped(): + allowed, reason = evaluate_tenancy(None, {"resource_org_id": "org-2"}) + assert allowed is False + assert reason == "missing organization context" + + +def test_org_id_compared_as_string(): + # A gateway/JWT could hand back an int-typed org_id; a resource_org_id + # supplied as a string (or vice versa) must not spuriously mismatch. + allowed, reason = evaluate_tenancy(1, {"resource_org_id": "1"}) + assert allowed is True