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