1#!/usr/bin/env python3
2#
3# Argument Clinic
4# Copyright 2012-2013 by Larry Hastings.
5# Licensed to the PSF under a contributor agreement.
6#
7
8import abc
9import ast
10import collections
11import contextlib
12import copy
13import cpp
14import functools
15import hashlib
16import inspect
17import io
18import itertools
19import os
20import pprint
21import re
22import shlex
23import string
24import sys
25import tempfile
26import textwrap
27import traceback
28import types
29
30from types import *
31NoneType = type(None)
32
33# TODO:
34#
35# soon:
36#
37# * allow mixing any two of {positional-only, positional-or-keyword,
38#   keyword-only}
39#       * dict constructor uses positional-only and keyword-only
40#       * max and min use positional only with an optional group
41#         and keyword-only
42#
43
44version = '1'
45
46NoneType = type(None)
47NO_VARARG = "PY_SSIZE_T_MAX"
48CLINIC_PREFIX = "__clinic_"
49CLINIC_PREFIXED_ARGS = {"args"}
50
51class Unspecified:
52    def __repr__(self):
53        return '<Unspecified>'
54
55unspecified = Unspecified()
56
57
58class Null:
59    def __repr__(self):
60        return '<Null>'
61
62NULL = Null()
63
64
65class Unknown:
66    def __repr__(self):
67        return '<Unknown>'
68
69unknown = Unknown()
70
71sig_end_marker = '--'
72
73
74_text_accumulator_nt = collections.namedtuple("_text_accumulator", "text append output")
75
76def _text_accumulator():
77    text = []
78    def output():
79        s = ''.join(text)
80        text.clear()
81        return s
82    return _text_accumulator_nt(text, text.append, output)
83
84
85text_accumulator_nt = collections.namedtuple("text_accumulator", "text append")
86
87def text_accumulator():
88    """
89    Creates a simple text accumulator / joiner.
90
91    Returns a pair of callables:
92        append, output
93    "append" appends a string to the accumulator.
94    "output" returns the contents of the accumulator
95       joined together (''.join(accumulator)) and
96       empties the accumulator.
97    """
98    text, append, output = _text_accumulator()
99    return text_accumulator_nt(append, output)
100
101
102def warn_or_fail(fail=False, *args, filename=None, line_number=None):
103    joined = " ".join([str(a) for a in args])
104    add, output = text_accumulator()
105    if fail:
106        add("Error")
107    else:
108        add("Warning")
109    if clinic:
110        if filename is None:
111            filename = clinic.filename
112        if getattr(clinic, 'block_parser', None) and (line_number is None):
113            line_number = clinic.block_parser.line_number
114    if filename is not None:
115        add(' in file "' + filename + '"')
116    if line_number is not None:
117        add(" on line " + str(line_number))
118    add(':\n')
119    add(joined)
120    print(output())
121    if fail:
122        sys.exit(-1)
123
124
125def warn(*args, filename=None, line_number=None):
126    return warn_or_fail(False, *args, filename=filename, line_number=line_number)
127
128def fail(*args, filename=None, line_number=None):
129    return warn_or_fail(True, *args, filename=filename, line_number=line_number)
130
131
132def quoted_for_c_string(s):
133    for old, new in (
134        ('\\', '\\\\'), # must be first!
135        ('"', '\\"'),
136        ("'", "\\'"),
137        ):
138        s = s.replace(old, new)
139    return s
140
141def c_repr(s):
142    return '"' + s + '"'
143
144
145is_legal_c_identifier = re.compile('^[A-Za-z_][A-Za-z0-9_]*$').match
146
147def is_legal_py_identifier(s):
148    return all(is_legal_c_identifier(field) for field in s.split('.'))
149
150# identifiers that are okay in Python but aren't a good idea in C.
151# so if they're used Argument Clinic will add "_value" to the end
152# of the name in C.
153c_keywords = set("""
154asm auto break case char const continue default do double
155else enum extern float for goto if inline int long
156register return short signed sizeof static struct switch
157typedef typeof union unsigned void volatile while
158""".strip().split())
159
160def ensure_legal_c_identifier(s):
161    # for now, just complain if what we're given isn't legal
162    if not is_legal_c_identifier(s):
163        fail("Illegal C identifier: {}".format(s))
164    # but if we picked a C keyword, pick something else
165    if s in c_keywords:
166        return s + "_value"
167    return s
168
169def rstrip_lines(s):
170    text, add, output = _text_accumulator()
171    for line in s.split('\n'):
172        add(line.rstrip())
173        add('\n')
174    text.pop()
175    return output()
176
177def format_escape(s):
178    # double up curly-braces, this string will be used
179    # as part of a format_map() template later
180    s = s.replace('{', '{{')
181    s = s.replace('}', '}}')
182    return s
183
184def linear_format(s, **kwargs):
185    """
186    Perform str.format-like substitution, except:
187      * The strings substituted must be on lines by
188        themselves.  (This line is the "source line".)
189      * If the substitution text is empty, the source line
190        is removed in the output.
191      * If the field is not recognized, the original line
192        is passed unmodified through to the output.
193      * If the substitution text is not empty:
194          * Each line of the substituted text is indented
195            by the indent of the source line.
196          * A newline will be added to the end.
197    """
198
199    add, output = text_accumulator()
200    for line in s.split('\n'):
201        indent, curly, trailing = line.partition('{')
202        if not curly:
203            add(line)
204            add('\n')
205            continue
206
207        name, curly, trailing = trailing.partition('}')
208        if not curly or name not in kwargs:
209            add(line)
210            add('\n')
211            continue
212
213        if trailing:
214            fail("Text found after {" + name + "} block marker!  It must be on a line by itself.")
215        if indent.strip():
216            fail("Non-whitespace characters found before {" + name + "} block marker!  It must be on a line by itself.")
217
218        value = kwargs[name]
219        if not value:
220            continue
221
222        value = textwrap.indent(rstrip_lines(value), indent)
223        add(value)
224        add('\n')
225
226    return output()[:-1]
227
228def indent_all_lines(s, prefix):
229    """
230    Returns 's', with 'prefix' prepended to all lines.
231
232    If the last line is empty, prefix is not prepended
233    to it.  (If s is blank, returns s unchanged.)
234
235    (textwrap.indent only adds to non-blank lines.)
236    """
237    split = s.split('\n')
238    last = split.pop()
239    final = []
240    for line in split:
241        final.append(prefix)
242        final.append(line)
243        final.append('\n')
244    if last:
245        final.append(prefix)
246        final.append(last)
247    return ''.join(final)
248
249def suffix_all_lines(s, suffix):
250    """
251    Returns 's', with 'suffix' appended to all lines.
252
253    If the last line is empty, suffix is not appended
254    to it.  (If s is blank, returns s unchanged.)
255    """
256    split = s.split('\n')
257    last = split.pop()
258    final = []
259    for line in split:
260        final.append(line)
261        final.append(suffix)
262        final.append('\n')
263    if last:
264        final.append(last)
265        final.append(suffix)
266    return ''.join(final)
267
268
269def version_splitter(s):
270    """Splits a version string into a tuple of integers.
271
272    The following ASCII characters are allowed, and employ
273    the following conversions:
274        a -> -3
275        b -> -2
276        c -> -1
277    (This permits Python-style version strings such as "1.4b3".)
278    """
279    version = []
280    accumulator = []
281    def flush():
282        if not accumulator:
283            raise ValueError('Unsupported version string: ' + repr(s))
284        version.append(int(''.join(accumulator)))
285        accumulator.clear()
286
287    for c in s:
288        if c.isdigit():
289            accumulator.append(c)
290        elif c == '.':
291            flush()
292        elif c in 'abc':
293            flush()
294            version.append('abc'.index(c) - 3)
295        else:
296            raise ValueError('Illegal character ' + repr(c) + ' in version string ' + repr(s))
297    flush()
298    return tuple(version)
299
300def version_comparitor(version1, version2):
301    iterator = itertools.zip_longest(version_splitter(version1), version_splitter(version2), fillvalue=0)
302    for i, (a, b) in enumerate(iterator):
303        if a < b:
304            return -1
305        if a > b:
306            return 1
307    return 0
308
309
310class CRenderData:
311    def __init__(self):
312
313        # The C statements to declare variables.
314        # Should be full lines with \n eol characters.
315        self.declarations = []
316
317        # The C statements required to initialize the variables before the parse call.
318        # Should be full lines with \n eol characters.
319        self.initializers = []
320
321        # The C statements needed to dynamically modify the values
322        # parsed by the parse call, before calling the impl.
323        self.modifications = []
324
325        # The entries for the "keywords" array for PyArg_ParseTuple.
326        # Should be individual strings representing the names.
327        self.keywords = []
328
329        # The "format units" for PyArg_ParseTuple.
330        # Should be individual strings that will get
331        self.format_units = []
332
333        # The varargs arguments for PyArg_ParseTuple.
334        self.parse_arguments = []
335
336        # The parameter declarations for the impl function.
337        self.impl_parameters = []
338
339        # The arguments to the impl function at the time it's called.
340        self.impl_arguments = []
341
342        # For return converters: the name of the variable that
343        # should receive the value returned by the impl.
344        self.return_value = "return_value"
345
346        # For return converters: the code to convert the return
347        # value from the parse function.  This is also where
348        # you should check the _return_value for errors, and
349        # "goto exit" if there are any.
350        self.return_conversion = []
351
352        # The C statements required to do some operations
353        # after the end of parsing but before cleaning up.
354        # These operations may be, for example, memory deallocations which
355        # can only be done without any error happening during argument parsing.
356        self.post_parsing = []
357
358        # The C statements required to clean up after the impl call.
359        self.cleanup = []
360
361
362class FormatCounterFormatter(string.Formatter):
363    """
364    This counts how many instances of each formatter
365    "replacement string" appear in the format string.
366
367    e.g. after evaluating "string {a}, {b}, {c}, {a}"
368         the counts dict would now look like
369         {'a': 2, 'b': 1, 'c': 1}
370    """
371    def __init__(self):
372        self.counts = collections.Counter()
373
374    def get_value(self, key, args, kwargs):
375        self.counts[key] += 1
376        return ''
377
378class Language(metaclass=abc.ABCMeta):
379
380    start_line = ""
381    body_prefix = ""
382    stop_line = ""
383    checksum_line = ""
384
385    def __init__(self, filename):
386        pass
387
388    @abc.abstractmethod
389    def render(self, clinic, signatures):
390        pass
391
392    def parse_line(self, line):
393        pass
394
395    def validate(self):
396        def assert_only_one(attr, *additional_fields):
397            """
398            Ensures that the string found at getattr(self, attr)
399            contains exactly one formatter replacement string for
400            each valid field.  The list of valid fields is
401            ['dsl_name'] extended by additional_fields.
402
403            e.g.
404                self.fmt = "{dsl_name} {a} {b}"
405
406                # this passes
407                self.assert_only_one('fmt', 'a', 'b')
408
409                # this fails, the format string has a {b} in it
410                self.assert_only_one('fmt', 'a')
411
412                # this fails, the format string doesn't have a {c} in it
413                self.assert_only_one('fmt', 'a', 'b', 'c')
414
415                # this fails, the format string has two {a}s in it,
416                # it must contain exactly one
417                self.fmt2 = '{dsl_name} {a} {a}'
418                self.assert_only_one('fmt2', 'a')
419
420            """
421            fields = ['dsl_name']
422            fields.extend(additional_fields)
423            line = getattr(self, attr)
424            fcf = FormatCounterFormatter()
425            fcf.format(line)
426            def local_fail(should_be_there_but_isnt):
427                if should_be_there_but_isnt:
428                    fail("{} {} must contain {{{}}} exactly once!".format(
429                        self.__class__.__name__, attr, name))
430                else:
431                    fail("{} {} must not contain {{{}}}!".format(
432                        self.__class__.__name__, attr, name))
433
434            for name, count in fcf.counts.items():
435                if name in fields:
436                    if count > 1:
437                        local_fail(True)
438                else:
439                    local_fail(False)
440            for name in fields:
441                if fcf.counts.get(name) != 1:
442                    local_fail(True)
443
444        assert_only_one('start_line')
445        assert_only_one('stop_line')
446
447        field = "arguments" if "{arguments}" in self.checksum_line else "checksum"
448        assert_only_one('checksum_line', field)
449
450
451
452class PythonLanguage(Language):
453
454    language      = 'Python'
455    start_line    = "#/*[{dsl_name} input]"
456    body_prefix   = "#"
457    stop_line     = "#[{dsl_name} start generated code]*/"
458    checksum_line = "#/*[{dsl_name} end generated code: {arguments}]*/"
459
460
461def permute_left_option_groups(l):
462    """
463    Given [1, 2, 3], should yield:
464       ()
465       (3,)
466       (2, 3)
467       (1, 2, 3)
468    """
469    yield tuple()
470    accumulator = []
471    for group in reversed(l):
472        accumulator = list(group) + accumulator
473        yield tuple(accumulator)
474
475
476def permute_right_option_groups(l):
477    """
478    Given [1, 2, 3], should yield:
479      ()
480      (1,)
481      (1, 2)
482      (1, 2, 3)
483    """
484    yield tuple()
485    accumulator = []
486    for group in l:
487        accumulator.extend(group)
488        yield tuple(accumulator)
489
490
491def permute_optional_groups(left, required, right):
492    """
493    Generator function that computes the set of acceptable
494    argument lists for the provided iterables of
495    argument groups.  (Actually it generates a tuple of tuples.)
496
497    Algorithm: prefer left options over right options.
498
499    If required is empty, left must also be empty.
500    """
501    required = tuple(required)
502    result = []
503
504    if not required:
505        assert not left
506
507    accumulator = []
508    counts = set()
509    for r in permute_right_option_groups(right):
510        for l in permute_left_option_groups(left):
511            t = l + required + r
512            if len(t) in counts:
513                continue
514            counts.add(len(t))
515            accumulator.append(t)
516
517    accumulator.sort(key=len)
518    return tuple(accumulator)
519
520
521def strip_leading_and_trailing_blank_lines(s):
522    lines = s.rstrip().split('\n')
523    while lines:
524        line = lines[0]
525        if line.strip():
526            break
527        del lines[0]
528    return '\n'.join(lines)
529
530@functools.lru_cache()
531def normalize_snippet(s, *, indent=0):
532    """
533    Reformats s:
534        * removes leading and trailing blank lines
535        * ensures that it does not end with a newline
536        * dedents so the first nonwhite character on any line is at column "indent"
537    """
538    s = strip_leading_and_trailing_blank_lines(s)
539    s = textwrap.dedent(s)
540    if indent:
541        s = textwrap.indent(s, ' ' * indent)
542    return s
543
544
545def wrap_declarations(text, length=78):
546    """
547    A simple-minded text wrapper for C function declarations.
548
549    It views a declaration line as looking like this:
550        xxxxxxxx(xxxxxxxxx,xxxxxxxxx)
551    If called with length=30, it would wrap that line into
552        xxxxxxxx(xxxxxxxxx,
553                 xxxxxxxxx)
554    (If the declaration has zero or one parameters, this
555    function won't wrap it.)
556
557    If this doesn't work properly, it's probably better to
558    start from scratch with a more sophisticated algorithm,
559    rather than try and improve/debug this dumb little function.
560    """
561    lines = []
562    for line in text.split('\n'):
563        prefix, _, after_l_paren = line.partition('(')
564        if not after_l_paren:
565            lines.append(line)
566            continue
567        parameters, _, after_r_paren = after_l_paren.partition(')')
568        if not _:
569            lines.append(line)
570            continue
571        if ',' not in parameters:
572            lines.append(line)
573            continue
574        parameters = [x.strip() + ", " for x in parameters.split(',')]
575        prefix += "("
576        if len(prefix) < length:
577            spaces = " " * len(prefix)
578        else:
579            spaces = " " * 4
580
581        while parameters:
582            line = prefix
583            first = True
584            while parameters:
585                if (not first and
586                    (len(line) + len(parameters[0]) > length)):
587                    break
588                line += parameters.pop(0)
589                first = False
590            if not parameters:
591                line = line.rstrip(", ") + ")" + after_r_paren
592            lines.append(line.rstrip())
593            prefix = spaces
594    return "\n".join(lines)
595
596
597class CLanguage(Language):
598
599    body_prefix   = "#"
600    language      = 'C'
601    start_line    = "/*[{dsl_name} input]"
602    body_prefix   = ""
603    stop_line     = "[{dsl_name} start generated code]*/"
604    checksum_line = "/*[{dsl_name} end generated code: {arguments}]*/"
605
606    def __init__(self, filename):
607        super().__init__(filename)
608        self.cpp = cpp.Monitor(filename)
609        self.cpp.fail = fail
610
611    def parse_line(self, line):
612        self.cpp.writeline(line)
613
614    def render(self, clinic, signatures):
615        function = None
616        for o in signatures:
617            if isinstance(o, Function):
618                if function:
619                    fail("You may specify at most one function per block.\nFound a block containing at least two:\n\t" + repr(function) + " and " + repr(o))
620                function = o
621        return self.render_function(clinic, function)
622
623    def docstring_for_c_string(self, f):
624        if re.search(r'[^\x00-\x7F]', f.docstring):
625            warn("Non-ascii character appear in docstring.")
626
627        text, add, output = _text_accumulator()
628        # turn docstring into a properly quoted C string
629        for line in f.docstring.split('\n'):
630            add('"')
631            add(quoted_for_c_string(line))
632            add('\\n"\n')
633
634        if text[-2] == sig_end_marker:
635            # If we only have a signature, add the blank line that the
636            # __text_signature__ getter expects to be there.
637            add('"\\n"')
638        else:
639            text.pop()
640            add('"')
641        return ''.join(text)
642
643    def output_templates(self, f):
644        parameters = list(f.parameters.values())
645        assert parameters
646        assert isinstance(parameters[0].converter, self_converter)
647        del parameters[0]
648        requires_defining_class = False
649        if parameters and isinstance(parameters[0].converter, defining_class_converter):
650            requires_defining_class = True
651            del parameters[0]
652        converters = [p.converter for p in parameters]
653
654        has_option_groups = parameters and (parameters[0].group or parameters[-1].group)
655        default_return_converter = (not f.return_converter or
656            f.return_converter.type == 'PyObject *')
657
658        new_or_init = f.kind in (METHOD_NEW, METHOD_INIT)
659
660        vararg = NO_VARARG
661        pos_only = min_pos = max_pos = min_kw_only = pseudo_args = 0
662        for i, p in enumerate(parameters, 1):
663            if p.is_keyword_only():
664                assert not p.is_positional_only()
665                if not p.is_optional():
666                    min_kw_only = i - max_pos
667            elif p.is_vararg():
668                if vararg != NO_VARARG:
669                    fail("Too many var args")
670                pseudo_args += 1
671                vararg = i - 1
672            else:
673                if vararg == NO_VARARG:
674                    max_pos = i
675                if p.is_positional_only():
676                    pos_only = i
677                if not p.is_optional():
678                    min_pos = i
679
680        meth_o = (len(parameters) == 1 and
681              parameters[0].is_positional_only() and
682              not converters[0].is_optional() and
683              not requires_defining_class and
684              not new_or_init)
685
686        # we have to set these things before we're done:
687        #
688        # docstring_prototype
689        # docstring_definition
690        # impl_prototype
691        # methoddef_define
692        # parser_prototype
693        # parser_definition
694        # impl_definition
695        # cpp_if
696        # cpp_endif
697        # methoddef_ifndef
698
699        return_value_declaration = "PyObject *return_value = NULL;"
700
701        methoddef_define = normalize_snippet("""
702            #define {methoddef_name}    \\
703                {{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}},
704            """)
705        if new_or_init and not f.docstring:
706            docstring_prototype = docstring_definition = ''
707        else:
708            docstring_prototype = normalize_snippet("""
709                PyDoc_VAR({c_basename}__doc__);
710                """)
711            docstring_definition = normalize_snippet("""
712                PyDoc_STRVAR({c_basename}__doc__,
713                {docstring});
714                """)
715        impl_definition = normalize_snippet("""
716            static {impl_return_type}
717            {c_basename}_impl({impl_parameters})
718            """)
719        impl_prototype = parser_prototype = parser_definition = None
720
721        parser_prototype_keyword = normalize_snippet("""
722            static PyObject *
723            {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs)
724            """)
725
726        parser_prototype_varargs = normalize_snippet("""
727            static PyObject *
728            {c_basename}({self_type}{self_name}, PyObject *args)
729            """)
730
731        parser_prototype_fastcall = normalize_snippet("""
732            static PyObject *
733            {c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs)
734            """)
735
736        parser_prototype_fastcall_keywords = normalize_snippet("""
737            static PyObject *
738            {c_basename}({self_type}{self_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
739            """)
740
741        parser_prototype_def_class = normalize_snippet("""
742            static PyObject *
743            {c_basename}({self_type}{self_name}, PyTypeObject *{defining_class_name}, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
744        """)
745
746        # parser_body_fields remembers the fields passed in to the
747        # previous call to parser_body. this is used for an awful hack.
748        parser_body_fields = ()
749        parser_body_declarations = ''
750        def parser_body(prototype, *fields, declarations=''):
751            nonlocal parser_body_fields, parser_body_declarations
752            add, output = text_accumulator()
753            add(prototype)
754            parser_body_fields = fields
755            parser_body_declarations = declarations
756
757            fields = list(fields)
758            fields.insert(0, normalize_snippet("""
759                {{
760                    {return_value_declaration}
761                    {parser_declarations}
762                    {declarations}
763                    {initializers}
764                """) + "\n")
765            # just imagine--your code is here in the middle
766            fields.append(normalize_snippet("""
767                    {modifications}
768                    {return_value} = {c_basename}_impl({impl_arguments});
769                    {return_conversion}
770                    {post_parsing}
771
772                {exit_label}
773                    {cleanup}
774                    return return_value;
775                }}
776                """))
777            for field in fields:
778                add('\n')
779                add(field)
780            return linear_format(output(), parser_declarations=declarations)
781
782        if not parameters:
783            if not requires_defining_class:
784                # no parameters, METH_NOARGS
785                flags = "METH_NOARGS"
786
787                parser_prototype = normalize_snippet("""
788                    static PyObject *
789                    {c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored))
790                    """)
791                parser_code = []
792
793            else:
794                assert not new_or_init
795
796                flags = "METH_METHOD|METH_FASTCALL|METH_KEYWORDS"
797
798                parser_prototype = parser_prototype_def_class
799                return_error = ('return NULL;' if default_return_converter
800                                else 'goto exit;')
801                parser_code = [normalize_snippet("""
802                    if (nargs) {{
803                        PyErr_SetString(PyExc_TypeError, "{name}() takes no arguments");
804                        %s
805                    }}
806                    """ % return_error, indent=4)]
807
808            if default_return_converter:
809                parser_definition = '\n'.join([
810                    parser_prototype,
811                    '{{',
812                    *parser_code,
813                    '    return {c_basename}_impl({impl_arguments});',
814                    '}}'])
815            else:
816                parser_definition = parser_body(parser_prototype, *parser_code)
817
818        elif meth_o:
819            flags = "METH_O"
820
821            if (isinstance(converters[0], object_converter) and
822                converters[0].format_unit == 'O'):
823                meth_o_prototype = normalize_snippet("""
824                    static PyObject *
825                    {c_basename}({impl_parameters})
826                    """)
827
828                if default_return_converter:
829                    # maps perfectly to METH_O, doesn't need a return converter.
830                    # so we skip making a parse function
831                    # and call directly into the impl function.
832                    impl_prototype = parser_prototype = parser_definition = ''
833                    impl_definition = meth_o_prototype
834                else:
835                    # SLIGHT HACK
836                    # use impl_parameters for the parser here!
837                    parser_prototype = meth_o_prototype
838                    parser_definition = parser_body(parser_prototype)
839
840            else:
841                argname = 'arg'
842                if parameters[0].name == argname:
843                    argname += '_'
844                parser_prototype = normalize_snippet("""
845                    static PyObject *
846                    {c_basename}({self_type}{self_name}, PyObject *%s)
847                    """ % argname)
848
849                displayname = parameters[0].get_displayname(0)
850                parsearg = converters[0].parse_arg(argname, displayname)
851                if parsearg is None:
852                    parsearg = """
853                        if (!PyArg_Parse(%s, "{format_units}:{name}", {parse_arguments})) {{
854                            goto exit;
855                        }}
856                        """ % argname
857                parser_definition = parser_body(parser_prototype,
858                                                normalize_snippet(parsearg, indent=4))
859
860        elif has_option_groups:
861            # positional parameters with option groups
862            # (we have to generate lots of PyArg_ParseTuple calls
863            #  in a big switch statement)
864
865            flags = "METH_VARARGS"
866            parser_prototype = parser_prototype_varargs
867
868            parser_definition = parser_body(parser_prototype, '    {option_group_parsing}')
869
870        elif not requires_defining_class and pos_only == len(parameters) - pseudo_args:
871            if not new_or_init:
872                # positional-only, but no option groups
873                # we only need one call to _PyArg_ParseStack
874
875                flags = "METH_FASTCALL"
876                parser_prototype = parser_prototype_fastcall
877                nargs = 'nargs'
878                argname_fmt = 'args[%d]'
879            else:
880                # positional-only, but no option groups
881                # we only need one call to PyArg_ParseTuple
882
883                flags = "METH_VARARGS"
884                parser_prototype = parser_prototype_varargs
885                nargs = 'PyTuple_GET_SIZE(args)'
886                argname_fmt = 'PyTuple_GET_ITEM(args, %d)'
887
888
889            left_args = "{} - {}".format(nargs, max_pos)
890            max_args = NO_VARARG if (vararg != NO_VARARG) else max_pos
891            parser_code = [normalize_snippet("""
892                if (!_PyArg_CheckPositional("{name}", %s, %d, %s)) {{
893                    goto exit;
894                }}
895                """ % (nargs, min_pos, max_args), indent=4)]
896
897            has_optional = False
898            for i, p in enumerate(parameters):
899                displayname = p.get_displayname(i+1)
900                argname = argname_fmt % i
901
902                if p.is_vararg():
903                    if not new_or_init:
904                        parser_code.append(normalize_snippet("""
905                            %s = PyTuple_New(%s);
906                            if (!%s) {{
907                                goto exit;
908                            }}
909                            for (Py_ssize_t i = 0; i < %s; ++i) {{
910                                PyTuple_SET_ITEM(%s, i, Py_NewRef(args[%d + i]));
911                            }}
912                            """ % (
913                                p.converter.parser_name,
914                                left_args,
915                                p.converter.parser_name,
916                                left_args,
917                                p.converter.parser_name,
918                                max_pos
919                            ), indent=4))
920                    else:
921                        parser_code.append(normalize_snippet("""
922                            %s = PyTuple_GetSlice(%d, -1);
923                            """ % (
924                                p.converter.parser_name,
925                                max_pos
926                            ), indent=4))
927                    continue
928
929                parsearg = p.converter.parse_arg(argname, displayname)
930                if parsearg is None:
931                    #print('Cannot convert %s %r for %s' % (p.converter.__class__.__name__, p.converter.format_unit, p.converter.name), file=sys.stderr)
932                    parser_code = None
933                    break
934                if has_optional or p.is_optional():
935                    has_optional = True
936                    parser_code.append(normalize_snippet("""
937                        if (%s < %d) {{
938                            goto skip_optional;
939                        }}
940                        """, indent=4) % (nargs, i + 1))
941                parser_code.append(normalize_snippet(parsearg, indent=4))
942
943            if parser_code is not None:
944                if has_optional:
945                    parser_code.append("skip_optional:")
946            else:
947                if not new_or_init:
948                    parser_code = [normalize_snippet("""
949                        if (!_PyArg_ParseStack(args, nargs, "{format_units}:{name}",
950                            {parse_arguments})) {{
951                            goto exit;
952                        }}
953                        """, indent=4)]
954                else:
955                    parser_code = [normalize_snippet("""
956                        if (!PyArg_ParseTuple(args, "{format_units}:{name}",
957                            {parse_arguments})) {{
958                            goto exit;
959                        }}
960                        """, indent=4)]
961            parser_definition = parser_body(parser_prototype, *parser_code)
962
963        else:
964            has_optional_kw = (max(pos_only, min_pos) + min_kw_only < len(converters) - int(vararg != NO_VARARG))
965            if vararg == NO_VARARG:
966                args_declaration = "_PyArg_UnpackKeywords", "%s, %s, %s" % (
967                    min_pos,
968                    max_pos,
969                    min_kw_only
970                )
971                nargs = "nargs"
972            else:
973                args_declaration = "_PyArg_UnpackKeywordsWithVararg", "%s, %s, %s, %s" % (
974                    min_pos,
975                    max_pos,
976                    min_kw_only,
977                    vararg
978                )
979                nargs = f"Py_MIN(nargs, {max_pos})" if max_pos else "0"
980            if not new_or_init:
981                flags = "METH_FASTCALL|METH_KEYWORDS"
982                parser_prototype = parser_prototype_fastcall_keywords
983                argname_fmt = 'args[%d]'
984                declarations = normalize_snippet("""
985                    static const char * const _keywords[] = {{{keywords} NULL}};
986                    static _PyArg_Parser _parser = {{NULL, _keywords, "{name}", 0}};
987                    PyObject *argsbuf[%s];
988                    """ % len(converters))
989                if has_optional_kw:
990                    declarations += "\nPy_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (nargs, min_pos + min_kw_only)
991                parser_code = [normalize_snippet("""
992                    args = %s(args, nargs, NULL, kwnames, &_parser, %s, argsbuf);
993                    if (!args) {{
994                        goto exit;
995                    }}
996                    """ % args_declaration, indent=4)]
997            else:
998                # positional-or-keyword arguments
999                flags = "METH_VARARGS|METH_KEYWORDS"
1000                parser_prototype = parser_prototype_keyword
1001                argname_fmt = 'fastargs[%d]'
1002                declarations = normalize_snippet("""
1003                    static const char * const _keywords[] = {{{keywords} NULL}};
1004                    static _PyArg_Parser _parser = {{NULL, _keywords, "{name}", 0}};
1005                    PyObject *argsbuf[%s];
1006                    PyObject * const *fastargs;
1007                    Py_ssize_t nargs = PyTuple_GET_SIZE(args);
1008                    """ % len(converters))
1009                if has_optional_kw:
1010                    declarations += "\nPy_ssize_t noptargs = %s + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (nargs, min_pos + min_kw_only)
1011                parser_code = [normalize_snippet("""
1012                    fastargs = %s(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, %s, argsbuf);
1013                    if (!fastargs) {{
1014                        goto exit;
1015                    }}
1016                    """ % args_declaration, indent=4)]
1017
1018            if requires_defining_class:
1019                flags = 'METH_METHOD|' + flags
1020                parser_prototype = parser_prototype_def_class
1021
1022            add_label = None
1023            for i, p in enumerate(parameters):
1024                if isinstance(p.converter, defining_class_converter):
1025                    raise ValueError("defining_class should be the first "
1026                                     "parameter (after self)")
1027                displayname = p.get_displayname(i+1)
1028                parsearg = p.converter.parse_arg(argname_fmt % i, displayname)
1029                if parsearg is None:
1030                    #print('Cannot convert %s %r for %s' % (p.converter.__class__.__name__, p.converter.format_unit, p.converter.name), file=sys.stderr)
1031                    parser_code = None
1032                    break
1033                if add_label and (i == pos_only or i == max_pos):
1034                    parser_code.append("%s:" % add_label)
1035                    add_label = None
1036                if not p.is_optional():
1037                    parser_code.append(normalize_snippet(parsearg, indent=4))
1038                elif i < pos_only:
1039                    add_label = 'skip_optional_posonly'
1040                    parser_code.append(normalize_snippet("""
1041                        if (nargs < %d) {{
1042                            goto %s;
1043                        }}
1044                        """ % (i + 1, add_label), indent=4))
1045                    if has_optional_kw:
1046                        parser_code.append(normalize_snippet("""
1047                            noptargs--;
1048                            """, indent=4))
1049                    parser_code.append(normalize_snippet(parsearg, indent=4))
1050                else:
1051                    if i < max_pos:
1052                        label = 'skip_optional_pos'
1053                        first_opt = max(min_pos, pos_only)
1054                    else:
1055                        label = 'skip_optional_kwonly'
1056                        first_opt = max_pos + min_kw_only
1057                        if vararg != NO_VARARG:
1058                            first_opt += 1
1059                    if i == first_opt:
1060                        add_label = label
1061                        parser_code.append(normalize_snippet("""
1062                            if (!noptargs) {{
1063                                goto %s;
1064                            }}
1065                            """ % add_label, indent=4))
1066                    if i + 1 == len(parameters):
1067                        parser_code.append(normalize_snippet(parsearg, indent=4))
1068                    else:
1069                        add_label = label
1070                        parser_code.append(normalize_snippet("""
1071                            if (%s) {{
1072                            """ % (argname_fmt % i), indent=4))
1073                        parser_code.append(normalize_snippet(parsearg, indent=8))
1074                        parser_code.append(normalize_snippet("""
1075                                if (!--noptargs) {{
1076                                    goto %s;
1077                                }}
1078                            }}
1079                            """ % add_label, indent=4))
1080
1081            if parser_code is not None:
1082                if add_label:
1083                    parser_code.append("%s:" % add_label)
1084            else:
1085                declarations = (
1086                    'static const char * const _keywords[] = {{{keywords} NULL}};\n'
1087                    'static _PyArg_Parser _parser = {{"{format_units}:{name}", _keywords, 0}};')
1088                if not new_or_init:
1089                    parser_code = [normalize_snippet("""
1090                        if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser{parse_arguments_comma}
1091                            {parse_arguments})) {{
1092                            goto exit;
1093                        }}
1094                        """, indent=4)]
1095                else:
1096                    parser_code = [normalize_snippet("""
1097                        if (!_PyArg_ParseTupleAndKeywordsFast(args, kwargs, &_parser,
1098                            {parse_arguments})) {{
1099                            goto exit;
1100                        }}
1101                        """, indent=4)]
1102            parser_definition = parser_body(parser_prototype, *parser_code,
1103                                            declarations=declarations)
1104
1105
1106        if new_or_init:
1107            methoddef_define = ''
1108
1109            if f.kind == METHOD_NEW:
1110                parser_prototype = parser_prototype_keyword
1111            else:
1112                return_value_declaration = "int return_value = -1;"
1113                parser_prototype = normalize_snippet("""
1114                    static int
1115                    {c_basename}({self_type}{self_name}, PyObject *args, PyObject *kwargs)
1116                    """)
1117
1118            fields = list(parser_body_fields)
1119            parses_positional = 'METH_NOARGS' not in flags
1120            parses_keywords = 'METH_KEYWORDS' in flags
1121            if parses_keywords:
1122                assert parses_positional
1123
1124            if requires_defining_class:
1125                raise ValueError("Slot methods cannot access their defining class.")
1126
1127            if not parses_keywords:
1128                fields.insert(0, normalize_snippet("""
1129                    if ({self_type_check}!_PyArg_NoKeywords("{name}", kwargs)) {{
1130                        goto exit;
1131                    }}
1132                    """, indent=4))
1133                if not parses_positional:
1134                    fields.insert(0, normalize_snippet("""
1135                        if ({self_type_check}!_PyArg_NoPositional("{name}", args)) {{
1136                            goto exit;
1137                        }}
1138                        """, indent=4))
1139
1140            parser_definition = parser_body(parser_prototype, *fields,
1141                                            declarations=parser_body_declarations)
1142
1143
1144        if flags in ('METH_NOARGS', 'METH_O', 'METH_VARARGS'):
1145            methoddef_cast = "(PyCFunction)"
1146            methoddef_cast_end = ""
1147        else:
1148            methoddef_cast = "_PyCFunction_CAST("
1149            methoddef_cast_end = ")"
1150
1151        if f.methoddef_flags:
1152            flags += '|' + f.methoddef_flags
1153
1154        methoddef_define = methoddef_define.replace('{methoddef_flags}', flags)
1155        methoddef_define = methoddef_define.replace('{methoddef_cast}', methoddef_cast)
1156        methoddef_define = methoddef_define.replace('{methoddef_cast_end}', methoddef_cast_end)
1157
1158        methoddef_ifndef = ''
1159        conditional = self.cpp.condition()
1160        if not conditional:
1161            cpp_if = cpp_endif = ''
1162        else:
1163            cpp_if = "#if " + conditional
1164            cpp_endif = "#endif /* " + conditional + " */"
1165
1166            if methoddef_define and f.full_name not in clinic.ifndef_symbols:
1167                clinic.ifndef_symbols.add(f.full_name)
1168                methoddef_ifndef = normalize_snippet("""
1169                    #ifndef {methoddef_name}
1170                        #define {methoddef_name}
1171                    #endif /* !defined({methoddef_name}) */
1172                    """)
1173
1174
1175        # add ';' to the end of parser_prototype and impl_prototype
1176        # (they mustn't be None, but they could be an empty string.)
1177        assert parser_prototype is not None
1178        if parser_prototype:
1179            assert not parser_prototype.endswith(';')
1180            parser_prototype += ';'
1181
1182        if impl_prototype is None:
1183            impl_prototype = impl_definition
1184        if impl_prototype:
1185            impl_prototype += ";"
1186
1187        parser_definition = parser_definition.replace("{return_value_declaration}", return_value_declaration)
1188
1189        d = {
1190            "docstring_prototype" : docstring_prototype,
1191            "docstring_definition" : docstring_definition,
1192            "impl_prototype" : impl_prototype,
1193            "methoddef_define" : methoddef_define,
1194            "parser_prototype" : parser_prototype,
1195            "parser_definition" : parser_definition,
1196            "impl_definition" : impl_definition,
1197            "cpp_if" : cpp_if,
1198            "cpp_endif" : cpp_endif,
1199            "methoddef_ifndef" : methoddef_ifndef,
1200        }
1201
1202        # make sure we didn't forget to assign something,
1203        # and wrap each non-empty value in \n's
1204        d2 = {}
1205        for name, value in d.items():
1206            assert value is not None, "got a None value for template " + repr(name)
1207            if value:
1208                value = '\n' + value + '\n'
1209            d2[name] = value
1210        return d2
1211
1212    @staticmethod
1213    def group_to_variable_name(group):
1214        adjective = "left_" if group < 0 else "right_"
1215        return "group_" + adjective + str(abs(group))
1216
1217    def render_option_group_parsing(self, f, template_dict):
1218        # positional only, grouped, optional arguments!
1219        # can be optional on the left or right.
1220        # here's an example:
1221        #
1222        # [ [ [ A1 A2 ] B1 B2 B3 ] C1 C2 ] D1 D2 D3 [ E1 E2 E3 [ F1 F2 F3 ] ]
1223        #
1224        # Here group D are required, and all other groups are optional.
1225        # (Group D's "group" is actually None.)
1226        # We can figure out which sets of arguments we have based on
1227        # how many arguments are in the tuple.
1228        #
1229        # Note that you need to count up on both sides.  For example,
1230        # you could have groups C+D, or C+D+E, or C+D+E+F.
1231        #
1232        # What if the number of arguments leads us to an ambiguous result?
1233        # Clinic prefers groups on the left.  So in the above example,
1234        # five arguments would map to B+C, not C+D.
1235
1236        add, output = text_accumulator()
1237        parameters = list(f.parameters.values())
1238        if isinstance(parameters[0].converter, self_converter):
1239            del parameters[0]
1240
1241        groups = []
1242        group = None
1243        left = []
1244        right = []
1245        required = []
1246        last = unspecified
1247
1248        for p in parameters:
1249            group_id = p.group
1250            if group_id != last:
1251                last = group_id
1252                group = []
1253                if group_id < 0:
1254                    left.append(group)
1255                elif group_id == 0:
1256                    group = required
1257                else:
1258                    right.append(group)
1259            group.append(p)
1260
1261        count_min = sys.maxsize
1262        count_max = -1
1263
1264        add("switch (PyTuple_GET_SIZE(args)) {\n")
1265        for subset in permute_optional_groups(left, required, right):
1266            count = len(subset)
1267            count_min = min(count_min, count)
1268            count_max = max(count_max, count)
1269
1270            if count == 0:
1271                add("""    case 0:
1272        break;
1273""")
1274                continue
1275
1276            group_ids = {p.group for p in subset}  # eliminate duplicates
1277            d = {}
1278            d['count'] = count
1279            d['name'] = f.name
1280            d['format_units'] = "".join(p.converter.format_unit for p in subset)
1281
1282            parse_arguments = []
1283            for p in subset:
1284                p.converter.parse_argument(parse_arguments)
1285            d['parse_arguments'] = ", ".join(parse_arguments)
1286
1287            group_ids.discard(0)
1288            lines = [self.group_to_variable_name(g) + " = 1;" for g in group_ids]
1289            lines = "\n".join(lines)
1290
1291            s = """\
1292    case {count}:
1293        if (!PyArg_ParseTuple(args, "{format_units}:{name}", {parse_arguments})) {{
1294            goto exit;
1295        }}
1296        {group_booleans}
1297        break;
1298"""
1299            s = linear_format(s, group_booleans=lines)
1300            s = s.format_map(d)
1301            add(s)
1302
1303        add("    default:\n")
1304        s = '        PyErr_SetString(PyExc_TypeError, "{} requires {} to {} arguments");\n'
1305        add(s.format(f.full_name, count_min, count_max))
1306        add('        goto exit;\n')
1307        add("}")
1308        template_dict['option_group_parsing'] = format_escape(output())
1309
1310    def render_function(self, clinic, f):
1311        if not f:
1312            return ""
1313
1314        add, output = text_accumulator()
1315        data = CRenderData()
1316
1317        assert f.parameters, "We should always have a 'self' at this point!"
1318        parameters = f.render_parameters
1319        converters = [p.converter for p in parameters]
1320
1321        templates = self.output_templates(f)
1322
1323        f_self = parameters[0]
1324        selfless = parameters[1:]
1325        assert isinstance(f_self.converter, self_converter), "No self parameter in " + repr(f.full_name) + "!"
1326
1327        last_group = 0
1328        first_optional = len(selfless)
1329        positional = selfless and selfless[-1].is_positional_only()
1330        new_or_init = f.kind in (METHOD_NEW, METHOD_INIT)
1331        default_return_converter = (not f.return_converter or
1332            f.return_converter.type == 'PyObject *')
1333        has_option_groups = False
1334
1335        # offset i by -1 because first_optional needs to ignore self
1336        for i, p in enumerate(parameters, -1):
1337            c = p.converter
1338
1339            if (i != -1) and (p.default is not unspecified):
1340                first_optional = min(first_optional, i)
1341
1342            if p.is_vararg():
1343                data.cleanup.append("Py_XDECREF({});".format(c.parser_name))
1344
1345            # insert group variable
1346            group = p.group
1347            if last_group != group:
1348                last_group = group
1349                if group:
1350                    group_name = self.group_to_variable_name(group)
1351                    data.impl_arguments.append(group_name)
1352                    data.declarations.append("int " + group_name + " = 0;")
1353                    data.impl_parameters.append("int " + group_name)
1354                    has_option_groups = True
1355
1356            c.render(p, data)
1357
1358        if has_option_groups and (not positional):
1359            fail("You cannot use optional groups ('[' and ']')\nunless all parameters are positional-only ('/').")
1360
1361        # HACK
1362        # when we're METH_O, but have a custom return converter,
1363        # we use "impl_parameters" for the parsing function
1364        # because that works better.  but that means we must
1365        # suppress actually declaring the impl's parameters
1366        # as variables in the parsing function.  but since it's
1367        # METH_O, we have exactly one anyway, so we know exactly
1368        # where it is.
1369        if ("METH_O" in templates['methoddef_define'] and
1370            '{impl_parameters}' in templates['parser_prototype']):
1371            data.declarations.pop(0)
1372
1373        template_dict = {}
1374
1375        full_name = f.full_name
1376        template_dict['full_name'] = full_name
1377
1378        if new_or_init:
1379            name = f.cls.name
1380        else:
1381            name = f.name
1382
1383        template_dict['name'] = name
1384
1385        if f.c_basename:
1386            c_basename = f.c_basename
1387        else:
1388            fields = full_name.split(".")
1389            if fields[-1] == '__new__':
1390                fields.pop()
1391            c_basename = "_".join(fields)
1392
1393        template_dict['c_basename'] = c_basename
1394
1395        methoddef_name = "{}_METHODDEF".format(c_basename.upper())
1396        template_dict['methoddef_name'] = methoddef_name
1397
1398        template_dict['docstring'] = self.docstring_for_c_string(f)
1399
1400        template_dict['self_name'] = template_dict['self_type'] = template_dict['self_type_check'] = ''
1401        for converter in converters:
1402            converter.set_template_dict(template_dict)
1403
1404        f.return_converter.render(f, data)
1405        template_dict['impl_return_type'] = f.return_converter.type
1406
1407        template_dict['declarations'] = format_escape("\n".join(data.declarations))
1408        template_dict['initializers'] = "\n\n".join(data.initializers)
1409        template_dict['modifications'] = '\n\n'.join(data.modifications)
1410        template_dict['keywords'] = ' '.join('"' + k + '",' for k in data.keywords)
1411        template_dict['format_units'] = ''.join(data.format_units)
1412        template_dict['parse_arguments'] = ', '.join(data.parse_arguments)
1413        if data.parse_arguments:
1414            template_dict['parse_arguments_comma'] = ',';
1415        else:
1416            template_dict['parse_arguments_comma'] = '';
1417        template_dict['impl_parameters'] = ", ".join(data.impl_parameters)
1418        template_dict['impl_arguments'] = ", ".join(data.impl_arguments)
1419        template_dict['return_conversion'] = format_escape("".join(data.return_conversion).rstrip())
1420        template_dict['post_parsing'] = format_escape("".join(data.post_parsing).rstrip())
1421        template_dict['cleanup'] = format_escape("".join(data.cleanup))
1422        template_dict['return_value'] = data.return_value
1423
1424        # used by unpack tuple code generator
1425        ignore_self = -1 if isinstance(converters[0], self_converter) else 0
1426        unpack_min = first_optional
1427        unpack_max = len(selfless)
1428        template_dict['unpack_min'] = str(unpack_min)
1429        template_dict['unpack_max'] = str(unpack_max)
1430
1431        if has_option_groups:
1432            self.render_option_group_parsing(f, template_dict)
1433
1434        # buffers, not destination
1435        for name, destination in clinic.destination_buffers.items():
1436            template = templates[name]
1437            if has_option_groups:
1438                template = linear_format(template,
1439                        option_group_parsing=template_dict['option_group_parsing'])
1440            template = linear_format(template,
1441                declarations=template_dict['declarations'],
1442                return_conversion=template_dict['return_conversion'],
1443                initializers=template_dict['initializers'],
1444                modifications=template_dict['modifications'],
1445                post_parsing=template_dict['post_parsing'],
1446                cleanup=template_dict['cleanup'],
1447                )
1448
1449            # Only generate the "exit:" label
1450            # if we have any gotos
1451            need_exit_label = "goto exit;" in template
1452            template = linear_format(template,
1453                exit_label="exit:" if need_exit_label else ''
1454                )
1455
1456            s = template.format_map(template_dict)
1457
1458            # mild hack:
1459            # reflow long impl declarations
1460            if name in {"impl_prototype", "impl_definition"}:
1461                s = wrap_declarations(s)
1462
1463            if clinic.line_prefix:
1464                s = indent_all_lines(s, clinic.line_prefix)
1465            if clinic.line_suffix:
1466                s = suffix_all_lines(s, clinic.line_suffix)
1467
1468            destination.append(s)
1469
1470        return clinic.get_destination('block').dump()
1471
1472
1473
1474
1475@contextlib.contextmanager
1476def OverrideStdioWith(stdout):
1477    saved_stdout = sys.stdout
1478    sys.stdout = stdout
1479    try:
1480        yield
1481    finally:
1482        assert sys.stdout is stdout
1483        sys.stdout = saved_stdout
1484
1485
1486def create_regex(before, after, word=True, whole_line=True):
1487    """Create an re object for matching marker lines."""
1488    group_re = r"\w+" if word else ".+"
1489    pattern = r'{}({}){}'
1490    if whole_line:
1491        pattern = '^' + pattern + '$'
1492    pattern = pattern.format(re.escape(before), group_re, re.escape(after))
1493    return re.compile(pattern)
1494
1495
1496class Block:
1497    r"""
1498    Represents a single block of text embedded in
1499    another file.  If dsl_name is None, the block represents
1500    verbatim text, raw original text from the file, in
1501    which case "input" will be the only non-false member.
1502    If dsl_name is not None, the block represents a Clinic
1503    block.
1504
1505    input is always str, with embedded \n characters.
1506    input represents the original text from the file;
1507    if it's a Clinic block, it is the original text with
1508    the body_prefix and redundant leading whitespace removed.
1509
1510    dsl_name is either str or None.  If str, it's the text
1511    found on the start line of the block between the square
1512    brackets.
1513
1514    signatures is either list or None.  If it's a list,
1515    it may only contain clinic.Module, clinic.Class, and
1516    clinic.Function objects.  At the moment it should
1517    contain at most one of each.
1518
1519    output is either str or None.  If str, it's the output
1520    from this block, with embedded '\n' characters.
1521
1522    indent is either str or None.  It's the leading whitespace
1523    that was found on every line of input.  (If body_prefix is
1524    not empty, this is the indent *after* removing the
1525    body_prefix.)
1526
1527    preindent is either str or None.  It's the whitespace that
1528    was found in front of every line of input *before* the
1529    "body_prefix" (see the Language object).  If body_prefix
1530    is empty, preindent must always be empty too.
1531
1532    To illustrate indent and preindent: Assume that '_'
1533    represents whitespace.  If the block processed was in a
1534    Python file, and looked like this:
1535      ____#/*[python]
1536      ____#__for a in range(20):
1537      ____#____print(a)
1538      ____#[python]*/
1539    "preindent" would be "____" and "indent" would be "__".
1540
1541    """
1542    def __init__(self, input, dsl_name=None, signatures=None, output=None, indent='', preindent=''):
1543        assert isinstance(input, str)
1544        self.input = input
1545        self.dsl_name = dsl_name
1546        self.signatures = signatures or []
1547        self.output = output
1548        self.indent = indent
1549        self.preindent = preindent
1550
1551    def __repr__(self):
1552        dsl_name = self.dsl_name or "text"
1553        def summarize(s):
1554            s = repr(s)
1555            if len(s) > 30:
1556                return s[:26] + "..." + s[0]
1557            return s
1558        return "".join((
1559            "<Block ", dsl_name, " input=", summarize(self.input), " output=", summarize(self.output), ">"))
1560
1561
1562class BlockParser:
1563    """
1564    Block-oriented parser for Argument Clinic.
1565    Iterator, yields Block objects.
1566    """
1567
1568    def __init__(self, input, language, *, verify=True):
1569        """
1570        "input" should be a str object
1571        with embedded \n characters.
1572
1573        "language" should be a Language object.
1574        """
1575        language.validate()
1576
1577        self.input = collections.deque(reversed(input.splitlines(keepends=True)))
1578        self.block_start_line_number = self.line_number = 0
1579
1580        self.language = language
1581        before, _, after = language.start_line.partition('{dsl_name}')
1582        assert _ == '{dsl_name}'
1583        self.find_start_re = create_regex(before, after, whole_line=False)
1584        self.start_re = create_regex(before, after)
1585        self.verify = verify
1586        self.last_checksum_re = None
1587        self.last_dsl_name = None
1588        self.dsl_name = None
1589        self.first_block = True
1590
1591    def __iter__(self):
1592        return self
1593
1594    def __next__(self):
1595        while True:
1596            if not self.input:
1597                raise StopIteration
1598
1599            if self.dsl_name:
1600                return_value = self.parse_clinic_block(self.dsl_name)
1601                self.dsl_name = None
1602                self.first_block = False
1603                return return_value
1604            block = self.parse_verbatim_block()
1605            if self.first_block and not block.input:
1606                continue
1607            self.first_block = False
1608            return block
1609
1610
1611    def is_start_line(self, line):
1612        match = self.start_re.match(line.lstrip())
1613        return match.group(1) if match else None
1614
1615    def _line(self, lookahead=False):
1616        self.line_number += 1
1617        line = self.input.pop()
1618        if not lookahead:
1619            self.language.parse_line(line)
1620        return line
1621
1622    def parse_verbatim_block(self):
1623        add, output = text_accumulator()
1624        self.block_start_line_number = self.line_number
1625
1626        while self.input:
1627            line = self._line()
1628            dsl_name = self.is_start_line(line)
1629            if dsl_name:
1630                self.dsl_name = dsl_name
1631                break
1632            add(line)
1633
1634        return Block(output())
1635
1636    def parse_clinic_block(self, dsl_name):
1637        input_add, input_output = text_accumulator()
1638        self.block_start_line_number = self.line_number + 1
1639        stop_line = self.language.stop_line.format(dsl_name=dsl_name)
1640        body_prefix = self.language.body_prefix.format(dsl_name=dsl_name)
1641
1642        def is_stop_line(line):
1643            # make sure to recognize stop line even if it
1644            # doesn't end with EOL (it could be the very end of the file)
1645            if line.startswith(stop_line):
1646                remainder = line[len(stop_line):]
1647                if remainder and not remainder.isspace():
1648                    fail(f"Garbage after stop line: {remainder!r}")
1649                return True
1650            else:
1651                # gh-92256: don't allow incorrectly formatted stop lines
1652                if line.lstrip().startswith(stop_line):
1653                    fail(f"Whitespace is not allowed before the stop line: {line!r}")
1654                return False
1655
1656        # consume body of program
1657        while self.input:
1658            line = self._line()
1659            if is_stop_line(line) or self.is_start_line(line):
1660                break
1661            if body_prefix:
1662                line = line.lstrip()
1663                assert line.startswith(body_prefix)
1664                line = line[len(body_prefix):]
1665            input_add(line)
1666
1667        # consume output and checksum line, if present.
1668        if self.last_dsl_name == dsl_name:
1669            checksum_re = self.last_checksum_re
1670        else:
1671            before, _, after = self.language.checksum_line.format(dsl_name=dsl_name, arguments='{arguments}').partition('{arguments}')
1672            assert _ == '{arguments}'
1673            checksum_re = create_regex(before, after, word=False)
1674            self.last_dsl_name = dsl_name
1675            self.last_checksum_re = checksum_re
1676
1677        # scan forward for checksum line
1678        output_add, output_output = text_accumulator()
1679        arguments = None
1680        while self.input:
1681            line = self._line(lookahead=True)
1682            match = checksum_re.match(line.lstrip())
1683            arguments = match.group(1) if match else None
1684            if arguments:
1685                break
1686            output_add(line)
1687            if self.is_start_line(line):
1688                break
1689
1690        output = output_output()
1691        if arguments:
1692            d = {}
1693            for field in shlex.split(arguments):
1694                name, equals, value = field.partition('=')
1695                if not equals:
1696                    fail("Mangled Argument Clinic marker line: {!r}".format(line))
1697                d[name.strip()] = value.strip()
1698
1699            if self.verify:
1700                if 'input' in d:
1701                    checksum = d['output']
1702                    input_checksum = d['input']
1703                else:
1704                    checksum = d['checksum']
1705                    input_checksum = None
1706
1707                computed = compute_checksum(output, len(checksum))
1708                if checksum != computed:
1709                    fail("Checksum mismatch!\nExpected: {}\nComputed: {}\n"
1710                         "Suggested fix: remove all generated code including "
1711                         "the end marker,\n"
1712                         "or use the '-f' option."
1713                        .format(checksum, computed))
1714        else:
1715            # put back output
1716            output_lines = output.splitlines(keepends=True)
1717            self.line_number -= len(output_lines)
1718            self.input.extend(reversed(output_lines))
1719            output = None
1720
1721        return Block(input_output(), dsl_name, output=output)
1722
1723
1724class BlockPrinter:
1725
1726    def __init__(self, language, f=None):
1727        self.language = language
1728        self.f = f or io.StringIO()
1729
1730    def print_block(self, block):
1731        input = block.input
1732        output = block.output
1733        dsl_name = block.dsl_name
1734        write = self.f.write
1735
1736        assert not ((dsl_name is None) ^ (output is None)), "you must specify dsl_name and output together, dsl_name " + repr(dsl_name)
1737
1738        if not dsl_name:
1739            write(input)
1740            return
1741
1742        write(self.language.start_line.format(dsl_name=dsl_name))
1743        write("\n")
1744
1745        body_prefix = self.language.body_prefix.format(dsl_name=dsl_name)
1746        if not body_prefix:
1747            write(input)
1748        else:
1749            for line in input.split('\n'):
1750                write(body_prefix)
1751                write(line)
1752                write("\n")
1753
1754        write(self.language.stop_line.format(dsl_name=dsl_name))
1755        write("\n")
1756
1757        input = ''.join(block.input)
1758        output = ''.join(block.output)
1759        if output:
1760            if not output.endswith('\n'):
1761                output += '\n'
1762            write(output)
1763
1764        arguments="output={} input={}".format(compute_checksum(output, 16), compute_checksum(input, 16))
1765        write(self.language.checksum_line.format(dsl_name=dsl_name, arguments=arguments))
1766        write("\n")
1767
1768    def write(self, text):
1769        self.f.write(text)
1770
1771
1772class BufferSeries:
1773    """
1774    Behaves like a "defaultlist".
1775    When you ask for an index that doesn't exist yet,
1776    the object grows the list until that item exists.
1777    So o[n] will always work.
1778
1779    Supports negative indices for actual items.
1780    e.g. o[-1] is an element immediately preceding o[0].
1781    """
1782
1783    def __init__(self):
1784        self._start = 0
1785        self._array = []
1786        self._constructor = _text_accumulator
1787
1788    def __getitem__(self, i):
1789        i -= self._start
1790        if i < 0:
1791            self._start += i
1792            prefix = [self._constructor() for x in range(-i)]
1793            self._array = prefix + self._array
1794            i = 0
1795        while i >= len(self._array):
1796            self._array.append(self._constructor())
1797        return self._array[i]
1798
1799    def clear(self):
1800        for ta in self._array:
1801            ta._text.clear()
1802
1803    def dump(self):
1804        texts = [ta.output() for ta in self._array]
1805        return "".join(texts)
1806
1807
1808class Destination:
1809    def __init__(self, name, type, clinic, *args):
1810        self.name = name
1811        self.type = type
1812        self.clinic = clinic
1813        valid_types = ('buffer', 'file', 'suppress')
1814        if type not in valid_types:
1815            fail("Invalid destination type " + repr(type) + " for " + name + " , must be " + ', '.join(valid_types))
1816        extra_arguments = 1 if type == "file" else 0
1817        if len(args) < extra_arguments:
1818            fail("Not enough arguments for destination " + name + " new " + type)
1819        if len(args) > extra_arguments:
1820            fail("Too many arguments for destination " + name + " new " + type)
1821        if type =='file':
1822            d = {}
1823            filename = clinic.filename
1824            d['path'] = filename
1825            dirname, basename = os.path.split(filename)
1826            if not dirname:
1827                dirname = '.'
1828            d['dirname'] = dirname
1829            d['basename'] = basename
1830            d['basename_root'], d['basename_extension'] = os.path.splitext(filename)
1831            self.filename = args[0].format_map(d)
1832
1833        self.buffers = BufferSeries()
1834
1835    def __repr__(self):
1836        if self.type == 'file':
1837            file_repr = " " + repr(self.filename)
1838        else:
1839            file_repr = ''
1840        return "".join(("<Destination ", self.name, " ", self.type, file_repr, ">"))
1841
1842    def clear(self):
1843        if self.type != 'buffer':
1844            fail("Can't clear destination" + self.name + " , it's not of type buffer")
1845        self.buffers.clear()
1846
1847    def dump(self):
1848        return self.buffers.dump()
1849
1850
1851# maps strings to Language objects.
1852# "languages" maps the name of the language ("C", "Python").
1853# "extensions" maps the file extension ("c", "py").
1854languages = { 'C': CLanguage, 'Python': PythonLanguage }
1855extensions = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() }
1856extensions['py'] = PythonLanguage
1857
1858
1859# maps strings to callables.
1860# these callables must be of the form:
1861#   def foo(name, default, *, ...)
1862# The callable may have any number of keyword-only parameters.
1863# The callable must return a CConverter object.
1864# The callable should not call builtins.print.
1865converters = {}
1866
1867# maps strings to callables.
1868# these callables follow the same rules as those for "converters" above.
1869# note however that they will never be called with keyword-only parameters.
1870legacy_converters = {}
1871
1872
1873# maps strings to callables.
1874# these callables must be of the form:
1875#   def foo(*, ...)
1876# The callable may have any number of keyword-only parameters.
1877# The callable must return a CConverter object.
1878# The callable should not call builtins.print.
1879return_converters = {}
1880
1881
1882def write_file(filename, new_contents):
1883    try:
1884        with open(filename, 'r', encoding="utf-8") as fp:
1885            old_contents = fp.read()
1886
1887        if old_contents == new_contents:
1888            # no change: avoid modifying the file modification time
1889            return
1890    except FileNotFoundError:
1891        pass
1892
1893    # Atomic write using a temporary file and os.replace()
1894    filename_new = f"{filename}.new"
1895    with open(filename_new, "w", encoding="utf-8") as fp:
1896        fp.write(new_contents)
1897
1898    try:
1899        os.replace(filename_new, filename)
1900    except:
1901        os.unlink(filename_new)
1902        raise
1903
1904
1905clinic = None
1906class Clinic:
1907
1908    presets_text = """
1909preset block
1910everything block
1911methoddef_ifndef buffer 1
1912docstring_prototype suppress
1913parser_prototype suppress
1914cpp_if suppress
1915cpp_endif suppress
1916
1917preset original
1918everything block
1919methoddef_ifndef buffer 1
1920docstring_prototype suppress
1921parser_prototype suppress
1922cpp_if suppress
1923cpp_endif suppress
1924
1925preset file
1926everything file
1927methoddef_ifndef file 1
1928docstring_prototype suppress
1929parser_prototype suppress
1930impl_definition block
1931
1932preset buffer
1933everything buffer
1934methoddef_ifndef buffer 1
1935impl_definition block
1936docstring_prototype suppress
1937impl_prototype suppress
1938parser_prototype suppress
1939
1940preset partial-buffer
1941everything buffer
1942methoddef_ifndef buffer 1
1943docstring_prototype block
1944impl_prototype suppress
1945methoddef_define block
1946parser_prototype block
1947impl_definition block
1948
1949"""
1950
1951    def __init__(self, language, printer=None, *, verify=True, filename=None):
1952        # maps strings to Parser objects.
1953        # (instantiated from the "parsers" global.)
1954        self.parsers = {}
1955        self.language = language
1956        if printer:
1957            fail("Custom printers are broken right now")
1958        self.printer = printer or BlockPrinter(language)
1959        self.verify = verify
1960        self.filename = filename
1961        self.modules = collections.OrderedDict()
1962        self.classes = collections.OrderedDict()
1963        self.functions = []
1964
1965        self.line_prefix = self.line_suffix = ''
1966
1967        self.destinations = {}
1968        self.add_destination("block", "buffer")
1969        self.add_destination("suppress", "suppress")
1970        self.add_destination("buffer", "buffer")
1971        if filename:
1972            self.add_destination("file", "file", "{dirname}/clinic/{basename}.h")
1973
1974        d = self.get_destination_buffer
1975        self.destination_buffers = collections.OrderedDict((
1976            ('cpp_if', d('file')),
1977            ('docstring_prototype', d('suppress')),
1978            ('docstring_definition', d('file')),
1979            ('methoddef_define', d('file')),
1980            ('impl_prototype', d('file')),
1981            ('parser_prototype', d('suppress')),
1982            ('parser_definition', d('file')),
1983            ('cpp_endif', d('file')),
1984            ('methoddef_ifndef', d('file', 1)),
1985            ('impl_definition', d('block')),
1986        ))
1987
1988        self.destination_buffers_stack = []
1989        self.ifndef_symbols = set()
1990
1991        self.presets = {}
1992        preset = None
1993        for line in self.presets_text.strip().split('\n'):
1994            line = line.strip()
1995            if not line:
1996                continue
1997            name, value, *options = line.split()
1998            if name == 'preset':
1999                self.presets[value] = preset = collections.OrderedDict()
2000                continue
2001
2002            if len(options):
2003                index = int(options[0])
2004            else:
2005                index = 0
2006            buffer = self.get_destination_buffer(value, index)
2007
2008            if name == 'everything':
2009                for name in self.destination_buffers:
2010                    preset[name] = buffer
2011                continue
2012
2013            assert name in self.destination_buffers
2014            preset[name] = buffer
2015
2016        global clinic
2017        clinic = self
2018
2019    def add_destination(self, name, type, *args):
2020        if name in self.destinations:
2021            fail("Destination already exists: " + repr(name))
2022        self.destinations[name] = Destination(name, type, self, *args)
2023
2024    def get_destination(self, name):
2025        d = self.destinations.get(name)
2026        if not d:
2027            fail("Destination does not exist: " + repr(name))
2028        return d
2029
2030    def get_destination_buffer(self, name, item=0):
2031        d = self.get_destination(name)
2032        return d.buffers[item]
2033
2034    def parse(self, input):
2035        printer = self.printer
2036        self.block_parser = BlockParser(input, self.language, verify=self.verify)
2037        for block in self.block_parser:
2038            dsl_name = block.dsl_name
2039            if dsl_name:
2040                if dsl_name not in self.parsers:
2041                    assert dsl_name in parsers, "No parser to handle {!r} block.".format(dsl_name)
2042                    self.parsers[dsl_name] = parsers[dsl_name](self)
2043                parser = self.parsers[dsl_name]
2044                try:
2045                    parser.parse(block)
2046                except Exception:
2047                    fail('Exception raised during parsing:\n' +
2048                         traceback.format_exc().rstrip())
2049            printer.print_block(block)
2050
2051        second_pass_replacements = {}
2052
2053        # these are destinations not buffers
2054        for name, destination in self.destinations.items():
2055            if destination.type == 'suppress':
2056                continue
2057            output = destination.dump()
2058
2059            if output:
2060
2061                block = Block("", dsl_name="clinic", output=output)
2062
2063                if destination.type == 'buffer':
2064                    block.input = "dump " + name + "\n"
2065                    warn("Destination buffer " + repr(name) + " not empty at end of file, emptying.")
2066                    printer.write("\n")
2067                    printer.print_block(block)
2068                    continue
2069
2070                if destination.type == 'file':
2071                    try:
2072                        dirname = os.path.dirname(destination.filename)
2073                        try:
2074                            os.makedirs(dirname)
2075                        except FileExistsError:
2076                            if not os.path.isdir(dirname):
2077                                fail("Can't write to destination {}, "
2078                                     "can't make directory {}!".format(
2079                                        destination.filename, dirname))
2080                        if self.verify:
2081                            with open(destination.filename, "rt") as f:
2082                                parser_2 = BlockParser(f.read(), language=self.language)
2083                                blocks = list(parser_2)
2084                                if (len(blocks) != 1) or (blocks[0].input != 'preserve\n'):
2085                                    fail("Modified destination file " + repr(destination.filename) + ", not overwriting!")
2086                    except FileNotFoundError:
2087                        pass
2088
2089                    block.input = 'preserve\n'
2090                    printer_2 = BlockPrinter(self.language)
2091                    printer_2.print_block(block)
2092                    write_file(destination.filename, printer_2.f.getvalue())
2093                    continue
2094        text = printer.f.getvalue()
2095
2096        if second_pass_replacements:
2097            printer_2 = BlockPrinter(self.language)
2098            parser_2 = BlockParser(text, self.language)
2099            changed = False
2100            for block in parser_2:
2101                if block.dsl_name:
2102                    for id, replacement in second_pass_replacements.items():
2103                        if id in block.output:
2104                            changed = True
2105                            block.output = block.output.replace(id, replacement)
2106                printer_2.print_block(block)
2107            if changed:
2108                text = printer_2.f.getvalue()
2109
2110        return text
2111
2112
2113    def _module_and_class(self, fields):
2114        """
2115        fields should be an iterable of field names.
2116        returns a tuple of (module, class).
2117        the module object could actually be self (a clinic object).
2118        this function is only ever used to find the parent of where
2119        a new class/module should go.
2120        """
2121        in_classes = False
2122        parent = module = self
2123        cls = None
2124        so_far = []
2125
2126        for field in fields:
2127            so_far.append(field)
2128            if not in_classes:
2129                child = parent.modules.get(field)
2130                if child:
2131                    parent = module = child
2132                    continue
2133                in_classes = True
2134            if not hasattr(parent, 'classes'):
2135                return module, cls
2136            child = parent.classes.get(field)
2137            if not child:
2138                fail('Parent class or module ' + '.'.join(so_far) + " does not exist.")
2139            cls = parent = child
2140
2141        return module, cls
2142
2143
2144def parse_file(filename, *, verify=True, output=None):
2145    if not output:
2146        output = filename
2147
2148    extension = os.path.splitext(filename)[1][1:]
2149    if not extension:
2150        fail("Can't extract file type for file " + repr(filename))
2151
2152    try:
2153        language = extensions[extension](filename)
2154    except KeyError:
2155        fail("Can't identify file type for file " + repr(filename))
2156
2157    with open(filename, 'r', encoding="utf-8") as f:
2158        raw = f.read()
2159
2160    # exit quickly if there are no clinic markers in the file
2161    find_start_re = BlockParser("", language).find_start_re
2162    if not find_start_re.search(raw):
2163        return
2164
2165    clinic = Clinic(language, verify=verify, filename=filename)
2166    cooked = clinic.parse(raw)
2167
2168    write_file(output, cooked)
2169
2170
2171def compute_checksum(input, length=None):
2172    input = input or ''
2173    s = hashlib.sha1(input.encode('utf-8')).hexdigest()
2174    if length:
2175        s = s[:length]
2176    return s
2177
2178
2179
2180
2181class PythonParser:
2182    def __init__(self, clinic):
2183        pass
2184
2185    def parse(self, block):
2186        s = io.StringIO()
2187        with OverrideStdioWith(s):
2188            exec(block.input)
2189        block.output = s.getvalue()
2190
2191
2192class Module:
2193    def __init__(self, name, module=None):
2194        self.name = name
2195        self.module = self.parent = module
2196
2197        self.modules = collections.OrderedDict()
2198        self.classes = collections.OrderedDict()
2199        self.functions = []
2200
2201    def __repr__(self):
2202        return "<clinic.Module " + repr(self.name) + " at " + str(id(self)) + ">"
2203
2204class Class:
2205    def __init__(self, name, module=None, cls=None, typedef=None, type_object=None):
2206        self.name = name
2207        self.module = module
2208        self.cls = cls
2209        self.typedef = typedef
2210        self.type_object = type_object
2211        self.parent = cls or module
2212
2213        self.classes = collections.OrderedDict()
2214        self.functions = []
2215
2216    def __repr__(self):
2217        return "<clinic.Class " + repr(self.name) + " at " + str(id(self)) + ">"
2218
2219unsupported_special_methods = set("""
2220
2221__abs__
2222__add__
2223__and__
2224__call__
2225__delitem__
2226__divmod__
2227__eq__
2228__float__
2229__floordiv__
2230__ge__
2231__getattr__
2232__getattribute__
2233__getitem__
2234__gt__
2235__hash__
2236__iadd__
2237__iand__
2238__ifloordiv__
2239__ilshift__
2240__imatmul__
2241__imod__
2242__imul__
2243__index__
2244__int__
2245__invert__
2246__ior__
2247__ipow__
2248__irshift__
2249__isub__
2250__iter__
2251__itruediv__
2252__ixor__
2253__le__
2254__len__
2255__lshift__
2256__lt__
2257__matmul__
2258__mod__
2259__mul__
2260__neg__
2261__next__
2262__or__
2263__pos__
2264__pow__
2265__radd__
2266__rand__
2267__rdivmod__
2268__repr__
2269__rfloordiv__
2270__rlshift__
2271__rmatmul__
2272__rmod__
2273__rmul__
2274__ror__
2275__rpow__
2276__rrshift__
2277__rshift__
2278__rsub__
2279__rtruediv__
2280__rxor__
2281__setattr__
2282__setitem__
2283__str__
2284__sub__
2285__truediv__
2286__xor__
2287
2288""".strip().split())
2289
2290
2291INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = """
2292INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW
2293""".replace(",", "").strip().split()
2294
2295class Function:
2296    """
2297    Mutable duck type for inspect.Function.
2298
2299    docstring - a str containing
2300        * embedded line breaks
2301        * text outdented to the left margin
2302        * no trailing whitespace.
2303        It will always be true that
2304            (not docstring) or ((not docstring[0].isspace()) and (docstring.rstrip() == docstring))
2305    """
2306
2307    def __init__(self, parameters=None, *, name,
2308                 module, cls=None, c_basename=None,
2309                 full_name=None,
2310                 return_converter, return_annotation=inspect.Signature.empty,
2311                 docstring=None, kind=CALLABLE, coexist=False,
2312                 docstring_only=False):
2313        self.parameters = parameters or collections.OrderedDict()
2314        self.return_annotation = return_annotation
2315        self.name = name
2316        self.full_name = full_name
2317        self.module = module
2318        self.cls = cls
2319        self.parent = cls or module
2320        self.c_basename = c_basename
2321        self.return_converter = return_converter
2322        self.docstring = docstring or ''
2323        self.kind = kind
2324        self.coexist = coexist
2325        self.self_converter = None
2326        # docstring_only means "don't generate a machine-readable
2327        # signature, just a normal docstring".  it's True for
2328        # functions with optional groups because we can't represent
2329        # those accurately with inspect.Signature in 3.4.
2330        self.docstring_only = docstring_only
2331
2332        self.rendered_parameters = None
2333
2334    __render_parameters__ = None
2335    @property
2336    def render_parameters(self):
2337        if not self.__render_parameters__:
2338            self.__render_parameters__ = l = []
2339            for p in self.parameters.values():
2340                p = p.copy()
2341                p.converter.pre_render()
2342                l.append(p)
2343        return self.__render_parameters__
2344
2345    @property
2346    def methoddef_flags(self):
2347        if self.kind in (METHOD_INIT, METHOD_NEW):
2348            return None
2349        flags = []
2350        if self.kind == CLASS_METHOD:
2351            flags.append('METH_CLASS')
2352        elif self.kind == STATIC_METHOD:
2353            flags.append('METH_STATIC')
2354        else:
2355            assert self.kind == CALLABLE, "unknown kind: " + repr(self.kind)
2356        if self.coexist:
2357            flags.append('METH_COEXIST')
2358        return '|'.join(flags)
2359
2360    def __repr__(self):
2361        return '<clinic.Function ' + self.name + '>'
2362
2363    def copy(self, **overrides):
2364        kwargs = {
2365            'name': self.name, 'module': self.module, 'parameters': self.parameters,
2366            'cls': self.cls, 'c_basename': self.c_basename,
2367            'full_name': self.full_name,
2368            'return_converter': self.return_converter, 'return_annotation': self.return_annotation,
2369            'docstring': self.docstring, 'kind': self.kind, 'coexist': self.coexist,
2370            'docstring_only': self.docstring_only,
2371            }
2372        kwargs.update(overrides)
2373        f = Function(**kwargs)
2374
2375        parameters = collections.OrderedDict()
2376        for name, value in f.parameters.items():
2377            value = value.copy(function=f)
2378            parameters[name] = value
2379        f.parameters = parameters
2380        return f
2381
2382
2383class Parameter:
2384    """
2385    Mutable duck type of inspect.Parameter.
2386    """
2387
2388    def __init__(self, name, kind, *, default=inspect.Parameter.empty,
2389                 function, converter, annotation=inspect.Parameter.empty,
2390                 docstring=None, group=0):
2391        self.name = name
2392        self.kind = kind
2393        self.default = default
2394        self.function = function
2395        self.converter = converter
2396        self.annotation = annotation
2397        self.docstring = docstring or ''
2398        self.group = group
2399
2400    def __repr__(self):
2401        return '<clinic.Parameter ' + self.name + '>'
2402
2403    def is_keyword_only(self):
2404        return self.kind == inspect.Parameter.KEYWORD_ONLY
2405
2406    def is_positional_only(self):
2407        return self.kind == inspect.Parameter.POSITIONAL_ONLY
2408
2409    def is_vararg(self):
2410        return self.kind == inspect.Parameter.VAR_POSITIONAL
2411
2412    def is_optional(self):
2413        return not self.is_vararg() and (self.default is not unspecified)
2414
2415    def copy(self, **overrides):
2416        kwargs = {
2417            'name': self.name, 'kind': self.kind, 'default':self.default,
2418                 'function': self.function, 'converter': self.converter, 'annotation': self.annotation,
2419                 'docstring': self.docstring, 'group': self.group,
2420            }
2421        kwargs.update(overrides)
2422        if 'converter' not in overrides:
2423            converter = copy.copy(self.converter)
2424            converter.function = kwargs['function']
2425            kwargs['converter'] = converter
2426        return Parameter(**kwargs)
2427
2428    def get_displayname(self, i):
2429        if i == 0:
2430            return '"argument"'
2431        if not self.is_positional_only():
2432            return '''"argument '{}'"'''.format(self.name)
2433        else:
2434            return '"argument {}"'.format(i)
2435
2436
2437class LandMine:
2438    # try to access any
2439    def __init__(self, message):
2440        self.__message__ = message
2441
2442    def __repr__(self):
2443        return '<LandMine ' + repr(self.__message__) + ">"
2444
2445    def __getattribute__(self, name):
2446        if name in ('__repr__', '__message__'):
2447            return super().__getattribute__(name)
2448        # raise RuntimeError(repr(name))
2449        fail("Stepped on a land mine, trying to access attribute " + repr(name) + ":\n" + self.__message__)
2450
2451
2452def add_c_converter(f, name=None):
2453    if not name:
2454        name = f.__name__
2455        if not name.endswith('_converter'):
2456            return f
2457        name = name[:-len('_converter')]
2458    converters[name] = f
2459    return f
2460
2461def add_default_legacy_c_converter(cls):
2462    # automatically add converter for default format unit
2463    # (but without stomping on the existing one if it's already
2464    # set, in case you subclass)
2465    if ((cls.format_unit not in ('O&', '')) and
2466        (cls.format_unit not in legacy_converters)):
2467        legacy_converters[cls.format_unit] = cls
2468    return cls
2469
2470def add_legacy_c_converter(format_unit, **kwargs):
2471    """
2472    Adds a legacy converter.
2473    """
2474    def closure(f):
2475        if not kwargs:
2476            added_f = f
2477        else:
2478            added_f = functools.partial(f, **kwargs)
2479        if format_unit:
2480            legacy_converters[format_unit] = added_f
2481        return f
2482    return closure
2483
2484class CConverterAutoRegister(type):
2485    def __init__(cls, name, bases, classdict):
2486        add_c_converter(cls)
2487        add_default_legacy_c_converter(cls)
2488
2489class CConverter(metaclass=CConverterAutoRegister):
2490    """
2491    For the init function, self, name, function, and default
2492    must be keyword-or-positional parameters.  All other
2493    parameters must be keyword-only.
2494    """
2495
2496    # The C name to use for this variable.
2497    name = None
2498
2499    # The Python name to use for this variable.
2500    py_name = None
2501
2502    # The C type to use for this variable.
2503    # 'type' should be a Python string specifying the type, e.g. "int".
2504    # If this is a pointer type, the type string should end with ' *'.
2505    type = None
2506
2507    # The Python default value for this parameter, as a Python value.
2508    # Or the magic value "unspecified" if there is no default.
2509    # Or the magic value "unknown" if this value is a cannot be evaluated
2510    # at Argument-Clinic-preprocessing time (but is presumed to be valid
2511    # at runtime).
2512    default = unspecified
2513
2514    # If not None, default must be isinstance() of this type.
2515    # (You can also specify a tuple of types.)
2516    default_type = None
2517
2518    # "default" converted into a C value, as a string.
2519    # Or None if there is no default.
2520    c_default = None
2521
2522    # "default" converted into a Python value, as a string.
2523    # Or None if there is no default.
2524    py_default = None
2525
2526    # The default value used to initialize the C variable when
2527    # there is no default, but not specifying a default may
2528    # result in an "uninitialized variable" warning.  This can
2529    # easily happen when using option groups--although
2530    # properly-written code won't actually use the variable,
2531    # the variable does get passed in to the _impl.  (Ah, if
2532    # only dataflow analysis could inline the static function!)
2533    #
2534    # This value is specified as a string.
2535    # Every non-abstract subclass should supply a valid value.
2536    c_ignored_default = 'NULL'
2537
2538    # The C converter *function* to be used, if any.
2539    # (If this is not None, format_unit must be 'O&'.)
2540    converter = None
2541
2542    # Should Argument Clinic add a '&' before the name of
2543    # the variable when passing it into the _impl function?
2544    impl_by_reference = False
2545
2546    # Should Argument Clinic add a '&' before the name of
2547    # the variable when passing it into PyArg_ParseTuple (AndKeywords)?
2548    parse_by_reference = True
2549
2550    #############################################################
2551    #############################################################
2552    ## You shouldn't need to read anything below this point to ##
2553    ## write your own converter functions.                     ##
2554    #############################################################
2555    #############################################################
2556
2557    # The "format unit" to specify for this variable when
2558    # parsing arguments using PyArg_ParseTuple (AndKeywords).
2559    # Custom converters should always use the default value of 'O&'.
2560    format_unit = 'O&'
2561
2562    # What encoding do we want for this variable?  Only used
2563    # by format units starting with 'e'.
2564    encoding = None
2565
2566    # Should this object be required to be a subclass of a specific type?
2567    # If not None, should be a string representing a pointer to a
2568    # PyTypeObject (e.g. "&PyUnicode_Type").
2569    # Only used by the 'O!' format unit (and the "object" converter).
2570    subclass_of = None
2571
2572    # Do we want an adjacent '_length' variable for this variable?
2573    # Only used by format units ending with '#'.
2574    length = False
2575
2576    # Should we show this parameter in the generated
2577    # __text_signature__? This is *almost* always True.
2578    # (It's only False for __new__, __init__, and METH_STATIC functions.)
2579    show_in_signature = True
2580
2581    # Overrides the name used in a text signature.
2582    # The name used for a "self" parameter must be one of
2583    # self, type, or module; however users can set their own.
2584    # This lets the self_converter overrule the user-settable
2585    # name, *just* for the text signature.
2586    # Only set by self_converter.
2587    signature_name = None
2588
2589    # keep in sync with self_converter.__init__!
2590    def __init__(self, name, py_name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs):
2591        self.name = ensure_legal_c_identifier(name)
2592        self.py_name = py_name
2593
2594        if default is not unspecified:
2595            if self.default_type and not isinstance(default, (self.default_type, Unknown)):
2596                if isinstance(self.default_type, type):
2597                    types_str = self.default_type.__name__
2598                else:
2599                    types_str = ', '.join((cls.__name__ for cls in self.default_type))
2600                fail("{}: default value {!r} for field {} is not of type {}".format(
2601                    self.__class__.__name__, default, name, types_str))
2602            self.default = default
2603
2604        if c_default:
2605            self.c_default = c_default
2606        if py_default:
2607            self.py_default = py_default
2608
2609        if annotation != unspecified:
2610            fail("The 'annotation' parameter is not currently permitted.")
2611
2612        # this is deliberate, to prevent you from caching information
2613        # about the function in the init.
2614        # (that breaks if we get cloned.)
2615        # so after this change we will noisily fail.
2616        self.function = LandMine("Don't access members of self.function inside converter_init!")
2617        self.converter_init(**kwargs)
2618        self.function = function
2619
2620    def converter_init(self):
2621        pass
2622
2623    def is_optional(self):
2624        return (self.default is not unspecified)
2625
2626    def _render_self(self, parameter, data):
2627        self.parameter = parameter
2628        name = self.parser_name
2629
2630        # impl_arguments
2631        s = ("&" if self.impl_by_reference else "") + name
2632        data.impl_arguments.append(s)
2633        if self.length:
2634            data.impl_arguments.append(self.length_name())
2635
2636        # impl_parameters
2637        data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference))
2638        if self.length:
2639            data.impl_parameters.append("Py_ssize_t " + self.length_name())
2640
2641    def _render_non_self(self, parameter, data):
2642        self.parameter = parameter
2643        name = self.name
2644
2645        # declarations
2646        d = self.declaration(in_parser=True)
2647        data.declarations.append(d)
2648
2649        # initializers
2650        initializers = self.initialize()
2651        if initializers:
2652            data.initializers.append('/* initializers for ' + name + ' */\n' + initializers.rstrip())
2653
2654        # modifications
2655        modifications = self.modify()
2656        if modifications:
2657            data.modifications.append('/* modifications for ' + name + ' */\n' + modifications.rstrip())
2658
2659        # keywords
2660        if parameter.is_vararg():
2661            pass
2662        elif parameter.is_positional_only():
2663            data.keywords.append('')
2664        else:
2665            data.keywords.append(parameter.name)
2666
2667        # format_units
2668        if self.is_optional() and '|' not in data.format_units:
2669            data.format_units.append('|')
2670        if parameter.is_keyword_only() and '$' not in data.format_units:
2671            data.format_units.append('$')
2672        data.format_units.append(self.format_unit)
2673
2674        # parse_arguments
2675        self.parse_argument(data.parse_arguments)
2676
2677        # post_parsing
2678        if post_parsing := self.post_parsing():
2679            data.post_parsing.append('/* Post parse cleanup for ' + name + ' */\n' + post_parsing.rstrip() + '\n')
2680
2681        # cleanup
2682        cleanup = self.cleanup()
2683        if cleanup:
2684            data.cleanup.append('/* Cleanup for ' + name + ' */\n' + cleanup.rstrip() + "\n")
2685
2686    def render(self, parameter, data):
2687        """
2688        parameter is a clinic.Parameter instance.
2689        data is a CRenderData instance.
2690        """
2691        self._render_self(parameter, data)
2692        self._render_non_self(parameter, data)
2693
2694    def length_name(self):
2695        """Computes the name of the associated "length" variable."""
2696        if not self.length:
2697            return None
2698        return self.parser_name + "_length"
2699
2700    # Why is this one broken out separately?
2701    # For "positional-only" function parsing,
2702    # which generates a bunch of PyArg_ParseTuple calls.
2703    def parse_argument(self, list):
2704        assert not (self.converter and self.encoding)
2705        if self.format_unit == 'O&':
2706            assert self.converter
2707            list.append(self.converter)
2708
2709        if self.encoding:
2710            list.append(c_repr(self.encoding))
2711        elif self.subclass_of:
2712            list.append(self.subclass_of)
2713
2714        s = ("&" if self.parse_by_reference else "") + self.name
2715        list.append(s)
2716
2717        if self.length:
2718            list.append("&" + self.length_name())
2719
2720    #
2721    # All the functions after here are intended as extension points.
2722    #
2723
2724    def simple_declaration(self, by_reference=False, *, in_parser=False):
2725        """
2726        Computes the basic declaration of the variable.
2727        Used in computing the prototype declaration and the
2728        variable declaration.
2729        """
2730        prototype = [self.type]
2731        if by_reference or not self.type.endswith('*'):
2732            prototype.append(" ")
2733        if by_reference:
2734            prototype.append('*')
2735        if in_parser:
2736            name = self.parser_name
2737        else:
2738            name = self.name
2739        prototype.append(name)
2740        return "".join(prototype)
2741
2742    def declaration(self, *, in_parser=False):
2743        """
2744        The C statement to declare this variable.
2745        """
2746        declaration = [self.simple_declaration(in_parser=True)]
2747        default = self.c_default
2748        if not default and self.parameter.group:
2749            default = self.c_ignored_default
2750        if default:
2751            declaration.append(" = ")
2752            declaration.append(default)
2753        declaration.append(";")
2754        if self.length:
2755            declaration.append('\nPy_ssize_t ')
2756            declaration.append(self.length_name())
2757            declaration.append(';')
2758        return "".join(declaration)
2759
2760    def initialize(self):
2761        """
2762        The C statements required to set up this variable before parsing.
2763        Returns a string containing this code indented at column 0.
2764        If no initialization is necessary, returns an empty string.
2765        """
2766        return ""
2767
2768    def modify(self):
2769        """
2770        The C statements required to modify this variable after parsing.
2771        Returns a string containing this code indented at column 0.
2772        If no initialization is necessary, returns an empty string.
2773        """
2774        return ""
2775
2776    def post_parsing(self):
2777        """
2778        The C statements required to do some operations after the end of parsing but before cleaning up.
2779        Return a string containing this code indented at column 0.
2780        If no operation is necessary, return an empty string.
2781        """
2782        return ""
2783
2784    def cleanup(self):
2785        """
2786        The C statements required to clean up after this variable.
2787        Returns a string containing this code indented at column 0.
2788        If no cleanup is necessary, returns an empty string.
2789        """
2790        return ""
2791
2792    def pre_render(self):
2793        """
2794        A second initialization function, like converter_init,
2795        called just before rendering.
2796        You are permitted to examine self.function here.
2797        """
2798        pass
2799
2800    def parse_arg(self, argname, displayname):
2801        if self.format_unit == 'O&':
2802            return """
2803                if (!{converter}({argname}, &{paramname})) {{{{
2804                    goto exit;
2805                }}}}
2806                """.format(argname=argname, paramname=self.parser_name,
2807                           converter=self.converter)
2808        if self.format_unit == 'O!':
2809            cast = '(%s)' % self.type if self.type != 'PyObject *' else ''
2810            if self.subclass_of in type_checks:
2811                typecheck, typename = type_checks[self.subclass_of]
2812                return """
2813                    if (!{typecheck}({argname})) {{{{
2814                        _PyArg_BadArgument("{{name}}", {displayname}, "{typename}", {argname});
2815                        goto exit;
2816                    }}}}
2817                    {paramname} = {cast}{argname};
2818                    """.format(argname=argname, paramname=self.parser_name,
2819                               displayname=displayname, typecheck=typecheck,
2820                               typename=typename, cast=cast)
2821            return """
2822                if (!PyObject_TypeCheck({argname}, {subclass_of})) {{{{
2823                    _PyArg_BadArgument("{{name}}", {displayname}, ({subclass_of})->tp_name, {argname});
2824                    goto exit;
2825                }}}}
2826                {paramname} = {cast}{argname};
2827                """.format(argname=argname, paramname=self.parser_name,
2828                           subclass_of=self.subclass_of, cast=cast,
2829                           displayname=displayname)
2830        if self.format_unit == 'O':
2831            cast = '(%s)' % self.type if self.type != 'PyObject *' else ''
2832            return """
2833                {paramname} = {cast}{argname};
2834                """.format(argname=argname, paramname=self.parser_name, cast=cast)
2835        return None
2836
2837    def set_template_dict(self, template_dict):
2838        pass
2839
2840    @property
2841    def parser_name(self):
2842        if self.name in CLINIC_PREFIXED_ARGS: # bpo-39741
2843            return CLINIC_PREFIX + self.name
2844        else:
2845            return self.name
2846
2847type_checks = {
2848    '&PyLong_Type': ('PyLong_Check', 'int'),
2849    '&PyTuple_Type': ('PyTuple_Check', 'tuple'),
2850    '&PyList_Type': ('PyList_Check', 'list'),
2851    '&PySet_Type': ('PySet_Check', 'set'),
2852    '&PyFrozenSet_Type': ('PyFrozenSet_Check', 'frozenset'),
2853    '&PyDict_Type': ('PyDict_Check', 'dict'),
2854    '&PyUnicode_Type': ('PyUnicode_Check', 'str'),
2855    '&PyBytes_Type': ('PyBytes_Check', 'bytes'),
2856    '&PyByteArray_Type': ('PyByteArray_Check', 'bytearray'),
2857}
2858
2859
2860class bool_converter(CConverter):
2861    type = 'int'
2862    default_type = bool
2863    format_unit = 'p'
2864    c_ignored_default = '0'
2865
2866    def converter_init(self, *, accept={object}):
2867        if accept == {int}:
2868            self.format_unit = 'i'
2869        elif accept != {object}:
2870            fail("bool_converter: illegal 'accept' argument " + repr(accept))
2871        if self.default is not unspecified:
2872            self.default = bool(self.default)
2873            self.c_default = str(int(self.default))
2874
2875    def parse_arg(self, argname, displayname):
2876        if self.format_unit == 'i':
2877            return """
2878                {paramname} = _PyLong_AsInt({argname});
2879                if ({paramname} == -1 && PyErr_Occurred()) {{{{
2880                    goto exit;
2881                }}}}
2882                """.format(argname=argname, paramname=self.parser_name)
2883        elif self.format_unit == 'p':
2884            return """
2885                {paramname} = PyObject_IsTrue({argname});
2886                if ({paramname} < 0) {{{{
2887                    goto exit;
2888                }}}}
2889                """.format(argname=argname, paramname=self.parser_name)
2890        return super().parse_arg(argname, displayname)
2891
2892class defining_class_converter(CConverter):
2893    """
2894    A special-case converter:
2895    this is the default converter used for the defining class.
2896    """
2897    type = 'PyTypeObject *'
2898    format_unit = ''
2899    show_in_signature = False
2900
2901    def converter_init(self, *, type=None):
2902        self.specified_type = type
2903
2904    def render(self, parameter, data):
2905        self._render_self(parameter, data)
2906
2907    def set_template_dict(self, template_dict):
2908        template_dict['defining_class_name'] = self.name
2909
2910
2911class char_converter(CConverter):
2912    type = 'char'
2913    default_type = (bytes, bytearray)
2914    format_unit = 'c'
2915    c_ignored_default = "'\0'"
2916
2917    def converter_init(self):
2918        if isinstance(self.default, self.default_type):
2919            if len(self.default) != 1:
2920                fail("char_converter: illegal default value " + repr(self.default))
2921
2922            self.c_default = repr(bytes(self.default))[1:]
2923            if self.c_default == '"\'"':
2924                self.c_default = r"'\''"
2925
2926    def parse_arg(self, argname, displayname):
2927        if self.format_unit == 'c':
2928            return """
2929                if (PyBytes_Check({argname}) && PyBytes_GET_SIZE({argname}) == 1) {{{{
2930                    {paramname} = PyBytes_AS_STRING({argname})[0];
2931                }}}}
2932                else if (PyByteArray_Check({argname}) && PyByteArray_GET_SIZE({argname}) == 1) {{{{
2933                    {paramname} = PyByteArray_AS_STRING({argname})[0];
2934                }}}}
2935                else {{{{
2936                    _PyArg_BadArgument("{{name}}", {displayname}, "a byte string of length 1", {argname});
2937                    goto exit;
2938                }}}}
2939                """.format(argname=argname, paramname=self.parser_name,
2940                           displayname=displayname)
2941        return super().parse_arg(argname, displayname)
2942
2943
2944@add_legacy_c_converter('B', bitwise=True)
2945class unsigned_char_converter(CConverter):
2946    type = 'unsigned char'
2947    default_type = int
2948    format_unit = 'b'
2949    c_ignored_default = "'\0'"
2950
2951    def converter_init(self, *, bitwise=False):
2952        if bitwise:
2953            self.format_unit = 'B'
2954
2955    def parse_arg(self, argname, displayname):
2956        if self.format_unit == 'b':
2957            return """
2958                {{{{
2959                    long ival = PyLong_AsLong({argname});
2960                    if (ival == -1 && PyErr_Occurred()) {{{{
2961                        goto exit;
2962                    }}}}
2963                    else if (ival < 0) {{{{
2964                        PyErr_SetString(PyExc_OverflowError,
2965                                        "unsigned byte integer is less than minimum");
2966                        goto exit;
2967                    }}}}
2968                    else if (ival > UCHAR_MAX) {{{{
2969                        PyErr_SetString(PyExc_OverflowError,
2970                                        "unsigned byte integer is greater than maximum");
2971                        goto exit;
2972                    }}}}
2973                    else {{{{
2974                        {paramname} = (unsigned char) ival;
2975                    }}}}
2976                }}}}
2977                """.format(argname=argname, paramname=self.parser_name)
2978        elif self.format_unit == 'B':
2979            return """
2980                {{{{
2981                    unsigned long ival = PyLong_AsUnsignedLongMask({argname});
2982                    if (ival == (unsigned long)-1 && PyErr_Occurred()) {{{{
2983                        goto exit;
2984                    }}}}
2985                    else {{{{
2986                        {paramname} = (unsigned char) ival;
2987                    }}}}
2988                }}}}
2989                """.format(argname=argname, paramname=self.parser_name)
2990        return super().parse_arg(argname, displayname)
2991
2992class byte_converter(unsigned_char_converter): pass
2993
2994class short_converter(CConverter):
2995    type = 'short'
2996    default_type = int
2997    format_unit = 'h'
2998    c_ignored_default = "0"
2999
3000    def parse_arg(self, argname, displayname):
3001        if self.format_unit == 'h':
3002            return """
3003                {{{{
3004                    long ival = PyLong_AsLong({argname});
3005                    if (ival == -1 && PyErr_Occurred()) {{{{
3006                        goto exit;
3007                    }}}}
3008                    else if (ival < SHRT_MIN) {{{{
3009                        PyErr_SetString(PyExc_OverflowError,
3010                                        "signed short integer is less than minimum");
3011                        goto exit;
3012                    }}}}
3013                    else if (ival > SHRT_MAX) {{{{
3014                        PyErr_SetString(PyExc_OverflowError,
3015                                        "signed short integer is greater than maximum");
3016                        goto exit;
3017                    }}}}
3018                    else {{{{
3019                        {paramname} = (short) ival;
3020                    }}}}
3021                }}}}
3022                """.format(argname=argname, paramname=self.parser_name)
3023        return super().parse_arg(argname, displayname)
3024
3025class unsigned_short_converter(CConverter):
3026    type = 'unsigned short'
3027    default_type = int
3028    c_ignored_default = "0"
3029
3030    def converter_init(self, *, bitwise=False):
3031        if bitwise:
3032            self.format_unit = 'H'
3033        else:
3034            self.converter = '_PyLong_UnsignedShort_Converter'
3035
3036    def parse_arg(self, argname, displayname):
3037        if self.format_unit == 'H':
3038            return """
3039                {paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname});
3040                if ({paramname} == (unsigned short)-1 && PyErr_Occurred()) {{{{
3041                    goto exit;
3042                }}}}
3043                """.format(argname=argname, paramname=self.parser_name)
3044        return super().parse_arg(argname, displayname)
3045
3046@add_legacy_c_converter('C', accept={str})
3047class int_converter(CConverter):
3048    type = 'int'
3049    default_type = int
3050    format_unit = 'i'
3051    c_ignored_default = "0"
3052
3053    def converter_init(self, *, accept={int}, type=None):
3054        if accept == {str}:
3055            self.format_unit = 'C'
3056        elif accept != {int}:
3057            fail("int_converter: illegal 'accept' argument " + repr(accept))
3058        if type is not None:
3059            self.type = type
3060
3061    def parse_arg(self, argname, displayname):
3062        if self.format_unit == 'i':
3063            return """
3064                {paramname} = _PyLong_AsInt({argname});
3065                if ({paramname} == -1 && PyErr_Occurred()) {{{{
3066                    goto exit;
3067                }}}}
3068                """.format(argname=argname, paramname=self.parser_name)
3069        elif self.format_unit == 'C':
3070            return """
3071                if (!PyUnicode_Check({argname})) {{{{
3072                    _PyArg_BadArgument("{{name}}", {displayname}, "a unicode character", {argname});
3073                    goto exit;
3074                }}}}
3075                if (PyUnicode_READY({argname})) {{{{
3076                    goto exit;
3077                }}}}
3078                if (PyUnicode_GET_LENGTH({argname}) != 1) {{{{
3079                    _PyArg_BadArgument("{{name}}", {displayname}, "a unicode character", {argname});
3080                    goto exit;
3081                }}}}
3082                {paramname} = PyUnicode_READ_CHAR({argname}, 0);
3083                """.format(argname=argname, paramname=self.parser_name,
3084                           displayname=displayname)
3085        return super().parse_arg(argname, displayname)
3086
3087class unsigned_int_converter(CConverter):
3088    type = 'unsigned int'
3089    default_type = int
3090    c_ignored_default = "0"
3091
3092    def converter_init(self, *, bitwise=False):
3093        if bitwise:
3094            self.format_unit = 'I'
3095        else:
3096            self.converter = '_PyLong_UnsignedInt_Converter'
3097
3098    def parse_arg(self, argname, displayname):
3099        if self.format_unit == 'I':
3100            return """
3101                {paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname});
3102                if ({paramname} == (unsigned int)-1 && PyErr_Occurred()) {{{{
3103                    goto exit;
3104                }}}}
3105                """.format(argname=argname, paramname=self.parser_name)
3106        return super().parse_arg(argname, displayname)
3107
3108class long_converter(CConverter):
3109    type = 'long'
3110    default_type = int
3111    format_unit = 'l'
3112    c_ignored_default = "0"
3113
3114    def parse_arg(self, argname, displayname):
3115        if self.format_unit == 'l':
3116            return """
3117                {paramname} = PyLong_AsLong({argname});
3118                if ({paramname} == -1 && PyErr_Occurred()) {{{{
3119                    goto exit;
3120                }}}}
3121                """.format(argname=argname, paramname=self.parser_name)
3122        return super().parse_arg(argname, displayname)
3123
3124class unsigned_long_converter(CConverter):
3125    type = 'unsigned long'
3126    default_type = int
3127    c_ignored_default = "0"
3128
3129    def converter_init(self, *, bitwise=False):
3130        if bitwise:
3131            self.format_unit = 'k'
3132        else:
3133            self.converter = '_PyLong_UnsignedLong_Converter'
3134
3135    def parse_arg(self, argname, displayname):
3136        if self.format_unit == 'k':
3137            return """
3138                if (!PyLong_Check({argname})) {{{{
3139                    _PyArg_BadArgument("{{name}}", {displayname}, "int", {argname});
3140                    goto exit;
3141                }}}}
3142                {paramname} = PyLong_AsUnsignedLongMask({argname});
3143                """.format(argname=argname, paramname=self.parser_name,
3144                           displayname=displayname)
3145        return super().parse_arg(argname, displayname)
3146
3147class long_long_converter(CConverter):
3148    type = 'long long'
3149    default_type = int
3150    format_unit = 'L'
3151    c_ignored_default = "0"
3152
3153    def parse_arg(self, argname, displayname):
3154        if self.format_unit == 'L':
3155            return """
3156                {paramname} = PyLong_AsLongLong({argname});
3157                if ({paramname} == -1 && PyErr_Occurred()) {{{{
3158                    goto exit;
3159                }}}}
3160                """.format(argname=argname, paramname=self.parser_name)
3161        return super().parse_arg(argname, displayname)
3162
3163class unsigned_long_long_converter(CConverter):
3164    type = 'unsigned long long'
3165    default_type = int
3166    c_ignored_default = "0"
3167
3168    def converter_init(self, *, bitwise=False):
3169        if bitwise:
3170            self.format_unit = 'K'
3171        else:
3172            self.converter = '_PyLong_UnsignedLongLong_Converter'
3173
3174    def parse_arg(self, argname, displayname):
3175        if self.format_unit == 'K':
3176            return """
3177                if (!PyLong_Check({argname})) {{{{
3178                    _PyArg_BadArgument("{{name}}", {displayname}, "int", {argname});
3179                    goto exit;
3180                }}}}
3181                {paramname} = PyLong_AsUnsignedLongLongMask({argname});
3182                """.format(argname=argname, paramname=self.parser_name,
3183                           displayname=displayname)
3184        return super().parse_arg(argname, displayname)
3185
3186class Py_ssize_t_converter(CConverter):
3187    type = 'Py_ssize_t'
3188    c_ignored_default = "0"
3189
3190    def converter_init(self, *, accept={int}):
3191        if accept == {int}:
3192            self.format_unit = 'n'
3193            self.default_type = int
3194        elif accept == {int, NoneType}:
3195            self.converter = '_Py_convert_optional_to_ssize_t'
3196        else:
3197            fail("Py_ssize_t_converter: illegal 'accept' argument " + repr(accept))
3198
3199    def parse_arg(self, argname, displayname):
3200        if self.format_unit == 'n':
3201            return """
3202                {{{{
3203                    Py_ssize_t ival = -1;
3204                    PyObject *iobj = _PyNumber_Index({argname});
3205                    if (iobj != NULL) {{{{
3206                        ival = PyLong_AsSsize_t(iobj);
3207                        Py_DECREF(iobj);
3208                    }}}}
3209                    if (ival == -1 && PyErr_Occurred()) {{{{
3210                        goto exit;
3211                    }}}}
3212                    {paramname} = ival;
3213                }}}}
3214                """.format(argname=argname, paramname=self.parser_name)
3215        return super().parse_arg(argname, displayname)
3216
3217
3218class slice_index_converter(CConverter):
3219    type = 'Py_ssize_t'
3220
3221    def converter_init(self, *, accept={int, NoneType}):
3222        if accept == {int}:
3223            self.converter = '_PyEval_SliceIndexNotNone'
3224        elif accept == {int, NoneType}:
3225            self.converter = '_PyEval_SliceIndex'
3226        else:
3227            fail("slice_index_converter: illegal 'accept' argument " + repr(accept))
3228
3229class size_t_converter(CConverter):
3230    type = 'size_t'
3231    converter = '_PyLong_Size_t_Converter'
3232    c_ignored_default = "0"
3233
3234    def parse_arg(self, argname, displayname):
3235        if self.format_unit == 'n':
3236            return """
3237                {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError);
3238                if ({paramname} == -1 && PyErr_Occurred()) {{{{
3239                    goto exit;
3240                }}}}
3241                """.format(argname=argname, paramname=self.parser_name)
3242        return super().parse_arg(argname, displayname)
3243
3244
3245class fildes_converter(CConverter):
3246    type = 'int'
3247    converter = '_PyLong_FileDescriptor_Converter'
3248
3249    def _parse_arg(self, argname, displayname):
3250        return """
3251            {paramname} = PyObject_AsFileDescriptor({argname});
3252            if ({paramname} == -1) {{{{
3253                goto exit;
3254            }}}}
3255            """.format(argname=argname, paramname=self.name)
3256
3257
3258class float_converter(CConverter):
3259    type = 'float'
3260    default_type = float
3261    format_unit = 'f'
3262    c_ignored_default = "0.0"
3263
3264    def parse_arg(self, argname, displayname):
3265        if self.format_unit == 'f':
3266            return """
3267                if (PyFloat_CheckExact({argname})) {{{{
3268                    {paramname} = (float) (PyFloat_AS_DOUBLE({argname}));
3269                }}}}
3270                else
3271                {{{{
3272                    {paramname} = (float) PyFloat_AsDouble({argname});
3273                    if ({paramname} == -1.0 && PyErr_Occurred()) {{{{
3274                        goto exit;
3275                    }}}}
3276                }}}}
3277                """.format(argname=argname, paramname=self.parser_name)
3278        return super().parse_arg(argname, displayname)
3279
3280class double_converter(CConverter):
3281    type = 'double'
3282    default_type = float
3283    format_unit = 'd'
3284    c_ignored_default = "0.0"
3285
3286    def parse_arg(self, argname, displayname):
3287        if self.format_unit == 'd':
3288            return """
3289                if (PyFloat_CheckExact({argname})) {{{{
3290                    {paramname} = PyFloat_AS_DOUBLE({argname});
3291                }}}}
3292                else
3293                {{{{
3294                    {paramname} = PyFloat_AsDouble({argname});
3295                    if ({paramname} == -1.0 && PyErr_Occurred()) {{{{
3296                        goto exit;
3297                    }}}}
3298                }}}}
3299                """.format(argname=argname, paramname=self.parser_name)
3300        return super().parse_arg(argname, displayname)
3301
3302
3303class Py_complex_converter(CConverter):
3304    type = 'Py_complex'
3305    default_type = complex
3306    format_unit = 'D'
3307    c_ignored_default = "{0.0, 0.0}"
3308
3309    def parse_arg(self, argname, displayname):
3310        if self.format_unit == 'D':
3311            return """
3312                {paramname} = PyComplex_AsCComplex({argname});
3313                if (PyErr_Occurred()) {{{{
3314                    goto exit;
3315                }}}}
3316                """.format(argname=argname, paramname=self.parser_name)
3317        return super().parse_arg(argname, displayname)
3318
3319
3320class object_converter(CConverter):
3321    type = 'PyObject *'
3322    format_unit = 'O'
3323
3324    def converter_init(self, *, converter=None, type=None, subclass_of=None):
3325        if converter:
3326            if subclass_of:
3327                fail("object: Cannot pass in both 'converter' and 'subclass_of'")
3328            self.format_unit = 'O&'
3329            self.converter = converter
3330        elif subclass_of:
3331            self.format_unit = 'O!'
3332            self.subclass_of = subclass_of
3333
3334        if type is not None:
3335            self.type = type
3336
3337
3338#
3339# We define three conventions for buffer types in the 'accept' argument:
3340#
3341#  buffer  : any object supporting the buffer interface
3342#  rwbuffer: any object supporting the buffer interface, but must be writeable
3343#  robuffer: any object supporting the buffer interface, but must not be writeable
3344#
3345
3346class buffer: pass
3347class rwbuffer: pass
3348class robuffer: pass
3349
3350def str_converter_key(types, encoding, zeroes):
3351    return (frozenset(types), bool(encoding), bool(zeroes))
3352
3353str_converter_argument_map = {}
3354
3355class str_converter(CConverter):
3356    type = 'const char *'
3357    default_type = (str, Null, NoneType)
3358    format_unit = 's'
3359
3360    def converter_init(self, *, accept={str}, encoding=None, zeroes=False):
3361
3362        key = str_converter_key(accept, encoding, zeroes)
3363        format_unit = str_converter_argument_map.get(key)
3364        if not format_unit:
3365            fail("str_converter: illegal combination of arguments", key)
3366
3367        self.format_unit = format_unit
3368        self.length = bool(zeroes)
3369        if encoding:
3370            if self.default not in (Null, None, unspecified):
3371                fail("str_converter: Argument Clinic doesn't support default values for encoded strings")
3372            self.encoding = encoding
3373            self.type = 'char *'
3374            # sorry, clinic can't support preallocated buffers
3375            # for es# and et#
3376            self.c_default = "NULL"
3377        if NoneType in accept and self.c_default == "Py_None":
3378            self.c_default = "NULL"
3379
3380    def post_parsing(self):
3381        if self.encoding:
3382            name = self.name
3383            return f"PyMem_FREE({name});\n"
3384
3385    def parse_arg(self, argname, displayname):
3386        if self.format_unit == 's':
3387            return """
3388                if (!PyUnicode_Check({argname})) {{{{
3389                    _PyArg_BadArgument("{{name}}", {displayname}, "str", {argname});
3390                    goto exit;
3391                }}}}
3392                Py_ssize_t {paramname}_length;
3393                {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{paramname}_length);
3394                if ({paramname} == NULL) {{{{
3395                    goto exit;
3396                }}}}
3397                if (strlen({paramname}) != (size_t){paramname}_length) {{{{
3398                    PyErr_SetString(PyExc_ValueError, "embedded null character");
3399                    goto exit;
3400                }}}}
3401                """.format(argname=argname, paramname=self.parser_name,
3402                           displayname=displayname)
3403        if self.format_unit == 'z':
3404            return """
3405                if ({argname} == Py_None) {{{{
3406                    {paramname} = NULL;
3407                }}}}
3408                else if (PyUnicode_Check({argname})) {{{{
3409                    Py_ssize_t {paramname}_length;
3410                    {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{paramname}_length);
3411                    if ({paramname} == NULL) {{{{
3412                        goto exit;
3413                    }}}}
3414                    if (strlen({paramname}) != (size_t){paramname}_length) {{{{
3415                        PyErr_SetString(PyExc_ValueError, "embedded null character");
3416                        goto exit;
3417                    }}}}
3418                }}}}
3419                else {{{{
3420                    _PyArg_BadArgument("{{name}}", {displayname}, "str or None", {argname});
3421                    goto exit;
3422                }}}}
3423                """.format(argname=argname, paramname=self.parser_name,
3424                           displayname=displayname)
3425        return super().parse_arg(argname, displayname)
3426
3427#
3428# This is the fourth or fifth rewrite of registering all the
3429# string converter format units.  Previous approaches hid
3430# bugs--generally mismatches between the semantics of the format
3431# unit and the arguments necessary to represent those semantics
3432# properly.  Hopefully with this approach we'll get it 100% right.
3433#
3434# The r() function (short for "register") both registers the
3435# mapping from arguments to format unit *and* registers the
3436# legacy C converter for that format unit.
3437#
3438def r(format_unit, *, accept, encoding=False, zeroes=False):
3439    if not encoding and format_unit != 's':
3440        # add the legacy c converters here too.
3441        #
3442        # note: add_legacy_c_converter can't work for
3443        #   es, es#, et, or et#
3444        #   because of their extra encoding argument
3445        #
3446        # also don't add the converter for 's' because
3447        # the metaclass for CConverter adds it for us.
3448        kwargs = {}
3449        if accept != {str}:
3450            kwargs['accept'] = accept
3451        if zeroes:
3452            kwargs['zeroes'] = True
3453        added_f = functools.partial(str_converter, **kwargs)
3454        legacy_converters[format_unit] = added_f
3455
3456    d = str_converter_argument_map
3457    key = str_converter_key(accept, encoding, zeroes)
3458    if key in d:
3459        sys.exit("Duplicate keys specified for str_converter_argument_map!")
3460    d[key] = format_unit
3461
3462r('es',  encoding=True,              accept={str})
3463r('es#', encoding=True, zeroes=True, accept={str})
3464r('et',  encoding=True,              accept={bytes, bytearray, str})
3465r('et#', encoding=True, zeroes=True, accept={bytes, bytearray, str})
3466r('s',                               accept={str})
3467r('s#',                 zeroes=True, accept={robuffer, str})
3468r('y',                               accept={robuffer})
3469r('y#',                 zeroes=True, accept={robuffer})
3470r('z',                               accept={str, NoneType})
3471r('z#',                 zeroes=True, accept={robuffer, str, NoneType})
3472del r
3473
3474
3475class PyBytesObject_converter(CConverter):
3476    type = 'PyBytesObject *'
3477    format_unit = 'S'
3478    # accept = {bytes}
3479
3480    def parse_arg(self, argname, displayname):
3481        if self.format_unit == 'S':
3482            return """
3483                if (!PyBytes_Check({argname})) {{{{
3484                    _PyArg_BadArgument("{{name}}", {displayname}, "bytes", {argname});
3485                    goto exit;
3486                }}}}
3487                {paramname} = ({type}){argname};
3488                """.format(argname=argname, paramname=self.parser_name,
3489                           type=self.type, displayname=displayname)
3490        return super().parse_arg(argname, displayname)
3491
3492class PyByteArrayObject_converter(CConverter):
3493    type = 'PyByteArrayObject *'
3494    format_unit = 'Y'
3495    # accept = {bytearray}
3496
3497    def parse_arg(self, argname, displayname):
3498        if self.format_unit == 'Y':
3499            return """
3500                if (!PyByteArray_Check({argname})) {{{{
3501                    _PyArg_BadArgument("{{name}}", {displayname}, "bytearray", {argname});
3502                    goto exit;
3503                }}}}
3504                {paramname} = ({type}){argname};
3505                """.format(argname=argname, paramname=self.parser_name,
3506                           type=self.type, displayname=displayname)
3507        return super().parse_arg(argname, displayname)
3508
3509class unicode_converter(CConverter):
3510    type = 'PyObject *'
3511    default_type = (str, Null, NoneType)
3512    format_unit = 'U'
3513
3514    def parse_arg(self, argname, displayname):
3515        if self.format_unit == 'U':
3516            return """
3517                if (!PyUnicode_Check({argname})) {{{{
3518                    _PyArg_BadArgument("{{name}}", {displayname}, "str", {argname});
3519                    goto exit;
3520                }}}}
3521                if (PyUnicode_READY({argname}) == -1) {{{{
3522                    goto exit;
3523                }}}}
3524                {paramname} = {argname};
3525                """.format(argname=argname, paramname=self.parser_name,
3526                           displayname=displayname)
3527        return super().parse_arg(argname, displayname)
3528
3529@add_legacy_c_converter('u')
3530@add_legacy_c_converter('u#', zeroes=True)
3531@add_legacy_c_converter('Z', accept={str, NoneType})
3532@add_legacy_c_converter('Z#', accept={str, NoneType}, zeroes=True)
3533class Py_UNICODE_converter(CConverter):
3534    type = 'const Py_UNICODE *'
3535    default_type = (str, Null, NoneType)
3536
3537    def converter_init(self, *, accept={str}, zeroes=False):
3538        format_unit = 'Z' if accept=={str, NoneType} else 'u'
3539        if zeroes:
3540            format_unit += '#'
3541            self.length = True
3542            self.format_unit = format_unit
3543        else:
3544            self.accept = accept
3545            if accept == {str}:
3546                self.converter = '_PyUnicode_WideCharString_Converter'
3547            elif accept == {str, NoneType}:
3548                self.converter = '_PyUnicode_WideCharString_Opt_Converter'
3549            else:
3550                fail("Py_UNICODE_converter: illegal 'accept' argument " + repr(accept))
3551        self.c_default = "NULL"
3552
3553    def cleanup(self):
3554        if not self.length:
3555            return """\
3556#if !USE_UNICODE_WCHAR_CACHE
3557PyMem_Free((void *){name});
3558#endif /* USE_UNICODE_WCHAR_CACHE */
3559""".format(name=self.name)
3560
3561    def parse_arg(self, argname, argnum):
3562        if not self.length:
3563            if self.accept == {str}:
3564                return """
3565                    if (!PyUnicode_Check({argname})) {{{{
3566                        _PyArg_BadArgument("{{name}}", {argnum}, "str", {argname});
3567                        goto exit;
3568                    }}}}
3569                    #if USE_UNICODE_WCHAR_CACHE
3570                    {paramname} = _PyUnicode_AsUnicode({argname});
3571                    #else /* USE_UNICODE_WCHAR_CACHE */
3572                    {paramname} = PyUnicode_AsWideCharString({argname}, NULL);
3573                    #endif /* USE_UNICODE_WCHAR_CACHE */
3574                    if ({paramname} == NULL) {{{{
3575                        goto exit;
3576                    }}}}
3577                    """.format(argname=argname, paramname=self.name, argnum=argnum)
3578            elif self.accept == {str, NoneType}:
3579                return """
3580                    if ({argname} == Py_None) {{{{
3581                        {paramname} = NULL;
3582                    }}}}
3583                    else if (PyUnicode_Check({argname})) {{{{
3584                        #if USE_UNICODE_WCHAR_CACHE
3585                        {paramname} = _PyUnicode_AsUnicode({argname});
3586                        #else /* USE_UNICODE_WCHAR_CACHE */
3587                        {paramname} = PyUnicode_AsWideCharString({argname}, NULL);
3588                        #endif /* USE_UNICODE_WCHAR_CACHE */
3589                        if ({paramname} == NULL) {{{{
3590                            goto exit;
3591                        }}}}
3592                    }}}}
3593                    else {{{{
3594                        _PyArg_BadArgument("{{name}}", {argnum}, "str or None", {argname});
3595                        goto exit;
3596                    }}}}
3597                    """.format(argname=argname, paramname=self.name, argnum=argnum)
3598        return super().parse_arg(argname, argnum)
3599
3600@add_legacy_c_converter('s*', accept={str, buffer})
3601@add_legacy_c_converter('z*', accept={str, buffer, NoneType})
3602@add_legacy_c_converter('w*', accept={rwbuffer})
3603class Py_buffer_converter(CConverter):
3604    type = 'Py_buffer'
3605    format_unit = 'y*'
3606    impl_by_reference = True
3607    c_ignored_default = "{NULL, NULL}"
3608
3609    def converter_init(self, *, accept={buffer}):
3610        if self.default not in (unspecified, None):
3611            fail("The only legal default value for Py_buffer is None.")
3612
3613        self.c_default = self.c_ignored_default
3614
3615        if accept == {str, buffer, NoneType}:
3616            format_unit = 'z*'
3617        elif accept == {str, buffer}:
3618            format_unit = 's*'
3619        elif accept == {buffer}:
3620            format_unit = 'y*'
3621        elif accept == {rwbuffer}:
3622            format_unit = 'w*'
3623        else:
3624            fail("Py_buffer_converter: illegal combination of arguments")
3625
3626        self.format_unit = format_unit
3627
3628    def cleanup(self):
3629        name = self.name
3630        return "".join(["if (", name, ".obj) {\n   PyBuffer_Release(&", name, ");\n}\n"])
3631
3632    def parse_arg(self, argname, displayname):
3633        if self.format_unit == 'y*':
3634            return """
3635                if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{
3636                    goto exit;
3637                }}}}
3638                if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{
3639                    _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname});
3640                    goto exit;
3641                }}}}
3642                """.format(argname=argname, paramname=self.parser_name,
3643                           displayname=displayname)
3644        elif self.format_unit == 's*':
3645            return """
3646                if (PyUnicode_Check({argname})) {{{{
3647                    Py_ssize_t len;
3648                    const char *ptr = PyUnicode_AsUTF8AndSize({argname}, &len);
3649                    if (ptr == NULL) {{{{
3650                        goto exit;
3651                    }}}}
3652                    PyBuffer_FillInfo(&{paramname}, {argname}, (void *)ptr, len, 1, 0);
3653                }}}}
3654                else {{{{ /* any bytes-like object */
3655                    if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{
3656                        goto exit;
3657                    }}}}
3658                    if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{
3659                        _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname});
3660                        goto exit;
3661                    }}}}
3662                }}}}
3663                """.format(argname=argname, paramname=self.parser_name,
3664                           displayname=displayname)
3665        elif self.format_unit == 'w*':
3666            return """
3667                if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_WRITABLE) < 0) {{{{
3668                    PyErr_Clear();
3669                    _PyArg_BadArgument("{{name}}", {displayname}, "read-write bytes-like object", {argname});
3670                    goto exit;
3671                }}}}
3672                if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{
3673                    _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname});
3674                    goto exit;
3675                }}}}
3676                """.format(argname=argname, paramname=self.parser_name,
3677                           displayname=displayname)
3678        return super().parse_arg(argname, displayname)
3679
3680
3681def correct_name_for_self(f):
3682    if f.kind in (CALLABLE, METHOD_INIT):
3683        if f.cls:
3684            return "PyObject *", "self"
3685        return "PyObject *", "module"
3686    if f.kind == STATIC_METHOD:
3687        return "void *", "null"
3688    if f.kind in (CLASS_METHOD, METHOD_NEW):
3689        return "PyTypeObject *", "type"
3690    raise RuntimeError("Unhandled type of function f: " + repr(f.kind))
3691
3692def required_type_for_self_for_parser(f):
3693    type, _ = correct_name_for_self(f)
3694    if f.kind in (METHOD_INIT, METHOD_NEW, STATIC_METHOD, CLASS_METHOD):
3695        return type
3696    return None
3697
3698
3699class self_converter(CConverter):
3700    """
3701    A special-case converter:
3702    this is the default converter used for "self".
3703    """
3704    type = None
3705    format_unit = ''
3706
3707    def converter_init(self, *, type=None):
3708        self.specified_type = type
3709
3710    def pre_render(self):
3711        f = self.function
3712        default_type, default_name = correct_name_for_self(f)
3713        self.signature_name = default_name
3714        self.type = self.specified_type or self.type or default_type
3715
3716        kind = self.function.kind
3717        new_or_init = kind in (METHOD_NEW, METHOD_INIT)
3718
3719        if (kind == STATIC_METHOD) or new_or_init:
3720            self.show_in_signature = False
3721
3722    # tp_new (METHOD_NEW) functions are of type newfunc:
3723    #     typedef PyObject *(*newfunc)(PyTypeObject *, PyObject *, PyObject *);
3724    #
3725    # tp_init (METHOD_INIT) functions are of type initproc:
3726    #     typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
3727    #
3728    # All other functions generated by Argument Clinic are stored in
3729    # PyMethodDef structures, in the ml_meth slot, which is of type PyCFunction:
3730    #     typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
3731    # However!  We habitually cast these functions to PyCFunction,
3732    # since functions that accept keyword arguments don't fit this signature
3733    # but are stored there anyway.  So strict type equality isn't important
3734    # for these functions.
3735    #
3736    # So:
3737    #
3738    # * The name of the first parameter to the impl and the parsing function will always
3739    #   be self.name.
3740    #
3741    # * The type of the first parameter to the impl will always be of self.type.
3742    #
3743    # * If the function is neither tp_new (METHOD_NEW) nor tp_init (METHOD_INIT):
3744    #   * The type of the first parameter to the parsing function is also self.type.
3745    #     This means that if you step into the parsing function, your "self" parameter
3746    #     is of the correct type, which may make debugging more pleasant.
3747    #
3748    # * Else if the function is tp_new (METHOD_NEW):
3749    #   * The type of the first parameter to the parsing function is "PyTypeObject *",
3750    #     so the type signature of the function call is an exact match.
3751    #   * If self.type != "PyTypeObject *", we cast the first parameter to self.type
3752    #     in the impl call.
3753    #
3754    # * Else if the function is tp_init (METHOD_INIT):
3755    #   * The type of the first parameter to the parsing function is "PyObject *",
3756    #     so the type signature of the function call is an exact match.
3757    #   * If self.type != "PyObject *", we cast the first parameter to self.type
3758    #     in the impl call.
3759
3760    @property
3761    def parser_type(self):
3762        return required_type_for_self_for_parser(self.function) or self.type
3763
3764    def render(self, parameter, data):
3765        """
3766        parameter is a clinic.Parameter instance.
3767        data is a CRenderData instance.
3768        """
3769        if self.function.kind == STATIC_METHOD:
3770            return
3771
3772        self._render_self(parameter, data)
3773
3774        if self.type != self.parser_type:
3775            # insert cast to impl_argument[0], aka self.
3776            # we know we're in the first slot in all the CRenderData lists,
3777            # because we render parameters in order, and self is always first.
3778            assert len(data.impl_arguments) == 1
3779            assert data.impl_arguments[0] == self.name
3780            data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0]
3781
3782    def set_template_dict(self, template_dict):
3783        template_dict['self_name'] = self.name
3784        template_dict['self_type'] = self.parser_type
3785        kind = self.function.kind
3786        cls = self.function.cls
3787
3788        if ((kind in (METHOD_NEW, METHOD_INIT)) and cls and cls.typedef):
3789            type_object = self.function.cls.type_object
3790            prefix = (type_object[1:] + '.' if type_object[0] == '&' else
3791                      type_object + '->')
3792            if kind == METHOD_NEW:
3793                type_check = ('({0} == {1} ||\n        '
3794                              ' {0}->tp_init == {2}tp_init)'
3795                             ).format(self.name, type_object, prefix)
3796            else:
3797                type_check = ('(Py_IS_TYPE({0}, {1}) ||\n        '
3798                              ' Py_TYPE({0})->tp_new == {2}tp_new)'
3799                             ).format(self.name, type_object, prefix)
3800
3801            line = '{} &&\n        '.format(type_check)
3802            template_dict['self_type_check'] = line
3803
3804
3805
3806def add_c_return_converter(f, name=None):
3807    if not name:
3808        name = f.__name__
3809        if not name.endswith('_return_converter'):
3810            return f
3811        name = name[:-len('_return_converter')]
3812    return_converters[name] = f
3813    return f
3814
3815
3816class CReturnConverterAutoRegister(type):
3817    def __init__(cls, name, bases, classdict):
3818        add_c_return_converter(cls)
3819
3820class CReturnConverter(metaclass=CReturnConverterAutoRegister):
3821
3822    # The C type to use for this variable.
3823    # 'type' should be a Python string specifying the type, e.g. "int".
3824    # If this is a pointer type, the type string should end with ' *'.
3825    type = 'PyObject *'
3826
3827    # The Python default value for this parameter, as a Python value.
3828    # Or the magic value "unspecified" if there is no default.
3829    default = None
3830
3831    def __init__(self, *, py_default=None, **kwargs):
3832        self.py_default = py_default
3833        try:
3834            self.return_converter_init(**kwargs)
3835        except TypeError as e:
3836            s = ', '.join(name + '=' + repr(value) for name, value in kwargs.items())
3837            sys.exit(self.__class__.__name__ + '(' + s + ')\n' + str(e))
3838
3839    def return_converter_init(self):
3840        pass
3841
3842    def declare(self, data, name="_return_value"):
3843        line = []
3844        add = line.append
3845        add(self.type)
3846        if not self.type.endswith('*'):
3847            add(' ')
3848        add(name + ';')
3849        data.declarations.append(''.join(line))
3850        data.return_value = name
3851
3852    def err_occurred_if(self, expr, data):
3853        data.return_conversion.append('if (({}) && PyErr_Occurred()) {{\n    goto exit;\n}}\n'.format(expr))
3854
3855    def err_occurred_if_null_pointer(self, variable, data):
3856        data.return_conversion.append('if ({} == NULL) {{\n    goto exit;\n}}\n'.format(variable))
3857
3858    def render(self, function, data):
3859        """
3860        function is a clinic.Function instance.
3861        data is a CRenderData instance.
3862        """
3863        pass
3864
3865add_c_return_converter(CReturnConverter, 'object')
3866
3867class NoneType_return_converter(CReturnConverter):
3868    def render(self, function, data):
3869        self.declare(data)
3870        data.return_conversion.append('''
3871if (_return_value != Py_None) {
3872    goto exit;
3873}
3874return_value = Py_None;
3875Py_INCREF(Py_None);
3876'''.strip())
3877
3878class bool_return_converter(CReturnConverter):
3879    type = 'int'
3880
3881    def render(self, function, data):
3882        self.declare(data)
3883        self.err_occurred_if("_return_value == -1", data)
3884        data.return_conversion.append('return_value = PyBool_FromLong((long)_return_value);\n')
3885
3886class long_return_converter(CReturnConverter):
3887    type = 'long'
3888    conversion_fn = 'PyLong_FromLong'
3889    cast = ''
3890    unsigned_cast = ''
3891
3892    def render(self, function, data):
3893        self.declare(data)
3894        self.err_occurred_if("_return_value == {}-1".format(self.unsigned_cast), data)
3895        data.return_conversion.append(
3896            ''.join(('return_value = ', self.conversion_fn, '(', self.cast, '_return_value);\n')))
3897
3898class int_return_converter(long_return_converter):
3899    type = 'int'
3900    cast = '(long)'
3901
3902class init_return_converter(long_return_converter):
3903    """
3904    Special return converter for __init__ functions.
3905    """
3906    type = 'int'
3907    cast = '(long)'
3908
3909    def render(self, function, data):
3910        pass
3911
3912class unsigned_long_return_converter(long_return_converter):
3913    type = 'unsigned long'
3914    conversion_fn = 'PyLong_FromUnsignedLong'
3915    unsigned_cast = '(unsigned long)'
3916
3917class unsigned_int_return_converter(unsigned_long_return_converter):
3918    type = 'unsigned int'
3919    cast = '(unsigned long)'
3920    unsigned_cast = '(unsigned int)'
3921
3922class Py_ssize_t_return_converter(long_return_converter):
3923    type = 'Py_ssize_t'
3924    conversion_fn = 'PyLong_FromSsize_t'
3925
3926class size_t_return_converter(long_return_converter):
3927    type = 'size_t'
3928    conversion_fn = 'PyLong_FromSize_t'
3929    unsigned_cast = '(size_t)'
3930
3931
3932class double_return_converter(CReturnConverter):
3933    type = 'double'
3934    cast = ''
3935
3936    def render(self, function, data):
3937        self.declare(data)
3938        self.err_occurred_if("_return_value == -1.0", data)
3939        data.return_conversion.append(
3940            'return_value = PyFloat_FromDouble(' + self.cast + '_return_value);\n')
3941
3942class float_return_converter(double_return_converter):
3943    type = 'float'
3944    cast = '(double)'
3945
3946
3947def eval_ast_expr(node, globals, *, filename='-'):
3948    """
3949    Takes an ast.Expr node.  Compiles and evaluates it.
3950    Returns the result of the expression.
3951
3952    globals represents the globals dict the expression
3953    should see.  (There's no equivalent for "locals" here.)
3954    """
3955
3956    if isinstance(node, ast.Expr):
3957        node = node.value
3958
3959    node = ast.Expression(node)
3960    co = compile(node, filename, 'eval')
3961    fn = types.FunctionType(co, globals)
3962    return fn()
3963
3964
3965class IndentStack:
3966    def __init__(self):
3967        self.indents = []
3968        self.margin = None
3969
3970    def _ensure(self):
3971        if not self.indents:
3972            fail('IndentStack expected indents, but none are defined.')
3973
3974    def measure(self, line):
3975        """
3976        Returns the length of the line's margin.
3977        """
3978        if '\t' in line:
3979            fail('Tab characters are illegal in the Argument Clinic DSL.')
3980        stripped = line.lstrip()
3981        if not len(stripped):
3982            # we can't tell anything from an empty line
3983            # so just pretend it's indented like our current indent
3984            self._ensure()
3985            return self.indents[-1]
3986        return len(line) - len(stripped)
3987
3988    def infer(self, line):
3989        """
3990        Infer what is now the current margin based on this line.
3991        Returns:
3992            1 if we have indented (or this is the first margin)
3993            0 if the margin has not changed
3994           -N if we have dedented N times
3995        """
3996        indent = self.measure(line)
3997        margin = ' ' * indent
3998        if not self.indents:
3999            self.indents.append(indent)
4000            self.margin = margin
4001            return 1
4002        current = self.indents[-1]
4003        if indent == current:
4004            return 0
4005        if indent > current:
4006            self.indents.append(indent)
4007            self.margin = margin
4008            return 1
4009        # indent < current
4010        if indent not in self.indents:
4011            fail("Illegal outdent.")
4012        outdent_count = 0
4013        while indent != current:
4014            self.indents.pop()
4015            current = self.indents[-1]
4016            outdent_count -= 1
4017        self.margin = margin
4018        return outdent_count
4019
4020    @property
4021    def depth(self):
4022        """
4023        Returns how many margins are currently defined.
4024        """
4025        return len(self.indents)
4026
4027    def indent(self, line):
4028        """
4029        Indents a line by the currently defined margin.
4030        """
4031        return self.margin + line
4032
4033    def dedent(self, line):
4034        """
4035        Dedents a line by the currently defined margin.
4036        (The inverse of 'indent'.)
4037        """
4038        margin = self.margin
4039        indent = self.indents[-1]
4040        if not line.startswith(margin):
4041            fail('Cannot dedent, line does not start with the previous margin:')
4042        return line[indent:]
4043
4044
4045class DSLParser:
4046    def __init__(self, clinic):
4047        self.clinic = clinic
4048
4049        self.directives = {}
4050        for name in dir(self):
4051            # functions that start with directive_ are added to directives
4052            _, s, key = name.partition("directive_")
4053            if s:
4054                self.directives[key] = getattr(self, name)
4055
4056            # functions that start with at_ are too, with an @ in front
4057            _, s, key = name.partition("at_")
4058            if s:
4059                self.directives['@' + key] = getattr(self, name)
4060
4061        self.reset()
4062
4063    def reset(self):
4064        self.function = None
4065        self.state = self.state_dsl_start
4066        self.parameter_indent = None
4067        self.keyword_only = False
4068        self.positional_only = False
4069        self.group = 0
4070        self.parameter_state = self.ps_start
4071        self.seen_positional_with_default = False
4072        self.indent = IndentStack()
4073        self.kind = CALLABLE
4074        self.coexist = False
4075        self.parameter_continuation = ''
4076        self.preserve_output = False
4077
4078    def directive_version(self, required):
4079        global version
4080        if version_comparitor(version, required) < 0:
4081            fail("Insufficient Clinic version!\n  Version: " + version + "\n  Required: " + required)
4082
4083    def directive_module(self, name):
4084        fields = name.split('.')
4085        new = fields.pop()
4086        module, cls = self.clinic._module_and_class(fields)
4087        if cls:
4088            fail("Can't nest a module inside a class!")
4089
4090        if name in module.classes:
4091            fail("Already defined module " + repr(name) + "!")
4092
4093        m = Module(name, module)
4094        module.modules[name] = m
4095        self.block.signatures.append(m)
4096
4097    def directive_class(self, name, typedef, type_object):
4098        fields = name.split('.')
4099        in_classes = False
4100        parent = self
4101        name = fields.pop()
4102        so_far = []
4103        module, cls = self.clinic._module_and_class(fields)
4104
4105        parent = cls or module
4106        if name in parent.classes:
4107            fail("Already defined class " + repr(name) + "!")
4108
4109        c = Class(name, module, cls, typedef, type_object)
4110        parent.classes[name] = c
4111        self.block.signatures.append(c)
4112
4113    def directive_set(self, name, value):
4114        if name not in ("line_prefix", "line_suffix"):
4115            fail("unknown variable", repr(name))
4116
4117        value = value.format_map({
4118            'block comment start': '/*',
4119            'block comment end': '*/',
4120            })
4121
4122        self.clinic.__dict__[name] = value
4123
4124    def directive_destination(self, name, command, *args):
4125        if command == 'new':
4126            self.clinic.add_destination(name, *args)
4127            return
4128
4129        if command == 'clear':
4130            self.clinic.get_destination(name).clear()
4131        fail("unknown destination command", repr(command))
4132
4133
4134    def directive_output(self, command_or_name, destination=''):
4135        fd = self.clinic.destination_buffers
4136
4137        if command_or_name == "preset":
4138            preset = self.clinic.presets.get(destination)
4139            if not preset:
4140                fail("Unknown preset " + repr(destination) + "!")
4141            fd.update(preset)
4142            return
4143
4144        if command_or_name == "push":
4145            self.clinic.destination_buffers_stack.append(fd.copy())
4146            return
4147
4148        if command_or_name == "pop":
4149            if not self.clinic.destination_buffers_stack:
4150                fail("Can't 'output pop', stack is empty!")
4151            previous_fd = self.clinic.destination_buffers_stack.pop()
4152            fd.update(previous_fd)
4153            return
4154
4155        # secret command for debugging!
4156        if command_or_name == "print":
4157            self.block.output.append(pprint.pformat(fd))
4158            self.block.output.append('\n')
4159            return
4160
4161        d = self.clinic.get_destination_buffer(destination)
4162
4163        if command_or_name == "everything":
4164            for name in list(fd):
4165                fd[name] = d
4166            return
4167
4168        if command_or_name not in fd:
4169            fail("Invalid command / destination name " + repr(command_or_name) + ", must be one of:\n  preset push pop print everything " + " ".join(fd))
4170        fd[command_or_name] = d
4171
4172    def directive_dump(self, name):
4173        self.block.output.append(self.clinic.get_destination(name).dump())
4174
4175    def directive_printout(self, *args):
4176        self.block.output.append(' '.join(args))
4177        self.block.output.append('\n')
4178
4179    def directive_preserve(self):
4180        if self.preserve_output:
4181            fail("Can't have preserve twice in one block!")
4182        self.preserve_output = True
4183
4184    def at_classmethod(self):
4185        if self.kind is not CALLABLE:
4186            fail("Can't set @classmethod, function is not a normal callable")
4187        self.kind = CLASS_METHOD
4188
4189    def at_staticmethod(self):
4190        if self.kind is not CALLABLE:
4191            fail("Can't set @staticmethod, function is not a normal callable")
4192        self.kind = STATIC_METHOD
4193
4194    def at_coexist(self):
4195        if self.coexist:
4196            fail("Called @coexist twice!")
4197        self.coexist = True
4198
4199    def parse(self, block):
4200        self.reset()
4201        self.block = block
4202        self.saved_output = self.block.output
4203        block.output = []
4204        block_start = self.clinic.block_parser.line_number
4205        lines = block.input.split('\n')
4206        for line_number, line in enumerate(lines, self.clinic.block_parser.block_start_line_number):
4207            if '\t' in line:
4208                fail('Tab characters are illegal in the Clinic DSL.\n\t' + repr(line), line_number=block_start)
4209            self.state(line)
4210
4211        self.next(self.state_terminal)
4212        self.state(None)
4213
4214        block.output.extend(self.clinic.language.render(clinic, block.signatures))
4215
4216        if self.preserve_output:
4217            if block.output:
4218                fail("'preserve' only works for blocks that don't produce any output!")
4219            block.output = self.saved_output
4220
4221    @staticmethod
4222    def ignore_line(line):
4223        # ignore comment-only lines
4224        if line.lstrip().startswith('#'):
4225            return True
4226
4227        # Ignore empty lines too
4228        # (but not in docstring sections!)
4229        if not line.strip():
4230            return True
4231
4232        return False
4233
4234    @staticmethod
4235    def calculate_indent(line):
4236        return len(line) - len(line.strip())
4237
4238    def next(self, state, line=None):
4239        # real_print(self.state.__name__, "->", state.__name__, ", line=", line)
4240        self.state = state
4241        if line is not None:
4242            self.state(line)
4243
4244    def state_dsl_start(self, line):
4245        # self.block = self.ClinicOutputBlock(self)
4246        if self.ignore_line(line):
4247            return
4248
4249        # is it a directive?
4250        fields = shlex.split(line)
4251        directive_name = fields[0]
4252        directive = self.directives.get(directive_name, None)
4253        if directive:
4254            try:
4255                directive(*fields[1:])
4256            except TypeError as e:
4257                fail(str(e))
4258            return
4259
4260        self.next(self.state_modulename_name, line)
4261
4262    def state_modulename_name(self, line):
4263        # looking for declaration, which establishes the leftmost column
4264        # line should be
4265        #     modulename.fnname [as c_basename] [-> return annotation]
4266        # square brackets denote optional syntax.
4267        #
4268        # alternatively:
4269        #     modulename.fnname [as c_basename] = modulename.existing_fn_name
4270        # clones the parameters and return converter from that
4271        # function.  you can't modify them.  you must enter a
4272        # new docstring.
4273        #
4274        # (but we might find a directive first!)
4275        #
4276        # this line is permitted to start with whitespace.
4277        # we'll call this number of spaces F (for "function").
4278
4279        if not line.strip():
4280            return
4281
4282        self.indent.infer(line)
4283
4284        # are we cloning?
4285        before, equals, existing = line.rpartition('=')
4286        if equals:
4287            full_name, _, c_basename = before.partition(' as ')
4288            full_name = full_name.strip()
4289            c_basename = c_basename.strip()
4290            existing = existing.strip()
4291            if (is_legal_py_identifier(full_name) and
4292                (not c_basename or is_legal_c_identifier(c_basename)) and
4293                is_legal_py_identifier(existing)):
4294                # we're cloning!
4295                fields = [x.strip() for x in existing.split('.')]
4296                function_name = fields.pop()
4297                module, cls = self.clinic._module_and_class(fields)
4298
4299                for existing_function in (cls or module).functions:
4300                    if existing_function.name == function_name:
4301                        break
4302                else:
4303                    existing_function = None
4304                if not existing_function:
4305                    print("class", cls, "module", module, "existing", existing)
4306                    print("cls. functions", cls.functions)
4307                    fail("Couldn't find existing function " + repr(existing) + "!")
4308
4309                fields = [x.strip() for x in full_name.split('.')]
4310                function_name = fields.pop()
4311                module, cls = self.clinic._module_and_class(fields)
4312
4313                if not (existing_function.kind == self.kind and existing_function.coexist == self.coexist):
4314                    fail("'kind' of function and cloned function don't match!  (@classmethod/@staticmethod/@coexist)")
4315                self.function = existing_function.copy(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, docstring='')
4316
4317                self.block.signatures.append(self.function)
4318                (cls or module).functions.append(self.function)
4319                self.next(self.state_function_docstring)
4320                return
4321
4322        line, _, returns = line.partition('->')
4323
4324        full_name, _, c_basename = line.partition(' as ')
4325        full_name = full_name.strip()
4326        c_basename = c_basename.strip() or None
4327
4328        if not is_legal_py_identifier(full_name):
4329            fail("Illegal function name: {}".format(full_name))
4330        if c_basename and not is_legal_c_identifier(c_basename):
4331            fail("Illegal C basename: {}".format(c_basename))
4332
4333        return_converter = None
4334        if returns:
4335            ast_input = "def x() -> {}: pass".format(returns)
4336            module = None
4337            try:
4338                module = ast.parse(ast_input)
4339            except SyntaxError:
4340                pass
4341            if not module:
4342                fail("Badly-formed annotation for " + full_name + ": " + returns)
4343            try:
4344                name, legacy, kwargs = self.parse_converter(module.body[0].returns)
4345                if legacy:
4346                    fail("Legacy converter {!r} not allowed as a return converter"
4347                         .format(name))
4348                if name not in return_converters:
4349                    fail("No available return converter called " + repr(name))
4350                return_converter = return_converters[name](**kwargs)
4351            except ValueError:
4352                fail("Badly-formed annotation for " + full_name + ": " + returns)
4353
4354        fields = [x.strip() for x in full_name.split('.')]
4355        function_name = fields.pop()
4356        module, cls = self.clinic._module_and_class(fields)
4357
4358        fields = full_name.split('.')
4359        if fields[-1] in unsupported_special_methods:
4360            fail(f"{fields[-1]} is a special method and cannot be converted to Argument Clinic!  (Yet.)")
4361
4362        if fields[-1] == '__new__':
4363            if (self.kind != CLASS_METHOD) or (not cls):
4364                fail("__new__ must be a class method!")
4365            self.kind = METHOD_NEW
4366        elif fields[-1] == '__init__':
4367            if (self.kind != CALLABLE) or (not cls):
4368                fail("__init__ must be a normal method, not a class or static method!")
4369            self.kind = METHOD_INIT
4370            if not return_converter:
4371                return_converter = init_return_converter()
4372
4373        if not return_converter:
4374            return_converter = CReturnConverter()
4375
4376        if not module:
4377            fail("Undefined module used in declaration of " + repr(full_name.strip()) + ".")
4378        self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename,
4379                                 return_converter=return_converter, kind=self.kind, coexist=self.coexist)
4380        self.block.signatures.append(self.function)
4381
4382        # insert a self converter automatically
4383        type, name = correct_name_for_self(self.function)
4384        kwargs = {}
4385        if cls and type == "PyObject *":
4386            kwargs['type'] = cls.typedef
4387        sc = self.function.self_converter = self_converter(name, name, self.function, **kwargs)
4388        p_self = Parameter(sc.name, inspect.Parameter.POSITIONAL_ONLY, function=self.function, converter=sc)
4389        self.function.parameters[sc.name] = p_self
4390
4391        (cls or module).functions.append(self.function)
4392        self.next(self.state_parameters_start)
4393
4394    # Now entering the parameters section.  The rules, formally stated:
4395    #
4396    #   * All lines must be indented with spaces only.
4397    #   * The first line must be a parameter declaration.
4398    #   * The first line must be indented.
4399    #       * This first line establishes the indent for parameters.
4400    #       * We'll call this number of spaces P (for "parameter").
4401    #   * Thenceforth:
4402    #       * Lines indented with P spaces specify a parameter.
4403    #       * Lines indented with > P spaces are docstrings for the previous
4404    #         parameter.
4405    #           * We'll call this number of spaces D (for "docstring").
4406    #           * All subsequent lines indented with >= D spaces are stored as
4407    #             part of the per-parameter docstring.
4408    #           * All lines will have the first D spaces of the indent stripped
4409    #             before they are stored.
4410    #           * It's illegal to have a line starting with a number of spaces X
4411    #             such that P < X < D.
4412    #       * A line with < P spaces is the first line of the function
4413    #         docstring, which ends processing for parameters and per-parameter
4414    #         docstrings.
4415    #           * The first line of the function docstring must be at the same
4416    #             indent as the function declaration.
4417    #       * It's illegal to have any line in the parameters section starting
4418    #         with X spaces such that F < X < P.  (As before, F is the indent
4419    #         of the function declaration.)
4420    #
4421    # Also, currently Argument Clinic places the following restrictions on groups:
4422    #   * Each group must contain at least one parameter.
4423    #   * Each group may contain at most one group, which must be the furthest
4424    #     thing in the group from the required parameters.  (The nested group
4425    #     must be the first in the group when it's before the required
4426    #     parameters, and the last thing in the group when after the required
4427    #     parameters.)
4428    #   * There may be at most one (top-level) group to the left or right of
4429    #     the required parameters.
4430    #   * You must specify a slash, and it must be after all parameters.
4431    #     (In other words: either all parameters are positional-only,
4432    #      or none are.)
4433    #
4434    #  Said another way:
4435    #   * Each group must contain at least one parameter.
4436    #   * All left square brackets before the required parameters must be
4437    #     consecutive.  (You can't have a left square bracket followed
4438    #     by a parameter, then another left square bracket.  You can't
4439    #     have a left square bracket, a parameter, a right square bracket,
4440    #     and then a left square bracket.)
4441    #   * All right square brackets after the required parameters must be
4442    #     consecutive.
4443    #
4444    # These rules are enforced with a single state variable:
4445    # "parameter_state".  (Previously the code was a miasma of ifs and
4446    # separate boolean state variables.)  The states are:
4447    #
4448    #  [ [ a, b, ] c, ] d, e, f=3, [ g, h, [ i ] ]   <- line
4449    # 01   2          3       4    5           6     <- state transitions
4450    #
4451    # 0: ps_start.  before we've seen anything.  legal transitions are to 1 or 3.
4452    # 1: ps_left_square_before.  left square brackets before required parameters.
4453    # 2: ps_group_before.  in a group, before required parameters.
4454    # 3: ps_required.  required parameters, positional-or-keyword or positional-only
4455    #     (we don't know yet).  (renumber left groups!)
4456    # 4: ps_optional.  positional-or-keyword or positional-only parameters that
4457    #    now must have default values.
4458    # 5: ps_group_after.  in a group, after required parameters.
4459    # 6: ps_right_square_after.  right square brackets after required parameters.
4460    ps_start, ps_left_square_before, ps_group_before, ps_required, \
4461    ps_optional, ps_group_after, ps_right_square_after = range(7)
4462
4463    def state_parameters_start(self, line):
4464        if self.ignore_line(line):
4465            return
4466
4467        # if this line is not indented, we have no parameters
4468        if not self.indent.infer(line):
4469            return self.next(self.state_function_docstring, line)
4470
4471        self.parameter_continuation = ''
4472        return self.next(self.state_parameter, line)
4473
4474
4475    def to_required(self):
4476        """
4477        Transition to the "required" parameter state.
4478        """
4479        if self.parameter_state != self.ps_required:
4480            self.parameter_state = self.ps_required
4481            for p in self.function.parameters.values():
4482                p.group = -p.group
4483
4484    def state_parameter(self, line):
4485        if self.parameter_continuation:
4486            line = self.parameter_continuation + ' ' + line.lstrip()
4487            self.parameter_continuation = ''
4488
4489        if self.ignore_line(line):
4490            return
4491
4492        assert self.indent.depth == 2
4493        indent = self.indent.infer(line)
4494        if indent == -1:
4495            # we outdented, must be to definition column
4496            return self.next(self.state_function_docstring, line)
4497
4498        if indent == 1:
4499            # we indented, must be to new parameter docstring column
4500            return self.next(self.state_parameter_docstring_start, line)
4501
4502        line = line.rstrip()
4503        if line.endswith('\\'):
4504            self.parameter_continuation = line[:-1]
4505            return
4506
4507        line = line.lstrip()
4508
4509        if line in ('*', '/', '[', ']'):
4510            self.parse_special_symbol(line)
4511            return
4512
4513        if self.parameter_state in (self.ps_start, self.ps_required):
4514            self.to_required()
4515        elif self.parameter_state == self.ps_left_square_before:
4516            self.parameter_state = self.ps_group_before
4517        elif self.parameter_state == self.ps_group_before:
4518            if not self.group:
4519                self.to_required()
4520        elif self.parameter_state in (self.ps_group_after, self.ps_optional):
4521            pass
4522        else:
4523            fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".a)")
4524
4525        # handle "as" for  parameters too
4526        c_name = None
4527        name, have_as_token, trailing = line.partition(' as ')
4528        if have_as_token:
4529            name = name.strip()
4530            if ' ' not in name:
4531                fields = trailing.strip().split(' ')
4532                if not fields:
4533                    fail("Invalid 'as' clause!")
4534                c_name = fields[0]
4535                if c_name.endswith(':'):
4536                    name += ':'
4537                    c_name = c_name[:-1]
4538                fields[0] = name
4539                line = ' '.join(fields)
4540
4541        base, equals, default = line.rpartition('=')
4542        if not equals:
4543            base = default
4544            default = None
4545
4546        module = None
4547        try:
4548            ast_input = "def x({}): pass".format(base)
4549            module = ast.parse(ast_input)
4550        except SyntaxError:
4551            try:
4552                # the last = was probably inside a function call, like
4553                #   c: int(accept={str})
4554                # so assume there was no actual default value.
4555                default = None
4556                ast_input = "def x({}): pass".format(line)
4557                module = ast.parse(ast_input)
4558            except SyntaxError:
4559                pass
4560        if not module:
4561            fail("Function " + self.function.name + " has an invalid parameter declaration:\n\t" + line)
4562
4563        function_args = module.body[0].args
4564
4565        if len(function_args.args) > 1:
4566            fail("Function " + self.function.name + " has an invalid parameter declaration (comma?):\n\t" + line)
4567        if function_args.defaults or function_args.kw_defaults:
4568            fail("Function " + self.function.name + " has an invalid parameter declaration (default value?):\n\t" + line)
4569        if function_args.kwarg:
4570            fail("Function " + self.function.name + " has an invalid parameter declaration (**kwargs?):\n\t" + line)
4571
4572        if function_args.vararg:
4573            is_vararg = True
4574            parameter = function_args.vararg
4575        else:
4576            is_vararg = False
4577            parameter = function_args.args[0]
4578
4579        parameter_name = parameter.arg
4580        name, legacy, kwargs = self.parse_converter(parameter.annotation)
4581
4582        if not default:
4583            if self.parameter_state == self.ps_optional:
4584                fail("Can't have a parameter without a default (" + repr(parameter_name) + ")\nafter a parameter with a default!")
4585            if is_vararg:
4586                value = NULL
4587                kwargs.setdefault('c_default', "NULL")
4588            else:
4589                value = unspecified
4590            if 'py_default' in kwargs:
4591                fail("You can't specify py_default without specifying a default value!")
4592        else:
4593            if is_vararg:
4594                fail("Vararg can't take a default value!")
4595
4596            if self.parameter_state == self.ps_required:
4597                self.parameter_state = self.ps_optional
4598            default = default.strip()
4599            bad = False
4600            ast_input = "x = {}".format(default)
4601            bad = False
4602            try:
4603                module = ast.parse(ast_input)
4604
4605                if 'c_default' not in kwargs:
4606                    # we can only represent very simple data values in C.
4607                    # detect whether default is okay, via a denylist
4608                    # of disallowed ast nodes.
4609                    class DetectBadNodes(ast.NodeVisitor):
4610                        bad = False
4611                        def bad_node(self, node):
4612                            self.bad = True
4613
4614                        # inline function call
4615                        visit_Call = bad_node
4616                        # inline if statement ("x = 3 if y else z")
4617                        visit_IfExp = bad_node
4618
4619                        # comprehensions and generator expressions
4620                        visit_ListComp = visit_SetComp = bad_node
4621                        visit_DictComp = visit_GeneratorExp = bad_node
4622
4623                        # literals for advanced types
4624                        visit_Dict = visit_Set = bad_node
4625                        visit_List = visit_Tuple = bad_node
4626
4627                        # "starred": "a = [1, 2, 3]; *a"
4628                        visit_Starred = bad_node
4629
4630                    denylist = DetectBadNodes()
4631                    denylist.visit(module)
4632                    bad = denylist.bad
4633                else:
4634                    # if they specify a c_default, we can be more lenient about the default value.
4635                    # but at least make an attempt at ensuring it's a valid expression.
4636                    try:
4637                        value = eval(default)
4638                        if value == unspecified:
4639                            fail("'unspecified' is not a legal default value!")
4640                    except NameError:
4641                        pass # probably a named constant
4642                    except Exception as e:
4643                        fail("Malformed expression given as default value\n"
4644                             "{!r} caused {!r}".format(default, e))
4645                if bad:
4646                    fail("Unsupported expression as default value: " + repr(default))
4647
4648                expr = module.body[0].value
4649                # mild hack: explicitly support NULL as a default value
4650                if isinstance(expr, ast.Name) and expr.id == 'NULL':
4651                    value = NULL
4652                    py_default = '<unrepresentable>'
4653                    c_default = "NULL"
4654                elif (isinstance(expr, ast.BinOp) or
4655                    (isinstance(expr, ast.UnaryOp) and
4656                     not (isinstance(expr.operand, ast.Num) or
4657                          (hasattr(ast, 'Constant') and
4658                           isinstance(expr.operand, ast.Constant) and
4659                           type(expr.operand.value) in (int, float, complex)))
4660                    )):
4661                    c_default = kwargs.get("c_default")
4662                    if not (isinstance(c_default, str) and c_default):
4663                        fail("When you specify an expression (" + repr(default) + ") as your default value,\nyou MUST specify a valid c_default." + ast.dump(expr))
4664                    py_default = default
4665                    value = unknown
4666                elif isinstance(expr, ast.Attribute):
4667                    a = []
4668                    n = expr
4669                    while isinstance(n, ast.Attribute):
4670                        a.append(n.attr)
4671                        n = n.value
4672                    if not isinstance(n, ast.Name):
4673                        fail("Unsupported default value " + repr(default) + " (looked like a Python constant)")
4674                    a.append(n.id)
4675                    py_default = ".".join(reversed(a))
4676
4677                    c_default = kwargs.get("c_default")
4678                    if not (isinstance(c_default, str) and c_default):
4679                        fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.")
4680
4681                    try:
4682                        value = eval(py_default)
4683                    except NameError:
4684                        value = unknown
4685                else:
4686                    value = ast.literal_eval(expr)
4687                    py_default = repr(value)
4688                    if isinstance(value, (bool, None.__class__)):
4689                        c_default = "Py_" + py_default
4690                    elif isinstance(value, str):
4691                        c_default = c_repr(value)
4692                    else:
4693                        c_default = py_default
4694
4695            except SyntaxError as e:
4696                fail("Syntax error: " + repr(e.text))
4697            except (ValueError, AttributeError):
4698                value = unknown
4699                c_default = kwargs.get("c_default")
4700                py_default = default
4701                if not (isinstance(c_default, str) and c_default):
4702                    fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.")
4703
4704            kwargs.setdefault('c_default', c_default)
4705            kwargs.setdefault('py_default', py_default)
4706
4707        dict = legacy_converters if legacy else converters
4708        legacy_str = "legacy " if legacy else ""
4709        if name not in dict:
4710            fail('{} is not a valid {}converter'.format(name, legacy_str))
4711        # if you use a c_name for the parameter, we just give that name to the converter
4712        # but the parameter object gets the python name
4713        converter = dict[name](c_name or parameter_name, parameter_name, self.function, value, **kwargs)
4714
4715        if is_vararg:
4716            kind = inspect.Parameter.VAR_POSITIONAL
4717        elif self.keyword_only:
4718            kind = inspect.Parameter.KEYWORD_ONLY
4719        else:
4720            kind = inspect.Parameter.POSITIONAL_OR_KEYWORD
4721
4722        if isinstance(converter, self_converter):
4723            if len(self.function.parameters) == 1:
4724                if (self.parameter_state != self.ps_required):
4725                    fail("A 'self' parameter cannot be marked optional.")
4726                if value is not unspecified:
4727                    fail("A 'self' parameter cannot have a default value.")
4728                if self.group:
4729                    fail("A 'self' parameter cannot be in an optional group.")
4730                kind = inspect.Parameter.POSITIONAL_ONLY
4731                self.parameter_state = self.ps_start
4732                self.function.parameters.clear()
4733            else:
4734                fail("A 'self' parameter, if specified, must be the very first thing in the parameter block.")
4735
4736        if isinstance(converter, defining_class_converter):
4737            _lp = len(self.function.parameters)
4738            if _lp == 1:
4739                if (self.parameter_state != self.ps_required):
4740                    fail("A 'defining_class' parameter cannot be marked optional.")
4741                if value is not unspecified:
4742                    fail("A 'defining_class' parameter cannot have a default value.")
4743                if self.group:
4744                    fail("A 'defining_class' parameter cannot be in an optional group.")
4745            else:
4746                fail("A 'defining_class' parameter, if specified, must either be the first thing in the parameter block, or come just after 'self'.")
4747
4748
4749        p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group)
4750
4751        names = [k.name for k in self.function.parameters.values()]
4752        if parameter_name in names[1:]:
4753            fail("You can't have two parameters named " + repr(parameter_name) + "!")
4754        elif names and parameter_name == names[0] and c_name is None:
4755            fail(f"Parameter '{parameter_name}' requires a custom C name")
4756
4757        key = f"{parameter_name}_as_{c_name}" if c_name else parameter_name
4758        self.function.parameters[key] = p
4759
4760    def parse_converter(self, annotation):
4761        if (hasattr(ast, 'Constant') and
4762            isinstance(annotation, ast.Constant) and
4763            type(annotation.value) is str):
4764            return annotation.value, True, {}
4765
4766        if isinstance(annotation, ast.Str):
4767            return annotation.s, True, {}
4768
4769        if isinstance(annotation, ast.Name):
4770            return annotation.id, False, {}
4771
4772        if not isinstance(annotation, ast.Call):
4773            fail("Annotations must be either a name, a function call, or a string.")
4774
4775        name = annotation.func.id
4776        symbols = globals()
4777
4778        kwargs = {node.arg: eval_ast_expr(node.value, symbols) for node in annotation.keywords}
4779        return name, False, kwargs
4780
4781    def parse_special_symbol(self, symbol):
4782        if symbol == '*':
4783            if self.keyword_only:
4784                fail("Function " + self.function.name + " uses '*' more than once.")
4785            self.keyword_only = True
4786        elif symbol == '[':
4787            if self.parameter_state in (self.ps_start, self.ps_left_square_before):
4788                self.parameter_state = self.ps_left_square_before
4789            elif self.parameter_state in (self.ps_required, self.ps_group_after):
4790                self.parameter_state = self.ps_group_after
4791            else:
4792                fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".b)")
4793            self.group += 1
4794            self.function.docstring_only = True
4795        elif symbol == ']':
4796            if not self.group:
4797                fail("Function " + self.function.name + " has a ] without a matching [.")
4798            if not any(p.group == self.group for p in self.function.parameters.values()):
4799                fail("Function " + self.function.name + " has an empty group.\nAll groups must contain at least one parameter.")
4800            self.group -= 1
4801            if self.parameter_state in (self.ps_left_square_before, self.ps_group_before):
4802                self.parameter_state = self.ps_group_before
4803            elif self.parameter_state in (self.ps_group_after, self.ps_right_square_after):
4804                self.parameter_state = self.ps_right_square_after
4805            else:
4806                fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".c)")
4807        elif symbol == '/':
4808            if self.positional_only:
4809                fail("Function " + self.function.name + " uses '/' more than once.")
4810            self.positional_only = True
4811            # ps_required and ps_optional are allowed here, that allows positional-only without option groups
4812            # to work (and have default values!)
4813            if (self.parameter_state not in (self.ps_required, self.ps_optional, self.ps_right_square_after, self.ps_group_before)) or self.group:
4814                fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".d)")
4815            if self.keyword_only:
4816                fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.")
4817            # fixup preceding parameters
4818            for p in self.function.parameters.values():
4819                if p.is_vararg():
4820                    continue
4821                if (p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD and not isinstance(p.converter, self_converter)):
4822                    fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.")
4823                p.kind = inspect.Parameter.POSITIONAL_ONLY
4824
4825    def state_parameter_docstring_start(self, line):
4826        self.parameter_docstring_indent = len(self.indent.margin)
4827        assert self.indent.depth == 3
4828        return self.next(self.state_parameter_docstring, line)
4829
4830    # every line of the docstring must start with at least F spaces,
4831    # where F > P.
4832    # these F spaces will be stripped.
4833    def state_parameter_docstring(self, line):
4834        stripped = line.strip()
4835        if stripped.startswith('#'):
4836            return
4837
4838        indent = self.indent.measure(line)
4839        if indent < self.parameter_docstring_indent:
4840            self.indent.infer(line)
4841            assert self.indent.depth < 3
4842            if self.indent.depth == 2:
4843                # back to a parameter
4844                return self.next(self.state_parameter, line)
4845            assert self.indent.depth == 1
4846            return self.next(self.state_function_docstring, line)
4847
4848        assert self.function.parameters
4849        last_parameter = next(reversed(list(self.function.parameters.values())))
4850
4851        new_docstring = last_parameter.docstring
4852
4853        if new_docstring:
4854            new_docstring += '\n'
4855        if stripped:
4856            new_docstring += self.indent.dedent(line)
4857
4858        last_parameter.docstring = new_docstring
4859
4860    # the final stanza of the DSL is the docstring.
4861    def state_function_docstring(self, line):
4862        if self.group:
4863            fail("Function " + self.function.name + " has a ] without a matching [.")
4864
4865        stripped = line.strip()
4866        if stripped.startswith('#'):
4867            return
4868
4869        new_docstring = self.function.docstring
4870        if new_docstring:
4871            new_docstring += "\n"
4872        if stripped:
4873            line = self.indent.dedent(line).rstrip()
4874        else:
4875            line = ''
4876        new_docstring += line
4877        self.function.docstring = new_docstring
4878
4879    def format_docstring(self):
4880        f = self.function
4881
4882        new_or_init = f.kind in (METHOD_NEW, METHOD_INIT)
4883        if new_or_init and not f.docstring:
4884            # don't render a docstring at all, no signature, nothing.
4885            return f.docstring
4886
4887        text, add, output = _text_accumulator()
4888        parameters = f.render_parameters
4889
4890        ##
4891        ## docstring first line
4892        ##
4893
4894        if new_or_init:
4895            # classes get *just* the name of the class
4896            # not __new__, not __init__, and not module.classname
4897            assert f.cls
4898            add(f.cls.name)
4899        else:
4900            add(f.name)
4901        add('(')
4902
4903        # populate "right_bracket_count" field for every parameter
4904        assert parameters, "We should always have a self parameter. " + repr(f)
4905        assert isinstance(parameters[0].converter, self_converter)
4906        # self is always positional-only.
4907        assert parameters[0].is_positional_only()
4908        parameters[0].right_bracket_count = 0
4909        positional_only = True
4910        for p in parameters[1:]:
4911            if not p.is_positional_only():
4912                positional_only = False
4913            else:
4914                assert positional_only
4915            if positional_only:
4916                p.right_bracket_count = abs(p.group)
4917            else:
4918                # don't put any right brackets around non-positional-only parameters, ever.
4919                p.right_bracket_count = 0
4920
4921        right_bracket_count = 0
4922
4923        def fix_right_bracket_count(desired):
4924            nonlocal right_bracket_count
4925            s = ''
4926            while right_bracket_count < desired:
4927                s += '['
4928                right_bracket_count += 1
4929            while right_bracket_count > desired:
4930                s += ']'
4931                right_bracket_count -= 1
4932            return s
4933
4934        need_slash = False
4935        added_slash = False
4936        need_a_trailing_slash = False
4937
4938        # we only need a trailing slash:
4939        #   * if this is not a "docstring_only" signature
4940        #   * and if the last *shown* parameter is
4941        #     positional only
4942        if not f.docstring_only:
4943            for p in reversed(parameters):
4944                if not p.converter.show_in_signature:
4945                    continue
4946                if p.is_positional_only():
4947                    need_a_trailing_slash = True
4948                break
4949
4950
4951        added_star = False
4952
4953        first_parameter = True
4954        last_p = parameters[-1]
4955        line_length = len(''.join(text))
4956        indent = " " * line_length
4957        def add_parameter(text):
4958            nonlocal line_length
4959            nonlocal first_parameter
4960            if first_parameter:
4961                s = text
4962                first_parameter = False
4963            else:
4964                s = ' ' + text
4965                if line_length + len(s) >= 72:
4966                    add('\n')
4967                    add(indent)
4968                    line_length = len(indent)
4969                    s = text
4970            line_length += len(s)
4971            add(s)
4972
4973        for p in parameters:
4974            if not p.converter.show_in_signature:
4975                continue
4976            assert p.name
4977
4978            is_self = isinstance(p.converter, self_converter)
4979            if is_self and f.docstring_only:
4980                # this isn't a real machine-parsable signature,
4981                # so let's not print the "self" parameter
4982                continue
4983
4984            if p.is_positional_only():
4985                need_slash = not f.docstring_only
4986            elif need_slash and not (added_slash or p.is_positional_only()):
4987                added_slash = True
4988                add_parameter('/,')
4989
4990            if p.is_keyword_only() and not added_star:
4991                added_star = True
4992                add_parameter('*,')
4993
4994            p_add, p_output = text_accumulator()
4995            p_add(fix_right_bracket_count(p.right_bracket_count))
4996
4997            if isinstance(p.converter, self_converter):
4998                # annotate first parameter as being a "self".
4999                #
5000                # if inspect.Signature gets this function,
5001                # and it's already bound, the self parameter
5002                # will be stripped off.
5003                #
5004                # if it's not bound, it should be marked
5005                # as positional-only.
5006                #
5007                # note: we don't print "self" for __init__,
5008                # because this isn't actually the signature
5009                # for __init__.  (it can't be, __init__ doesn't
5010                # have a docstring.)  if this is an __init__
5011                # (or __new__), then this signature is for
5012                # calling the class to construct a new instance.
5013                p_add('$')
5014
5015            if p.is_vararg():
5016                p_add("*")
5017
5018            name = p.converter.signature_name or p.name
5019            p_add(name)
5020
5021            if not p.is_vararg() and p.converter.is_optional():
5022                p_add('=')
5023                value = p.converter.py_default
5024                if not value:
5025                    value = repr(p.converter.default)
5026                p_add(value)
5027
5028            if (p != last_p) or need_a_trailing_slash:
5029                p_add(',')
5030
5031            add_parameter(p_output())
5032
5033        add(fix_right_bracket_count(0))
5034        if need_a_trailing_slash:
5035            add_parameter('/')
5036        add(')')
5037
5038        # PEP 8 says:
5039        #
5040        #     The Python standard library will not use function annotations
5041        #     as that would result in a premature commitment to a particular
5042        #     annotation style. Instead, the annotations are left for users
5043        #     to discover and experiment with useful annotation styles.
5044        #
5045        # therefore this is commented out:
5046        #
5047        # if f.return_converter.py_default:
5048        #     add(' -> ')
5049        #     add(f.return_converter.py_default)
5050
5051        if not f.docstring_only:
5052            add("\n" + sig_end_marker + "\n")
5053
5054        docstring_first_line = output()
5055
5056        # now fix up the places where the brackets look wrong
5057        docstring_first_line = docstring_first_line.replace(', ]', ',] ')
5058
5059        # okay.  now we're officially building the "parameters" section.
5060        # create substitution text for {parameters}
5061        spacer_line = False
5062        for p in parameters:
5063            if not p.docstring.strip():
5064                continue
5065            if spacer_line:
5066                add('\n')
5067            else:
5068                spacer_line = True
5069            add("  ")
5070            add(p.name)
5071            add('\n')
5072            add(textwrap.indent(rstrip_lines(p.docstring.rstrip()), "    "))
5073        parameters = output()
5074        if parameters:
5075            parameters += '\n'
5076
5077        ##
5078        ## docstring body
5079        ##
5080
5081        docstring = f.docstring.rstrip()
5082        lines = [line.rstrip() for line in docstring.split('\n')]
5083
5084        # Enforce the summary line!
5085        # The first line of a docstring should be a summary of the function.
5086        # It should fit on one line (80 columns? 79 maybe?) and be a paragraph
5087        # by itself.
5088        #
5089        # Argument Clinic enforces the following rule:
5090        #  * either the docstring is empty,
5091        #  * or it must have a summary line.
5092        #
5093        # Guido said Clinic should enforce this:
5094        # http://mail.python.org/pipermail/python-dev/2013-June/127110.html
5095
5096        if len(lines) >= 2:
5097            if lines[1]:
5098                fail("Docstring for " + f.full_name + " does not have a summary line!\n" +
5099                    "Every non-blank function docstring must start with\n" +
5100                    "a single line summary followed by an empty line.")
5101        elif len(lines) == 1:
5102            # the docstring is only one line right now--the summary line.
5103            # add an empty line after the summary line so we have space
5104            # between it and the {parameters} we're about to add.
5105            lines.append('')
5106
5107        parameters_marker_count = len(docstring.split('{parameters}')) - 1
5108        if parameters_marker_count > 1:
5109            fail('You may not specify {parameters} more than once in a docstring!')
5110
5111        if not parameters_marker_count:
5112            # insert after summary line
5113            lines.insert(2, '{parameters}')
5114
5115        # insert at front of docstring
5116        lines.insert(0, docstring_first_line)
5117
5118        docstring = "\n".join(lines)
5119
5120        add(docstring)
5121        docstring = output()
5122
5123        docstring = linear_format(docstring, parameters=parameters)
5124        docstring = docstring.rstrip()
5125
5126        return docstring
5127
5128    def state_terminal(self, line):
5129        """
5130        Called when processing the block is done.
5131        """
5132        assert not line
5133
5134        if not self.function:
5135            return
5136
5137        if self.keyword_only:
5138            values = self.function.parameters.values()
5139            if not values:
5140                no_parameter_after_star = True
5141            else:
5142                last_parameter = next(reversed(list(values)))
5143                no_parameter_after_star = last_parameter.kind != inspect.Parameter.KEYWORD_ONLY
5144            if no_parameter_after_star:
5145                fail("Function " + self.function.name + " specifies '*' without any parameters afterwards.")
5146
5147        # remove trailing whitespace from all parameter docstrings
5148        for name, value in self.function.parameters.items():
5149            if not value:
5150                continue
5151            value.docstring = value.docstring.rstrip()
5152
5153        self.function.docstring = self.format_docstring()
5154
5155
5156
5157
5158# maps strings to callables.
5159# the callable should return an object
5160# that implements the clinic parser
5161# interface (__init__ and parse).
5162#
5163# example parsers:
5164#   "clinic", handles the Clinic DSL
5165#   "python", handles running Python code
5166#
5167parsers = {'clinic' : DSLParser, 'python': PythonParser}
5168
5169
5170clinic = None
5171
5172
5173def main(argv):
5174    import sys
5175
5176    if sys.version_info.major < 3 or sys.version_info.minor < 3:
5177        sys.exit("Error: clinic.py requires Python 3.3 or greater.")
5178
5179    import argparse
5180    cmdline = argparse.ArgumentParser(
5181        description="""Preprocessor for CPython C files.
5182
5183The purpose of the Argument Clinic is automating all the boilerplate involved
5184with writing argument parsing code for builtins and providing introspection
5185signatures ("docstrings") for CPython builtins.
5186
5187For more information see https://docs.python.org/3/howto/clinic.html""")
5188    cmdline.add_argument("-f", "--force", action='store_true')
5189    cmdline.add_argument("-o", "--output", type=str)
5190    cmdline.add_argument("-v", "--verbose", action='store_true')
5191    cmdline.add_argument("--converters", action='store_true')
5192    cmdline.add_argument("--make", action='store_true',
5193                         help="Walk --srcdir to run over all relevant files.")
5194    cmdline.add_argument("--srcdir", type=str, default=os.curdir,
5195                         help="The directory tree to walk in --make mode.")
5196    cmdline.add_argument("filename", type=str, nargs="*")
5197    ns = cmdline.parse_args(argv)
5198
5199    if ns.converters:
5200        if ns.filename:
5201            print("Usage error: can't specify --converters and a filename at the same time.")
5202            print()
5203            cmdline.print_usage()
5204            sys.exit(-1)
5205        converters = []
5206        return_converters = []
5207        ignored = set("""
5208            add_c_converter
5209            add_c_return_converter
5210            add_default_legacy_c_converter
5211            add_legacy_c_converter
5212            """.strip().split())
5213        module = globals()
5214        for name in module:
5215            for suffix, ids in (
5216                ("_return_converter", return_converters),
5217                ("_converter", converters),
5218            ):
5219                if name in ignored:
5220                    continue
5221                if name.endswith(suffix):
5222                    ids.append((name, name[:-len(suffix)]))
5223                    break
5224        print()
5225
5226        print("Legacy converters:")
5227        legacy = sorted(legacy_converters)
5228        print('    ' + ' '.join(c for c in legacy if c[0].isupper()))
5229        print('    ' + ' '.join(c for c in legacy if c[0].islower()))
5230        print()
5231
5232        for title, attribute, ids in (
5233            ("Converters", 'converter_init', converters),
5234            ("Return converters", 'return_converter_init', return_converters),
5235        ):
5236            print(title + ":")
5237            longest = -1
5238            for name, short_name in ids:
5239                longest = max(longest, len(short_name))
5240            for name, short_name in sorted(ids, key=lambda x: x[1].lower()):
5241                cls = module[name]
5242                callable = getattr(cls, attribute, None)
5243                if not callable:
5244                    continue
5245                signature = inspect.signature(callable)
5246                parameters = []
5247                for parameter_name, parameter in signature.parameters.items():
5248                    if parameter.kind == inspect.Parameter.KEYWORD_ONLY:
5249                        if parameter.default != inspect.Parameter.empty:
5250                            s = '{}={!r}'.format(parameter_name, parameter.default)
5251                        else:
5252                            s = parameter_name
5253                        parameters.append(s)
5254                print('    {}({})'.format(short_name, ', '.join(parameters)))
5255            print()
5256        print("All converters also accept (c_default=None, py_default=None, annotation=None).")
5257        print("All return converters also accept (py_default=None).")
5258        sys.exit(0)
5259
5260    if ns.make:
5261        if ns.output or ns.filename:
5262            print("Usage error: can't use -o or filenames with --make.")
5263            print()
5264            cmdline.print_usage()
5265            sys.exit(-1)
5266        if not ns.srcdir:
5267            print("Usage error: --srcdir must not be empty with --make.")
5268            print()
5269            cmdline.print_usage()
5270            sys.exit(-1)
5271        for root, dirs, files in os.walk(ns.srcdir):
5272            for rcs_dir in ('.svn', '.git', '.hg', 'build', 'externals'):
5273                if rcs_dir in dirs:
5274                    dirs.remove(rcs_dir)
5275            for filename in files:
5276                if not (filename.endswith('.c') or filename.endswith('.h')):
5277                    continue
5278                path = os.path.join(root, filename)
5279                if ns.verbose:
5280                    print(path)
5281                parse_file(path, verify=not ns.force)
5282        return
5283
5284    if not ns.filename:
5285        cmdline.print_usage()
5286        sys.exit(-1)
5287
5288    if ns.output and len(ns.filename) > 1:
5289        print("Usage error: can't use -o with multiple filenames.")
5290        print()
5291        cmdline.print_usage()
5292        sys.exit(-1)
5293
5294    for filename in ns.filename:
5295        if ns.verbose:
5296            print(filename)
5297        parse_file(filename, output=ns.output, verify=not ns.force)
5298
5299
5300if __name__ == "__main__":
5301    sys.exit(main(sys.argv[1:]))
5302