aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Tools/clinic/libclinic/converters.py
diff options
context:
space:
mode:
Diffstat (limited to 'Tools/clinic/libclinic/converters.py')
-rw-r--r--Tools/clinic/libclinic/converters.py124
1 files changed, 58 insertions, 66 deletions
diff --git a/Tools/clinic/libclinic/converters.py b/Tools/clinic/libclinic/converters.py
index 633fb5f56a6..39d0ac557a6 100644
--- a/Tools/clinic/libclinic/converters.py
+++ b/Tools/clinic/libclinic/converters.py
@@ -17,6 +17,54 @@ from libclinic.converter import (
TypeSet = set[bltns.type[object]]
+class BaseUnsignedIntConverter(CConverter):
+
+ def use_converter(self) -> None:
+ if self.converter:
+ self.add_include('pycore_long.h',
+ f'{self.converter}()')
+
+ def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
+ if not limited_capi:
+ return super().parse_arg(argname, displayname, limited_capi=limited_capi)
+ return self.format_code("""
+ {{{{
+ Py_ssize_t _bytes = PyLong_AsNativeBytes({argname}, &{paramname}, sizeof({type}),
+ Py_ASNATIVEBYTES_NATIVE_ENDIAN |
+ Py_ASNATIVEBYTES_ALLOW_INDEX |
+ Py_ASNATIVEBYTES_REJECT_NEGATIVE |
+ Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
+ if (_bytes < 0) {{{{
+ goto exit;
+ }}}}
+ if ((size_t)_bytes > sizeof({type})) {{{{
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large for C {type}");
+ goto exit;
+ }}}}
+ }}}}
+ """,
+ argname=argname,
+ type=self.type)
+
+
+class uint8_converter(BaseUnsignedIntConverter):
+ type = "uint8_t"
+ converter = '_PyLong_UInt8_Converter'
+
+class uint16_converter(BaseUnsignedIntConverter):
+ type = "uint16_t"
+ converter = '_PyLong_UInt16_Converter'
+
+class uint32_converter(BaseUnsignedIntConverter):
+ type = "uint32_t"
+ converter = '_PyLong_UInt32_Converter'
+
+class uint64_converter(BaseUnsignedIntConverter):
+ type = "uint64_t"
+ converter = '_PyLong_UInt64_Converter'
+
+
class bool_converter(CConverter):
type = 'int'
default_type = bool
@@ -211,29 +259,7 @@ class short_converter(CConverter):
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
-def format_inline_unsigned_int_converter(self: CConverter, argname: str) -> str:
- return self.format_code("""
- {{{{
- Py_ssize_t _bytes = PyLong_AsNativeBytes({argname}, &{paramname}, sizeof({type}),
- Py_ASNATIVEBYTES_NATIVE_ENDIAN |
- Py_ASNATIVEBYTES_ALLOW_INDEX |
- Py_ASNATIVEBYTES_REJECT_NEGATIVE |
- Py_ASNATIVEBYTES_UNSIGNED_BUFFER);
- if (_bytes < 0) {{{{
- goto exit;
- }}}}
- if ((size_t)_bytes > sizeof({type})) {{{{
- PyErr_SetString(PyExc_OverflowError,
- "Python int too large for C {type}");
- goto exit;
- }}}}
- }}}}
- """,
- argname=argname,
- type=self.type)
-
-
-class unsigned_short_converter(CConverter):
+class unsigned_short_converter(BaseUnsignedIntConverter):
type = 'unsigned short'
default_type = int
c_ignored_default = "0"
@@ -244,11 +270,6 @@ class unsigned_short_converter(CConverter):
else:
self.converter = '_PyLong_UnsignedShort_Converter'
- def use_converter(self) -> None:
- if self.converter == '_PyLong_UnsignedShort_Converter':
- self.add_include('pycore_long.h',
- '_PyLong_UnsignedShort_Converter()')
-
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'H':
return self.format_code("""
@@ -258,9 +279,7 @@ class unsigned_short_converter(CConverter):
}}}}
""",
argname=argname)
- if not limited_capi:
- return super().parse_arg(argname, displayname, limited_capi=limited_capi)
- return format_inline_unsigned_int_converter(self, argname)
+ return super().parse_arg(argname, displayname, limited_capi=limited_capi)
@add_legacy_c_converter('C', accept={str})
@@ -311,7 +330,7 @@ class int_converter(CConverter):
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
-class unsigned_int_converter(CConverter):
+class unsigned_int_converter(BaseUnsignedIntConverter):
type = 'unsigned int'
default_type = int
c_ignored_default = "0"
@@ -322,11 +341,6 @@ class unsigned_int_converter(CConverter):
else:
self.converter = '_PyLong_UnsignedInt_Converter'
- def use_converter(self) -> None:
- if self.converter == '_PyLong_UnsignedInt_Converter':
- self.add_include('pycore_long.h',
- '_PyLong_UnsignedInt_Converter()')
-
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'I':
return self.format_code("""
@@ -336,9 +350,7 @@ class unsigned_int_converter(CConverter):
}}}}
""",
argname=argname)
- if not limited_capi:
- return super().parse_arg(argname, displayname, limited_capi=limited_capi)
- return format_inline_unsigned_int_converter(self, argname)
+ return super().parse_arg(argname, displayname, limited_capi=limited_capi)
class long_converter(CConverter):
@@ -359,7 +371,7 @@ class long_converter(CConverter):
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
-class unsigned_long_converter(CConverter):
+class unsigned_long_converter(BaseUnsignedIntConverter):
type = 'unsigned long'
default_type = int
c_ignored_default = "0"
@@ -370,11 +382,6 @@ class unsigned_long_converter(CConverter):
else:
self.converter = '_PyLong_UnsignedLong_Converter'
- def use_converter(self) -> None:
- if self.converter == '_PyLong_UnsignedLong_Converter':
- self.add_include('pycore_long.h',
- '_PyLong_UnsignedLong_Converter()')
-
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'k':
return self.format_code("""
@@ -387,9 +394,7 @@ class unsigned_long_converter(CConverter):
argname=argname,
bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi),
)
- if not limited_capi:
- return super().parse_arg(argname, displayname, limited_capi=limited_capi)
- return format_inline_unsigned_int_converter(self, argname)
+ return super().parse_arg(argname, displayname, limited_capi=limited_capi)
class long_long_converter(CConverter):
@@ -410,7 +415,7 @@ class long_long_converter(CConverter):
return super().parse_arg(argname, displayname, limited_capi=limited_capi)
-class unsigned_long_long_converter(CConverter):
+class unsigned_long_long_converter(BaseUnsignedIntConverter):
type = 'unsigned long long'
default_type = int
c_ignored_default = "0"
@@ -421,11 +426,6 @@ class unsigned_long_long_converter(CConverter):
else:
self.converter = '_PyLong_UnsignedLongLong_Converter'
- def use_converter(self) -> None:
- if self.converter == '_PyLong_UnsignedLongLong_Converter':
- self.add_include('pycore_long.h',
- '_PyLong_UnsignedLongLong_Converter()')
-
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'K':
return self.format_code("""
@@ -438,9 +438,7 @@ class unsigned_long_long_converter(CConverter):
argname=argname,
bad_argument=self.bad_argument(displayname, 'int', limited_capi=limited_capi),
)
- if not limited_capi:
- return super().parse_arg(argname, displayname, limited_capi=limited_capi)
- return format_inline_unsigned_int_converter(self, argname)
+ return super().parse_arg(argname, displayname, limited_capi=limited_capi)
class Py_ssize_t_converter(CConverter):
@@ -557,15 +555,11 @@ class slice_index_converter(CConverter):
argname=argname)
-class size_t_converter(CConverter):
+class size_t_converter(BaseUnsignedIntConverter):
type = 'size_t'
converter = '_PyLong_Size_t_Converter'
c_ignored_default = "0"
- def use_converter(self) -> None:
- self.add_include('pycore_long.h',
- '_PyLong_Size_t_Converter()')
-
def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> str | None:
if self.format_unit == 'n':
return self.format_code("""
@@ -575,9 +569,7 @@ class size_t_converter(CConverter):
}}}}
""",
argname=argname)
- if not limited_capi:
- return super().parse_arg(argname, displayname, limited_capi=limited_capi)
- return format_inline_unsigned_int_converter(self, argname)
+ return super().parse_arg(argname, displayname, limited_capi=limited_capi)
class fildes_converter(CConverter):