summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErlend E. Aasland <erlend.aasland@protonmail.com>2023-05-17 00:32:11 +0200
committerGitHub <noreply@github.com>2023-05-16 22:32:11 +0000
commit0afc473f500955b85c71725d8ae7d65787db5dd1 (patch)
tree8b0689e81f7c1c571dff73dfb8bebeb91f0035b4
parentb4a974792355cb0f525211b2962679e68949f02e (diff)
downloadcpython-git-0afc473f500955b85c71725d8ae7d65787db5dd1.tar.gz
gh-104050: Add typing to Argument Clinic converters (#104547)
-rwxr-xr-xTools/clinic/clinic.py110
1 files changed, 57 insertions, 53 deletions
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index dfe43c80ef..3e54ba03d7 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -82,6 +82,7 @@ sig_end_marker = '--'
Appender = Callable[[str], None]
Outputter = Callable[[], str]
+TemplateDict = dict[str, str]
class _TextAccumulator(NamedTuple):
text: list[str]
@@ -1971,20 +1972,6 @@ extensions['py'] = PythonLanguage
# maps strings to callables.
# these callables must be of the form:
-# def foo(name, default, *, ...)
-# The callable may have any number of keyword-only parameters.
-# The callable must return a CConverter object.
-# The callable should not call builtins.print.
-converters = {}
-
-# maps strings to callables.
-# these callables follow the same rules as those for "converters" above.
-# note however that they will never be called with keyword-only parameters.
-legacy_converters = {}
-
-
-# maps strings to callables.
-# these callables must be of the form:
# def foo(*, ...)
# The callable may have any number of keyword-only parameters.
# The callable must return a CConverter object.
@@ -2956,7 +2943,7 @@ class CConverter(metaclass=CConverterAutoRegister):
""".format(argname=argname, paramname=self.parser_name, cast=cast)
return None
- def set_template_dict(self, template_dict: dict[str, str]):
+ def set_template_dict(self, template_dict: TemplateDict) -> None:
pass
@property
@@ -2979,6 +2966,23 @@ type_checks = {
}
+ConverterType = Callable[..., CConverter]
+ConverterDict = dict[str, ConverterType]
+
+# maps strings to callables.
+# these callables must be of the form:
+# def foo(name, default, *, ...)
+# The callable may have any number of keyword-only parameters.
+# The callable must return a CConverter object.
+# The callable should not call builtins.print.
+converters: ConverterDict = {}
+
+# maps strings to callables.
+# these callables follow the same rules as those for "converters" above.
+# note however that they will never be called with keyword-only parameters.
+legacy_converters: ConverterDict = {}
+
+
class bool_converter(CConverter):
type = 'int'
default_type = bool
@@ -2994,7 +2998,7 @@ class bool_converter(CConverter):
self.default = bool(self.default)
self.c_default = str(int(self.default))
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'i':
return """
{paramname} = _PyLong_AsInt({argname});
@@ -3020,10 +3024,10 @@ class defining_class_converter(CConverter):
format_unit = ''
show_in_signature = False
- def converter_init(self, *, type=None):
+ def converter_init(self, *, type=None) -> None:
self.specified_type = type
- def render(self, parameter, data):
+ def render(self, parameter, data) -> None:
self._render_self(parameter, data)
def set_template_dict(self, template_dict):
@@ -3036,7 +3040,7 @@ class char_converter(CConverter):
format_unit = 'c'
c_ignored_default = "'\0'"
- def converter_init(self):
+ def converter_init(self) -> None:
if isinstance(self.default, self.default_type):
if len(self.default) != 1:
fail("char_converter: illegal default value " + repr(self.default))
@@ -3045,7 +3049,7 @@ class char_converter(CConverter):
if self.c_default == '"\'"':
self.c_default = r"'\''"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'c':
return """
if (PyBytes_Check({argname}) && PyBytes_GET_SIZE({argname}) == 1) {{{{
@@ -3070,11 +3074,11 @@ class unsigned_char_converter(CConverter):
format_unit = 'b'
c_ignored_default = "'\0'"
- def converter_init(self, *, bitwise=False):
+ def converter_init(self, *, bitwise: bool = False) -> None:
if bitwise:
self.format_unit = 'B'
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'b':
return """
{{{{
@@ -3119,7 +3123,7 @@ class short_converter(CConverter):
format_unit = 'h'
c_ignored_default = "0"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'h':
return """
{{{{
@@ -3149,13 +3153,13 @@ class unsigned_short_converter(CConverter):
default_type = int
c_ignored_default = "0"
- def converter_init(self, *, bitwise=False):
+ def converter_init(self, *, bitwise: bool = False) -> None:
if bitwise:
self.format_unit = 'H'
else:
self.converter = '_PyLong_UnsignedShort_Converter'
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'H':
return """
{paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname});
@@ -3172,7 +3176,7 @@ class int_converter(CConverter):
format_unit = 'i'
c_ignored_default = "0"
- def converter_init(self, *, accept={int}, type=None):
+ def converter_init(self, *, accept={int}, type=None) -> None:
if accept == {str}:
self.format_unit = 'C'
elif accept != {int}:
@@ -3180,7 +3184,7 @@ class int_converter(CConverter):
if type is not None:
self.type = type
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'i':
return """
{paramname} = _PyLong_AsInt({argname});
@@ -3211,13 +3215,13 @@ class unsigned_int_converter(CConverter):
default_type = int
c_ignored_default = "0"
- def converter_init(self, *, bitwise=False):
+ def converter_init(self, *, bitwise: bool = False) -> None:
if bitwise:
self.format_unit = 'I'
else:
self.converter = '_PyLong_UnsignedInt_Converter'
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'I':
return """
{paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname});
@@ -3233,7 +3237,7 @@ class long_converter(CConverter):
format_unit = 'l'
c_ignored_default = "0"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'l':
return """
{paramname} = PyLong_AsLong({argname});
@@ -3248,13 +3252,13 @@ class unsigned_long_converter(CConverter):
default_type = int
c_ignored_default = "0"
- def converter_init(self, *, bitwise=False):
+ def converter_init(self, *, bitwise: bool = False) -> None:
if bitwise:
self.format_unit = 'k'
else:
self.converter = '_PyLong_UnsignedLong_Converter'
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'k':
return """
if (!PyLong_Check({argname})) {{{{
@@ -3272,7 +3276,7 @@ class long_long_converter(CConverter):
format_unit = 'L'
c_ignored_default = "0"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'L':
return """
{paramname} = PyLong_AsLongLong({argname});
@@ -3287,13 +3291,13 @@ class unsigned_long_long_converter(CConverter):
default_type = int
c_ignored_default = "0"
- def converter_init(self, *, bitwise=False):
+ def converter_init(self, *, bitwise: bool = False) -> None:
if bitwise:
self.format_unit = 'K'
else:
self.converter = '_PyLong_UnsignedLongLong_Converter'
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'K':
return """
if (!PyLong_Check({argname})) {{{{
@@ -3309,7 +3313,7 @@ class Py_ssize_t_converter(CConverter):
type = 'Py_ssize_t'
c_ignored_default = "0"
- def converter_init(self, *, accept={int}):
+ def converter_init(self, *, accept={int}) -> None:
if accept == {int}:
self.format_unit = 'n'
self.default_type = int
@@ -3318,7 +3322,7 @@ class Py_ssize_t_converter(CConverter):
else:
fail("Py_ssize_t_converter: illegal 'accept' argument " + repr(accept))
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'n':
return """
{{{{
@@ -3340,7 +3344,7 @@ class Py_ssize_t_converter(CConverter):
class slice_index_converter(CConverter):
type = 'Py_ssize_t'
- def converter_init(self, *, accept={int, NoneType}):
+ def converter_init(self, *, accept={int, NoneType}) -> None:
if accept == {int}:
self.converter = '_PyEval_SliceIndexNotNone'
elif accept == {int, NoneType}:
@@ -3353,7 +3357,7 @@ class size_t_converter(CConverter):
converter = '_PyLong_Size_t_Converter'
c_ignored_default = "0"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'n':
return """
{paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError);
@@ -3368,7 +3372,7 @@ class fildes_converter(CConverter):
type = 'int'
converter = '_PyLong_FileDescriptor_Converter'
- def _parse_arg(self, argname, displayname):
+ def _parse_arg(self, argname: str, displayname: str) -> str:
return """
{paramname} = PyObject_AsFileDescriptor({argname});
if ({paramname} == -1) {{{{
@@ -3383,7 +3387,7 @@ class float_converter(CConverter):
format_unit = 'f'
c_ignored_default = "0.0"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'f':
return """
if (PyFloat_CheckExact({argname})) {{{{
@@ -3405,7 +3409,7 @@ class double_converter(CConverter):
format_unit = 'd'
c_ignored_default = "0.0"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'd':
return """
if (PyFloat_CheckExact({argname})) {{{{
@@ -3428,7 +3432,7 @@ class Py_complex_converter(CConverter):
format_unit = 'D'
c_ignored_default = "{0.0, 0.0}"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'D':
return """
{paramname} = PyComplex_AsCComplex({argname});
@@ -3504,7 +3508,7 @@ class str_converter(CConverter):
name = self.name
return f"PyMem_FREE({name});\n"
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 's':
return """
if (!PyUnicode_Check({argname})) {{{{
@@ -3599,7 +3603,7 @@ class PyBytesObject_converter(CConverter):
format_unit = 'S'
# accept = {bytes}
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'S':
return """
if (!PyBytes_Check({argname})) {{{{
@@ -3616,7 +3620,7 @@ class PyByteArrayObject_converter(CConverter):
format_unit = 'Y'
# accept = {bytearray}
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'Y':
return """
if (!PyByteArray_Check({argname})) {{{{
@@ -3633,7 +3637,7 @@ class unicode_converter(CConverter):
default_type = (str, Null, NoneType)
format_unit = 'U'
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'U':
return """
if (!PyUnicode_Check({argname})) {{{{
@@ -3656,7 +3660,7 @@ class Py_UNICODE_converter(CConverter):
type = 'const Py_UNICODE *'
default_type = (str, Null, NoneType)
- def converter_init(self, *, accept={str}, zeroes=False):
+ def converter_init(self, *, accept={str}, zeroes: bool = False) -> None:
format_unit = 'Z' if accept=={str, NoneType} else 'u'
if zeroes:
format_unit += '#'
@@ -3678,7 +3682,7 @@ class Py_UNICODE_converter(CConverter):
PyMem_Free((void *){name});
""".format(name=self.name)
- def parse_arg(self, argname, argnum):
+ def parse_arg(self, argname: str, argnum: str) -> str:
if not self.length:
if self.accept == {str}:
return """
@@ -3718,7 +3722,7 @@ class Py_buffer_converter(CConverter):
impl_by_reference = True
c_ignored_default = "{NULL, NULL}"
- def converter_init(self, *, accept={buffer}):
+ def converter_init(self, *, accept={buffer}) -> None:
if self.default not in (unspecified, None):
fail("The only legal default value for Py_buffer is None.")
@@ -3741,7 +3745,7 @@ class Py_buffer_converter(CConverter):
name = self.name
return "".join(["if (", name, ".obj) {\n PyBuffer_Release(&", name, ");\n}\n"])
- def parse_arg(self, argname, displayname):
+ def parse_arg(self, argname: str, displayname: str) -> str:
if self.format_unit == 'y*':
return """
if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{
@@ -3790,7 +3794,7 @@ class Py_buffer_converter(CConverter):
return super().parse_arg(argname, displayname)
-def correct_name_for_self(f):
+def correct_name_for_self(f) -> tuple[str, str]:
if f.kind in (CALLABLE, METHOD_INIT):
if f.cls:
return "PyObject *", "self"
@@ -3816,7 +3820,7 @@ class self_converter(CConverter):
type = None
format_unit = ''
- def converter_init(self, *, type=None):
+ def converter_init(self, *, type=None) -> None:
self.specified_type = type
def pre_render(self):