Optimize memoryview comparison: a memoryview is equal to itself, there is no
need to compare values, except if it uses float format.
Benchmark comparing 1 MiB:
from timeit import timeit
with open("/dev/random", 'br') as fp:
data = fp.read(2**20)
view = memoryview(data)
LOOPS = 1_000
b = timeit('x == x', number=LOOPS, globals={'x': data})
m = timeit('x == x', number=LOOPS, globals={'x': view})
print("bytes %f seconds" % b)
print("mview %f seconds" % m)
print("=> %f time slower" % (m / b))
Result before the change:
bytes 0.000026 seconds
mview 1.445791 seconds
=> 55660.873940 time slower
Result after the change:
bytes 0.000026 seconds
mview 0.000028 seconds
=> 1.104382 time slower
This missed optimization was discovered by Pierre-Yves David
while working on Mercurial.
Co-authored-by: Pieter Eendebak <pieter.eendebak@gmail.com>
PyDict_Contains() and PyDict_ContainsString() now fail with
SystemError if the first argument is not a dict, frozendict, dict
subclass or frozendict subclass.
PyDict_MergeFromSeq2() now fails with SystemError if the first
argument is not a dict or a dict subclass.
PyDict_Update(), PyDict_Merge() and _PyDict_MergeEx() no longer
accept frozendict.
can_modify_dict() is stricter than ASSERT_DICT_LOCKED() for
frozendict. It uses PyUnstable_Object_IsUniquelyReferenced() which
matters for free-threaded builds.
Replace anydict_setitem_take2() with setitem_take2_lock_held(). It's
no longer useful to have two functions.
Add TYPE_FROZENDICT to the marshal module.
Add C API functions:
* PyAnyDict_Check()
* PyAnyDict_CheckExact()
* PyFrozenDict_Check()
* PyFrozenDict_CheckExact()
* PyFrozenDict_New()
Add PyFrozenDict_Type C type.
Co-authored-by: Hugo van Kemenade <1324225+hugovk@users.noreply.github.com>
Co-authored-by: Adam Johnson <me@adamj.eu>
Co-authored-by: Benedikt Johannes <benedikt.johannes.hofer@gmail.com>
When integrating slots-based module creation is with the inittab,
which currently requires PyModuleDef, it would be convenient to
reuse the the same slots array for the MethodDef.
Allow slots that match what's already present in the PyModuleDef.
Fix thread-safety issues when accessing frame attributes while another
thread is executing the frame:
- Add critical section to frame_repr() to prevent races when accessing
the frame's code object and line number
- Add _Py_NO_SANITIZE_THREAD to PyUnstable_InterpreterFrame_GetLasti()
to allow intentional racy reads of instr_ptr.
- Fix take_ownership() to not write to the original frame's f_executable
Add `_Py_type_getattro_stackref`, a variant of type attribute lookup
that returns `_PyStackRef` instead of `PyObject*`. This allows returning
deferred references in the free-threaded build, reducing reference count
contention when accessing type attributes.
This significantly improves scaling of namedtuple instantiation across
multiple threads.
* Add blurb
* Rename PyObject_GetAttrStackRef to _PyObject_GetAttrStackRef
* Apply suggestion from @vstinner
Co-authored-by: Victor Stinner <vstinner@python.org>
* Apply suggestion from @vstinner
Co-authored-by: Victor Stinner <vstinner@python.org>
* format
* Update Include/internal/pycore_function.h
Co-authored-by: Victor Stinner <vstinner@python.org>
---------
Co-authored-by: Victor Stinner <vstinner@python.org>
Move classmethod and staticmethod initialization from __init__() to
__new__().
PyClassMethod_New() and PyStaticMethod_New() now copy attributes of
the wrapped functions: __module__, __name__, __qualname__ and
__doc__.
Change static type initialization: initialize PyStaticMethod_Type and
PyCFunction_Type earlier.
Remove test_refleaks_in_classmethod___init__() and
test_refleaks_in_staticmethod___init__() tests from test_descr since
classmethod and staticmethod have no __init__() method anymore.
Add `gi_state`, `cr_state`, and `ag_state` attributes to generators,
coroutines, and async generators respectively. These attributes return the
current state as a string (e.g., `GEN_RUNNING`, `CORO_SUSPENDED`).
The `inspect.getgeneratorstate()`, `inspect.getcoroutinestate()`, and
`inspect.getasyncgenstate()` functions now return these attributes directly.
This is in preparation for making `gi_frame` thread-safe, which may involve
stop-the-world synchronization. The new state attributes avoid potential
performance cliffs in `inspect.getgeneratorstate()` and similar functions by
not requiring frame access.
Also removes unused `FRAME_COMPLETED` state and renumbers the frame state enum
to start at 0 instead of -1.
The positional arguments passed to _PyStack_UnpackDict are already
kept alive by the caller, so we can avoid the extra reference count
operations by using borrowed references instead of creating new ones.
This reduces reference count contention in the free-threaded build
when calling functions with keyword arguments. In particular, this
avoids contention on the type argument to `__new__` when instantiating
namedtuples with keyword arguments.