Python-checkins
Threads by month
- ----- 2025 -----
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
January 2025
- 1 participants
- 705 discussions
gh-128889: Zero out memory ctypes for generated struct layout tests (GH-128944)
by encukou Jan. 21, 2025
by encukou Jan. 21, 2025
Jan. 21, 2025
https://github.com/python/cpython/commit/13475e0a5a317fa61f302f030b0effcb02…
commit: 13475e0a5a317fa61f302f030b0effcb021873d6
branch: main
author: Petr Viktorin <encukou(a)gmail.com>
committer: encukou <encukou(a)gmail.com>
date: 2025-01-21T16:29:02+01:00
summary:
gh-128889: Zero out memory ctypes for generated struct layout tests (GH-128944)
files:
M Lib/test/test_ctypes/test_generated_structs.py
M Modules/_ctypes/_ctypes_test_generated.c.h
diff --git a/Lib/test/test_ctypes/test_generated_structs.py b/Lib/test/test_ctypes/test_generated_structs.py
index d61754d6d49e70..1df9f0dc16368f 100644
--- a/Lib/test/test_ctypes/test_generated_structs.py
+++ b/Lib/test/test_ctypes/test_generated_structs.py
@@ -443,7 +443,7 @@ def test_generated_data(self):
- None
- reason to skip the test (str)
- This does depend on the C compiler keeping padding bits zero.
+ This does depend on the C compiler keeping padding bits unchanged.
Common compilers seem to do so.
"""
for name, cls in TESTCASES.items():
@@ -696,7 +696,8 @@ def output(string):
output(' ' + line)
typename = f'{struct_or_union(cls)} {name}'
output(f"""
- {typename} value = {{0}};
+ {typename} value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString({c_str_repr(name)}));
APPEND(PyLong_FromLong(sizeof({typename})));
APPEND(PyLong_FromLong(_Alignof({typename})));
diff --git a/Modules/_ctypes/_ctypes_test_generated.c.h b/Modules/_ctypes/_ctypes_test_generated.c.h
index 46a3e4b01e2259..d70b33eaa8b515 100644
--- a/Modules/_ctypes/_ctypes_test_generated.c.h
+++ b/Modules/_ctypes/_ctypes_test_generated.c.h
@@ -56,7 +56,8 @@
struct SingleInt {
int a;
};
- struct SingleInt value = {0};
+ struct SingleInt value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("SingleInt"));
APPEND(PyLong_FromLong(sizeof(struct SingleInt)));
APPEND(PyLong_FromLong(_Alignof(struct SingleInt)));
@@ -69,7 +70,8 @@
union SingleInt_Union {
int a;
};
- union SingleInt_Union value = {0};
+ union SingleInt_Union value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("SingleInt_Union"));
APPEND(PyLong_FromLong(sizeof(union SingleInt_Union)));
APPEND(PyLong_FromLong(_Alignof(union SingleInt_Union)));
@@ -82,7 +84,8 @@
struct SingleU32 {
uint32_t a;
};
- struct SingleU32 value = {0};
+ struct SingleU32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("SingleU32"));
APPEND(PyLong_FromLong(sizeof(struct SingleU32)));
APPEND(PyLong_FromLong(_Alignof(struct SingleU32)));
@@ -97,7 +100,8 @@
int8_t y;
uint16_t z;
};
- struct SimpleStruct value = {0};
+ struct SimpleStruct value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("SimpleStruct"));
APPEND(PyLong_FromLong(sizeof(struct SimpleStruct)));
APPEND(PyLong_FromLong(_Alignof(struct SimpleStruct)));
@@ -114,7 +118,8 @@
int8_t y;
uint16_t z;
};
- union SimpleUnion value = {0};
+ union SimpleUnion value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("SimpleUnion"));
APPEND(PyLong_FromLong(sizeof(union SimpleUnion)));
APPEND(PyLong_FromLong(_Alignof(union SimpleUnion)));
@@ -136,7 +141,8 @@
int64_t i64;
uint64_t u64;
};
- struct ManyTypes value = {0};
+ struct ManyTypes value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("ManyTypes"));
APPEND(PyLong_FromLong(sizeof(struct ManyTypes)));
APPEND(PyLong_FromLong(_Alignof(struct ManyTypes)));
@@ -163,7 +169,8 @@
int64_t i64;
uint64_t u64;
};
- union ManyTypesU value = {0};
+ union ManyTypesU value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("ManyTypesU"));
APPEND(PyLong_FromLong(sizeof(union ManyTypesU)));
APPEND(PyLong_FromLong(_Alignof(union ManyTypesU)));
@@ -197,7 +204,8 @@
uint16_t z;
};
};
- struct Nested value = {0};
+ struct Nested value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Nested"));
APPEND(PyLong_FromLong(sizeof(struct Nested)));
APPEND(PyLong_FromLong(_Alignof(struct Nested)));
@@ -223,7 +231,8 @@
int64_t b;
};
#pragma pack(pop)
- struct Packed1 value = {0};
+ struct Packed1 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Packed1"));
APPEND(PyLong_FromLong(sizeof(struct Packed1)));
APPEND(PyLong_FromLong(_Alignof(struct Packed1)));
@@ -247,7 +256,8 @@
int64_t b;
};
#pragma pack(pop)
- struct Packed2 value = {0};
+ struct Packed2 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Packed2"));
APPEND(PyLong_FromLong(sizeof(struct Packed2)));
APPEND(PyLong_FromLong(_Alignof(struct Packed2)));
@@ -271,7 +281,8 @@
int64_t b;
};
#pragma pack(pop)
- struct Packed3 value = {0};
+ struct Packed3 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Packed3"));
APPEND(PyLong_FromLong(sizeof(struct Packed3)));
APPEND(PyLong_FromLong(_Alignof(struct Packed3)));
@@ -295,7 +306,8 @@
int64_t b;
};
#pragma pack(pop)
- struct Packed4 value = {0};
+ struct Packed4 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Packed4"));
APPEND(PyLong_FromLong(sizeof(struct Packed4)));
APPEND(PyLong_FromLong(_Alignof(struct Packed4)));
@@ -316,7 +328,8 @@
int64_t b;
int32_t c;
};
- struct X86_32EdgeCase value = {0};
+ struct X86_32EdgeCase value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("X86_32EdgeCase"));
APPEND(PyLong_FromLong(sizeof(struct X86_32EdgeCase)));
APPEND(PyLong_FromLong(_Alignof(struct X86_32EdgeCase)));
@@ -333,7 +346,8 @@
unsigned int b :5;
unsigned int c :7;
};
- struct MSBitFieldExample value = {0};
+ struct MSBitFieldExample value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("MSBitFieldExample"));
APPEND(PyLong_FromLong(sizeof(struct MSBitFieldExample)));
APPEND(PyLong_FromLong(_Alignof(struct MSBitFieldExample)));
@@ -351,7 +365,8 @@
unsigned int may_straddle :30;
unsigned int last :18;
};
- struct MSStraddlingExample value = {0};
+ struct MSStraddlingExample value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("MSStraddlingExample"));
APPEND(PyLong_FromLong(sizeof(struct MSStraddlingExample)));
APPEND(PyLong_FromLong(_Alignof(struct MSStraddlingExample)));
@@ -375,7 +390,8 @@
int H :8;
int I :9;
};
- struct IntBits value = {0};
+ struct IntBits value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("IntBits"));
APPEND(PyLong_FromLong(sizeof(struct IntBits)));
APPEND(PyLong_FromLong(_Alignof(struct IntBits)));
@@ -413,7 +429,8 @@
short R :6;
short S :7;
};
- struct Bits value = {0};
+ struct Bits value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Bits"));
APPEND(PyLong_FromLong(sizeof(struct Bits)));
APPEND(PyLong_FromLong(_Alignof(struct Bits)));
@@ -456,7 +473,8 @@
int H :8;
int I :9;
};
- struct IntBits_MSVC value = {0};
+ struct IntBits_MSVC value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("IntBits_MSVC"));
APPEND(PyLong_FromLong(sizeof(struct IntBits_MSVC)));
APPEND(PyLong_FromLong(_Alignof(struct IntBits_MSVC)));
@@ -499,7 +517,8 @@
short R :6;
short S :7;
};
- struct Bits_MSVC value = {0};
+ struct Bits_MSVC value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Bits_MSVC"));
APPEND(PyLong_FromLong(sizeof(struct Bits_MSVC)));
APPEND(PyLong_FromLong(_Alignof(struct Bits_MSVC)));
@@ -536,7 +555,8 @@
int64_t b :62;
int64_t c :1;
};
- struct I64Bits value = {0};
+ struct I64Bits value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("I64Bits"));
APPEND(PyLong_FromLong(sizeof(struct I64Bits)));
APPEND(PyLong_FromLong(_Alignof(struct I64Bits)));
@@ -560,7 +580,8 @@
uint64_t b :62;
uint64_t c :1;
};
- struct U64Bits value = {0};
+ struct U64Bits value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("U64Bits"));
APPEND(PyLong_FromLong(sizeof(struct U64Bits)));
APPEND(PyLong_FromLong(_Alignof(struct U64Bits)));
@@ -584,7 +605,8 @@
int8_t b :3;
int8_t c :1;
};
- struct Struct331_8 value = {0};
+ struct Struct331_8 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct331_8"));
APPEND(PyLong_FromLong(sizeof(struct Struct331_8)));
APPEND(PyLong_FromLong(_Alignof(struct Struct331_8)));
@@ -608,7 +630,8 @@
int8_t b :6;
int8_t c :1;
};
- struct Struct1x1_8 value = {0};
+ struct Struct1x1_8 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1x1_8"));
APPEND(PyLong_FromLong(sizeof(struct Struct1x1_8)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_8)));
@@ -633,7 +656,8 @@
int8_t b :6;
int8_t c :1;
};
- struct Struct1nx1_8 value = {0};
+ struct Struct1nx1_8 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1nx1_8"));
APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_8)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_8)));
@@ -658,7 +682,8 @@
int8_t b :6;
int8_t c :6;
};
- struct Struct3xx_8 value = {0};
+ struct Struct3xx_8 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct3xx_8"));
APPEND(PyLong_FromLong(sizeof(struct Struct3xx_8)));
APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_8)));
@@ -682,7 +707,8 @@
uint8_t b :3;
uint8_t c :1;
};
- struct Struct331_u8 value = {0};
+ struct Struct331_u8 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct331_u8"));
APPEND(PyLong_FromLong(sizeof(struct Struct331_u8)));
APPEND(PyLong_FromLong(_Alignof(struct Struct331_u8)));
@@ -706,7 +732,8 @@
uint8_t b :6;
uint8_t c :1;
};
- struct Struct1x1_u8 value = {0};
+ struct Struct1x1_u8 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1x1_u8"));
APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u8)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u8)));
@@ -731,7 +758,8 @@
uint8_t b :6;
uint8_t c :1;
};
- struct Struct1nx1_u8 value = {0};
+ struct Struct1nx1_u8 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1nx1_u8"));
APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u8)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u8)));
@@ -756,7 +784,8 @@
uint8_t b :6;
uint8_t c :6;
};
- struct Struct3xx_u8 value = {0};
+ struct Struct3xx_u8 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct3xx_u8"));
APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u8)));
APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u8)));
@@ -780,7 +809,8 @@
int16_t b :3;
int16_t c :1;
};
- struct Struct331_16 value = {0};
+ struct Struct331_16 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct331_16"));
APPEND(PyLong_FromLong(sizeof(struct Struct331_16)));
APPEND(PyLong_FromLong(_Alignof(struct Struct331_16)));
@@ -804,7 +834,8 @@
int16_t b :14;
int16_t c :1;
};
- struct Struct1x1_16 value = {0};
+ struct Struct1x1_16 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1x1_16"));
APPEND(PyLong_FromLong(sizeof(struct Struct1x1_16)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_16)));
@@ -829,7 +860,8 @@
int16_t b :14;
int16_t c :1;
};
- struct Struct1nx1_16 value = {0};
+ struct Struct1nx1_16 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1nx1_16"));
APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_16)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_16)));
@@ -854,7 +886,8 @@
int16_t b :14;
int16_t c :14;
};
- struct Struct3xx_16 value = {0};
+ struct Struct3xx_16 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct3xx_16"));
APPEND(PyLong_FromLong(sizeof(struct Struct3xx_16)));
APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_16)));
@@ -878,7 +911,8 @@
uint16_t b :3;
uint16_t c :1;
};
- struct Struct331_u16 value = {0};
+ struct Struct331_u16 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct331_u16"));
APPEND(PyLong_FromLong(sizeof(struct Struct331_u16)));
APPEND(PyLong_FromLong(_Alignof(struct Struct331_u16)));
@@ -902,7 +936,8 @@
uint16_t b :14;
uint16_t c :1;
};
- struct Struct1x1_u16 value = {0};
+ struct Struct1x1_u16 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1x1_u16"));
APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u16)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u16)));
@@ -927,7 +962,8 @@
uint16_t b :14;
uint16_t c :1;
};
- struct Struct1nx1_u16 value = {0};
+ struct Struct1nx1_u16 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1nx1_u16"));
APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u16)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u16)));
@@ -952,7 +988,8 @@
uint16_t b :14;
uint16_t c :14;
};
- struct Struct3xx_u16 value = {0};
+ struct Struct3xx_u16 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct3xx_u16"));
APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u16)));
APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u16)));
@@ -976,7 +1013,8 @@
int32_t b :3;
int32_t c :1;
};
- struct Struct331_32 value = {0};
+ struct Struct331_32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct331_32"));
APPEND(PyLong_FromLong(sizeof(struct Struct331_32)));
APPEND(PyLong_FromLong(_Alignof(struct Struct331_32)));
@@ -1000,7 +1038,8 @@
int32_t b :30;
int32_t c :1;
};
- struct Struct1x1_32 value = {0};
+ struct Struct1x1_32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1x1_32"));
APPEND(PyLong_FromLong(sizeof(struct Struct1x1_32)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_32)));
@@ -1025,7 +1064,8 @@
int32_t b :30;
int32_t c :1;
};
- struct Struct1nx1_32 value = {0};
+ struct Struct1nx1_32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1nx1_32"));
APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_32)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_32)));
@@ -1050,7 +1090,8 @@
int32_t b :30;
int32_t c :30;
};
- struct Struct3xx_32 value = {0};
+ struct Struct3xx_32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct3xx_32"));
APPEND(PyLong_FromLong(sizeof(struct Struct3xx_32)));
APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_32)));
@@ -1074,7 +1115,8 @@
uint32_t b :3;
uint32_t c :1;
};
- struct Struct331_u32 value = {0};
+ struct Struct331_u32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct331_u32"));
APPEND(PyLong_FromLong(sizeof(struct Struct331_u32)));
APPEND(PyLong_FromLong(_Alignof(struct Struct331_u32)));
@@ -1098,7 +1140,8 @@
uint32_t b :30;
uint32_t c :1;
};
- struct Struct1x1_u32 value = {0};
+ struct Struct1x1_u32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1x1_u32"));
APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u32)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u32)));
@@ -1123,7 +1166,8 @@
uint32_t b :30;
uint32_t c :1;
};
- struct Struct1nx1_u32 value = {0};
+ struct Struct1nx1_u32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1nx1_u32"));
APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u32)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u32)));
@@ -1148,7 +1192,8 @@
uint32_t b :30;
uint32_t c :30;
};
- struct Struct3xx_u32 value = {0};
+ struct Struct3xx_u32 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct3xx_u32"));
APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u32)));
APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u32)));
@@ -1172,7 +1217,8 @@
int64_t b :3;
int64_t c :1;
};
- struct Struct331_64 value = {0};
+ struct Struct331_64 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct331_64"));
APPEND(PyLong_FromLong(sizeof(struct Struct331_64)));
APPEND(PyLong_FromLong(_Alignof(struct Struct331_64)));
@@ -1196,7 +1242,8 @@
int64_t b :62;
int64_t c :1;
};
- struct Struct1x1_64 value = {0};
+ struct Struct1x1_64 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1x1_64"));
APPEND(PyLong_FromLong(sizeof(struct Struct1x1_64)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_64)));
@@ -1221,7 +1268,8 @@
int64_t b :62;
int64_t c :1;
};
- struct Struct1nx1_64 value = {0};
+ struct Struct1nx1_64 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1nx1_64"));
APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_64)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_64)));
@@ -1246,7 +1294,8 @@
int64_t b :62;
int64_t c :62;
};
- struct Struct3xx_64 value = {0};
+ struct Struct3xx_64 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct3xx_64"));
APPEND(PyLong_FromLong(sizeof(struct Struct3xx_64)));
APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_64)));
@@ -1270,7 +1319,8 @@
uint64_t b :3;
uint64_t c :1;
};
- struct Struct331_u64 value = {0};
+ struct Struct331_u64 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct331_u64"));
APPEND(PyLong_FromLong(sizeof(struct Struct331_u64)));
APPEND(PyLong_FromLong(_Alignof(struct Struct331_u64)));
@@ -1294,7 +1344,8 @@
uint64_t b :62;
uint64_t c :1;
};
- struct Struct1x1_u64 value = {0};
+ struct Struct1x1_u64 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1x1_u64"));
APPEND(PyLong_FromLong(sizeof(struct Struct1x1_u64)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1x1_u64)));
@@ -1319,7 +1370,8 @@
uint64_t b :62;
uint64_t c :1;
};
- struct Struct1nx1_u64 value = {0};
+ struct Struct1nx1_u64 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct1nx1_u64"));
APPEND(PyLong_FromLong(sizeof(struct Struct1nx1_u64)));
APPEND(PyLong_FromLong(_Alignof(struct Struct1nx1_u64)));
@@ -1344,7 +1396,8 @@
uint64_t b :62;
uint64_t c :62;
};
- struct Struct3xx_u64 value = {0};
+ struct Struct3xx_u64 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Struct3xx_u64"));
APPEND(PyLong_FromLong(sizeof(struct Struct3xx_u64)));
APPEND(PyLong_FromLong(_Alignof(struct Struct3xx_u64)));
@@ -1367,7 +1420,8 @@
signed char a :4;
int b :4;
};
- struct Mixed1 value = {0};
+ struct Mixed1 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed1"));
APPEND(PyLong_FromLong(sizeof(struct Mixed1)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed1)));
@@ -1389,7 +1443,8 @@
signed char a :4;
int32_t b :32;
};
- struct Mixed2 value = {0};
+ struct Mixed2 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed2"));
APPEND(PyLong_FromLong(sizeof(struct Mixed2)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed2)));
@@ -1411,7 +1466,8 @@
signed char a :4;
unsigned char b :4;
};
- struct Mixed3 value = {0};
+ struct Mixed3 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed3"));
APPEND(PyLong_FromLong(sizeof(struct Mixed3)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed3)));
@@ -1437,7 +1493,8 @@
short e :4;
int f :24;
};
- struct Mixed4 value = {0};
+ struct Mixed4 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed4"));
APPEND(PyLong_FromLong(sizeof(struct Mixed4)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed4)));
@@ -1463,7 +1520,8 @@
unsigned int A :1;
unsigned short B :16;
};
- struct Mixed5 value = {0};
+ struct Mixed5 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed5"));
APPEND(PyLong_FromLong(sizeof(struct Mixed5)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed5)));
@@ -1485,7 +1543,8 @@
unsigned long long A :1;
unsigned int B :32;
};
- struct Mixed6 value = {0};
+ struct Mixed6 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed6"));
APPEND(PyLong_FromLong(sizeof(struct Mixed6)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed6)));
@@ -1508,7 +1567,8 @@
uint32_t B :20;
uint64_t C :24;
};
- struct Mixed7 value = {0};
+ struct Mixed7 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed7"));
APPEND(PyLong_FromLong(sizeof(struct Mixed7)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed7)));
@@ -1532,7 +1592,8 @@
uint32_t B :32;
unsigned long long C :1;
};
- struct Mixed8_a value = {0};
+ struct Mixed8_a value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed8_a"));
APPEND(PyLong_FromLong(sizeof(struct Mixed8_a)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed8_a)));
@@ -1556,7 +1617,8 @@
uint32_t B;
unsigned long long C :1;
};
- struct Mixed8_b value = {0};
+ struct Mixed8_b value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed8_b"));
APPEND(PyLong_FromLong(sizeof(struct Mixed8_b)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed8_b)));
@@ -1579,7 +1641,8 @@
uint8_t A;
uint32_t B :1;
};
- struct Mixed9 value = {0};
+ struct Mixed9 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed9"));
APPEND(PyLong_FromLong(sizeof(struct Mixed9)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed9)));
@@ -1601,7 +1664,8 @@
uint32_t A :1;
uint64_t B :1;
};
- struct Mixed10 value = {0};
+ struct Mixed10 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Mixed10"));
APPEND(PyLong_FromLong(sizeof(struct Mixed10)));
APPEND(PyLong_FromLong(_Alignof(struct Mixed10)));
@@ -1623,7 +1687,8 @@
uint32_t A :1;
uint64_t B :1;
};
- struct Example_gh_95496 value = {0};
+ struct Example_gh_95496 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Example_gh_95496"));
APPEND(PyLong_FromLong(sizeof(struct Example_gh_95496)));
APPEND(PyLong_FromLong(_Alignof(struct Example_gh_95496)));
@@ -1655,7 +1720,8 @@
uint16_t b1 :12;
};
#pragma pack(pop)
- struct Example_gh_84039_bad value = {0};
+ struct Example_gh_84039_bad value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Example_gh_84039_bad"));
APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_bad)));
APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_bad)));
@@ -1693,7 +1759,8 @@
uint8_t a7 :1;
};
#pragma pack(pop)
- struct Example_gh_84039_good_a value = {0};
+ struct Example_gh_84039_good_a value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Example_gh_84039_good_a"));
APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_good_a)));
APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_good_a)));
@@ -1735,7 +1802,8 @@
uint16_t b1 :12;
};
#pragma pack(pop)
- struct Example_gh_84039_good value = {0};
+ struct Example_gh_84039_good value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Example_gh_84039_good"));
APPEND(PyLong_FromLong(sizeof(struct Example_gh_84039_good)));
APPEND(PyLong_FromLong(_Alignof(struct Example_gh_84039_good)));
@@ -1775,7 +1843,8 @@
uint32_t R2 :2;
};
#pragma pack(pop)
- struct Example_gh_73939 value = {0};
+ struct Example_gh_73939 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Example_gh_73939"));
APPEND(PyLong_FromLong(sizeof(struct Example_gh_73939)));
APPEND(PyLong_FromLong(_Alignof(struct Example_gh_73939)));
@@ -1806,7 +1875,8 @@
uint8_t b :8;
uint32_t c :16;
};
- struct Example_gh_86098 value = {0};
+ struct Example_gh_86098 value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Example_gh_86098"));
APPEND(PyLong_FromLong(sizeof(struct Example_gh_86098)));
APPEND(PyLong_FromLong(_Alignof(struct Example_gh_86098)));
@@ -1832,7 +1902,8 @@
uint32_t c :16;
};
#pragma pack(pop)
- struct Example_gh_86098_pack value = {0};
+ struct Example_gh_86098_pack value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("Example_gh_86098_pack"));
APPEND(PyLong_FromLong(sizeof(struct Example_gh_86098_pack)));
APPEND(PyLong_FromLong(_Alignof(struct Example_gh_86098_pack)));
@@ -1858,7 +1929,8 @@
};
signed char y;
};
- struct AnonBitfields value = {0};
+ struct AnonBitfields value;
+ memset(&value, 0, sizeof(value));
APPEND(PyUnicode_FromString("AnonBitfields"));
APPEND(PyLong_FromLong(sizeof(struct AnonBitfields)));
APPEND(PyLong_FromLong(_Alignof(struct AnonBitfields)));
1
0
gh-71339: Fix an order-dependent failure in test_unittest (GH-129133)
by serhiy-storchaka Jan. 21, 2025
by serhiy-storchaka Jan. 21, 2025
Jan. 21, 2025
https://github.com/python/cpython/commit/4b37a6bda236121c130b4a60e573f123cb…
commit: 4b37a6bda236121c130b4a60e573f123cb5e4c58
branch: main
author: Serhiy Storchaka <storchaka(a)gmail.com>
committer: serhiy-storchaka <storchaka(a)gmail.com>
date: 2025-01-21T16:45:20+02:00
summary:
gh-71339: Fix an order-dependent failure in test_unittest (GH-129133)
It failed if it was preceded by test_builtin.
files:
M Lib/test/test_builtin.py
M Lib/test/test_unittest/test_case.py
diff --git a/Lib/test/test_builtin.py b/Lib/test/test_builtin.py
index 73b139e405ae59..913d007a126d72 100644
--- a/Lib/test/test_builtin.py
+++ b/Lib/test/test_builtin.py
@@ -1833,7 +1833,10 @@ def test_bug_27936(self):
def test_setattr(self):
setattr(sys, 'spam', 1)
- self.assertEqual(sys.spam, 1)
+ try:
+ self.assertEqual(sys.spam, 1)
+ finally:
+ del sys.spam
self.assertRaises(TypeError, setattr)
self.assertRaises(TypeError, setattr, sys)
self.assertRaises(TypeError, setattr, sys, 'spam')
diff --git a/Lib/test/test_unittest/test_case.py b/Lib/test/test_unittest/test_case.py
index df1381451b7ebc..a04af55f3fc0ae 100644
--- a/Lib/test/test_unittest/test_case.py
+++ b/Lib/test/test_unittest/test_case.py
@@ -801,9 +801,9 @@ def testAssertHasAttr(self):
self.assertEqual(str(cm.exception),
"type object 'List' has no attribute 'spam'")
with self.assertRaises(self.failureException) as cm:
- self.assertHasAttr(sys, 'spam')
+ self.assertHasAttr(sys, 'nonexistent')
self.assertEqual(str(cm.exception),
- "module 'sys' has no attribute 'spam'")
+ "module 'sys' has no attribute 'nonexistent'")
with self.assertRaises(self.failureException) as cm:
self.assertHasAttr(a, 'y', 'ababahalamaha')
1
0
Jan. 21, 2025
https://github.com/python/cpython/commit/5809b2590956d51ce805f877e4708d21f5…
commit: 5809b2590956d51ce805f877e4708d21f59fb222
branch: main
author: Ken Jin <kenjin(a)python.org>
committer: Fidget-Spinner <kenjin4096(a)gmail.com>
date: 2025-01-21T22:17:15+08:00
summary:
gh-128563: Move lltrace into the frame struct (GH-129113)
files:
M Include/internal/pycore_frame.h
M Python/bytecodes.c
M Python/ceval.c
M Python/ceval_macros.h
M Python/executor_cases.c.h
diff --git a/Include/internal/pycore_frame.h b/Include/internal/pycore_frame.h
index 77a922630cde08..14dc91e54298ce 100644
--- a/Include/internal/pycore_frame.h
+++ b/Include/internal/pycore_frame.h
@@ -76,7 +76,12 @@ typedef struct _PyInterpreterFrame {
_PyStackRef *stackpointer;
uint16_t return_offset; /* Only relevant during a function call */
char owner;
- char visited;
+#ifdef Py_DEBUG
+ uint8_t visited:1;
+ uint8_t lltrace:7;
+#else
+ uint8_t visited;
+#endif
/* Locals and stack */
_PyStackRef localsplus[1];
} _PyInterpreterFrame;
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 8bda4501df5f74..8bed29ca2c8fc7 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -4990,7 +4990,7 @@ dummy_func(
_Py_CODEUNIT *target = _PyFrame_GetBytecode(frame) + exit->target;
#if defined(Py_DEBUG) && !defined(_Py_JIT)
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
- if (lltrace >= 2) {
+ if (frame->lltrace >= 2) {
printf("SIDE EXIT: [UOp ");
_PyUOpPrint(&next_uop[-1]);
printf(", exit %u, temp %d, target %d -> %s]\n",
@@ -5108,7 +5108,7 @@ dummy_func(
_Py_CODEUNIT *target = frame->instr_ptr;
#if defined(Py_DEBUG) && !defined(_Py_JIT)
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
- if (lltrace >= 2) {
+ if (frame->lltrace >= 2) {
printf("DYNAMIC EXIT: [UOp ");
_PyUOpPrint(&next_uop[-1]);
printf(", exit %u, temp %d, target %d -> %s]\n",
diff --git a/Python/ceval.c b/Python/ceval.c
index 813d980acf5aab..58a54467f06bb0 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -799,9 +799,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
#endif
uint8_t opcode; /* Current opcode */
int oparg; /* Current opcode argument, if any */
-#ifdef LLTRACE
- int lltrace = 0;
-#endif
_PyInterpreterFrame entry_frame;
@@ -821,6 +818,9 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
entry_frame.owner = FRAME_OWNED_BY_INTERPRETER;
entry_frame.visited = 0;
entry_frame.return_offset = 0;
+#ifdef LLTRACE
+ entry_frame.lltrace = 0;
+#endif
/* Push frame */
entry_frame.previous = tstate->current_frame;
frame->previous = &entry_frame;
@@ -880,9 +880,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
stack_pointer = _PyFrame_GetStackPointer(frame);
#ifdef LLTRACE
- lltrace = maybe_lltrace_resume_frame(frame, GLOBALS());
- if (lltrace < 0) {
- goto exit_unwind;
+ {
+ int lltrace = maybe_lltrace_resume_frame(frame, GLOBALS());
+ frame->lltrace = lltrace;
+ if (lltrace < 0) {
+ goto exit_unwind;
+ }
}
#endif
@@ -1002,7 +1005,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
}
/* Resume normal execution */
#ifdef LLTRACE
- if (lltrace >= 5) {
+ if (frame->lltrace >= 5) {
lltrace_resume_frame(frame);
}
#endif
@@ -1079,7 +1082,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
for (;;) {
uopcode = next_uop->opcode;
#ifdef Py_DEBUG
- if (lltrace >= 3) {
+ if (frame->lltrace >= 3) {
dump_stack(frame, stack_pointer);
if (next_uop->opcode == _START_EXECUTOR) {
printf("%4d uop: ", 0);
@@ -1121,7 +1124,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
jump_to_error_target:
#ifdef Py_DEBUG
- if (lltrace >= 2) {
+ if (frame->lltrace >= 2) {
printf("Error: [UOp ");
_PyUOpPrint(&next_uop[-1]);
printf(" @ %d -> %s]\n",
@@ -1157,7 +1160,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
next_instr = next_uop[-1].target + _PyFrame_GetBytecode(frame);
goto_to_tier1:
#ifdef Py_DEBUG
- if (lltrace >= 2) {
+ if (frame->lltrace >= 2) {
printf("DEOPT: [UOp ");
_PyUOpPrint(&next_uop[-1]);
printf(" -> %s]\n",
diff --git a/Python/ceval_macros.h b/Python/ceval_macros.h
index 6a982ee2ca5d9a..feaac07fe435b6 100644
--- a/Python/ceval_macros.h
+++ b/Python/ceval_macros.h
@@ -80,7 +80,7 @@
/* PRE_DISPATCH_GOTO() does lltrace if enabled. Normally a no-op */
#ifdef LLTRACE
-#define PRE_DISPATCH_GOTO() if (lltrace >= 5) { \
+#define PRE_DISPATCH_GOTO() if (frame->lltrace >= 5) { \
lltrace_instruction(frame, stack_pointer, next_instr, opcode, oparg); }
#else
#define PRE_DISPATCH_GOTO() ((void)0)
@@ -89,7 +89,8 @@
#if LLTRACE
#define LLTRACE_RESUME_FRAME() \
do { \
- lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); \
+ int lltrace = maybe_lltrace_resume_frame(frame, GLOBALS()); \
+ frame->lltrace = lltrace; \
if (lltrace < 0) { \
goto exit_unwind; \
} \
diff --git a/Python/executor_cases.c.h b/Python/executor_cases.c.h
index 0d6719a5c40bdd..93072304e6e111 100644
--- a/Python/executor_cases.c.h
+++ b/Python/executor_cases.c.h
@@ -5878,7 +5878,7 @@
stack_pointer = _PyFrame_GetStackPointer(frame);
#if defined(Py_DEBUG) && !defined(_Py_JIT)
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
- if (lltrace >= 2) {
+ if (frame->lltrace >= 2) {
_PyFrame_SetStackPointer(frame, stack_pointer);
printf("SIDE EXIT: [UOp ");
_PyUOpPrint(&next_uop[-1]);
@@ -6072,7 +6072,7 @@
_Py_CODEUNIT *target = frame->instr_ptr;
#if defined(Py_DEBUG) && !defined(_Py_JIT)
OPT_HIST(trace_uop_execution_counter, trace_run_length_hist);
- if (lltrace >= 2) {
+ if (frame->lltrace >= 2) {
_PyFrame_SetStackPointer(frame, stack_pointer);
printf("DYNAMIC EXIT: [UOp ");
_PyUOpPrint(&next_uop[-1]);
1
0
Jan. 21, 2025
https://github.com/python/cpython/commit/31f149d5b3a5c6cb1160a052c96a35c36f…
commit: 31f149d5b3a5c6cb1160a052c96a35c36f2a27db
branch: main
author: Victor Stinner <vstinner(a)python.org>
committer: vstinner <vstinner(a)python.org>
date: 2025-01-21T14:43:31+01:00
summary:
gh-128679: Use _PyThreadState_GET() in tracemalloc.c (#129126)
Replace uncommon PyGILState_GetThisThreadState() with common
_PyThreadState_GET().
files:
M Python/tracemalloc.c
diff --git a/Python/tracemalloc.c b/Python/tracemalloc.c
index a9f45e5ead1a11..b398ea379e0607 100644
--- a/Python/tracemalloc.c
+++ b/Python/tracemalloc.c
@@ -338,13 +338,8 @@ traceback_hash(traceback_t *traceback)
static void
traceback_get_frames(traceback_t *traceback)
{
- PyThreadState *tstate = PyGILState_GetThisThreadState();
- if (tstate == NULL) {
-#ifdef TRACE_DEBUG
- tracemalloc_error("failed to get the current thread state");
-#endif
- return;
- }
+ PyThreadState *tstate = _PyThreadState_GET();
+ assert(tstate != NULL);
_PyInterpreterFrame *pyframe = _PyThreadState_GetFrame(tstate);
while (pyframe) {
1
0
Jan. 21, 2025
https://github.com/python/cpython/commit/6a0f915aaea869cae799349047eef6f9f3…
commit: 6a0f915aaea869cae799349047eef6f9f3c6e2dc
branch: main
author: Bénédikt Tran <10796600+picnixz(a)users.noreply.github.com>
committer: picnixz <10796600+picnixz(a)users.noreply.github.com>
date: 2025-01-21T12:43:09+01:00
summary:
gh-129064: Fix RST markup for the NEWS and What's New entries (#129131)
This amends the NEWS and What's New entries introduced in 0a6412f9cc9e694e76299cfbd73ec969b7d47af6.
files:
M Doc/deprecations/pending-removal-in-3.16.rst
M Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst
diff --git a/Doc/deprecations/pending-removal-in-3.16.rst b/Doc/deprecations/pending-removal-in-3.16.rst
index 58f7c01bf39469..b408a6d72febe0 100644
--- a/Doc/deprecations/pending-removal-in-3.16.rst
+++ b/Doc/deprecations/pending-removal-in-3.16.rst
@@ -82,7 +82,7 @@ Pending removal in Python 3.16
* :mod:`sysconfig`:
- * The ``~sysconfig.expand_makefile_vars`` function
+ * The :func:`!sysconfig.expand_makefile_vars` function
has been deprecated since Python 3.14.
Use the ``vars`` argument of :func:`sysconfig.get_paths` instead.
diff --git a/Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst b/Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst
index 5939fdc8ef3469..93a1eda350d1fc 100644
--- a/Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst
+++ b/Misc/NEWS.d/next/Library/2025-01-20-16-02-38.gh-issue-129064.JXasgJ.rst
@@ -1,2 +1,2 @@
-Deprecate ``sysconfig.expand_makefile_vars``, in favor of using
+Deprecate :func:`!sysconfig.expand_makefile_vars`, in favor of using
:func:`sysconfig.get_paths` with the ``vars`` argument.
1
0
Jan. 21, 2025
https://github.com/python/cpython/commit/01de4af3e18992d3aad12dbe5d23dbb196…
commit: 01de4af3e18992d3aad12dbe5d23dbb19602609d
branch: main
author: Victor Stinner <vstinner(a)python.org>
committer: vstinner <vstinner(a)python.org>
date: 2025-01-21T12:02:38+01:00
summary:
gh-126925: Make PyConfig.use_system_logger read-only (#129124)
The variable is only used once during early Python initialization, it
doesn't make sense to modify it at runtime.
files:
M Python/initconfig.c
diff --git a/Python/initconfig.c b/Python/initconfig.c
index 7851b86db1f6d0..4db77ef47d2362 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -169,7 +169,7 @@ static const PyConfigSpec PYCONFIG_SPEC[] = {
SPEC(use_frozen_modules, BOOL, READ_ONLY, NO_SYS),
SPEC(use_hash_seed, BOOL, READ_ONLY, NO_SYS),
#ifdef __APPLE__
- SPEC(use_system_logger, BOOL, PUBLIC, NO_SYS),
+ SPEC(use_system_logger, BOOL, READ_ONLY, NO_SYS),
#endif
SPEC(user_site_directory, BOOL, READ_ONLY, NO_SYS), // sys.flags.no_user_site
SPEC(warn_default_encoding, BOOL, READ_ONLY, NO_SYS),
1
0
https://github.com/python/cpython/commit/80189ff6475d8ab667de1199e659d5070f…
commit: 80189ff6475d8ab667de1199e659d5070f457ab9
branch: main
author: Victor Stinner <vstinner(a)python.org>
committer: vstinner <vstinner(a)python.org>
date: 2025-01-21T11:58:43+01:00
summary:
Remove PyInit__imp() function (#129125)
This function was exposed by mistake to the public C API. It's the
only "PyInit" function which is exposed.
files:
M Include/cpython/import.h
diff --git a/Include/cpython/import.h b/Include/cpython/import.h
index 7daf0b84fcf71b..0fd61c28cafa0e 100644
--- a/Include/cpython/import.h
+++ b/Include/cpython/import.h
@@ -2,8 +2,6 @@
# error "this header file must not be included directly"
#endif
-PyMODINIT_FUNC PyInit__imp(void);
-
struct _inittab {
const char *name; /* ASCII encoded string */
PyObject* (*initfunc)(void);
1
0
https://github.com/python/cpython/commit/fafc618e2f535dc972f9502d8547e089d4…
commit: fafc618e2f535dc972f9502d8547e089d4c7908d
branch: main
author: Bénédikt Tran <10796600+picnixz(a)users.noreply.github.com>
committer: picnixz <10796600+picnixz(a)users.noreply.github.com>
date: 2025-01-21T11:50:13+01:00
summary:
gh-111178: fix UBSan failures in `Modules/_ctypes` (#129071)
This fixes UBSan failures for the following objects:
- `DictRemoverObject` and `StructParamObject`,
- `CDataObject` and `CFieldObject`, and
- `PyCFuncPtrObject` and `PyCArgObject`.
On the default build, we convert the `LOCK_PTR` and `UNLOCK_PTR` macros to
functions with an unused parameter to ease "unused variable" compiler warnings
suppression. Finally, we also remove some redundant casts to `PyObject *`.
files:
M Modules/_ctypes/_ctypes.c
M Modules/_ctypes/callproc.c
M Modules/_ctypes/cfield.c
M Modules/_ctypes/ctypes.h
diff --git a/Modules/_ctypes/_ctypes.c b/Modules/_ctypes/_ctypes.c
index 5d37610cc1c970..d86adec0aeca58 100644
--- a/Modules/_ctypes/_ctypes.c
+++ b/Modules/_ctypes/_ctypes.c
@@ -146,9 +146,12 @@ typedef struct {
PyObject *dict;
} DictRemoverObject;
+#define _DictRemoverObject_CAST(op) ((DictRemoverObject *)(op))
+
static int
-_DictRemover_traverse(DictRemoverObject *self, visitproc visit, void *arg)
+_DictRemover_traverse(PyObject *myself, visitproc visit, void *arg)
{
+ DictRemoverObject *self = _DictRemoverObject_CAST(myself);
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->key);
Py_VISIT(self->dict);
@@ -156,8 +159,9 @@ _DictRemover_traverse(DictRemoverObject *self, visitproc visit, void *arg)
}
static int
-_DictRemover_clear(DictRemoverObject *self)
+_DictRemover_clear(PyObject *myself)
{
+ DictRemoverObject *self = _DictRemoverObject_CAST(myself);
Py_CLEAR(self->key);
Py_CLEAR(self->dict);
return 0;
@@ -167,9 +171,8 @@ static void
_DictRemover_dealloc(PyObject *myself)
{
PyTypeObject *tp = Py_TYPE(myself);
- DictRemoverObject *self = (DictRemoverObject *)myself;
PyObject_GC_UnTrack(myself);
- (void)_DictRemover_clear(self);
+ (void)_DictRemover_clear(myself);
tp->tp_free(myself);
Py_DECREF(tp);
}
@@ -177,7 +180,7 @@ _DictRemover_dealloc(PyObject *myself)
static PyObject *
_DictRemover_call(PyObject *myself, PyObject *args, PyObject *kw)
{
- DictRemoverObject *self = (DictRemoverObject *)myself;
+ DictRemoverObject *self = _DictRemoverObject_CAST(myself);
if (self->key && self->dict) {
if (-1 == PyDict_DelItem(self->dict, self->key)) {
PyErr_FormatUnraisable("Exception ignored on calling _ctypes.DictRemover");
@@ -402,16 +405,19 @@ typedef struct {
PyObject *keep; // If set, a reference to the original CDataObject.
} StructParamObject;
+#define _StructParamObject_CAST(op) ((StructParamObject *)(op))
+
static int
-StructParam_traverse(StructParamObject *self, visitproc visit, void *arg)
+StructParam_traverse(PyObject *self, visitproc visit, void *arg)
{
Py_VISIT(Py_TYPE(self));
return 0;
}
static int
-StructParam_clear(StructParamObject *self)
+StructParam_clear(PyObject *myself)
{
+ StructParamObject *self = _StructParamObject_CAST(myself);
Py_CLEAR(self->keep);
return 0;
}
@@ -419,10 +425,10 @@ StructParam_clear(StructParamObject *self)
static void
StructParam_dealloc(PyObject *myself)
{
- StructParamObject *self = (StructParamObject *)myself;
+ StructParamObject *self = _StructParamObject_CAST(myself);
PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(myself);
- (void)StructParam_clear(self);
+ (void)StructParam_clear(myself);
PyMem_Free(self->ptr);
tp->tp_free(myself);
Py_DECREF(tp);
@@ -675,7 +681,7 @@ StructUnionType_init(PyObject *self, PyObject *args, PyObject *kwds, int isStruc
info->paramfunc = StructUnionType_paramfunc;
- if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_fields_), &fields) < 0) {
+ if (PyDict_GetItemRef(attrdict, &_Py_ID(_fields_), &fields) < 0) {
Py_DECREF(attrdict);
return -1;
}
@@ -1411,11 +1417,12 @@ static PyType_Spec pycpointer_type_spec = {
*/
static int
-CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
+CharArray_set_raw(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
{
char *ptr;
Py_ssize_t size;
Py_buffer view;
+ CDataObject *self = _CDataObject_CAST(op);
if (value == NULL) {
PyErr_SetString(PyExc_AttributeError, "cannot delete attribute");
@@ -1441,9 +1448,10 @@ CharArray_set_raw(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
}
static PyObject *
-CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored))
+CharArray_get_raw(PyObject *op, void *Py_UNUSED(ignored))
{
PyObject *res;
+ CDataObject *self = _CDataObject_CAST(op);
LOCK_PTR(self);
res = PyBytes_FromStringAndSize(self->b_ptr, self->b_size);
UNLOCK_PTR(self);
@@ -1451,10 +1459,11 @@ CharArray_get_raw(CDataObject *self, void *Py_UNUSED(ignored))
}
static PyObject *
-CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
+CharArray_get_value(PyObject *op, void *Py_UNUSED(ignored))
{
Py_ssize_t i;
PyObject *res;
+ CDataObject *self = _CDataObject_CAST(op);
LOCK_PTR(self);
char *ptr = self->b_ptr;
for (i = 0; i < self->b_size; ++i)
@@ -1466,10 +1475,11 @@ CharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
}
static int
-CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
+CharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
{
const char *ptr;
Py_ssize_t size;
+ CDataObject *self = _CDataObject_CAST(op);
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
@@ -1504,18 +1514,17 @@ CharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored)
}
static PyGetSetDef CharArray_getsets[] = {
- { "raw", (getter)CharArray_get_raw, (setter)CharArray_set_raw,
- "value", NULL },
- { "value", (getter)CharArray_get_value, (setter)CharArray_set_value,
- "string value"},
+ { "raw", CharArray_get_raw, CharArray_set_raw, "value", NULL },
+ { "value", CharArray_get_value, CharArray_set_value, "string value" },
{ NULL, NULL }
};
static PyObject *
-WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
+WCharArray_get_value(PyObject *op, void *Py_UNUSED(ignored))
{
Py_ssize_t i;
PyObject *res;
+ CDataObject *self = _CDataObject_CAST(op);
wchar_t *ptr = (wchar_t *)self->b_ptr;
LOCK_PTR(self);
for (i = 0; i < self->b_size/(Py_ssize_t)sizeof(wchar_t); ++i)
@@ -1527,8 +1536,10 @@ WCharArray_get_value(CDataObject *self, void *Py_UNUSED(ignored))
}
static int
-WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
+WCharArray_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
{
+ CDataObject *self = _CDataObject_CAST(op);
+
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
"can't delete attribute");
@@ -1561,8 +1572,7 @@ WCharArray_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored
}
static PyGetSetDef WCharArray_getsets[] = {
- { "value", (getter)WCharArray_get_value, (setter)WCharArray_set_value,
- "string value"},
+ { "value", WCharArray_get_value, WCharArray_set_value, "string value" },
{ NULL, NULL }
};
@@ -2627,7 +2637,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
stginfo->getfunc = NULL;
stginfo->ffi_type_pointer = ffi_type_pointer;
- if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_flags_), &ob) < 0) {
+ if (PyDict_GetItemRef(attrdict, &_Py_ID(_flags_), &ob) < 0) {
return -1;
}
if (!ob || !PyLong_Check(ob)) {
@@ -2640,7 +2650,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
Py_DECREF(ob);
/* _argtypes_ is optional... */
- if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_argtypes_), &ob) < 0) {
+ if (PyDict_GetItemRef(attrdict, &_Py_ID(_argtypes_), &ob) < 0) {
return -1;
}
if (ob) {
@@ -2653,7 +2663,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
stginfo->converters = converters;
}
- if (PyDict_GetItemRef((PyObject *)attrdict, &_Py_ID(_restype_), &ob) < 0) {
+ if (PyDict_GetItemRef(attrdict, &_Py_ID(_restype_), &ob) < 0) {
return -1;
}
if (ob) {
@@ -2675,7 +2685,7 @@ make_funcptrtype_dict(ctypes_state *st, PyObject *attrdict, StgInfo *stginfo)
}
}
/* XXX later, maybe.
- if (PyDict_GetItemRef((PyObject *)attrdict, &_Py _ID(_errcheck_), &ob) < 0) {
+ if (PyDict_GetItemRef(attrdict, &_Py _ID(_errcheck_), &ob) < 0) {
return -1;
}
if (ob) {
@@ -2877,8 +2887,9 @@ class _ctypes.PyCData "PyObject *" "clinic_state()->PyCData_Type"
static int
-PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
+PyCData_traverse(PyObject *op, visitproc visit, void *arg)
{
+ CDataObject *self = _CDataObject_CAST(op);
Py_VISIT(self->b_objects);
Py_VISIT((PyObject *)self->b_base);
PyTypeObject *type = Py_TYPE(self);
@@ -2887,8 +2898,9 @@ PyCData_traverse(CDataObject *self, visitproc visit, void *arg)
}
static int
-PyCData_clear(CDataObject *self)
+PyCData_clear(PyObject *op)
{
+ CDataObject *self = _CDataObject_CAST(op);
Py_CLEAR(self->b_objects);
if ((self->b_needsfree)
&& _CDataObject_HasExternalBuffer(self))
@@ -2903,7 +2915,7 @@ PyCData_dealloc(PyObject *self)
{
PyTypeObject *type = Py_TYPE(self);
PyObject_GC_UnTrack(self);
- PyCData_clear((CDataObject *)self);
+ (void)PyCData_clear(self);
type->tp_free(self);
Py_DECREF(type);
}
@@ -2946,7 +2958,7 @@ PyCData_item_type(ctypes_state *st, PyObject *type)
static int
PyCData_NewGetBuffer(PyObject *myself, Py_buffer *view, int flags)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
StgInfo *info;
@@ -3005,7 +3017,7 @@ static PyObject *
PyCData_reduce_impl(PyObject *myself, PyTypeObject *cls)
/*[clinic end generated code: output=1a025ccfdd8c935d input=34097a5226ea63c1]*/
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
ctypes_state *st = get_module_state_by_class(cls);
StgInfo *info;
@@ -3038,7 +3050,7 @@ PyCData_setstate(PyObject *myself, PyObject *args)
Py_ssize_t len;
int res;
PyObject *dict, *mydict;
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
if (!PyArg_ParseTuple(args, "O!s#",
&PyDict_Type, &dict, &data, &len))
{
@@ -3238,10 +3250,7 @@ PyObject *
PyCData_get(ctypes_state *st, PyObject *type, GETFUNC getfunc, PyObject *src,
Py_ssize_t index, Py_ssize_t size, char *adr)
{
-#ifdef Py_GIL_DISABLED
- // This isn't used if the GIL is enabled, so it causes a compiler warning.
- CDataObject *cdata = (CDataObject *)src;
-#endif
+ CDataObject *cdata = _CDataObject_CAST(src);
if (getfunc) {
PyObject *res;
LOCK_PTR(cdata);
@@ -4394,7 +4403,7 @@ _build_result(PyObject *result, PyObject *callargs,
}
static PyObject *
-PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
+PyCFuncPtr_call(PyObject *op, PyObject *inargs, PyObject *kwds)
{
PyObject *restype;
PyObject *converters;
@@ -4407,6 +4416,7 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
IUnknown *piunk = NULL;
#endif
void *pProc = NULL;
+ PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
int inoutmask;
int outmask;
@@ -4414,7 +4424,7 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *info;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
+ if (PyStgInfo_FromObject(st, op, &info) < 0) {
return NULL;
}
assert(info); /* Cannot be NULL for PyCFuncPtrObject instances */
@@ -4532,8 +4542,9 @@ PyCFuncPtr_call(PyCFuncPtrObject *self, PyObject *inargs, PyObject *kwds)
}
static int
-PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
+PyCFuncPtr_traverse(PyObject *op, visitproc visit, void *arg)
{
+ PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
Py_VISIT(self->callable);
Py_VISIT(self->restype);
Py_VISIT(self->checker);
@@ -4542,12 +4553,13 @@ PyCFuncPtr_traverse(PyCFuncPtrObject *self, visitproc visit, void *arg)
Py_VISIT(self->converters);
Py_VISIT(self->paramflags);
Py_VISIT(self->thunk);
- return PyCData_traverse((CDataObject *)self, visit, arg);
+ return PyCData_traverse(op, visit, arg);
}
static int
-PyCFuncPtr_clear(PyCFuncPtrObject *self)
+PyCFuncPtr_clear(PyObject *op)
{
+ PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
Py_CLEAR(self->callable);
Py_CLEAR(self->restype);
Py_CLEAR(self->checker);
@@ -4556,22 +4568,23 @@ PyCFuncPtr_clear(PyCFuncPtrObject *self)
Py_CLEAR(self->converters);
Py_CLEAR(self->paramflags);
Py_CLEAR(self->thunk);
- return PyCData_clear((CDataObject *)self);
+ return PyCData_clear(op);
}
static void
-PyCFuncPtr_dealloc(PyCFuncPtrObject *self)
+PyCFuncPtr_dealloc(PyObject *self)
{
PyObject_GC_UnTrack(self);
- PyCFuncPtr_clear(self);
+ (void)PyCFuncPtr_clear(self);
PyTypeObject *type = Py_TYPE(self);
- type->tp_free((PyObject *)self);
+ type->tp_free(self);
Py_DECREF(type);
}
static PyObject *
-PyCFuncPtr_repr(PyCFuncPtrObject *self)
+PyCFuncPtr_repr(PyObject *op)
{
+ PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
#ifdef MS_WIN32
if (self->index)
return PyUnicode_FromFormat("<COM method offset %d: %s at %p>",
@@ -4585,8 +4598,9 @@ PyCFuncPtr_repr(PyCFuncPtrObject *self)
}
static int
-PyCFuncPtr_bool(PyCFuncPtrObject *self)
+PyCFuncPtr_bool(PyObject *op)
{
+ PyCFuncPtrObject *self = _PyCFuncPtrObject_CAST(op);
return ((*(void **)self->b_ptr != NULL)
#ifdef MS_WIN32
|| (self->index != 0)
@@ -4774,7 +4788,7 @@ static PyType_Spec pycunion_spec = {
PyCArray_Type
*/
static int
-Array_init(CDataObject *self, PyObject *args, PyObject *kw)
+Array_init(PyObject *self, PyObject *args, PyObject *kw)
{
Py_ssize_t i;
Py_ssize_t n;
@@ -4788,7 +4802,7 @@ Array_init(CDataObject *self, PyObject *args, PyObject *kw)
for (i = 0; i < n; ++i) {
PyObject *v;
v = PyTuple_GET_ITEM(args, i);
- if (-1 == PySequence_SetItem((PyObject *)self, i, v))
+ if (-1 == PySequence_SetItem(self, i, v))
return -1;
}
return 0;
@@ -4797,7 +4811,7 @@ Array_init(CDataObject *self, PyObject *args, PyObject *kw)
static PyObject *
Array_item(PyObject *myself, Py_ssize_t index)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
Py_ssize_t offset, size;
if (index < 0 || index >= self->b_length) {
@@ -4808,7 +4822,7 @@ Array_item(PyObject *myself, Py_ssize_t index)
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *stginfo;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+ if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
return NULL;
}
@@ -4818,14 +4832,14 @@ Array_item(PyObject *myself, Py_ssize_t index)
size = stginfo->size / stginfo->length;
offset = index * size;
- return PyCData_get(st, stginfo->proto, stginfo->getfunc, (PyObject *)self,
- index, size, self->b_ptr + offset);
+ return PyCData_get(st, stginfo->proto, stginfo->getfunc, myself,
+ index, size, self->b_ptr + offset);
}
static PyObject *
Array_subscript(PyObject *myself, PyObject *item)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
if (PyIndex_Check(item)) {
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
@@ -4849,7 +4863,7 @@ Array_subscript(PyObject *myself, PyObject *item)
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *stginfo;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+ if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
return NULL;
}
assert(stginfo); /* Cannot be NULL for array object instances */
@@ -4950,7 +4964,7 @@ Array_subscript(PyObject *myself, PyObject *item)
static int
Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
Py_ssize_t size, offset;
char *ptr;
@@ -4962,7 +4976,7 @@ Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *stginfo;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+ if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
return -1;
}
assert(stginfo); /* Cannot be NULL for array object instances */
@@ -4976,14 +4990,14 @@ Array_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
offset = index * size;
ptr = self->b_ptr + offset;
- return PyCData_set(st, (PyObject *)self, stginfo->proto, stginfo->setfunc, value,
- index, size, ptr);
+ return PyCData_set(st, myself, stginfo->proto, stginfo->setfunc, value,
+ index, size, ptr);
}
static int
Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
@@ -5040,7 +5054,7 @@ Array_ass_subscript(PyObject *myself, PyObject *item, PyObject *value)
static Py_ssize_t
Array_length(PyObject *myself)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
return self->b_length;
}
@@ -5157,9 +5171,10 @@ class _ctypes.Simple "PyObject *" "clinic_state()->Simple_Type"
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=016c476c7aa8b8a8]*/
static int
-Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
+Simple_set_value(PyObject *op, PyObject *value, void *Py_UNUSED(ignored))
{
PyObject *result;
+ CDataObject *self = _CDataObject_CAST(op);
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
@@ -5169,7 +5184,7 @@ Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *info;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
+ if (PyStgInfo_FromObject(st, op, &info) < 0) {
return -1;
}
assert(info); /* Cannot be NULL for CDataObject instances */
@@ -5186,7 +5201,7 @@ Simple_set_value(CDataObject *self, PyObject *value, void *Py_UNUSED(ignored))
}
static int
-Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
+Simple_init(PyObject *self, PyObject *args, PyObject *kw)
{
PyObject *value = NULL;
if (!PyArg_UnpackTuple(args, "__init__", 0, 1, &value))
@@ -5197,11 +5212,12 @@ Simple_init(CDataObject *self, PyObject *args, PyObject *kw)
}
static PyObject *
-Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored))
+Simple_get_value(PyObject *op, void *Py_UNUSED(ignored))
{
+ CDataObject *self = _CDataObject_CAST(op);
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *info;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &info) < 0) {
+ if (PyStgInfo_FromObject(st, op, &info) < 0) {
return NULL;
}
assert(info); /* Cannot be NULL for CDataObject instances */
@@ -5214,7 +5230,7 @@ Simple_get_value(CDataObject *self, void *Py_UNUSED(ignored))
}
static PyGetSetDef Simple_getsets[] = {
- { "value", (getter)Simple_get_value, (setter)Simple_set_value,
+ { "value", Simple_get_value, Simple_set_value,
"current value", NULL },
{ NULL, NULL }
};
@@ -5236,7 +5252,7 @@ Simple_from_outparm_impl(PyObject *self, PyTypeObject *cls)
return Py_NewRef(self);
}
/* call stginfo->getfunc */
- return Simple_get_value((CDataObject *)self, NULL);
+ return Simple_get_value(self, NULL);
}
static PyMethodDef Simple_methods[] = {
@@ -5244,9 +5260,11 @@ static PyMethodDef Simple_methods[] = {
{ NULL, NULL },
};
-static int Simple_bool(CDataObject *self)
+static int
+Simple_bool(PyObject *op)
{
int cmp;
+ CDataObject *self = _CDataObject_CAST(op);
LOCK_PTR(self);
cmp = memcmp(self->b_ptr, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", self->b_size);
UNLOCK_PTR(self);
@@ -5255,7 +5273,7 @@ static int Simple_bool(CDataObject *self)
/* "%s(%s)" % (self.__class__.__name__, self.value) */
static PyObject *
-Simple_repr(CDataObject *self)
+Simple_repr(PyObject *self)
{
PyObject *val, *result;
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
@@ -5302,7 +5320,7 @@ static PyType_Spec pycsimple_spec = {
static PyObject *
Pointer_item(PyObject *myself, Py_ssize_t index)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
Py_ssize_t size;
Py_ssize_t offset;
PyObject *proto;
@@ -5316,7 +5334,7 @@ Pointer_item(PyObject *myself, Py_ssize_t index)
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
StgInfo *stginfo;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+ if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
return NULL;
}
assert(stginfo); /* Cannot be NULL for pointer object instances */
@@ -5334,14 +5352,14 @@ Pointer_item(PyObject *myself, Py_ssize_t index)
size = iteminfo->size;
offset = index * iteminfo->size;
- return PyCData_get(st, proto, stginfo->getfunc, (PyObject *)self,
+ return PyCData_get(st, proto, stginfo->getfunc, myself,
index, size, (char *)((char *)deref + offset));
}
static int
Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
Py_ssize_t size;
Py_ssize_t offset;
PyObject *proto;
@@ -5361,7 +5379,7 @@ Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
StgInfo *stginfo;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+ if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
return -1;
}
assert(stginfo); /* Cannot be NULL for pointer instances */
@@ -5379,14 +5397,14 @@ Pointer_ass_item(PyObject *myself, Py_ssize_t index, PyObject *value)
size = iteminfo->size;
offset = index * iteminfo->size;
- return PyCData_set(st, (PyObject *)self, proto, stginfo->setfunc, value,
+ return PyCData_set(st, myself, proto, stginfo->setfunc, value,
index, size, ((char *)deref + offset));
}
static PyObject *
-Pointer_get_contents(CDataObject *self, void *closure)
+Pointer_get_contents(PyObject *self, void *closure)
{
- void *deref = locked_deref(self);
+ void *deref = locked_deref(_CDataObject_CAST(self));
if (deref == NULL) {
PyErr_SetString(PyExc_ValueError,
"NULL pointer access");
@@ -5395,21 +5413,20 @@ Pointer_get_contents(CDataObject *self, void *closure)
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *stginfo;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+ if (PyStgInfo_FromObject(st, self, &stginfo) < 0) {
return NULL;
}
assert(stginfo); /* Cannot be NULL for pointer instances */
- return PyCData_FromBaseObj(st, stginfo->proto,
- (PyObject *)self, 0,
- deref);
+ return PyCData_FromBaseObj(st, stginfo->proto, self, 0, deref);
}
static int
-Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
+Pointer_set_contents(PyObject *op, PyObject *value, void *closure)
{
CDataObject *dst;
PyObject *keep;
+ CDataObject *self = _CDataObject_CAST(op);
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
@@ -5418,7 +5435,7 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
}
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(self)));
StgInfo *stginfo;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+ if (PyStgInfo_FromObject(st, op, &stginfo) < 0) {
return -1;
}
assert(stginfo); /* Cannot be NULL for pointer instances */
@@ -5457,17 +5474,15 @@ Pointer_set_contents(CDataObject *self, PyObject *value, void *closure)
}
static PyGetSetDef Pointer_getsets[] = {
- { "contents", (getter)Pointer_get_contents,
- (setter)Pointer_set_contents,
+ { "contents", Pointer_get_contents, Pointer_set_contents,
"the object this pointer points to (read-write)", NULL },
{ NULL, NULL }
};
static int
-Pointer_init(CDataObject *self, PyObject *args, PyObject *kw)
+Pointer_init(PyObject *self, PyObject *args, PyObject *kw)
{
PyObject *value = NULL;
-
if (!PyArg_UnpackTuple(args, "POINTER", 0, 1, &value))
return -1;
if (value == NULL)
@@ -5494,7 +5509,7 @@ Pointer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
static PyObject *
Pointer_subscript(PyObject *myself, PyObject *item)
{
- CDataObject *self = (CDataObject *)myself;
+ CDataObject *self = _CDataObject_CAST(myself);
if (PyIndex_Check(item)) {
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
@@ -5560,7 +5575,7 @@ Pointer_subscript(PyObject *myself, PyObject *item)
ctypes_state *st = get_module_state_by_def(Py_TYPE(Py_TYPE(myself)));
StgInfo *stginfo;
- if (PyStgInfo_FromObject(st, (PyObject *)self, &stginfo) < 0) {
+ if (PyStgInfo_FromObject(st, myself, &stginfo) < 0) {
return NULL;
}
assert(stginfo); /* Cannot be NULL for pointer instances */
@@ -5642,13 +5657,13 @@ Pointer_subscript(PyObject *myself, PyObject *item)
}
static int
-Pointer_bool(CDataObject *self)
+Pointer_bool(PyObject *self)
{
- return locked_deref(self) != NULL;
+ return locked_deref(_CDataObject_CAST(self)) != NULL;
}
static PyType_Slot pycpointer_slots[] = {
- {Py_tp_doc, PyDoc_STR("XXX to be provided")},
+ {Py_tp_doc, (void *)PyDoc_STR("XXX to be provided")},
{Py_tp_getset, Pointer_getsets},
{Py_tp_init, Pointer_init},
{Py_tp_new, Pointer_new},
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index 92eedff5ec94f1..c6b6460126ca90 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -493,27 +493,29 @@ PyCArgObject_new(ctypes_state *st)
}
static int
-PyCArg_traverse(PyCArgObject *self, visitproc visit, void *arg)
+PyCArg_traverse(PyObject *op, visitproc visit, void *arg)
{
+ PyCArgObject *self = _PyCArgObject_CAST(op);
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->obj);
return 0;
}
static int
-PyCArg_clear(PyCArgObject *self)
+PyCArg_clear(PyObject *op)
{
+ PyCArgObject *self = _PyCArgObject_CAST(op);
Py_CLEAR(self->obj);
return 0;
}
static void
-PyCArg_dealloc(PyCArgObject *self)
+PyCArg_dealloc(PyObject *self)
{
PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(self);
(void)PyCArg_clear(self);
- tp->tp_free((PyObject *)self);
+ tp->tp_free(self);
Py_DECREF(tp);
}
@@ -524,8 +526,9 @@ is_literal_char(unsigned char c)
}
static PyObject *
-PyCArg_repr(PyCArgObject *self)
+PyCArg_repr(PyObject *op)
{
+ PyCArgObject *self = _PyCArgObject_CAST(op);
switch(self->tag) {
case 'b':
case 'B':
diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c
index e045d206f05580..9924d62c0881d1 100644
--- a/Modules/_ctypes/cfield.c
+++ b/Modules/_ctypes/cfield.c
@@ -194,17 +194,18 @@ PyCField_new_impl(PyTypeObject *type, PyObject *name, PyObject *proto,
static int
-PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
+PyCField_set(PyObject *op, PyObject *inst, PyObject *value)
{
CDataObject *dst;
char *ptr;
+ CFieldObject *self = _CFieldObject_CAST(op);
ctypes_state *st = get_module_state_by_class(Py_TYPE(self));
if (!CDataObject_Check(st, inst)) {
PyErr_SetString(PyExc_TypeError,
"not a ctype instance");
return -1;
}
- dst = (CDataObject *)inst;
+ dst = _CDataObject_CAST(inst);
ptr = dst->b_ptr + self->offset;
if (value == NULL) {
PyErr_SetString(PyExc_TypeError,
@@ -212,13 +213,14 @@ PyCField_set(CFieldObject *self, PyObject *inst, PyObject *value)
return -1;
}
return PyCData_set(st, inst, self->proto, self->setfunc, value,
- self->index, self->size, ptr);
+ self->index, self->size, ptr);
}
static PyObject *
-PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
+PyCField_get(PyObject *op, PyObject *inst, PyTypeObject *type)
{
CDataObject *src;
+ CFieldObject *self = _CFieldObject_CAST(op);
if (inst == NULL) {
return Py_NewRef(self);
}
@@ -228,21 +230,21 @@ PyCField_get(CFieldObject *self, PyObject *inst, PyTypeObject *type)
"not a ctype instance");
return NULL;
}
- src = (CDataObject *)inst;
+ src = _CDataObject_CAST(inst);
return PyCData_get(st, self->proto, self->getfunc, inst,
- self->index, self->size, src->b_ptr + self->offset);
+ self->index, self->size, src->b_ptr + self->offset);
}
static PyObject *
PyCField_get_offset(PyObject *self, void *data)
{
- return PyLong_FromSsize_t(((CFieldObject *)self)->offset);
+ return PyLong_FromSsize_t(_CFieldObject_CAST(self)->offset);
}
static PyObject *
PyCField_get_size(PyObject *self, void *data)
{
- return PyLong_FromSsize_t(((CFieldObject *)self)->size);
+ return PyLong_FromSsize_t(_CFieldObject_CAST(self)->size);
}
static PyGetSetDef PyCField_getset[] = {
@@ -252,17 +254,20 @@ static PyGetSetDef PyCField_getset[] = {
};
static int
-PyCField_traverse(CFieldObject *self, visitproc visit, void *arg)
+PyCField_traverse(PyObject *op, visitproc visit, void *arg)
{
+ CFieldObject *self = _CFieldObject_CAST(op);
Py_VISIT(Py_TYPE(self));
Py_VISIT(self->proto);
return 0;
}
static int
-PyCField_clear(CFieldObject *self)
+PyCField_clear(PyObject *op)
{
+ CFieldObject *self = _CFieldObject_CAST(op);
Py_CLEAR(self->proto);
+ Py_CLEAR(self->name);
return 0;
}
@@ -271,17 +276,16 @@ PyCField_dealloc(PyObject *self)
{
PyTypeObject *tp = Py_TYPE(self);
PyObject_GC_UnTrack(self);
- CFieldObject *self_cf = (CFieldObject *)self;
- (void)PyCField_clear(self_cf);
- Py_CLEAR(self_cf->name);
+ (void)PyCField_clear(self);
Py_TYPE(self)->tp_free(self);
Py_DECREF(tp);
}
static PyObject *
-PyCField_repr(CFieldObject *self)
+PyCField_repr(PyObject *op)
{
PyObject *result;
+ CFieldObject *self = _CFieldObject_CAST(op);
Py_ssize_t bits = NUM_BITS(self->size);
Py_ssize_t size = LOW_BIT(self->size);
const char *name;
diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h
index 9e8097feae2c17..1330754a7e0607 100644
--- a/Modules/_ctypes/ctypes.h
+++ b/Modules/_ctypes/ctypes.h
@@ -121,7 +121,10 @@ extern PyType_Spec cfield_spec;
extern PyType_Spec cthunk_spec;
typedef struct tagPyCArgObject PyCArgObject;
+#define _PyCArgObject_CAST(op) ((PyCArgObject *)(op))
+
typedef struct tagCDataObject CDataObject;
+#define _CDataObject_CAST(op) ((CDataObject *)(op))
// GETFUNC: convert the C value at *ptr* to Python object, return the object
// SETFUNC: write content of the PyObject *value* to the location at *ptr*;
@@ -185,6 +188,8 @@ typedef struct {
ffi_type *ffi_restype;
ffi_type *atypes[1];
} CThunkObject;
+
+#define _CThunkObject_CAST(op) ((CThunkObject *)(op))
#define CThunk_CheckExact(st, v) Py_IS_TYPE(v, st->PyCThunk_Type)
typedef struct {
@@ -218,6 +223,8 @@ typedef struct {
PyObject *paramflags;
} PyCFuncPtrObject;
+#define _PyCFuncPtrObject_CAST(op) ((PyCFuncPtrObject *)(op))
+
extern int PyCStructUnionType_update_stginfo(PyObject *fields, PyObject *type, int isStruct);
extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength);
@@ -281,6 +288,8 @@ typedef struct CFieldObject {
PyObject *name; /* exact PyUnicode */
} CFieldObject;
+#define _CFieldObject_CAST(op) ((CFieldObject *)(op))
+
/****************************************************************
StgInfo
@@ -417,6 +426,8 @@ struct tagPyCArgObject {
Py_ssize_t size; /* for the 'V' tag */
};
+#define _PyCArgObject_CAST(op) ((PyCArgObject *)(op))
+
#define PyCArg_CheckExact(st, v) Py_IS_TYPE(v, st->PyCArg_Type)
extern PyCArgObject *PyCArgObject_new(ctypes_state *st);
@@ -562,8 +573,12 @@ PyStgInfo_Init(ctypes_state *state, PyTypeObject *type)
# define LOCK_PTR(self) Py_BEGIN_CRITICAL_SECTION(self)
# define UNLOCK_PTR(self) Py_END_CRITICAL_SECTION()
#else
-# define LOCK_PTR(self)
-# define UNLOCK_PTR(self)
+/*
+ * Dummy functions instead of macros so that 'self' can be
+ * unused in the caller without triggering a compiler warning.
+ */
+static inline void LOCK_PTR(CDataObject *Py_UNUSED(self)) {}
+static inline void UNLOCK_PTR(CDataObject *Py_UNUSED(self)) {}
#endif
static inline void
1
0
[3.13] gh-118915: C API: Document compiler flag macros (GH-129028) (GH-129086)
by encukou Jan. 21, 2025
by encukou Jan. 21, 2025
Jan. 21, 2025
https://github.com/python/cpython/commit/972d95313cbf8f9bc284d415866afb8bcd…
commit: 972d95313cbf8f9bc284d415866afb8bcdcae4b0
branch: 3.13
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: encukou <encukou(a)gmail.com>
date: 2025-01-21T11:47:55+01:00
summary:
[3.13] gh-118915: C API: Document compiler flag macros (GH-129028) (GH-129086)
(cherry picked from commit 6e02096e2f9a18671d608f79dd61c5757deca4e8)
Co-authored-by: Peter Bierma <zintensitydev(a)gmail.com>
files:
M Doc/c-api/veryhigh.rst
diff --git a/Doc/c-api/veryhigh.rst b/Doc/c-api/veryhigh.rst
index 9f02bdb5896563..1ef4181d52eb10 100644
--- a/Doc/c-api/veryhigh.rst
+++ b/Doc/c-api/veryhigh.rst
@@ -348,8 +348,20 @@ the same library that the Python runtime is using.
.. versionchanged:: 3.8
Added *cf_feature_version* field.
+ The available compiler flags are accessible as macros:
-.. c:var:: int CO_FUTURE_DIVISION
+ .. c:namespace:: NULL
- This bit can be set in *flags* to cause division operator ``/`` to be
- interpreted as "true division" according to :pep:`238`.
+ .. c:macro:: PyCF_ALLOW_TOP_LEVEL_AWAIT
+ PyCF_ONLY_AST
+ PyCF_OPTIMIZED_AST
+ PyCF_TYPE_COMMENTS
+
+ See :ref:`compiler flags <ast-compiler-flags>` in documentation of the
+ :py:mod:`!ast` Python module, which exports these constants under
+ the same names.
+
+ .. c:var:: int CO_FUTURE_DIVISION
+
+ This bit can be set in *flags* to cause division operator ``/`` to be
+ interpreted as "true division" according to :pep:`238`.
1
0
gh-127787: allow retrieving the clipped slice length in `_PyUnicodeError_GetParams` (GH-128980)
by encukou Jan. 21, 2025
by encukou Jan. 21, 2025
Jan. 21, 2025
https://github.com/python/cpython/commit/36f341ca3ecd5f0d54073c6dbfa82b95d8…
commit: 36f341ca3ecd5f0d54073c6dbfa82b95d843cab8
branch: main
author: Bénédikt Tran <10796600+picnixz(a)users.noreply.github.com>
committer: encukou <encukou(a)gmail.com>
date: 2025-01-21T11:45:53+01:00
summary:
gh-127787: allow retrieving the clipped slice length in `_PyUnicodeError_GetParams` (GH-128980)
files:
M Include/internal/pycore_pyerrors.h
M Objects/exceptions.c
diff --git a/Include/internal/pycore_pyerrors.h b/Include/internal/pycore_pyerrors.h
index 8dea2d34117430..fa7d9ee36d095d 100644
--- a/Include/internal/pycore_pyerrors.h
+++ b/Include/internal/pycore_pyerrors.h
@@ -196,9 +196,9 @@ extern int _PyUnicodeError_GetParams(
Py_ssize_t *objlen,
Py_ssize_t *start,
Py_ssize_t *end,
+ Py_ssize_t *slen,
int as_bytes);
-
#ifdef __cplusplus
}
#endif
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index d23b7f7c76c3e7..20fe55d2cc2955 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -2954,8 +2954,10 @@ unicode_error_set_end_impl(PyObject *self, Py_ssize_t end)
* The 'start' can be negative or not, but when adjusting the value,
* we clip it in [0, max(0, objlen - 1)] and do not interpret it as
* a relative offset.
+ *
+ * This function always succeeds.
*/
-static inline Py_ssize_t
+static Py_ssize_t
unicode_error_adjust_start(Py_ssize_t start, Py_ssize_t objlen)
{
assert(objlen >= 0);
@@ -2969,14 +2971,34 @@ unicode_error_adjust_start(Py_ssize_t start, Py_ssize_t objlen)
}
+/* Assert some properties of the adjusted 'start' value. */
+#ifndef NDEBUG
+static void
+assert_adjusted_unicode_error_start(Py_ssize_t start, Py_ssize_t objlen)
+{
+ assert(objlen >= 0);
+ /* in the future, `min_start` may be something else */
+ Py_ssize_t min_start = 0;
+ assert(start >= min_start);
+ /* in the future, `max_start` may be something else */
+ Py_ssize_t max_start = Py_MAX(min_start, objlen - 1);
+ assert(start <= max_start);
+}
+#else
+#define assert_adjusted_unicode_error_start(...)
+#endif
+
+
/*
* Adjust the (exclusive) 'end' value of a UnicodeError object.
*
* The 'end' can be negative or not, but when adjusting the value,
* we clip it in [min(1, objlen), max(min(1, objlen), objlen)] and
* do not interpret it as a relative offset.
+ *
+ * This function always succeeds.
*/
-static inline Py_ssize_t
+static Py_ssize_t
unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen)
{
assert(objlen >= 0);
@@ -2990,6 +3012,59 @@ unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen)
}
+/* Assert some properties of the adjusted 'end' value. */
+#ifndef NDEBUG
+static void
+assert_adjusted_unicode_error_end(Py_ssize_t end, Py_ssize_t objlen)
+{
+ assert(objlen >= 0);
+ /* in the future, `min_end` may be something else */
+ Py_ssize_t min_end = Py_MIN(1, objlen);
+ assert(end >= min_end);
+ /* in the future, `max_end` may be something else */
+ Py_ssize_t max_end = Py_MAX(min_end, objlen);
+ assert(end <= max_end);
+}
+#else
+#define assert_adjusted_unicode_error_end(...)
+#endif
+
+
+/*
+ * Adjust the length of the range described by a UnicodeError object.
+ *
+ * The 'start' and 'end' arguments must have been obtained by
+ * unicode_error_adjust_start() and unicode_error_adjust_end().
+ *
+ * The result is clipped in [0, objlen]. By construction, it
+ * will always be smaller than 'objlen' as 'start' and 'end'
+ * are smaller than 'objlen'.
+ */
+static Py_ssize_t
+unicode_error_adjust_len(Py_ssize_t start, Py_ssize_t end, Py_ssize_t objlen)
+{
+ assert_adjusted_unicode_error_start(start, objlen);
+ assert_adjusted_unicode_error_end(end, objlen);
+ Py_ssize_t ranlen = end - start;
+ assert(ranlen <= objlen);
+ return ranlen < 0 ? 0 : ranlen;
+}
+
+
+/* Assert some properties of the adjusted range 'len' value. */
+#ifndef NDEBUG
+static void
+assert_adjusted_unicode_error_len(Py_ssize_t ranlen, Py_ssize_t objlen)
+{
+ assert(objlen >= 0);
+ assert(ranlen >= 0);
+ assert(ranlen <= objlen);
+}
+#else
+#define assert_adjusted_unicode_error_len(...)
+#endif
+
+
/*
* Get various common parameters of a UnicodeError object.
*
@@ -3004,22 +3079,24 @@ unicode_error_adjust_end(Py_ssize_t end, Py_ssize_t objlen)
* objlen The 'object' length.
* start The clipped 'start' attribute.
* end The clipped 'end' attribute.
+ * slen The length of the slice described by the clipped 'start'
+ * and 'end' values. It always lies in [0, objlen].
*
* An output parameter can be NULL to indicate that
* the corresponding value does not need to be stored.
*
* Input parameter:
*
- * as_bytes If 1, the error's 'object' attribute must be a bytes object,
- * i.e. the call is for a `UnicodeDecodeError`. Otherwise, the
- * 'object' attribute must be a string.
+ * as_bytes If true, the error's 'object' attribute must be a `bytes`,
+ * i.e. 'self' is a `UnicodeDecodeError` instance. Otherwise,
+ * the 'object' attribute must be a string.
*
* A TypeError is raised if the 'object' type is incompatible.
*/
int
_PyUnicodeError_GetParams(PyObject *self,
PyObject **obj, Py_ssize_t *objlen,
- Py_ssize_t *start, Py_ssize_t *end,
+ Py_ssize_t *start, Py_ssize_t *end, Py_ssize_t *slen,
int as_bytes)
{
assert(self != NULL);
@@ -3034,16 +3111,30 @@ _PyUnicodeError_GetParams(PyObject *self,
if (objlen != NULL) {
*objlen = n;
}
+
+ Py_ssize_t start_value = -1;
+ if (start != NULL || slen != NULL) {
+ start_value = unicode_error_adjust_start(exc->start, n);
+ }
if (start != NULL) {
- *start = unicode_error_adjust_start(exc->start, n);
- assert(*start >= 0);
- assert(*start <= n);
+ assert_adjusted_unicode_error_start(start_value, n);
+ *start = start_value;
+ }
+
+ Py_ssize_t end_value = -1;
+ if (end != NULL || slen != NULL) {
+ end_value = unicode_error_adjust_end(exc->end, n);
}
if (end != NULL) {
- *end = unicode_error_adjust_end(exc->end, n);
- assert(*end >= 0);
- assert(*end <= n);
+ assert_adjusted_unicode_error_end(end_value, n);
+ *end = end_value;
+ }
+
+ if (slen != NULL) {
+ *slen = unicode_error_adjust_len(start_value, end_value, n);
+ assert_adjusted_unicode_error_len(*slen, n);
}
+
if (obj != NULL) {
*obj = r;
}
@@ -3111,7 +3202,9 @@ static inline int
unicode_error_get_start_impl(PyObject *self, Py_ssize_t *start, int as_bytes)
{
assert(self != NULL);
- return _PyUnicodeError_GetParams(self, NULL, NULL, start, NULL, as_bytes);
+ return _PyUnicodeError_GetParams(self, NULL, NULL,
+ start, NULL, NULL,
+ as_bytes);
}
@@ -3177,7 +3270,9 @@ static inline int
unicode_error_get_end_impl(PyObject *self, Py_ssize_t *end, int as_bytes)
{
assert(self != NULL);
- return _PyUnicodeError_GetParams(self, NULL, NULL, NULL, end, as_bytes);
+ return _PyUnicodeError_GetParams(self, NULL, NULL,
+ NULL, end, NULL,
+ as_bytes);
}
1
0