wrapt 2.3.0rc1__tar.gz → 2.4.0.dev1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wrapt-2.3.0rc1/src/wrapt.egg-info → wrapt-2.4.0.dev1}/PKG-INFO +1 -1
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/__init__.py +1 -1
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/_wrappers.c +97 -19
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1/src/wrapt.egg-info}/PKG-INFO +1 -1
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_object_proxy.py +49 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/LICENSE +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/MANIFEST.in +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/README.md +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/RELEASE.rst +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/pyproject.toml +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/setup.cfg +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/setup.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/__wrapt__.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/arguments.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/caching.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/decorators.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/importer.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/patches.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/proxies.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/signature.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/synchronization.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/weakrefs.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt/wrappers.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt-stubs/__init__.pyi +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt.egg-info/SOURCES.txt +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt.egg-info/dependency_links.txt +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt.egg-info/not-zip-safe +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt.egg-info/requires.txt +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/src/wrapt.egg-info/top_level.txt +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/conftest.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/compat.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/module1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/module2.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_adapter.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_adapter_annotations.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_adapter_kwonly.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_annotations.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_attribute_wrapper.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_auto_object_proxy.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_callable_binding_no_args.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_callable_object_proxy.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_class.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_class_mro_entries.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_copy.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_decorator_state.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_decorators.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_deferred_patching.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_descriptor_get_class_access.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_descriptors.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_enabled_bool_error.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_entry_points.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_formatargspec.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_function.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_function_wrapper.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_inheritance.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_inner_classmethod.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_inner_staticmethod.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_inplace_operators.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_instancemethod.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_lazy_object_proxy.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_lru_cache.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_memoize.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_monkey_patching.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_nested_function.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_object_proxy_hook.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_object_proxy_self_dict.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_object_proxy_type_checks.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_outer_classmethod.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_outer_staticmethod.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_pickle.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_post_import_hooks.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_pyerr_clear_propagation.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_resolve_path.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_runtime_type_hints.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_synchronized_async.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_synchronized_lock.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_synchronized_markers.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_type_module_attribute.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_update_attributes.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_weak_function_proxy.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/core/test_with_signature.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_auto_object_proxy_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_auto_object_proxy_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_decorator_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_decorator_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t2.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t2.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t3.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t3.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t4.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t4.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t5.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t5.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t6.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t6.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t7.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t7.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t8.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_cls_t8.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t2.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t2.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t3.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t3.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t4.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t4.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t5.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t5.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t6.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t6.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t7.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_function_wrapper_fn_t7.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_object_proxy_arithmetic_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_object_proxy_arithmetic_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_object_proxy_container_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_object_proxy_container_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_object_proxy_context_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_object_proxy_context_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_partial_callable_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_partial_callable_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_patch_function_wrapper_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_patch_function_wrapper_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_patching_primitives_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_patching_primitives_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_post_import_hooks_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_post_import_hooks_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_synchronized_lock_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_synchronized_lock_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_transient_function_wrapper_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_transient_function_wrapper_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_weak_function_proxy_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_weak_function_proxy_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t1.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t1.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t2.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t2.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t3.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t3.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t4.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t4.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t5.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t5.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t6.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t6.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t7.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t7.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t8.out +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tests/mypy/mypy_wrap_function_wrapper_t8.py +0 -0
- {wrapt-2.3.0rc1 → wrapt-2.4.0.dev1}/tox.ini +0 -0
|
@@ -153,6 +153,15 @@ static PyObject *PyType_GetModuleByDef(PyTypeObject *type,
|
|
|
153
153
|
}
|
|
154
154
|
#endif
|
|
155
155
|
|
|
156
|
+
/* Polyfill the critical section API for Python < 3.13. Free-threaded
|
|
157
|
+
* builds only exist on 3.13+, where the real macros are provided (and are
|
|
158
|
+
* no-ops on GIL builds), so expanding to plain blocks here is safe. */
|
|
159
|
+
|
|
160
|
+
#if PY_VERSION_HEX < 0x030D0000
|
|
161
|
+
#define Py_BEGIN_CRITICAL_SECTION(op) {
|
|
162
|
+
#define Py_END_CRITICAL_SECTION() }
|
|
163
|
+
#endif
|
|
164
|
+
|
|
156
165
|
/* Polyfill PyObject_GetOptionalAttrString for Python < 3.13. Matches the
|
|
157
166
|
* 3.13+ semantics: returns 1 if found, 0 if not found (AttributeError
|
|
158
167
|
* only), -1 on other errors with exception set. */
|
|
@@ -446,8 +455,16 @@ static int WraptObjectProxy_raw_init(WraptObjectProxyObject *self,
|
|
|
446
455
|
}
|
|
447
456
|
}
|
|
448
457
|
|
|
458
|
+
/* Serialise the swap for the same reason as in the __wrapped__ setter.
|
|
459
|
+
* Normally __init__ runs before the proxy is shared, but it can be
|
|
460
|
+
* re-invoked on an already published proxy, in which case concurrent
|
|
461
|
+
* callers on a free-threaded build could otherwise decref the same old
|
|
462
|
+
* wrapped object twice. */
|
|
463
|
+
|
|
449
464
|
Py_INCREF(wrapped);
|
|
465
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
450
466
|
Py_XSETREF(self->wrapped, wrapped);
|
|
467
|
+
Py_END_CRITICAL_SECTION();
|
|
451
468
|
|
|
452
469
|
self->init_called = 1;
|
|
453
470
|
|
|
@@ -1061,7 +1078,16 @@ static PyObject *WraptObjectProxy_inplace_add(WraptObjectProxyObject *self,
|
|
|
1061
1078
|
if (!object)
|
|
1062
1079
|
return NULL;
|
|
1063
1080
|
|
|
1081
|
+
/* As in the __wrapped__ setter, serialise the swap so that concurrent
|
|
1082
|
+
* in-place operations on the same proxy cannot decref the same old
|
|
1083
|
+
* wrapped object twice on a free-threaded build. The wrapped object
|
|
1084
|
+
* was read before the operation ran, so a concurrent mutation can
|
|
1085
|
+
* still be lost, matching pure Python semantics. The same applies to
|
|
1086
|
+
* all of the in-place operators which follow. */
|
|
1087
|
+
|
|
1088
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1064
1089
|
Py_SETREF(self->wrapped, object);
|
|
1090
|
+
Py_END_CRITICAL_SECTION();
|
|
1065
1091
|
|
|
1066
1092
|
Py_INCREF(self);
|
|
1067
1093
|
return (PyObject *)self;
|
|
@@ -1143,7 +1169,9 @@ static PyObject *WraptObjectProxy_inplace_subtract(WraptObjectProxyObject *self,
|
|
|
1143
1169
|
if (!object)
|
|
1144
1170
|
return NULL;
|
|
1145
1171
|
|
|
1172
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1146
1173
|
Py_SETREF(self->wrapped, object);
|
|
1174
|
+
Py_END_CRITICAL_SECTION();
|
|
1147
1175
|
|
|
1148
1176
|
Py_INCREF(self);
|
|
1149
1177
|
return (PyObject *)self;
|
|
@@ -1225,7 +1253,9 @@ static PyObject *WraptObjectProxy_inplace_multiply(WraptObjectProxyObject *self,
|
|
|
1225
1253
|
if (!object)
|
|
1226
1254
|
return NULL;
|
|
1227
1255
|
|
|
1256
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1228
1257
|
Py_SETREF(self->wrapped, object);
|
|
1258
|
+
Py_END_CRITICAL_SECTION();
|
|
1229
1259
|
|
|
1230
1260
|
Py_INCREF(self);
|
|
1231
1261
|
return (PyObject *)self;
|
|
@@ -1308,7 +1338,9 @@ WraptObjectProxy_inplace_remainder(WraptObjectProxyObject *self,
|
|
|
1308
1338
|
if (!object)
|
|
1309
1339
|
return NULL;
|
|
1310
1340
|
|
|
1341
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1311
1342
|
Py_SETREF(self->wrapped, object);
|
|
1343
|
+
Py_END_CRITICAL_SECTION();
|
|
1312
1344
|
|
|
1313
1345
|
Py_INCREF(self);
|
|
1314
1346
|
return (PyObject *)self;
|
|
@@ -1391,7 +1423,9 @@ static PyObject *WraptObjectProxy_inplace_power(WraptObjectProxyObject *self,
|
|
|
1391
1423
|
if (!object)
|
|
1392
1424
|
return NULL;
|
|
1393
1425
|
|
|
1426
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1394
1427
|
Py_SETREF(self->wrapped, object);
|
|
1428
|
+
Py_END_CRITICAL_SECTION();
|
|
1395
1429
|
|
|
1396
1430
|
Py_INCREF(self);
|
|
1397
1431
|
return (PyObject *)self;
|
|
@@ -1473,7 +1507,9 @@ static PyObject *WraptObjectProxy_inplace_lshift(WraptObjectProxyObject *self,
|
|
|
1473
1507
|
if (!object)
|
|
1474
1508
|
return NULL;
|
|
1475
1509
|
|
|
1510
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1476
1511
|
Py_SETREF(self->wrapped, object);
|
|
1512
|
+
Py_END_CRITICAL_SECTION();
|
|
1477
1513
|
|
|
1478
1514
|
Py_INCREF(self);
|
|
1479
1515
|
return (PyObject *)self;
|
|
@@ -1555,7 +1591,9 @@ static PyObject *WraptObjectProxy_inplace_rshift(WraptObjectProxyObject *self,
|
|
|
1555
1591
|
if (!object)
|
|
1556
1592
|
return NULL;
|
|
1557
1593
|
|
|
1594
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1558
1595
|
Py_SETREF(self->wrapped, object);
|
|
1596
|
+
Py_END_CRITICAL_SECTION();
|
|
1559
1597
|
|
|
1560
1598
|
Py_INCREF(self);
|
|
1561
1599
|
return (PyObject *)self;
|
|
@@ -1637,7 +1675,9 @@ static PyObject *WraptObjectProxy_inplace_and(WraptObjectProxyObject *self,
|
|
|
1637
1675
|
if (!object)
|
|
1638
1676
|
return NULL;
|
|
1639
1677
|
|
|
1678
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1640
1679
|
Py_SETREF(self->wrapped, object);
|
|
1680
|
+
Py_END_CRITICAL_SECTION();
|
|
1641
1681
|
|
|
1642
1682
|
Py_INCREF(self);
|
|
1643
1683
|
return (PyObject *)self;
|
|
@@ -1719,7 +1759,9 @@ static PyObject *WraptObjectProxy_inplace_xor(WraptObjectProxyObject *self,
|
|
|
1719
1759
|
if (!object)
|
|
1720
1760
|
return NULL;
|
|
1721
1761
|
|
|
1762
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1722
1763
|
Py_SETREF(self->wrapped, object);
|
|
1764
|
+
Py_END_CRITICAL_SECTION();
|
|
1723
1765
|
|
|
1724
1766
|
Py_INCREF(self);
|
|
1725
1767
|
return (PyObject *)self;
|
|
@@ -1801,7 +1843,9 @@ static PyObject *WraptObjectProxy_inplace_or(WraptObjectProxyObject *self,
|
|
|
1801
1843
|
if (!object)
|
|
1802
1844
|
return NULL;
|
|
1803
1845
|
|
|
1846
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1804
1847
|
Py_SETREF(self->wrapped, object);
|
|
1848
|
+
Py_END_CRITICAL_SECTION();
|
|
1805
1849
|
|
|
1806
1850
|
Py_INCREF(self);
|
|
1807
1851
|
return (PyObject *)self;
|
|
@@ -1942,7 +1986,9 @@ WraptObjectProxy_inplace_floor_divide(WraptObjectProxyObject *self,
|
|
|
1942
1986
|
if (!object)
|
|
1943
1987
|
return NULL;
|
|
1944
1988
|
|
|
1989
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
1945
1990
|
Py_SETREF(self->wrapped, object);
|
|
1991
|
+
Py_END_CRITICAL_SECTION();
|
|
1946
1992
|
|
|
1947
1993
|
Py_INCREF(self);
|
|
1948
1994
|
return (PyObject *)self;
|
|
@@ -2025,7 +2071,9 @@ WraptObjectProxy_inplace_true_divide(WraptObjectProxyObject *self,
|
|
|
2025
2071
|
if (!object)
|
|
2026
2072
|
return NULL;
|
|
2027
2073
|
|
|
2074
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
2028
2075
|
Py_SETREF(self->wrapped, object);
|
|
2076
|
+
Py_END_CRITICAL_SECTION();
|
|
2029
2077
|
|
|
2030
2078
|
Py_INCREF(self);
|
|
2031
2079
|
return (PyObject *)self;
|
|
@@ -2149,7 +2197,9 @@ static PyObject *WraptObjectProxy_inplace_matrix_multiply(
|
|
|
2149
2197
|
if (!object)
|
|
2150
2198
|
return NULL;
|
|
2151
2199
|
|
|
2200
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
2152
2201
|
Py_SETREF(self->wrapped, object);
|
|
2202
|
+
Py_END_CRITICAL_SECTION();
|
|
2153
2203
|
|
|
2154
2204
|
Py_INCREF(self);
|
|
2155
2205
|
return (PyObject *)self;
|
|
@@ -2450,7 +2500,8 @@ static PyObject *WraptObjectProxy_bytes(WraptObjectProxyObject *self,
|
|
|
2450
2500
|
return NULL;
|
|
2451
2501
|
}
|
|
2452
2502
|
|
|
2453
|
-
return
|
|
2503
|
+
return PyObject_CallFunctionObjArgs((PyObject *)&PyBytes_Type,
|
|
2504
|
+
self->wrapped, NULL);
|
|
2454
2505
|
}
|
|
2455
2506
|
|
|
2456
2507
|
/* ------------------------------------------------------------------------- */
|
|
@@ -2919,15 +2970,22 @@ static int WraptObjectProxy_set_dict(WraptObjectProxyObject *self,
|
|
|
2919
2970
|
|
|
2920
2971
|
static PyObject *WraptObjectProxy_get_self_dict(WraptObjectProxyObject *self)
|
|
2921
2972
|
{
|
|
2973
|
+
PyObject *result = NULL;
|
|
2974
|
+
|
|
2975
|
+
/* self->dict is only NULL after tp_clear has run. Perform the lazy
|
|
2976
|
+
* recreation and the reference acquisition inside a critical section
|
|
2977
|
+
* so that two threads racing here on a free-threaded build cannot both
|
|
2978
|
+
* create a dict, leaking one of them, or return a dict which the other
|
|
2979
|
+
* thread has already replaced. */
|
|
2980
|
+
|
|
2981
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
2922
2982
|
if (!self->dict)
|
|
2923
|
-
{
|
|
2924
2983
|
self->dict = PyDict_New();
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2984
|
+
result = self->dict;
|
|
2985
|
+
Py_XINCREF(result);
|
|
2986
|
+
Py_END_CRITICAL_SECTION();
|
|
2928
2987
|
|
|
2929
|
-
|
|
2930
|
-
return self->dict;
|
|
2988
|
+
return result;
|
|
2931
2989
|
}
|
|
2932
2990
|
|
|
2933
2991
|
/* ------------------------------------------------------------------------- */
|
|
@@ -2972,8 +3030,16 @@ static int WraptObjectProxy_set_wrapped(WraptObjectProxyObject *self,
|
|
|
2972
3030
|
return -1;
|
|
2973
3031
|
}
|
|
2974
3032
|
|
|
3033
|
+
/* On free-threaded builds the swap must be serialised, otherwise two
|
|
3034
|
+
* threads assigning __wrapped__ on the same proxy can both read the same
|
|
3035
|
+
* old value and both decref it, releasing it twice. The critical section
|
|
3036
|
+
* covers only the swap; __wrapped_setattr_fixups__ below runs arbitrary
|
|
3037
|
+
* Python code and must stay outside it. */
|
|
3038
|
+
|
|
2975
3039
|
Py_INCREF(value);
|
|
3040
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
2976
3041
|
Py_XSETREF(self->wrapped, value);
|
|
3042
|
+
Py_END_CRITICAL_SECTION();
|
|
2977
3043
|
|
|
2978
3044
|
fixups = PyObject_GetAttr((PyObject *)self, state->str_setattr_fixups);
|
|
2979
3045
|
|
|
@@ -3385,11 +3451,19 @@ static int WraptPartialCallableObjectProxy_raw_init(
|
|
|
3385
3451
|
|
|
3386
3452
|
if (result == 0)
|
|
3387
3453
|
{
|
|
3388
|
-
|
|
3389
|
-
|
|
3454
|
+
/* Serialise the swaps for the same reason as in the __wrapped__
|
|
3455
|
+
* setter. Initialisation normally happens before the proxy is shared,
|
|
3456
|
+
* but __init__ can be re-invoked on an already published proxy, in
|
|
3457
|
+
* which case concurrent callers on a free-threaded build could
|
|
3458
|
+
* otherwise decref the same old args or kwargs twice. */
|
|
3390
3459
|
|
|
3460
|
+
Py_INCREF(args);
|
|
3391
3461
|
Py_XINCREF(kwargs);
|
|
3462
|
+
|
|
3463
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
3464
|
+
Py_XSETREF(self->args, args);
|
|
3392
3465
|
Py_XSETREF(self->kwargs, kwargs);
|
|
3466
|
+
Py_END_CRITICAL_SECTION();
|
|
3393
3467
|
}
|
|
3394
3468
|
|
|
3395
3469
|
return result;
|
|
@@ -3617,23 +3691,27 @@ static int WraptFunctionWrapperBase_raw_init(
|
|
|
3617
3691
|
|
|
3618
3692
|
if (result == 0)
|
|
3619
3693
|
{
|
|
3620
|
-
|
|
3621
|
-
|
|
3694
|
+
/* Serialise the swaps for the same reason as in the __wrapped__
|
|
3695
|
+
* setter. These fields have no setters, so re-invocation of __init__
|
|
3696
|
+
* on an already published wrapper is the only path by which
|
|
3697
|
+
* concurrent callers on a free-threaded build could otherwise decref
|
|
3698
|
+
* the same old field values twice. */
|
|
3622
3699
|
|
|
3700
|
+
Py_INCREF(instance);
|
|
3623
3701
|
Py_INCREF(wrapper);
|
|
3624
|
-
Py_XSETREF(self->wrapper, wrapper);
|
|
3625
|
-
|
|
3626
3702
|
Py_INCREF(enabled);
|
|
3627
|
-
Py_XSETREF(self->enabled, enabled);
|
|
3628
|
-
|
|
3629
3703
|
Py_INCREF(binding);
|
|
3630
|
-
Py_XSETREF(self->binding, binding);
|
|
3631
|
-
|
|
3632
3704
|
Py_INCREF(parent);
|
|
3633
|
-
Py_XSETREF(self->parent, parent);
|
|
3634
|
-
|
|
3635
3705
|
Py_INCREF(owner);
|
|
3706
|
+
|
|
3707
|
+
Py_BEGIN_CRITICAL_SECTION(self);
|
|
3708
|
+
Py_XSETREF(self->instance, instance);
|
|
3709
|
+
Py_XSETREF(self->wrapper, wrapper);
|
|
3710
|
+
Py_XSETREF(self->enabled, enabled);
|
|
3711
|
+
Py_XSETREF(self->binding, binding);
|
|
3712
|
+
Py_XSETREF(self->parent, parent);
|
|
3636
3713
|
Py_XSETREF(self->owner, owner);
|
|
3714
|
+
Py_END_CRITICAL_SECTION();
|
|
3637
3715
|
}
|
|
3638
3716
|
|
|
3639
3717
|
return result;
|
|
@@ -1932,6 +1932,55 @@ class SpecialMethods(unittest.TestCase):
|
|
|
1932
1932
|
|
|
1933
1933
|
self.assertEqual(bytes(instance), bytes(proxy))
|
|
1934
1934
|
|
|
1935
|
+
def test_int_bytes(self):
|
|
1936
|
+
# bytes(proxy) should behave like bytes() on the wrapped object even
|
|
1937
|
+
# when it has no __bytes__ (e.g. an int, where bytes(n) yields a
|
|
1938
|
+
# zero-filled buffer of length n).
|
|
1939
|
+
instance = 3
|
|
1940
|
+
|
|
1941
|
+
proxy = wrapt.ObjectProxy(instance)
|
|
1942
|
+
|
|
1943
|
+
self.assertEqual(bytes(instance), bytes(proxy))
|
|
1944
|
+
|
|
1945
|
+
def test_index_bytes(self):
|
|
1946
|
+
# An object with __index__() but no __bytes__ converts like an int,
|
|
1947
|
+
# yielding a zero-filled buffer.
|
|
1948
|
+
class Class:
|
|
1949
|
+
def __index__(self):
|
|
1950
|
+
return 2
|
|
1951
|
+
|
|
1952
|
+
instance = Class()
|
|
1953
|
+
|
|
1954
|
+
proxy = wrapt.ObjectProxy(instance)
|
|
1955
|
+
|
|
1956
|
+
self.assertEqual(bytes(instance), bytes(proxy))
|
|
1957
|
+
|
|
1958
|
+
def test_buffer_bytes(self):
|
|
1959
|
+
# An object supporting the buffer protocol but no __bytes__.
|
|
1960
|
+
instance = bytearray(b"abcd")
|
|
1961
|
+
|
|
1962
|
+
proxy = wrapt.ObjectProxy(instance)
|
|
1963
|
+
|
|
1964
|
+
self.assertEqual(bytes(instance), bytes(proxy))
|
|
1965
|
+
|
|
1966
|
+
def test_iterable_bytes(self):
|
|
1967
|
+
# An iterable of ints, converted element by element.
|
|
1968
|
+
instance = [1, 2, 3]
|
|
1969
|
+
|
|
1970
|
+
proxy = wrapt.ObjectProxy(instance)
|
|
1971
|
+
|
|
1972
|
+
self.assertEqual(bytes(instance), bytes(proxy))
|
|
1973
|
+
|
|
1974
|
+
def test_str_bytes(self):
|
|
1975
|
+
# bytes() on a str without an encoding raises TypeError, and the
|
|
1976
|
+
# proxy should match rather than fall back to some other conversion.
|
|
1977
|
+
instance = "abcd"
|
|
1978
|
+
|
|
1979
|
+
proxy = wrapt.ObjectProxy(instance)
|
|
1980
|
+
|
|
1981
|
+
with self.assertRaises(TypeError):
|
|
1982
|
+
bytes(proxy)
|
|
1983
|
+
|
|
1935
1984
|
def test_str_format(self):
|
|
1936
1985
|
instance = "abcd"
|
|
1937
1986
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|