* ssl: Add hex error code to "unknown error" messages
To make it easier to vary the individual parts of the message,
replace the if-ladder with constant format strings by building
the string piece-wise with PyUnicodeWriter.
Use "unknown error (0x%x)" rather than just "unknown error" if we
can't get a better error message. (Hex makes sense as the error
includes two packed parts.)
This change, along with the LOAD_ATTR specializations, makes the
"thread_local_read" micro benchmark in Tools/ftscalingbench/ftscalingbench.py
scale well to multiple threads.
* Makes `_asyncio.Task` and `_asyncio.Future` thread-safe by adding critical sections
* Add assertions to check for thread safety checking locking of object by critical sections in internal functions
* Make `_asyncio.all_tasks` thread safe when eager tasks are used
* Add a thread safety test
Expose error code ``XML_ERROR_NOT_STARTED`` in `xml.parsers.expat.errors` which was
introduced in Expat 2.6.4.
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
* Add ssl.HAS_PHA to detect libssl Post-Handshake-Auth support
Co-authored-by: Tomas R. <tomas.roun8@gmail.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This should be a pure refactoring, without user-visible behaviour changes.
Before this change, ctypes uses traditional native C types, usually identified
by [`struct` format characters][struct-chars] when a short (and
identifier-friendly) name is needed:
- `signed char` (`b`) / `unsigned char` (`B`)
- `short` (`h`) / `unsigned short` (`h`)
- `int` (`i`) / `unsigned int` (`i`)
- `long` (`l`) / `unsigned long` (`l`)
- `long long` (`q`) / `unsigned long long` (`q`)
These map to C99 fixed-width types, which this PR switches to: -
- `int8_t`/`uint8_t`
- `int16_t`/`uint16_t`
- `int32_t`/`uint32_t`
- `int64_t`/`uint64_t`
The C standard doesn't guarantee that the “traditional” types must map to the
fixints. But, [`ctypes` currently requires it][swapdefs], so the assumption won't
break anything.
By “map” I mean that the *size* of the types matches. The *alignment*
requirements might not. This needs to be kept in mind but is not an issue in
`ctypes` accessors, which [explicitly handle unaligned memory][memcpy] for the
integer types.
Note that there are 5 “traditional” C type sizes, but 4 fixed-width ones. Two of
the former are functionally identical to one another; which ones they are is
platform-specific (e.g. `int`==`long`==`int32_t`.) This means that one of the
[current][current-impls-1] [implementations][current-impls-2] is redundant on
any given platform.
The fixint types are parametrized by the number of bytes/bits, and one bit for
signedness. This makes it easier to autogenerate code for them or to write
generic macros (though generic API like
[`PyLong_AsNativeBytes`][PyLong_AsNativeBytes] is problematic for performance
reasons -- especially compared to a `memcpy` with compile-time-constant size).
When one has a *different* integer type, determining the corresponding fixint
means a `sizeof` and signedness check. This is easier and more robust than the
current implementations (see [`wchar_t`][sizeof-wchar_t] or
[`_Bool`][sizeof-bool]).
[swapdefs]: https://github.com/python/cpython/blob/v3.13.0/Modules/_ctypes/cfield.c#L420-L444
[struct-chars]: https://docs.python.org/3/library/struct.html#format-characters
[current-impls-1]: https://github.com/python/cpython/blob/v3.13.0/Modules/_ctypes/cfield.c#L470-L653
[current-impls-2]: https://github.com/python/cpython/blob/v3.13.0/Modules/_ctypes/cfield.c#L703-L944
[memcpy]: https://github.com/python/cpython/blob/v3.13.0/Modules/_ctypes/cfield.c#L613
[PyLong_AsNativeBytes]: https://docs.python.org/3/c-api/long.html#c.PyLong_AsNativeBytes
[sizeof-wchar_t]: https://github.com/python/cpython/blob/v3.13.0/Modules/_ctypes/cfield.c#L1547-L1555
[sizeof-bool]: https://github.com/python/cpython/blob/v3.13.0/Modules/_ctypes/cfield.c#L1562-L1572
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
* Add `_PyDictKeys_StringLookupSplit` which does locking on dict keys and
use in place of `_PyDictKeys_StringLookup`.
* Change `_PyObject_TryGetInstanceAttribute` to use that function
in the case of split keys.
* Add `unicodekeys_lookup_split` helper which allows code sharing
between `_Py_dict_lookup` and `_PyDictKeys_StringLookupSplit`.
* Fix locking for `STORE_ATTR_INSTANCE_VALUE`. Create
`_GUARD_TYPE_VERSION_AND_LOCK` uop so that object stays locked and
`tp_version_tag` cannot change.
* Pass `tp_version_tag` to `specialize_dict_access()`, ensuring
the version we store on the cache is the correct one (in case of
it changing during the specalize analysis).
* Split `analyze_descriptor` into `analyze_descriptor_load` and
`analyze_descriptor_store` since those don't share much logic.
Add `descriptor_is_class` helper function.
* In `specialize_dict_access`, double check `_PyObject_GetManagedDict()`
in case we race and dict was materialized before the lock.
* Avoid borrowed references in `_Py_Specialize_StoreAttr()`.
* Use `specialize()` and `unspecialize()` helpers.
* Add unit tests to ensure specializing happens as expected in FT builds.
* Add unit tests to attempt to trigger data races (useful for running under TSAN).
* Add `has_split_table` function to `_testinternalcapi`.
The `PyWeakref_IsDead()` function tests if a weak reference is dead
without any side effects. Although you can also detect if a weak
reference is dead using `PyWeakref_GetRef()`, that function returns a
strong reference that must be `Py_DECREF()`'d, which can introduce side
effects if the last reference is concurrently dropped (at least in the
free threading build).
gh-127897: Update HACL* module from upstream sources to get:
- Lib_Memzero0.c: don't use memset_s() on macOS <10.9
- Use _mm_malloc() for KRML_ALIGNED_MALLOC on macOS <10.15
- Add LEGACY_MACOS macros, use _mm_free() for KRML_ALIGNED_FREE on macOS <10.15
- Add a helper to set an error from locale-encoded `char*`
- Use the helper for gdbm & dlerror messages
Co-authored-by: Victor Stinner <vstinner@python.org>