diff --git a/Lib/ctypes/_endian.py b/Lib/ctypes/_endian.py index 6382dd22b8acc8..0b71caef421482 100644 --- a/Lib/ctypes/_endian.py +++ b/Lib/ctypes/_endian.py @@ -3,34 +3,41 @@ _array_type = type(Array) +def _get_other_endian_attr(): + """Return the appropriate other endian attribute based on system byte order.""" + return "__ctype_be__" if sys.byteorder == "little" else "__ctype_le__" + def _other_endian(typ): - """Return the type with the 'other' byte order. Simple types like + """Return the type with the 'other' byte order. Simple types like c_int and so on already have __ctype_be__ and __ctype_le__ - attributes which contain the types, for more complicated types + attributes which contain the types; for more complicated types, arrays and structures are supported. """ - # check _OTHER_ENDIAN attribute (present if typ is primitive type) - if hasattr(typ, _OTHER_ENDIAN): - return getattr(typ, _OTHER_ENDIAN) + other_endian_attr = _get_other_endian_attr() + # if typ is array if isinstance(typ, _array_type): return _other_endian(typ._type_) * typ._length_ # if typ is structure or union if issubclass(typ, (Structure, Union)): return typ + # check other endian attribute (present if typ is primitive type) + if hasattr(typ, other_endian_attr): + return getattr(typ, other_endian_attr) + raise TypeError("This type does not support other endian: %s" % typ) class _swapped_meta: def __setattr__(self, attrname, value): if attrname == "_fields_": - fields = [] - for desc in value: - name = desc[0] - typ = desc[1] - rest = desc[2:] - fields.append((name, _other_endian(typ)) + rest) + # Use a generator expression to avoid creating a new list + fields = [ + (desc[0], _other_endian(desc[1])) + desc[2:] + for desc in value + ] value = fields super().__setattr__(attrname, value) + class _swapped_struct_meta(_swapped_meta, type(Structure)): pass class _swapped_union_meta(_swapped_meta, type(Union)): pass @@ -40,9 +47,8 @@ class _swapped_union_meta(_swapped_meta, type(Union)): pass # value!) of a _swappedbytes_ attribute to determine the bit order in # structures containing bit fields. +# Determine the byte order and define types accordingly if sys.byteorder == "little": - _OTHER_ENDIAN = "__ctype_be__" - LittleEndianStructure = Structure class BigEndianStructure(Structure, metaclass=_swapped_struct_meta): @@ -58,8 +64,6 @@ class BigEndianUnion(Union, metaclass=_swapped_union_meta): _swappedbytes_ = None elif sys.byteorder == "big": - _OTHER_ENDIAN = "__ctype_le__" - BigEndianStructure = Structure class LittleEndianStructure(Structure, metaclass=_swapped_struct_meta): diff --git a/Misc/NEWS.d/next/C_API/2024-09-23-17-05-34.gh-issue-124351.ba9txm.rst b/Misc/NEWS.d/next/C_API/2024-09-23-17-05-34.gh-issue-124351.ba9txm.rst new file mode 100644 index 00000000000000..b5c0e02b911af8 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-09-23-17-05-34.gh-issue-124351.ba9txm.rst @@ -0,0 +1,3 @@ +```rst +Optimized endianness handling in the ctypes module. The `_other_endian` function has been refactored to reduce redundant type checks, improving performance during frequent calls. Additionally, the `_swapped_meta` class now efficiently handles attribute assignments without unnecessary list creation, enhancing overall efficiency. This update provides better handling of data serialization across different byte orders, ensuring compatibility and performance improvements in cross-platform applications. +``` diff --git a/Misc/NEWS.d/next/C_API/2024-09-23-17-25-37.gh-issue-124351.YJ6wdd.rst b/Misc/NEWS.d/next/C_API/2024-09-23-17-25-37.gh-issue-124351.YJ6wdd.rst new file mode 100644 index 00000000000000..002e7093591829 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-09-23-17-25-37.gh-issue-124351.YJ6wdd.rst @@ -0,0 +1,2 @@ +.. default-role:: code +Optimized endianness handling in the ctypes module. The `_other_endian` function has been refactored to reduce redundant type checks, improving performance during frequent calls. Additionally, the `_swapped_meta` class now efficiently handles attribute assignments without unnecessary list creation, enhancing overall efficiency. This update provides better handling of data serialization across different byte orders, ensuring compatibility and performance improvements in cross-platform applications. diff --git a/Misc/NEWS.d/next/C_API/2024-09-23-17-28-37.gh-issue-124351.hszcK-.rst b/Misc/NEWS.d/next/C_API/2024-09-23-17-28-37.gh-issue-124351.hszcK-.rst new file mode 100644 index 00000000000000..3673cc2a7019f0 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-09-23-17-28-37.gh-issue-124351.hszcK-.rst @@ -0,0 +1,3 @@ +.. default-role:: code + +Optimized endianness handling in the ctypes module. The `_other_endian` function has been refactored to reduce redundant type checks, improving performance during frequent calls. Additionally, the `_swapped_meta` class now efficiently handles attribute assignments without unnecessary list creation, enhancing overall efficiency. This update provides better handling of data serialization across different byte orders, ensuring compatibility and performance improvements in cross-platform applications. diff --git a/Misc/NEWS.d/next/C_API/2024-09-24-02-50-54.gh-issue-124351.BuQG-z.rst b/Misc/NEWS.d/next/C_API/2024-09-24-02-50-54.gh-issue-124351.BuQG-z.rst new file mode 100644 index 00000000000000..a39cc0e8be499d --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-09-24-02-50-54.gh-issue-124351.BuQG-z.rst @@ -0,0 +1,3 @@ +- Fixed a potential side effect from the global variable `_OTHER_ENDIAN` in the `_other_endian` function by ensuring it’s not declared at the module level. +- Reduced redundant type checks within the `_other_endian` recursion to enhance performance during frequent calls. +- Optimized the `setattr` method in `_swapped_meta` to prevent unnecessary list creation, reducing overhead when no modifications are required. diff --git a/Misc/NEWS.d/next/C_API/2024-09-24-02-54-51.gh-issue-124351.XtNTlp.rst b/Misc/NEWS.d/next/C_API/2024-09-24-02-54-51.gh-issue-124351.XtNTlp.rst new file mode 100644 index 00000000000000..ff93cf9eff6f57 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-09-24-02-54-51.gh-issue-124351.XtNTlp.rst @@ -0,0 +1,6 @@ +Fix potential side effect from the global variable `_OTHER_ENDIAN` in the +`_other_endian` function by ensuring it is not declared at the module level. +Reduce redundant type checks within the `_other_endian` recursion to enhance +performance during frequent calls. Optimize the `setattr` method in +`_swapped_meta` to prevent unnecessary list creation, reducing overhead when +no modifications are required. diff --git a/Misc/NEWS.d/next/C_API/2024-09-24-02-54-59.gh-issue-124351.XtNTlp.rst b/Misc/NEWS.d/next/C_API/2024-09-24-02-54-59.gh-issue-124351.XtNTlp.rst new file mode 100644 index 00000000000000..ff93cf9eff6f57 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-09-24-02-54-59.gh-issue-124351.XtNTlp.rst @@ -0,0 +1,6 @@ +Fix potential side effect from the global variable `_OTHER_ENDIAN` in the +`_other_endian` function by ensuring it is not declared at the module level. +Reduce redundant type checks within the `_other_endian` recursion to enhance +performance during frequent calls. Optimize the `setattr` method in +`_swapped_meta` to prevent unnecessary list creation, reducing overhead when +no modifications are required. diff --git a/Misc/NEWS.d/next/C_API/2024-09-24-02-59-23.gh-issue-124351.XtNTlp.rst b/Misc/NEWS.d/next/C_API/2024-09-24-02-59-23.gh-issue-124351.XtNTlp.rst new file mode 100644 index 00000000000000..ff93cf9eff6f57 --- /dev/null +++ b/Misc/NEWS.d/next/C_API/2024-09-24-02-59-23.gh-issue-124351.XtNTlp.rst @@ -0,0 +1,6 @@ +Fix potential side effect from the global variable `_OTHER_ENDIAN` in the +`_other_endian` function by ensuring it is not declared at the module level. +Reduce redundant type checks within the `_other_endian` recursion to enhance +performance during frequent calls. Optimize the `setattr` method in +`_swapped_meta` to prevent unnecessary list creation, reducing overhead when +no modifications are required.