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 == None) ^ (output == 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__new__
2163__next__
2164__or__
2165__pos__
2166__pow__
2167__radd__
2168__rand__
2169__rdivmod__
2170__repr__
2171__rfloordiv__
2172__rlshift__
2173__rmatmul__
2174__rmod__
2175__rmul__
2176__ror__
2177__rpow__
2178__rrshift__
2179__rshift__
2180__rsub__
2181__rtruediv__
2182__rxor__
2183__setattr__
2184__setitem__
2185__str__
2186__sub__
2187__truediv__
2188__xor__
2189
2190""".strip().split())
2191
2192
2193INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = """
2194INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW
2195""".replace(",", "").strip().split()
2196
2197class Function:
2198    """
2199    Mutable duck type for inspect.Function.
2200
2201    docstring - a str containing
2202        * embedded line breaks
2203        * text outdented to the left margin
2204        * no trailing whitespace.
2205        It will always be true that
2206            (not docstring) or ((not docstring[0].isspace()) and (docstring.rstrip() == docstring))
2207    """
2208
2209    def __init__(self, parameters=None, *, name,
2210                 module, cls=None, c_basename=None,
2211                 full_name=None,
2212                 return_converter, return_annotation=inspect.Signature.empty,
2213                 docstring=None, kind=CALLABLE, coexist=False,
2214                 docstring_only=False):
2215        self.parameters = parameters or collections.OrderedDict()
2216        self.return_annotation = return_annotation
2217        self.name = name
2218        self.full_name = full_name
2219        self.module = module
2220        self.cls = cls
2221        self.parent = cls or module
2222        self.c_basename = c_basename
2223        self.return_converter = return_converter
2224        self.docstring = docstring or ''
2225        self.kind = kind
2226        self.coexist = coexist
2227        self.self_converter = None
2228        # docstring_only means "don't generate a machine-readable
2229        # signature, just a normal docstring".  it's True for
2230        # functions with optional groups because we can't represent
2231        # those accurately with inspect.Signature in 3.4.
2232        self.docstring_only = docstring_only
2233
2234        self.rendered_parameters = None
2235
2236    __render_parameters__ = None
2237    @property
2238    def render_parameters(self):
2239        if not self.__render_parameters__:
2240            self.__render_parameters__ = l = []
2241            for p in self.parameters.values():
2242                p = p.copy()
2243                p.converter.pre_render()
2244                l.append(p)
2245        return self.__render_parameters__
2246
2247    @property
2248    def methoddef_flags(self):
2249        if self.kind in (METHOD_INIT, METHOD_NEW):
2250            return None
2251        flags = []
2252        if self.kind == CLASS_METHOD:
2253            flags.append('METH_CLASS')
2254        elif self.kind == STATIC_METHOD:
2255            flags.append('METH_STATIC')
2256        else:
2257            assert self.kind == CALLABLE, "unknown kind: " + repr(self.kind)
2258        if self.coexist:
2259            flags.append('METH_COEXIST')
2260        return '|'.join(flags)
2261
2262    def __repr__(self):
2263        return '<clinic.Function ' + self.name + '>'
2264
2265    def copy(self, **overrides):
2266        kwargs = {
2267            'name': self.name, 'module': self.module, 'parameters': self.parameters,
2268            'cls': self.cls, 'c_basename': self.c_basename,
2269            'full_name': self.full_name,
2270            'return_converter': self.return_converter, 'return_annotation': self.return_annotation,
2271            'docstring': self.docstring, 'kind': self.kind, 'coexist': self.coexist,
2272            'docstring_only': self.docstring_only,
2273            }
2274        kwargs.update(overrides)
2275        f = Function(**kwargs)
2276
2277        parameters = collections.OrderedDict()
2278        for name, value in f.parameters.items():
2279            value = value.copy(function=f)
2280            parameters[name] = value
2281        f.parameters = parameters
2282        return f
2283
2284
2285class Parameter:
2286    """
2287    Mutable duck type of inspect.Parameter.
2288    """
2289
2290    def __init__(self, name, kind, *, default=inspect.Parameter.empty,
2291                 function, converter, annotation=inspect.Parameter.empty,
2292                 docstring=None, group=0):
2293        self.name = name
2294        self.kind = kind
2295        self.default = default
2296        self.function = function
2297        self.converter = converter
2298        self.annotation = annotation
2299        self.docstring = docstring or ''
2300        self.group = group
2301
2302    def __repr__(self):
2303        return '<clinic.Parameter ' + self.name + '>'
2304
2305    def is_keyword_only(self):
2306        return self.kind == inspect.Parameter.KEYWORD_ONLY
2307
2308    def is_positional_only(self):
2309        return self.kind == inspect.Parameter.POSITIONAL_ONLY
2310
2311    def is_optional(self):
2312        return (self.default is not unspecified)
2313
2314    def copy(self, **overrides):
2315        kwargs = {
2316            'name': self.name, 'kind': self.kind, 'default':self.default,
2317                 'function': self.function, 'converter': self.converter, 'annotation': self.annotation,
2318                 'docstring': self.docstring, 'group': self.group,
2319            }
2320        kwargs.update(overrides)
2321        if 'converter' not in overrides:
2322            converter = copy.copy(self.converter)
2323            converter.function = kwargs['function']
2324            kwargs['converter'] = converter
2325        return Parameter(**kwargs)
2326
2327    def get_displayname(self, i):
2328        if i == 0:
2329            return '"argument"'
2330        if not self.is_positional_only():
2331            return '''"argument '{}'"'''.format(self.name)
2332        else:
2333            return '"argument {}"'.format(i)
2334
2335
2336class LandMine:
2337    # try to access any
2338    def __init__(self, message):
2339        self.__message__ = message
2340
2341    def __repr__(self):
2342        return '<LandMine ' + repr(self.__message__) + ">"
2343
2344    def __getattribute__(self, name):
2345        if name in ('__repr__', '__message__'):
2346            return super().__getattribute__(name)
2347        # raise RuntimeError(repr(name))
2348        fail("Stepped on a land mine, trying to access attribute " + repr(name) + ":\n" + self.__message__)
2349
2350
2351def add_c_converter(f, name=None):
2352    if not name:
2353        name = f.__name__
2354        if not name.endswith('_converter'):
2355            return f
2356        name = name[:-len('_converter')]
2357    converters[name] = f
2358    return f
2359
2360def add_default_legacy_c_converter(cls):
2361    # automatically add converter for default format unit
2362    # (but without stomping on the existing one if it's already
2363    # set, in case you subclass)
2364    if ((cls.format_unit not in ('O&', '')) and
2365        (cls.format_unit not in legacy_converters)):
2366        legacy_converters[cls.format_unit] = cls
2367    return cls
2368
2369def add_legacy_c_converter(format_unit, **kwargs):
2370    """
2371    Adds a legacy converter.
2372    """
2373    def closure(f):
2374        if not kwargs:
2375            added_f = f
2376        else:
2377            added_f = functools.partial(f, **kwargs)
2378        if format_unit:
2379            legacy_converters[format_unit] = added_f
2380        return f
2381    return closure
2382
2383class CConverterAutoRegister(type):
2384    def __init__(cls, name, bases, classdict):
2385        add_c_converter(cls)
2386        add_default_legacy_c_converter(cls)
2387
2388class CConverter(metaclass=CConverterAutoRegister):
2389    """
2390    For the init function, self, name, function, and default
2391    must be keyword-or-positional parameters.  All other
2392    parameters must be keyword-only.
2393    """
2394
2395    # The C name to use for this variable.
2396    name = None
2397
2398    # The Python name to use for this variable.
2399    py_name = None
2400
2401    # The C type to use for this variable.
2402    # 'type' should be a Python string specifying the type, e.g. "int".
2403    # If this is a pointer type, the type string should end with ' *'.
2404    type = None
2405
2406    # The Python default value for this parameter, as a Python value.
2407    # Or the magic value "unspecified" if there is no default.
2408    # Or the magic value "unknown" if this value is a cannot be evaluated
2409    # at Argument-Clinic-preprocessing time (but is presumed to be valid
2410    # at runtime).
2411    default = unspecified
2412
2413    # If not None, default must be isinstance() of this type.
2414    # (You can also specify a tuple of types.)
2415    default_type = None
2416
2417    # "default" converted into a C value, as a string.
2418    # Or None if there is no default.
2419    c_default = None
2420
2421    # "default" converted into a Python value, as a string.
2422    # Or None if there is no default.
2423    py_default = None
2424
2425    # The default value used to initialize the C variable when
2426    # there is no default, but not specifying a default may
2427    # result in an "uninitialized variable" warning.  This can
2428    # easily happen when using option groups--although
2429    # properly-written code won't actually use the variable,
2430    # the variable does get passed in to the _impl.  (Ah, if
2431    # only dataflow analysis could inline the static function!)
2432    #
2433    # This value is specified as a string.
2434    # Every non-abstract subclass should supply a valid value.
2435    c_ignored_default = 'NULL'
2436
2437    # The C converter *function* to be used, if any.
2438    # (If this is not None, format_unit must be 'O&'.)
2439    converter = None
2440
2441    # Should Argument Clinic add a '&' before the name of
2442    # the variable when passing it into the _impl function?
2443    impl_by_reference = False
2444
2445    # Should Argument Clinic add a '&' before the name of
2446    # the variable when passing it into PyArg_ParseTuple (AndKeywords)?
2447    parse_by_reference = True
2448
2449    #############################################################
2450    #############################################################
2451    ## You shouldn't need to read anything below this point to ##
2452    ## write your own converter functions.                     ##
2453    #############################################################
2454    #############################################################
2455
2456    # The "format unit" to specify for this variable when
2457    # parsing arguments using PyArg_ParseTuple (AndKeywords).
2458    # Custom converters should always use the default value of 'O&'.
2459    format_unit = 'O&'
2460
2461    # What encoding do we want for this variable?  Only used
2462    # by format units starting with 'e'.
2463    encoding = None
2464
2465    # Should this object be required to be a subclass of a specific type?
2466    # If not None, should be a string representing a pointer to a
2467    # PyTypeObject (e.g. "&PyUnicode_Type").
2468    # Only used by the 'O!' format unit (and the "object" converter).
2469    subclass_of = None
2470
2471    # Do we want an adjacent '_length' variable for this variable?
2472    # Only used by format units ending with '#'.
2473    length = False
2474
2475    # Should we show this parameter in the generated
2476    # __text_signature__? This is *almost* always True.
2477    # (It's only False for __new__, __init__, and METH_STATIC functions.)
2478    show_in_signature = True
2479
2480    # Overrides the name used in a text signature.
2481    # The name used for a "self" parameter must be one of
2482    # self, type, or module; however users can set their own.
2483    # This lets the self_converter overrule the user-settable
2484    # name, *just* for the text signature.
2485    # Only set by self_converter.
2486    signature_name = None
2487
2488    # keep in sync with self_converter.__init__!
2489    def __init__(self, name, py_name, function, default=unspecified, *, c_default=None, py_default=None, annotation=unspecified, **kwargs):
2490        self.name = ensure_legal_c_identifier(name)
2491        self.py_name = py_name
2492
2493        if default is not unspecified:
2494            if self.default_type and not isinstance(default, (self.default_type, Unknown)):
2495                if isinstance(self.default_type, type):
2496                    types_str = self.default_type.__name__
2497                else:
2498                    types_str = ', '.join((cls.__name__ for cls in self.default_type))
2499                fail("{}: default value {!r} for field {} is not of type {}".format(
2500                    self.__class__.__name__, default, name, types_str))
2501            self.default = default
2502
2503        if c_default:
2504            self.c_default = c_default
2505        if py_default:
2506            self.py_default = py_default
2507
2508        if annotation != unspecified:
2509            fail("The 'annotation' parameter is not currently permitted.")
2510
2511        # this is deliberate, to prevent you from caching information
2512        # about the function in the init.
2513        # (that breaks if we get cloned.)
2514        # so after this change we will noisily fail.
2515        self.function = LandMine("Don't access members of self.function inside converter_init!")
2516        self.converter_init(**kwargs)
2517        self.function = function
2518
2519    def converter_init(self):
2520        pass
2521
2522    def is_optional(self):
2523        return (self.default is not unspecified)
2524
2525    def _render_self(self, parameter, data):
2526        self.parameter = parameter
2527        name = self.name
2528
2529        # impl_arguments
2530        s = ("&" if self.impl_by_reference else "") + name
2531        data.impl_arguments.append(s)
2532        if self.length:
2533            data.impl_arguments.append(self.length_name())
2534
2535        # impl_parameters
2536        data.impl_parameters.append(self.simple_declaration(by_reference=self.impl_by_reference))
2537        if self.length:
2538            data.impl_parameters.append("Py_ssize_clean_t " + self.length_name())
2539
2540    def _render_non_self(self, parameter, data):
2541        self.parameter = parameter
2542        name = self.name
2543
2544        # declarations
2545        d = self.declaration()
2546        data.declarations.append(d)
2547
2548        # initializers
2549        initializers = self.initialize()
2550        if initializers:
2551            data.initializers.append('/* initializers for ' + name + ' */\n' + initializers.rstrip())
2552
2553        # modifications
2554        modifications = self.modify()
2555        if modifications:
2556            data.modifications.append('/* modifications for ' + name + ' */\n' + modifications.rstrip())
2557
2558        # keywords
2559        if parameter.is_positional_only():
2560            data.keywords.append('')
2561        else:
2562            data.keywords.append(parameter.name)
2563
2564        # format_units
2565        if self.is_optional() and '|' not in data.format_units:
2566            data.format_units.append('|')
2567        if parameter.is_keyword_only() and '$' not in data.format_units:
2568            data.format_units.append('$')
2569        data.format_units.append(self.format_unit)
2570
2571        # parse_arguments
2572        self.parse_argument(data.parse_arguments)
2573
2574        # cleanup
2575        cleanup = self.cleanup()
2576        if cleanup:
2577            data.cleanup.append('/* Cleanup for ' + name + ' */\n' + cleanup.rstrip() + "\n")
2578
2579    def render(self, parameter, data):
2580        """
2581        parameter is a clinic.Parameter instance.
2582        data is a CRenderData instance.
2583        """
2584        self._render_self(parameter, data)
2585        self._render_non_self(parameter, data)
2586
2587    def length_name(self):
2588        """Computes the name of the associated "length" variable."""
2589        if not self.length:
2590            return None
2591        return self.name + "_length"
2592
2593    # Why is this one broken out separately?
2594    # For "positional-only" function parsing,
2595    # which generates a bunch of PyArg_ParseTuple calls.
2596    def parse_argument(self, list):
2597        assert not (self.converter and self.encoding)
2598        if self.format_unit == 'O&':
2599            assert self.converter
2600            list.append(self.converter)
2601
2602        if self.encoding:
2603            list.append(c_repr(self.encoding))
2604        elif self.subclass_of:
2605            list.append(self.subclass_of)
2606
2607        s = ("&" if self.parse_by_reference else "") + self.name
2608        list.append(s)
2609
2610        if self.length:
2611            list.append("&" + self.length_name())
2612
2613    #
2614    # All the functions after here are intended as extension points.
2615    #
2616
2617    def simple_declaration(self, by_reference=False):
2618        """
2619        Computes the basic declaration of the variable.
2620        Used in computing the prototype declaration and the
2621        variable declaration.
2622        """
2623        prototype = [self.type]
2624        if by_reference or not self.type.endswith('*'):
2625            prototype.append(" ")
2626        if by_reference:
2627            prototype.append('*')
2628        prototype.append(self.name)
2629        return "".join(prototype)
2630
2631    def declaration(self):
2632        """
2633        The C statement to declare this variable.
2634        """
2635        declaration = [self.simple_declaration()]
2636        default = self.c_default
2637        if not default and self.parameter.group:
2638            default = self.c_ignored_default
2639        if default:
2640            declaration.append(" = ")
2641            declaration.append(default)
2642        declaration.append(";")
2643        if self.length:
2644            declaration.append('\nPy_ssize_clean_t ')
2645            declaration.append(self.length_name())
2646            declaration.append(';')
2647        return "".join(declaration)
2648
2649    def initialize(self):
2650        """
2651        The C statements required to set up this variable before parsing.
2652        Returns a string containing this code indented at column 0.
2653        If no initialization is necessary, returns an empty string.
2654        """
2655        return ""
2656
2657    def modify(self):
2658        """
2659        The C statements required to modify this variable after parsing.
2660        Returns a string containing this code indented at column 0.
2661        If no initialization is necessary, returns an empty string.
2662        """
2663        return ""
2664
2665    def cleanup(self):
2666        """
2667        The C statements required to clean up after this variable.
2668        Returns a string containing this code indented at column 0.
2669        If no cleanup is necessary, returns an empty string.
2670        """
2671        return ""
2672
2673    def pre_render(self):
2674        """
2675        A second initialization function, like converter_init,
2676        called just before rendering.
2677        You are permitted to examine self.function here.
2678        """
2679        pass
2680
2681    def parse_arg(self, argname, displayname):
2682        if self.format_unit == 'O&':
2683            return """
2684                if (!{converter}({argname}, &{paramname})) {{{{
2685                    goto exit;
2686                }}}}
2687                """.format(argname=argname, paramname=self.name,
2688                           converter=self.converter)
2689        if self.format_unit == 'O!':
2690            cast = '(%s)' % self.type if self.type != 'PyObject *' else ''
2691            if self.subclass_of in type_checks:
2692                typecheck, typename = type_checks[self.subclass_of]
2693                return """
2694                    if (!{typecheck}({argname})) {{{{
2695                        _PyArg_BadArgument("{{name}}", {displayname}, "{typename}", {argname});
2696                        goto exit;
2697                    }}}}
2698                    {paramname} = {cast}{argname};
2699                    """.format(argname=argname, paramname=self.name,
2700                               displayname=displayname, typecheck=typecheck,
2701                               typename=typename, cast=cast)
2702            return """
2703                if (!PyObject_TypeCheck({argname}, {subclass_of})) {{{{
2704                    _PyArg_BadArgument("{{name}}", {displayname}, ({subclass_of})->tp_name, {argname});
2705                    goto exit;
2706                }}}}
2707                {paramname} = {cast}{argname};
2708                """.format(argname=argname, paramname=self.name,
2709                           subclass_of=self.subclass_of, cast=cast,
2710                           displayname=displayname)
2711        if self.format_unit == 'O':
2712            cast = '(%s)' % self.type if self.type != 'PyObject *' else ''
2713            return """
2714                {paramname} = {cast}{argname};
2715                """.format(argname=argname, paramname=self.name, cast=cast)
2716        return None
2717
2718    def set_template_dict(self, template_dict):
2719        pass
2720
2721
2722type_checks = {
2723    '&PyLong_Type': ('PyLong_Check', 'int'),
2724    '&PyTuple_Type': ('PyTuple_Check', 'tuple'),
2725    '&PyList_Type': ('PyList_Check', 'list'),
2726    '&PySet_Type': ('PySet_Check', 'set'),
2727    '&PyFrozenSet_Type': ('PyFrozenSet_Check', 'frozenset'),
2728    '&PyDict_Type': ('PyDict_Check', 'dict'),
2729    '&PyUnicode_Type': ('PyUnicode_Check', 'str'),
2730    '&PyBytes_Type': ('PyBytes_Check', 'bytes'),
2731    '&PyByteArray_Type': ('PyByteArray_Check', 'bytearray'),
2732}
2733
2734
2735class bool_converter(CConverter):
2736    type = 'int'
2737    default_type = bool
2738    format_unit = 'p'
2739    c_ignored_default = '0'
2740
2741    def converter_init(self, *, accept={object}):
2742        if accept == {int}:
2743            self.format_unit = 'i'
2744        elif accept != {object}:
2745            fail("bool_converter: illegal 'accept' argument " + repr(accept))
2746        if self.default is not unspecified:
2747            self.default = bool(self.default)
2748            self.c_default = str(int(self.default))
2749
2750    def parse_arg(self, argname, displayname):
2751        if self.format_unit == 'i':
2752            # XXX PyFloat_Check can be removed after the end of the
2753            # deprecation in _PyLong_FromNbIndexOrNbInt.
2754            return """
2755                if (PyFloat_Check({argname})) {{{{
2756                    PyErr_SetString(PyExc_TypeError,
2757                                    "integer argument expected, got float" );
2758                    goto exit;
2759                }}}}
2760                {paramname} = _PyLong_AsInt({argname});
2761                if ({paramname} == -1 && PyErr_Occurred()) {{{{
2762                    goto exit;
2763                }}}}
2764                """.format(argname=argname, paramname=self.name)
2765        elif self.format_unit == 'p':
2766            return """
2767                {paramname} = PyObject_IsTrue({argname});
2768                if ({paramname} < 0) {{{{
2769                    goto exit;
2770                }}}}
2771                """.format(argname=argname, paramname=self.name)
2772        return super().parse_arg(argname, displayname)
2773
2774class defining_class_converter(CConverter):
2775    """
2776    A special-case converter:
2777    this is the default converter used for the defining class.
2778    """
2779    type = 'PyTypeObject *'
2780    format_unit = ''
2781    show_in_signature = False
2782
2783    def converter_init(self, *, type=None):
2784        self.specified_type = type
2785
2786    def render(self, parameter, data):
2787        self._render_self(parameter, data)
2788
2789    def set_template_dict(self, template_dict):
2790        template_dict['defining_class_name'] = self.name
2791
2792
2793class char_converter(CConverter):
2794    type = 'char'
2795    default_type = (bytes, bytearray)
2796    format_unit = 'c'
2797    c_ignored_default = "'\0'"
2798
2799    def converter_init(self):
2800        if isinstance(self.default, self.default_type):
2801            if len(self.default) != 1:
2802                fail("char_converter: illegal default value " + repr(self.default))
2803
2804            self.c_default = repr(bytes(self.default))[1:]
2805            if self.c_default == '"\'"':
2806                self.c_default = r"'\''"
2807
2808    def parse_arg(self, argname, displayname):
2809        if self.format_unit == 'c':
2810            return """
2811                if (PyBytes_Check({argname}) && PyBytes_GET_SIZE({argname}) == 1) {{{{
2812                    {paramname} = PyBytes_AS_STRING({argname})[0];
2813                }}}}
2814                else if (PyByteArray_Check({argname}) && PyByteArray_GET_SIZE({argname}) == 1) {{{{
2815                    {paramname} = PyByteArray_AS_STRING({argname})[0];
2816                }}}}
2817                else {{{{
2818                    _PyArg_BadArgument("{{name}}", {displayname}, "a byte string of length 1", {argname});
2819                    goto exit;
2820                }}}}
2821                """.format(argname=argname, paramname=self.name,
2822                           displayname=displayname)
2823        return super().parse_arg(argname, displayname)
2824
2825
2826@add_legacy_c_converter('B', bitwise=True)
2827class unsigned_char_converter(CConverter):
2828    type = 'unsigned char'
2829    default_type = int
2830    format_unit = 'b'
2831    c_ignored_default = "'\0'"
2832
2833    def converter_init(self, *, bitwise=False):
2834        if bitwise:
2835            self.format_unit = 'B'
2836
2837    def parse_arg(self, argname, displayname):
2838        if self.format_unit == 'b':
2839            return """
2840                if (PyFloat_Check({argname})) {{{{
2841                    PyErr_SetString(PyExc_TypeError,
2842                                    "integer argument expected, got float" );
2843                    goto exit;
2844                }}}}
2845                {{{{
2846                    long ival = PyLong_AsLong({argname});
2847                    if (ival == -1 && PyErr_Occurred()) {{{{
2848                        goto exit;
2849                    }}}}
2850                    else if (ival < 0) {{{{
2851                        PyErr_SetString(PyExc_OverflowError,
2852                                        "unsigned byte integer is less than minimum");
2853                        goto exit;
2854                    }}}}
2855                    else if (ival > UCHAR_MAX) {{{{
2856                        PyErr_SetString(PyExc_OverflowError,
2857                                        "unsigned byte integer is greater than maximum");
2858                        goto exit;
2859                    }}}}
2860                    else {{{{
2861                        {paramname} = (unsigned char) ival;
2862                    }}}}
2863                }}}}
2864                """.format(argname=argname, paramname=self.name)
2865        elif self.format_unit == 'B':
2866            return """
2867                if (PyFloat_Check({argname})) {{{{
2868                    PyErr_SetString(PyExc_TypeError,
2869                                    "integer argument expected, got float" );
2870                    goto exit;
2871                }}}}
2872                {{{{
2873                    long ival = PyLong_AsUnsignedLongMask({argname});
2874                    if (ival == -1 && PyErr_Occurred()) {{{{
2875                        goto exit;
2876                    }}}}
2877                    else {{{{
2878                        {paramname} = (unsigned char) ival;
2879                    }}}}
2880                }}}}
2881                """.format(argname=argname, paramname=self.name)
2882        return super().parse_arg(argname, displayname)
2883
2884class byte_converter(unsigned_char_converter): pass
2885
2886class short_converter(CConverter):
2887    type = 'short'
2888    default_type = int
2889    format_unit = 'h'
2890    c_ignored_default = "0"
2891
2892    def parse_arg(self, argname, displayname):
2893        if self.format_unit == 'h':
2894            return """
2895                if (PyFloat_Check({argname})) {{{{
2896                    PyErr_SetString(PyExc_TypeError,
2897                                    "integer argument expected, got float" );
2898                    goto exit;
2899                }}}}
2900                {{{{
2901                    long ival = PyLong_AsLong({argname});
2902                    if (ival == -1 && PyErr_Occurred()) {{{{
2903                        goto exit;
2904                    }}}}
2905                    else if (ival < SHRT_MIN) {{{{
2906                        PyErr_SetString(PyExc_OverflowError,
2907                                        "signed short integer is less than minimum");
2908                        goto exit;
2909                    }}}}
2910                    else if (ival > SHRT_MAX) {{{{
2911                        PyErr_SetString(PyExc_OverflowError,
2912                                        "signed short integer is greater than maximum");
2913                        goto exit;
2914                    }}}}
2915                    else {{{{
2916                        {paramname} = (short) ival;
2917                    }}}}
2918                }}}}
2919                """.format(argname=argname, paramname=self.name)
2920        return super().parse_arg(argname, displayname)
2921
2922class unsigned_short_converter(CConverter):
2923    type = 'unsigned short'
2924    default_type = int
2925    c_ignored_default = "0"
2926
2927    def converter_init(self, *, bitwise=False):
2928        if bitwise:
2929            self.format_unit = 'H'
2930        else:
2931            self.converter = '_PyLong_UnsignedShort_Converter'
2932
2933    def parse_arg(self, argname, displayname):
2934        if self.format_unit == 'H':
2935            return """
2936                if (PyFloat_Check({argname})) {{{{
2937                    PyErr_SetString(PyExc_TypeError,
2938                                    "integer argument expected, got float" );
2939                    goto exit;
2940                }}}}
2941                {paramname} = (unsigned short)PyLong_AsUnsignedLongMask({argname});
2942                if ({paramname} == (unsigned short)-1 && PyErr_Occurred()) {{{{
2943                    goto exit;
2944                }}}}
2945                """.format(argname=argname, paramname=self.name)
2946        return super().parse_arg(argname, displayname)
2947
2948@add_legacy_c_converter('C', accept={str})
2949class int_converter(CConverter):
2950    type = 'int'
2951    default_type = int
2952    format_unit = 'i'
2953    c_ignored_default = "0"
2954
2955    def converter_init(self, *, accept={int}, type=None):
2956        if accept == {str}:
2957            self.format_unit = 'C'
2958        elif accept != {int}:
2959            fail("int_converter: illegal 'accept' argument " + repr(accept))
2960        if type != None:
2961            self.type = type
2962
2963    def parse_arg(self, argname, displayname):
2964        if self.format_unit == 'i':
2965            return """
2966                if (PyFloat_Check({argname})) {{{{
2967                    PyErr_SetString(PyExc_TypeError,
2968                                    "integer argument expected, got float" );
2969                    goto exit;
2970                }}}}
2971                {paramname} = _PyLong_AsInt({argname});
2972                if ({paramname} == -1 && PyErr_Occurred()) {{{{
2973                    goto exit;
2974                }}}}
2975                """.format(argname=argname, paramname=self.name)
2976        elif self.format_unit == 'C':
2977            return """
2978                if (!PyUnicode_Check({argname})) {{{{
2979                    _PyArg_BadArgument("{{name}}", {displayname}, "a unicode character", {argname});
2980                    goto exit;
2981                }}}}
2982                if (PyUnicode_READY({argname})) {{{{
2983                    goto exit;
2984                }}}}
2985                if (PyUnicode_GET_LENGTH({argname}) != 1) {{{{
2986                    _PyArg_BadArgument("{{name}}", {displayname}, "a unicode character", {argname});
2987                    goto exit;
2988                }}}}
2989                {paramname} = PyUnicode_READ_CHAR({argname}, 0);
2990                """.format(argname=argname, paramname=self.name,
2991                           displayname=displayname)
2992        return super().parse_arg(argname, displayname)
2993
2994class unsigned_int_converter(CConverter):
2995    type = 'unsigned int'
2996    default_type = int
2997    c_ignored_default = "0"
2998
2999    def converter_init(self, *, bitwise=False):
3000        if bitwise:
3001            self.format_unit = 'I'
3002        else:
3003            self.converter = '_PyLong_UnsignedInt_Converter'
3004
3005    def parse_arg(self, argname, displayname):
3006        if self.format_unit == 'I':
3007            return """
3008                if (PyFloat_Check({argname})) {{{{
3009                    PyErr_SetString(PyExc_TypeError,
3010                                    "integer argument expected, got float" );
3011                    goto exit;
3012                }}}}
3013                {paramname} = (unsigned int)PyLong_AsUnsignedLongMask({argname});
3014                if ({paramname} == (unsigned int)-1 && PyErr_Occurred()) {{{{
3015                    goto exit;
3016                }}}}
3017                """.format(argname=argname, paramname=self.name)
3018        return super().parse_arg(argname, displayname)
3019
3020class long_converter(CConverter):
3021    type = 'long'
3022    default_type = int
3023    format_unit = 'l'
3024    c_ignored_default = "0"
3025
3026    def parse_arg(self, argname, displayname):
3027        if self.format_unit == 'l':
3028            return """
3029                if (PyFloat_Check({argname})) {{{{
3030                    PyErr_SetString(PyExc_TypeError,
3031                                    "integer argument expected, got float" );
3032                    goto exit;
3033                }}}}
3034                {paramname} = PyLong_AsLong({argname});
3035                if ({paramname} == -1 && PyErr_Occurred()) {{{{
3036                    goto exit;
3037                }}}}
3038                """.format(argname=argname, paramname=self.name)
3039        return super().parse_arg(argname, displayname)
3040
3041class unsigned_long_converter(CConverter):
3042    type = 'unsigned long'
3043    default_type = int
3044    c_ignored_default = "0"
3045
3046    def converter_init(self, *, bitwise=False):
3047        if bitwise:
3048            self.format_unit = 'k'
3049        else:
3050            self.converter = '_PyLong_UnsignedLong_Converter'
3051
3052    def parse_arg(self, argname, displayname):
3053        if self.format_unit == 'k':
3054            return """
3055                if (!PyLong_Check({argname})) {{{{
3056                    _PyArg_BadArgument("{{name}}", {displayname}, "int", {argname});
3057                    goto exit;
3058                }}}}
3059                {paramname} = PyLong_AsUnsignedLongMask({argname});
3060                """.format(argname=argname, paramname=self.name,
3061                           displayname=displayname)
3062        return super().parse_arg(argname, displayname)
3063
3064class long_long_converter(CConverter):
3065    type = 'long long'
3066    default_type = int
3067    format_unit = 'L'
3068    c_ignored_default = "0"
3069
3070    def parse_arg(self, argname, displayname):
3071        if self.format_unit == 'L':
3072            return """
3073                if (PyFloat_Check({argname})) {{{{
3074                    PyErr_SetString(PyExc_TypeError,
3075                                    "integer argument expected, got float" );
3076                    goto exit;
3077                }}}}
3078                {paramname} = PyLong_AsLongLong({argname});
3079                if ({paramname} == -1 && PyErr_Occurred()) {{{{
3080                    goto exit;
3081                }}}}
3082                """.format(argname=argname, paramname=self.name)
3083        return super().parse_arg(argname, displayname)
3084
3085class unsigned_long_long_converter(CConverter):
3086    type = 'unsigned long long'
3087    default_type = int
3088    c_ignored_default = "0"
3089
3090    def converter_init(self, *, bitwise=False):
3091        if bitwise:
3092            self.format_unit = 'K'
3093        else:
3094            self.converter = '_PyLong_UnsignedLongLong_Converter'
3095
3096    def parse_arg(self, argname, displayname):
3097        if self.format_unit == 'K':
3098            return """
3099                if (!PyLong_Check({argname})) {{{{
3100                    _PyArg_BadArgument("{{name}}", {displayname}, "int", {argname});
3101                    goto exit;
3102                }}}}
3103                {paramname} = PyLong_AsUnsignedLongLongMask({argname});
3104                """.format(argname=argname, paramname=self.name,
3105                           displayname=displayname)
3106        return super().parse_arg(argname, displayname)
3107
3108class Py_ssize_t_converter(CConverter):
3109    type = 'Py_ssize_t'
3110    c_ignored_default = "0"
3111
3112    def converter_init(self, *, accept={int}):
3113        if accept == {int}:
3114            self.format_unit = 'n'
3115            self.default_type = int
3116        elif accept == {int, NoneType}:
3117            self.converter = '_Py_convert_optional_to_ssize_t'
3118        else:
3119            fail("Py_ssize_t_converter: illegal 'accept' argument " + repr(accept))
3120
3121    def parse_arg(self, argname, displayname):
3122        if self.format_unit == 'n':
3123            return """
3124                if (PyFloat_Check({argname})) {{{{
3125                    PyErr_SetString(PyExc_TypeError,
3126                                    "integer argument expected, got float" );
3127                    goto exit;
3128                }}}}
3129                {{{{
3130                    Py_ssize_t ival = -1;
3131                    PyObject *iobj = PyNumber_Index({argname});
3132                    if (iobj != NULL) {{{{
3133                        ival = PyLong_AsSsize_t(iobj);
3134                        Py_DECREF(iobj);
3135                    }}}}
3136                    if (ival == -1 && PyErr_Occurred()) {{{{
3137                        goto exit;
3138                    }}}}
3139                    {paramname} = ival;
3140                }}}}
3141                """.format(argname=argname, paramname=self.name)
3142        return super().parse_arg(argname, displayname)
3143
3144
3145class slice_index_converter(CConverter):
3146    type = 'Py_ssize_t'
3147
3148    def converter_init(self, *, accept={int, NoneType}):
3149        if accept == {int}:
3150            self.converter = '_PyEval_SliceIndexNotNone'
3151        elif accept == {int, NoneType}:
3152            self.converter = '_PyEval_SliceIndex'
3153        else:
3154            fail("slice_index_converter: illegal 'accept' argument " + repr(accept))
3155
3156class size_t_converter(CConverter):
3157    type = 'size_t'
3158    converter = '_PyLong_Size_t_Converter'
3159    c_ignored_default = "0"
3160
3161    def parse_arg(self, argname, displayname):
3162        if self.format_unit == 'n':
3163            return """
3164                {paramname} = PyNumber_AsSsize_t({argname}, PyExc_OverflowError);
3165                if ({paramname} == -1 && PyErr_Occurred()) {{{{
3166                    goto exit;
3167                }}}}
3168                """.format(argname=argname, paramname=self.name)
3169        return super().parse_arg(argname, displayname)
3170
3171
3172class float_converter(CConverter):
3173    type = 'float'
3174    default_type = float
3175    format_unit = 'f'
3176    c_ignored_default = "0.0"
3177
3178    def parse_arg(self, argname, displayname):
3179        if self.format_unit == 'f':
3180            return """
3181                if (PyFloat_CheckExact({argname})) {{{{
3182                    {paramname} = (float) (PyFloat_AS_DOUBLE({argname}));
3183                }}}}
3184                else
3185                {{{{
3186                    {paramname} = (float) PyFloat_AsDouble({argname});
3187                    if ({paramname} == -1.0 && PyErr_Occurred()) {{{{
3188                        goto exit;
3189                    }}}}
3190                }}}}
3191                """.format(argname=argname, paramname=self.name)
3192        return super().parse_arg(argname, displayname)
3193
3194class double_converter(CConverter):
3195    type = 'double'
3196    default_type = float
3197    format_unit = 'd'
3198    c_ignored_default = "0.0"
3199
3200    def parse_arg(self, argname, displayname):
3201        if self.format_unit == 'd':
3202            return """
3203                if (PyFloat_CheckExact({argname})) {{{{
3204                    {paramname} = PyFloat_AS_DOUBLE({argname});
3205                }}}}
3206                else
3207                {{{{
3208                    {paramname} = PyFloat_AsDouble({argname});
3209                    if ({paramname} == -1.0 && PyErr_Occurred()) {{{{
3210                        goto exit;
3211                    }}}}
3212                }}}}
3213                """.format(argname=argname, paramname=self.name)
3214        return super().parse_arg(argname, displayname)
3215
3216
3217class Py_complex_converter(CConverter):
3218    type = 'Py_complex'
3219    default_type = complex
3220    format_unit = 'D'
3221    c_ignored_default = "{0.0, 0.0}"
3222
3223    def parse_arg(self, argname, displayname):
3224        if self.format_unit == 'D':
3225            return """
3226                {paramname} = PyComplex_AsCComplex({argname});
3227                if (PyErr_Occurred()) {{{{
3228                    goto exit;
3229                }}}}
3230                """.format(argname=argname, paramname=self.name)
3231        return super().parse_arg(argname, displayname)
3232
3233
3234class object_converter(CConverter):
3235    type = 'PyObject *'
3236    format_unit = 'O'
3237
3238    def converter_init(self, *, converter=None, type=None, subclass_of=None):
3239        if converter:
3240            if subclass_of:
3241                fail("object: Cannot pass in both 'converter' and 'subclass_of'")
3242            self.format_unit = 'O&'
3243            self.converter = converter
3244        elif subclass_of:
3245            self.format_unit = 'O!'
3246            self.subclass_of = subclass_of
3247
3248        if type is not None:
3249            self.type = type
3250
3251
3252#
3253# We define three conventions for buffer types in the 'accept' argument:
3254#
3255#  buffer  : any object supporting the buffer interface
3256#  rwbuffer: any object supporting the buffer interface, but must be writeable
3257#  robuffer: any object supporting the buffer interface, but must not be writeable
3258#
3259
3260class buffer: pass
3261class rwbuffer: pass
3262class robuffer: pass
3263
3264def str_converter_key(types, encoding, zeroes):
3265    return (frozenset(types), bool(encoding), bool(zeroes))
3266
3267str_converter_argument_map = {}
3268
3269class str_converter(CConverter):
3270    type = 'const char *'
3271    default_type = (str, Null, NoneType)
3272    format_unit = 's'
3273
3274    def converter_init(self, *, accept={str}, encoding=None, zeroes=False):
3275
3276        key = str_converter_key(accept, encoding, zeroes)
3277        format_unit = str_converter_argument_map.get(key)
3278        if not format_unit:
3279            fail("str_converter: illegal combination of arguments", key)
3280
3281        self.format_unit = format_unit
3282        self.length = bool(zeroes)
3283        if encoding:
3284            if self.default not in (Null, None, unspecified):
3285                fail("str_converter: Argument Clinic doesn't support default values for encoded strings")
3286            self.encoding = encoding
3287            self.type = 'char *'
3288            # sorry, clinic can't support preallocated buffers
3289            # for es# and et#
3290            self.c_default = "NULL"
3291        if NoneType in accept and self.c_default == "Py_None":
3292            self.c_default = "NULL"
3293
3294    def cleanup(self):
3295        if self.encoding:
3296            name = self.name
3297            return "".join(["if (", name, ") {\n   PyMem_FREE(", name, ");\n}\n"])
3298
3299    def parse_arg(self, argname, displayname):
3300        if self.format_unit == 's':
3301            return """
3302                if (!PyUnicode_Check({argname})) {{{{
3303                    _PyArg_BadArgument("{{name}}", {displayname}, "str", {argname});
3304                    goto exit;
3305                }}}}
3306                Py_ssize_t {paramname}_length;
3307                {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{paramname}_length);
3308                if ({paramname} == NULL) {{{{
3309                    goto exit;
3310                }}}}
3311                if (strlen({paramname}) != (size_t){paramname}_length) {{{{
3312                    PyErr_SetString(PyExc_ValueError, "embedded null character");
3313                    goto exit;
3314                }}}}
3315                """.format(argname=argname, paramname=self.name,
3316                           displayname=displayname)
3317        if self.format_unit == 'z':
3318            return """
3319                if ({argname} == Py_None) {{{{
3320                    {paramname} = NULL;
3321                }}}}
3322                else if (PyUnicode_Check({argname})) {{{{
3323                    Py_ssize_t {paramname}_length;
3324                    {paramname} = PyUnicode_AsUTF8AndSize({argname}, &{paramname}_length);
3325                    if ({paramname} == NULL) {{{{
3326                        goto exit;
3327                    }}}}
3328                    if (strlen({paramname}) != (size_t){paramname}_length) {{{{
3329                        PyErr_SetString(PyExc_ValueError, "embedded null character");
3330                        goto exit;
3331                    }}}}
3332                }}}}
3333                else {{{{
3334                    _PyArg_BadArgument("{{name}}", {displayname}, "str or None", {argname});
3335                    goto exit;
3336                }}}}
3337                """.format(argname=argname, paramname=self.name,
3338                           displayname=displayname)
3339        return super().parse_arg(argname, displayname)
3340
3341#
3342# This is the fourth or fifth rewrite of registering all the
3343# string converter format units.  Previous approaches hid
3344# bugs--generally mismatches between the semantics of the format
3345# unit and the arguments necessary to represent those semantics
3346# properly.  Hopefully with this approach we'll get it 100% right.
3347#
3348# The r() function (short for "register") both registers the
3349# mapping from arguments to format unit *and* registers the
3350# legacy C converter for that format unit.
3351#
3352def r(format_unit, *, accept, encoding=False, zeroes=False):
3353    if not encoding and format_unit != 's':
3354        # add the legacy c converters here too.
3355        #
3356        # note: add_legacy_c_converter can't work for
3357        #   es, es#, et, or et#
3358        #   because of their extra encoding argument
3359        #
3360        # also don't add the converter for 's' because
3361        # the metaclass for CConverter adds it for us.
3362        kwargs = {}
3363        if accept != {str}:
3364            kwargs['accept'] = accept
3365        if zeroes:
3366            kwargs['zeroes'] = True
3367        added_f = functools.partial(str_converter, **kwargs)
3368        legacy_converters[format_unit] = added_f
3369
3370    d = str_converter_argument_map
3371    key = str_converter_key(accept, encoding, zeroes)
3372    if key in d:
3373        sys.exit("Duplicate keys specified for str_converter_argument_map!")
3374    d[key] = format_unit
3375
3376r('es',  encoding=True,              accept={str})
3377r('es#', encoding=True, zeroes=True, accept={str})
3378r('et',  encoding=True,              accept={bytes, bytearray, str})
3379r('et#', encoding=True, zeroes=True, accept={bytes, bytearray, str})
3380r('s',                               accept={str})
3381r('s#',                 zeroes=True, accept={robuffer, str})
3382r('y',                               accept={robuffer})
3383r('y#',                 zeroes=True, accept={robuffer})
3384r('z',                               accept={str, NoneType})
3385r('z#',                 zeroes=True, accept={robuffer, str, NoneType})
3386del r
3387
3388
3389class PyBytesObject_converter(CConverter):
3390    type = 'PyBytesObject *'
3391    format_unit = 'S'
3392    # accept = {bytes}
3393
3394    def parse_arg(self, argname, displayname):
3395        if self.format_unit == 'S':
3396            return """
3397                if (!PyBytes_Check({argname})) {{{{
3398                    _PyArg_BadArgument("{{name}}", {displayname}, "bytes", {argname});
3399                    goto exit;
3400                }}}}
3401                {paramname} = ({type}){argname};
3402                """.format(argname=argname, paramname=self.name,
3403                           type=self.type, displayname=displayname)
3404        return super().parse_arg(argname, displayname)
3405
3406class PyByteArrayObject_converter(CConverter):
3407    type = 'PyByteArrayObject *'
3408    format_unit = 'Y'
3409    # accept = {bytearray}
3410
3411    def parse_arg(self, argname, displayname):
3412        if self.format_unit == 'Y':
3413            return """
3414                if (!PyByteArray_Check({argname})) {{{{
3415                    _PyArg_BadArgument("{{name}}", {displayname}, "bytearray", {argname});
3416                    goto exit;
3417                }}}}
3418                {paramname} = ({type}){argname};
3419                """.format(argname=argname, paramname=self.name,
3420                           type=self.type, displayname=displayname)
3421        return super().parse_arg(argname, displayname)
3422
3423class unicode_converter(CConverter):
3424    type = 'PyObject *'
3425    default_type = (str, Null, NoneType)
3426    format_unit = 'U'
3427
3428    def parse_arg(self, argname, displayname):
3429        if self.format_unit == 'U':
3430            return """
3431                if (!PyUnicode_Check({argname})) {{{{
3432                    _PyArg_BadArgument("{{name}}", {displayname}, "str", {argname});
3433                    goto exit;
3434                }}}}
3435                if (PyUnicode_READY({argname}) == -1) {{{{
3436                    goto exit;
3437                }}}}
3438                {paramname} = {argname};
3439                """.format(argname=argname, paramname=self.name,
3440                           displayname=displayname)
3441        return super().parse_arg(argname, displayname)
3442
3443@add_legacy_c_converter('u#', zeroes=True)
3444@add_legacy_c_converter('Z', accept={str, NoneType})
3445@add_legacy_c_converter('Z#', accept={str, NoneType}, zeroes=True)
3446class Py_UNICODE_converter(CConverter):
3447    type = 'const Py_UNICODE *'
3448    default_type = (str, Null, NoneType)
3449    format_unit = 'u'
3450
3451    def converter_init(self, *, accept={str}, zeroes=False):
3452        format_unit = 'Z' if accept=={str, NoneType} else 'u'
3453        if zeroes:
3454            format_unit += '#'
3455            self.length = True
3456        self.format_unit = format_unit
3457
3458@add_legacy_c_converter('s*', accept={str, buffer})
3459@add_legacy_c_converter('z*', accept={str, buffer, NoneType})
3460@add_legacy_c_converter('w*', accept={rwbuffer})
3461class Py_buffer_converter(CConverter):
3462    type = 'Py_buffer'
3463    format_unit = 'y*'
3464    impl_by_reference = True
3465    c_ignored_default = "{NULL, NULL}"
3466
3467    def converter_init(self, *, accept={buffer}):
3468        if self.default not in (unspecified, None):
3469            fail("The only legal default value for Py_buffer is None.")
3470
3471        self.c_default = self.c_ignored_default
3472
3473        if accept == {str, buffer, NoneType}:
3474            format_unit = 'z*'
3475        elif accept == {str, buffer}:
3476            format_unit = 's*'
3477        elif accept == {buffer}:
3478            format_unit = 'y*'
3479        elif accept == {rwbuffer}:
3480            format_unit = 'w*'
3481        else:
3482            fail("Py_buffer_converter: illegal combination of arguments")
3483
3484        self.format_unit = format_unit
3485
3486    def cleanup(self):
3487        name = self.name
3488        return "".join(["if (", name, ".obj) {\n   PyBuffer_Release(&", name, ");\n}\n"])
3489
3490    def parse_arg(self, argname, displayname):
3491        if self.format_unit == 'y*':
3492            return """
3493                if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{
3494                    goto exit;
3495                }}}}
3496                if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{
3497                    _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname});
3498                    goto exit;
3499                }}}}
3500                """.format(argname=argname, paramname=self.name,
3501                           displayname=displayname)
3502        elif self.format_unit == 's*':
3503            return """
3504                if (PyUnicode_Check({argname})) {{{{
3505                    Py_ssize_t len;
3506                    const char *ptr = PyUnicode_AsUTF8AndSize({argname}, &len);
3507                    if (ptr == NULL) {{{{
3508                        goto exit;
3509                    }}}}
3510                    PyBuffer_FillInfo(&{paramname}, {argname}, (void *)ptr, len, 1, 0);
3511                }}}}
3512                else {{{{ /* any bytes-like object */
3513                    if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_SIMPLE) != 0) {{{{
3514                        goto exit;
3515                    }}}}
3516                    if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{
3517                        _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname});
3518                        goto exit;
3519                    }}}}
3520                }}}}
3521                """.format(argname=argname, paramname=self.name,
3522                           displayname=displayname)
3523        elif self.format_unit == 'w*':
3524            return """
3525                if (PyObject_GetBuffer({argname}, &{paramname}, PyBUF_WRITABLE) < 0) {{{{
3526                    PyErr_Clear();
3527                    _PyArg_BadArgument("{{name}}", {displayname}, "read-write bytes-like object", {argname});
3528                    goto exit;
3529                }}}}
3530                if (!PyBuffer_IsContiguous(&{paramname}, 'C')) {{{{
3531                    _PyArg_BadArgument("{{name}}", {displayname}, "contiguous buffer", {argname});
3532                    goto exit;
3533                }}}}
3534                """.format(argname=argname, paramname=self.name,
3535                           displayname=displayname)
3536        return super().parse_arg(argname, displayname)
3537
3538
3539def correct_name_for_self(f):
3540    if f.kind in (CALLABLE, METHOD_INIT):
3541        if f.cls:
3542            return "PyObject *", "self"
3543        return "PyObject *", "module"
3544    if f.kind == STATIC_METHOD:
3545        return "void *", "null"
3546    if f.kind in (CLASS_METHOD, METHOD_NEW):
3547        return "PyTypeObject *", "type"
3548    raise RuntimeError("Unhandled type of function f: " + repr(f.kind))
3549
3550def required_type_for_self_for_parser(f):
3551    type, _ = correct_name_for_self(f)
3552    if f.kind in (METHOD_INIT, METHOD_NEW, STATIC_METHOD, CLASS_METHOD):
3553        return type
3554    return None
3555
3556
3557class self_converter(CConverter):
3558    """
3559    A special-case converter:
3560    this is the default converter used for "self".
3561    """
3562    type = None
3563    format_unit = ''
3564
3565    def converter_init(self, *, type=None):
3566        self.specified_type = type
3567
3568    def pre_render(self):
3569        f = self.function
3570        default_type, default_name = correct_name_for_self(f)
3571        self.signature_name = default_name
3572        self.type = self.specified_type or self.type or default_type
3573
3574        kind = self.function.kind
3575        new_or_init = kind in (METHOD_NEW, METHOD_INIT)
3576
3577        if (kind == STATIC_METHOD) or new_or_init:
3578            self.show_in_signature = False
3579
3580    # tp_new (METHOD_NEW) functions are of type newfunc:
3581    #     typedef PyObject *(*newfunc)(struct _typeobject *, PyObject *, PyObject *);
3582    # PyTypeObject is a typedef for struct _typeobject.
3583    #
3584    # tp_init (METHOD_INIT) functions are of type initproc:
3585    #     typedef int (*initproc)(PyObject *, PyObject *, PyObject *);
3586    #
3587    # All other functions generated by Argument Clinic are stored in
3588    # PyMethodDef structures, in the ml_meth slot, which is of type PyCFunction:
3589    #     typedef PyObject *(*PyCFunction)(PyObject *, PyObject *);
3590    # However!  We habitually cast these functions to PyCFunction,
3591    # since functions that accept keyword arguments don't fit this signature
3592    # but are stored there anyway.  So strict type equality isn't important
3593    # for these functions.
3594    #
3595    # So:
3596    #
3597    # * The name of the first parameter to the impl and the parsing function will always
3598    #   be self.name.
3599    #
3600    # * The type of the first parameter to the impl will always be of self.type.
3601    #
3602    # * If the function is neither tp_new (METHOD_NEW) nor tp_init (METHOD_INIT):
3603    #   * The type of the first parameter to the parsing function is also self.type.
3604    #     This means that if you step into the parsing function, your "self" parameter
3605    #     is of the correct type, which may make debugging more pleasant.
3606    #
3607    # * Else if the function is tp_new (METHOD_NEW):
3608    #   * The type of the first parameter to the parsing function is "PyTypeObject *",
3609    #     so the type signature of the function call is an exact match.
3610    #   * If self.type != "PyTypeObject *", we cast the first parameter to self.type
3611    #     in the impl call.
3612    #
3613    # * Else if the function is tp_init (METHOD_INIT):
3614    #   * The type of the first parameter to the parsing function is "PyObject *",
3615    #     so the type signature of the function call is an exact match.
3616    #   * If self.type != "PyObject *", we cast the first parameter to self.type
3617    #     in the impl call.
3618
3619    @property
3620    def parser_type(self):
3621        return required_type_for_self_for_parser(self.function) or self.type
3622
3623    def render(self, parameter, data):
3624        """
3625        parameter is a clinic.Parameter instance.
3626        data is a CRenderData instance.
3627        """
3628        if self.function.kind == STATIC_METHOD:
3629            return
3630
3631        self._render_self(parameter, data)
3632
3633        if self.type != self.parser_type:
3634            # insert cast to impl_argument[0], aka self.
3635            # we know we're in the first slot in all the CRenderData lists,
3636            # because we render parameters in order, and self is always first.
3637            assert len(data.impl_arguments) == 1
3638            assert data.impl_arguments[0] == self.name
3639            data.impl_arguments[0] = '(' + self.type + ")" + data.impl_arguments[0]
3640
3641    def set_template_dict(self, template_dict):
3642        template_dict['self_name'] = self.name
3643        template_dict['self_type'] = self.parser_type
3644        kind = self.function.kind
3645        cls = self.function.cls
3646
3647        if ((kind in (METHOD_NEW, METHOD_INIT)) and cls and cls.typedef):
3648            type_object = self.function.cls.type_object
3649            if kind == METHOD_NEW:
3650                type_check = '({} == {})'.format(self.name, type_object)
3651            else:
3652                type_check = 'Py_IS_TYPE({}, {})'.format(self.name, type_object)
3653
3654            line = '{} &&\n        '.format(type_check)
3655            template_dict['self_type_check'] = line
3656
3657
3658
3659def add_c_return_converter(f, name=None):
3660    if not name:
3661        name = f.__name__
3662        if not name.endswith('_return_converter'):
3663            return f
3664        name = name[:-len('_return_converter')]
3665    return_converters[name] = f
3666    return f
3667
3668
3669class CReturnConverterAutoRegister(type):
3670    def __init__(cls, name, bases, classdict):
3671        add_c_return_converter(cls)
3672
3673class CReturnConverter(metaclass=CReturnConverterAutoRegister):
3674
3675    # The C type to use for this variable.
3676    # 'type' should be a Python string specifying the type, e.g. "int".
3677    # If this is a pointer type, the type string should end with ' *'.
3678    type = 'PyObject *'
3679
3680    # The Python default value for this parameter, as a Python value.
3681    # Or the magic value "unspecified" if there is no default.
3682    default = None
3683
3684    def __init__(self, *, py_default=None, **kwargs):
3685        self.py_default = py_default
3686        try:
3687            self.return_converter_init(**kwargs)
3688        except TypeError as e:
3689            s = ', '.join(name + '=' + repr(value) for name, value in kwargs.items())
3690            sys.exit(self.__class__.__name__ + '(' + s + ')\n' + str(e))
3691
3692    def return_converter_init(self):
3693        pass
3694
3695    def declare(self, data, name="_return_value"):
3696        line = []
3697        add = line.append
3698        add(self.type)
3699        if not self.type.endswith('*'):
3700            add(' ')
3701        add(name + ';')
3702        data.declarations.append(''.join(line))
3703        data.return_value = name
3704
3705    def err_occurred_if(self, expr, data):
3706        data.return_conversion.append('if (({}) && PyErr_Occurred()) {{\n    goto exit;\n}}\n'.format(expr))
3707
3708    def err_occurred_if_null_pointer(self, variable, data):
3709        data.return_conversion.append('if ({} == NULL) {{\n    goto exit;\n}}\n'.format(variable))
3710
3711    def render(self, function, data):
3712        """
3713        function is a clinic.Function instance.
3714        data is a CRenderData instance.
3715        """
3716        pass
3717
3718add_c_return_converter(CReturnConverter, 'object')
3719
3720class NoneType_return_converter(CReturnConverter):
3721    def render(self, function, data):
3722        self.declare(data)
3723        data.return_conversion.append('''
3724if (_return_value != Py_None) {
3725    goto exit;
3726}
3727return_value = Py_None;
3728Py_INCREF(Py_None);
3729'''.strip())
3730
3731class bool_return_converter(CReturnConverter):
3732    type = 'int'
3733
3734    def render(self, function, data):
3735        self.declare(data)
3736        self.err_occurred_if("_return_value == -1", data)
3737        data.return_conversion.append('return_value = PyBool_FromLong((long)_return_value);\n')
3738
3739class long_return_converter(CReturnConverter):
3740    type = 'long'
3741    conversion_fn = 'PyLong_FromLong'
3742    cast = ''
3743    unsigned_cast = ''
3744
3745    def render(self, function, data):
3746        self.declare(data)
3747        self.err_occurred_if("_return_value == {}-1".format(self.unsigned_cast), data)
3748        data.return_conversion.append(
3749            ''.join(('return_value = ', self.conversion_fn, '(', self.cast, '_return_value);\n')))
3750
3751class int_return_converter(long_return_converter):
3752    type = 'int'
3753    cast = '(long)'
3754
3755class init_return_converter(long_return_converter):
3756    """
3757    Special return converter for __init__ functions.
3758    """
3759    type = 'int'
3760    cast = '(long)'
3761
3762    def render(self, function, data):
3763        pass
3764
3765class unsigned_long_return_converter(long_return_converter):
3766    type = 'unsigned long'
3767    conversion_fn = 'PyLong_FromUnsignedLong'
3768    unsigned_cast = '(unsigned long)'
3769
3770class unsigned_int_return_converter(unsigned_long_return_converter):
3771    type = 'unsigned int'
3772    cast = '(unsigned long)'
3773    unsigned_cast = '(unsigned int)'
3774
3775class Py_ssize_t_return_converter(long_return_converter):
3776    type = 'Py_ssize_t'
3777    conversion_fn = 'PyLong_FromSsize_t'
3778
3779class size_t_return_converter(long_return_converter):
3780    type = 'size_t'
3781    conversion_fn = 'PyLong_FromSize_t'
3782    unsigned_cast = '(size_t)'
3783
3784
3785class double_return_converter(CReturnConverter):
3786    type = 'double'
3787    cast = ''
3788
3789    def render(self, function, data):
3790        self.declare(data)
3791        self.err_occurred_if("_return_value == -1.0", data)
3792        data.return_conversion.append(
3793            'return_value = PyFloat_FromDouble(' + self.cast + '_return_value);\n')
3794
3795class float_return_converter(double_return_converter):
3796    type = 'float'
3797    cast = '(double)'
3798
3799
3800def eval_ast_expr(node, globals, *, filename='-'):
3801    """
3802    Takes an ast.Expr node.  Compiles and evaluates it.
3803    Returns the result of the expression.
3804
3805    globals represents the globals dict the expression
3806    should see.  (There's no equivalent for "locals" here.)
3807    """
3808
3809    if isinstance(node, ast.Expr):
3810        node = node.value
3811
3812    node = ast.Expression(node)
3813    co = compile(node, filename, 'eval')
3814    fn = types.FunctionType(co, globals)
3815    return fn()
3816
3817
3818class IndentStack:
3819    def __init__(self):
3820        self.indents = []
3821        self.margin = None
3822
3823    def _ensure(self):
3824        if not self.indents:
3825            fail('IndentStack expected indents, but none are defined.')
3826
3827    def measure(self, line):
3828        """
3829        Returns the length of the line's margin.
3830        """
3831        if '\t' in line:
3832            fail('Tab characters are illegal in the Argument Clinic DSL.')
3833        stripped = line.lstrip()
3834        if not len(stripped):
3835            # we can't tell anything from an empty line
3836            # so just pretend it's indented like our current indent
3837            self._ensure()
3838            return self.indents[-1]
3839        return len(line) - len(stripped)
3840
3841    def infer(self, line):
3842        """
3843        Infer what is now the current margin based on this line.
3844        Returns:
3845            1 if we have indented (or this is the first margin)
3846            0 if the margin has not changed
3847           -N if we have dedented N times
3848        """
3849        indent = self.measure(line)
3850        margin = ' ' * indent
3851        if not self.indents:
3852            self.indents.append(indent)
3853            self.margin = margin
3854            return 1
3855        current = self.indents[-1]
3856        if indent == current:
3857            return 0
3858        if indent > current:
3859            self.indents.append(indent)
3860            self.margin = margin
3861            return 1
3862        # indent < current
3863        if indent not in self.indents:
3864            fail("Illegal outdent.")
3865        outdent_count = 0
3866        while indent != current:
3867            self.indents.pop()
3868            current = self.indents[-1]
3869            outdent_count -= 1
3870        self.margin = margin
3871        return outdent_count
3872
3873    @property
3874    def depth(self):
3875        """
3876        Returns how many margins are currently defined.
3877        """
3878        return len(self.indents)
3879
3880    def indent(self, line):
3881        """
3882        Indents a line by the currently defined margin.
3883        """
3884        return self.margin + line
3885
3886    def dedent(self, line):
3887        """
3888        Dedents a line by the currently defined margin.
3889        (The inverse of 'indent'.)
3890        """
3891        margin = self.margin
3892        indent = self.indents[-1]
3893        if not line.startswith(margin):
3894            fail('Cannot dedent, line does not start with the previous margin:')
3895        return line[indent:]
3896
3897
3898class DSLParser:
3899    def __init__(self, clinic):
3900        self.clinic = clinic
3901
3902        self.directives = {}
3903        for name in dir(self):
3904            # functions that start with directive_ are added to directives
3905            _, s, key = name.partition("directive_")
3906            if s:
3907                self.directives[key] = getattr(self, name)
3908
3909            # functions that start with at_ are too, with an @ in front
3910            _, s, key = name.partition("at_")
3911            if s:
3912                self.directives['@' + key] = getattr(self, name)
3913
3914        self.reset()
3915
3916    def reset(self):
3917        self.function = None
3918        self.state = self.state_dsl_start
3919        self.parameter_indent = None
3920        self.keyword_only = False
3921        self.positional_only = False
3922        self.group = 0
3923        self.parameter_state = self.ps_start
3924        self.seen_positional_with_default = False
3925        self.indent = IndentStack()
3926        self.kind = CALLABLE
3927        self.coexist = False
3928        self.parameter_continuation = ''
3929        self.preserve_output = False
3930
3931    def directive_version(self, required):
3932        global version
3933        if version_comparitor(version, required) < 0:
3934            fail("Insufficient Clinic version!\n  Version: " + version + "\n  Required: " + required)
3935
3936    def directive_module(self, name):
3937        fields = name.split('.')
3938        new = fields.pop()
3939        module, cls = self.clinic._module_and_class(fields)
3940        if cls:
3941            fail("Can't nest a module inside a class!")
3942
3943        if name in module.classes:
3944            fail("Already defined module " + repr(name) + "!")
3945
3946        m = Module(name, module)
3947        module.modules[name] = m
3948        self.block.signatures.append(m)
3949
3950    def directive_class(self, name, typedef, type_object):
3951        fields = name.split('.')
3952        in_classes = False
3953        parent = self
3954        name = fields.pop()
3955        so_far = []
3956        module, cls = self.clinic._module_and_class(fields)
3957
3958        parent = cls or module
3959        if name in parent.classes:
3960            fail("Already defined class " + repr(name) + "!")
3961
3962        c = Class(name, module, cls, typedef, type_object)
3963        parent.classes[name] = c
3964        self.block.signatures.append(c)
3965
3966    def directive_set(self, name, value):
3967        if name not in ("line_prefix", "line_suffix"):
3968            fail("unknown variable", repr(name))
3969
3970        value = value.format_map({
3971            'block comment start': '/*',
3972            'block comment end': '*/',
3973            })
3974
3975        self.clinic.__dict__[name] = value
3976
3977    def directive_destination(self, name, command, *args):
3978        if command == 'new':
3979            self.clinic.add_destination(name, *args)
3980            return
3981
3982        if command == 'clear':
3983            self.clinic.get_destination(name).clear()
3984        fail("unknown destination command", repr(command))
3985
3986
3987    def directive_output(self, command_or_name, destination=''):
3988        fd = self.clinic.destination_buffers
3989
3990        if command_or_name == "preset":
3991            preset = self.clinic.presets.get(destination)
3992            if not preset:
3993                fail("Unknown preset " + repr(destination) + "!")
3994            fd.update(preset)
3995            return
3996
3997        if command_or_name == "push":
3998            self.clinic.destination_buffers_stack.append(fd.copy())
3999            return
4000
4001        if command_or_name == "pop":
4002            if not self.clinic.destination_buffers_stack:
4003                fail("Can't 'output pop', stack is empty!")
4004            previous_fd = self.clinic.destination_buffers_stack.pop()
4005            fd.update(previous_fd)
4006            return
4007
4008        # secret command for debugging!
4009        if command_or_name == "print":
4010            self.block.output.append(pprint.pformat(fd))
4011            self.block.output.append('\n')
4012            return
4013
4014        d = self.clinic.get_destination(destination)
4015
4016        if command_or_name == "everything":
4017            for name in list(fd):
4018                fd[name] = d
4019            return
4020
4021        if command_or_name not in fd:
4022            fail("Invalid command / destination name " + repr(command_or_name) + ", must be one of:\n  preset push pop print everything " + " ".join(fd))
4023        fd[command_or_name] = d
4024
4025    def directive_dump(self, name):
4026        self.block.output.append(self.clinic.get_destination(name).dump())
4027
4028    def directive_print(self, *args):
4029        self.block.output.append(' '.join(args))
4030        self.block.output.append('\n')
4031
4032    def directive_preserve(self):
4033        if self.preserve_output:
4034            fail("Can't have preserve twice in one block!")
4035        self.preserve_output = True
4036
4037    def at_classmethod(self):
4038        if self.kind is not CALLABLE:
4039            fail("Can't set @classmethod, function is not a normal callable")
4040        self.kind = CLASS_METHOD
4041
4042    def at_staticmethod(self):
4043        if self.kind is not CALLABLE:
4044            fail("Can't set @staticmethod, function is not a normal callable")
4045        self.kind = STATIC_METHOD
4046
4047    def at_coexist(self):
4048        if self.coexist:
4049            fail("Called @coexist twice!")
4050        self.coexist = True
4051
4052    def parse(self, block):
4053        self.reset()
4054        self.block = block
4055        self.saved_output = self.block.output
4056        block.output = []
4057        block_start = self.clinic.block_parser.line_number
4058        lines = block.input.split('\n')
4059        for line_number, line in enumerate(lines, self.clinic.block_parser.block_start_line_number):
4060            if '\t' in line:
4061                fail('Tab characters are illegal in the Clinic DSL.\n\t' + repr(line), line_number=block_start)
4062            self.state(line)
4063
4064        self.next(self.state_terminal)
4065        self.state(None)
4066
4067        block.output.extend(self.clinic.language.render(clinic, block.signatures))
4068
4069        if self.preserve_output:
4070            if block.output:
4071                fail("'preserve' only works for blocks that don't produce any output!")
4072            block.output = self.saved_output
4073
4074    @staticmethod
4075    def ignore_line(line):
4076        # ignore comment-only lines
4077        if line.lstrip().startswith('#'):
4078            return True
4079
4080        # Ignore empty lines too
4081        # (but not in docstring sections!)
4082        if not line.strip():
4083            return True
4084
4085        return False
4086
4087    @staticmethod
4088    def calculate_indent(line):
4089        return len(line) - len(line.strip())
4090
4091    def next(self, state, line=None):
4092        # real_print(self.state.__name__, "->", state.__name__, ", line=", line)
4093        self.state = state
4094        if line is not None:
4095            self.state(line)
4096
4097    def state_dsl_start(self, line):
4098        # self.block = self.ClinicOutputBlock(self)
4099        if self.ignore_line(line):
4100            return
4101
4102        # is it a directive?
4103        fields = shlex.split(line)
4104        directive_name = fields[0]
4105        directive = self.directives.get(directive_name, None)
4106        if directive:
4107            try:
4108                directive(*fields[1:])
4109            except TypeError as e:
4110                fail(str(e))
4111            return
4112
4113        self.next(self.state_modulename_name, line)
4114
4115    def state_modulename_name(self, line):
4116        # looking for declaration, which establishes the leftmost column
4117        # line should be
4118        #     modulename.fnname [as c_basename] [-> return annotation]
4119        # square brackets denote optional syntax.
4120        #
4121        # alternatively:
4122        #     modulename.fnname [as c_basename] = modulename.existing_fn_name
4123        # clones the parameters and return converter from that
4124        # function.  you can't modify them.  you must enter a
4125        # new docstring.
4126        #
4127        # (but we might find a directive first!)
4128        #
4129        # this line is permitted to start with whitespace.
4130        # we'll call this number of spaces F (for "function").
4131
4132        if not line.strip():
4133            return
4134
4135        self.indent.infer(line)
4136
4137        # are we cloning?
4138        before, equals, existing = line.rpartition('=')
4139        if equals:
4140            full_name, _, c_basename = before.partition(' as ')
4141            full_name = full_name.strip()
4142            c_basename = c_basename.strip()
4143            existing = existing.strip()
4144            if (is_legal_py_identifier(full_name) and
4145                (not c_basename or is_legal_c_identifier(c_basename)) and
4146                is_legal_py_identifier(existing)):
4147                # we're cloning!
4148                fields = [x.strip() for x in existing.split('.')]
4149                function_name = fields.pop()
4150                module, cls = self.clinic._module_and_class(fields)
4151
4152                for existing_function in (cls or module).functions:
4153                    if existing_function.name == function_name:
4154                        break
4155                else:
4156                    existing_function = None
4157                if not existing_function:
4158                    print("class", cls, "module", module, "existing", existing)
4159                    print("cls. functions", cls.functions)
4160                    fail("Couldn't find existing function " + repr(existing) + "!")
4161
4162                fields = [x.strip() for x in full_name.split('.')]
4163                function_name = fields.pop()
4164                module, cls = self.clinic._module_and_class(fields)
4165
4166                if not (existing_function.kind == self.kind and existing_function.coexist == self.coexist):
4167                    fail("'kind' of function and cloned function don't match!  (@classmethod/@staticmethod/@coexist)")
4168                self.function = existing_function.copy(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, docstring='')
4169
4170                self.block.signatures.append(self.function)
4171                (cls or module).functions.append(self.function)
4172                self.next(self.state_function_docstring)
4173                return
4174
4175        line, _, returns = line.partition('->')
4176
4177        full_name, _, c_basename = line.partition(' as ')
4178        full_name = full_name.strip()
4179        c_basename = c_basename.strip() or None
4180
4181        if not is_legal_py_identifier(full_name):
4182            fail("Illegal function name: {}".format(full_name))
4183        if c_basename and not is_legal_c_identifier(c_basename):
4184            fail("Illegal C basename: {}".format(c_basename))
4185
4186        return_converter = None
4187        if returns:
4188            ast_input = "def x() -> {}: pass".format(returns)
4189            module = None
4190            try:
4191                module = ast.parse(ast_input)
4192            except SyntaxError:
4193                pass
4194            if not module:
4195                fail("Badly-formed annotation for " + full_name + ": " + returns)
4196            try:
4197                name, legacy, kwargs = self.parse_converter(module.body[0].returns)
4198                if legacy:
4199                    fail("Legacy converter {!r} not allowed as a return converter"
4200                         .format(name))
4201                if name not in return_converters:
4202                    fail("No available return converter called " + repr(name))
4203                return_converter = return_converters[name](**kwargs)
4204            except ValueError:
4205                fail("Badly-formed annotation for " + full_name + ": " + returns)
4206
4207        fields = [x.strip() for x in full_name.split('.')]
4208        function_name = fields.pop()
4209        module, cls = self.clinic._module_and_class(fields)
4210
4211        fields = full_name.split('.')
4212        if fields[-1] == '__new__':
4213            if (self.kind != CLASS_METHOD) or (not cls):
4214                fail("__new__ must be a class method!")
4215            self.kind = METHOD_NEW
4216        elif fields[-1] == '__init__':
4217            if (self.kind != CALLABLE) or (not cls):
4218                fail("__init__ must be a normal method, not a class or static method!")
4219            self.kind = METHOD_INIT
4220            if not return_converter:
4221                return_converter = init_return_converter()
4222        elif fields[-1] in unsupported_special_methods:
4223            fail(fields[-1] + " is a special method and cannot be converted to Argument Clinic!  (Yet.)")
4224
4225        if not return_converter:
4226            return_converter = CReturnConverter()
4227
4228        if not module:
4229            fail("Undefined module used in declaration of " + repr(full_name.strip()) + ".")
4230        self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename,
4231                                 return_converter=return_converter, kind=self.kind, coexist=self.coexist)
4232        self.block.signatures.append(self.function)
4233
4234        # insert a self converter automatically
4235        type, name = correct_name_for_self(self.function)
4236        kwargs = {}
4237        if cls and type == "PyObject *":
4238            kwargs['type'] = cls.typedef
4239        sc = self.function.self_converter = self_converter(name, name, self.function, **kwargs)
4240        p_self = Parameter(sc.name, inspect.Parameter.POSITIONAL_ONLY, function=self.function, converter=sc)
4241        self.function.parameters[sc.name] = p_self
4242
4243        (cls or module).functions.append(self.function)
4244        self.next(self.state_parameters_start)
4245
4246    # Now entering the parameters section.  The rules, formally stated:
4247    #
4248    #   * All lines must be indented with spaces only.
4249    #   * The first line must be a parameter declaration.
4250    #   * The first line must be indented.
4251    #       * This first line establishes the indent for parameters.
4252    #       * We'll call this number of spaces P (for "parameter").
4253    #   * Thenceforth:
4254    #       * Lines indented with P spaces specify a parameter.
4255    #       * Lines indented with > P spaces are docstrings for the previous
4256    #         parameter.
4257    #           * We'll call this number of spaces D (for "docstring").
4258    #           * All subsequent lines indented with >= D spaces are stored as
4259    #             part of the per-parameter docstring.
4260    #           * All lines will have the first D spaces of the indent stripped
4261    #             before they are stored.
4262    #           * It's illegal to have a line starting with a number of spaces X
4263    #             such that P < X < D.
4264    #       * A line with < P spaces is the first line of the function
4265    #         docstring, which ends processing for parameters and per-parameter
4266    #         docstrings.
4267    #           * The first line of the function docstring must be at the same
4268    #             indent as the function declaration.
4269    #       * It's illegal to have any line in the parameters section starting
4270    #         with X spaces such that F < X < P.  (As before, F is the indent
4271    #         of the function declaration.)
4272    #
4273    # Also, currently Argument Clinic places the following restrictions on groups:
4274    #   * Each group must contain at least one parameter.
4275    #   * Each group may contain at most one group, which must be the furthest
4276    #     thing in the group from the required parameters.  (The nested group
4277    #     must be the first in the group when it's before the required
4278    #     parameters, and the last thing in the group when after the required
4279    #     parameters.)
4280    #   * There may be at most one (top-level) group to the left or right of
4281    #     the required parameters.
4282    #   * You must specify a slash, and it must be after all parameters.
4283    #     (In other words: either all parameters are positional-only,
4284    #      or none are.)
4285    #
4286    #  Said another way:
4287    #   * Each group must contain at least one parameter.
4288    #   * All left square brackets before the required parameters must be
4289    #     consecutive.  (You can't have a left square bracket followed
4290    #     by a parameter, then another left square bracket.  You can't
4291    #     have a left square bracket, a parameter, a right square bracket,
4292    #     and then a left square bracket.)
4293    #   * All right square brackets after the required parameters must be
4294    #     consecutive.
4295    #
4296    # These rules are enforced with a single state variable:
4297    # "parameter_state".  (Previously the code was a miasma of ifs and
4298    # separate boolean state variables.)  The states are:
4299    #
4300    #  [ [ a, b, ] c, ] d, e, f=3, [ g, h, [ i ] ]   <- line
4301    # 01   2          3       4    5           6     <- state transitions
4302    #
4303    # 0: ps_start.  before we've seen anything.  legal transitions are to 1 or 3.
4304    # 1: ps_left_square_before.  left square brackets before required parameters.
4305    # 2: ps_group_before.  in a group, before required parameters.
4306    # 3: ps_required.  required parameters, positional-or-keyword or positional-only
4307    #     (we don't know yet).  (renumber left groups!)
4308    # 4: ps_optional.  positional-or-keyword or positional-only parameters that
4309    #    now must have default values.
4310    # 5: ps_group_after.  in a group, after required parameters.
4311    # 6: ps_right_square_after.  right square brackets after required parameters.
4312    ps_start, ps_left_square_before, ps_group_before, ps_required, \
4313    ps_optional, ps_group_after, ps_right_square_after = range(7)
4314
4315    def state_parameters_start(self, line):
4316        if self.ignore_line(line):
4317            return
4318
4319        # if this line is not indented, we have no parameters
4320        if not self.indent.infer(line):
4321            return self.next(self.state_function_docstring, line)
4322
4323        self.parameter_continuation = ''
4324        return self.next(self.state_parameter, line)
4325
4326
4327    def to_required(self):
4328        """
4329        Transition to the "required" parameter state.
4330        """
4331        if self.parameter_state != self.ps_required:
4332            self.parameter_state = self.ps_required
4333            for p in self.function.parameters.values():
4334                p.group = -p.group
4335
4336    def state_parameter(self, line):
4337        if self.parameter_continuation:
4338            line = self.parameter_continuation + ' ' + line.lstrip()
4339            self.parameter_continuation = ''
4340
4341        if self.ignore_line(line):
4342            return
4343
4344        assert self.indent.depth == 2
4345        indent = self.indent.infer(line)
4346        if indent == -1:
4347            # we outdented, must be to definition column
4348            return self.next(self.state_function_docstring, line)
4349
4350        if indent == 1:
4351            # we indented, must be to new parameter docstring column
4352            return self.next(self.state_parameter_docstring_start, line)
4353
4354        line = line.rstrip()
4355        if line.endswith('\\'):
4356            self.parameter_continuation = line[:-1]
4357            return
4358
4359        line = line.lstrip()
4360
4361        if line in ('*', '/', '[', ']'):
4362            self.parse_special_symbol(line)
4363            return
4364
4365        if self.parameter_state in (self.ps_start, self.ps_required):
4366            self.to_required()
4367        elif self.parameter_state == self.ps_left_square_before:
4368            self.parameter_state = self.ps_group_before
4369        elif self.parameter_state == self.ps_group_before:
4370            if not self.group:
4371                self.to_required()
4372        elif self.parameter_state in (self.ps_group_after, self.ps_optional):
4373            pass
4374        else:
4375            fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".a)")
4376
4377        # handle "as" for  parameters too
4378        c_name = None
4379        name, have_as_token, trailing = line.partition(' as ')
4380        if have_as_token:
4381            name = name.strip()
4382            if ' ' not in name:
4383                fields = trailing.strip().split(' ')
4384                if not fields:
4385                    fail("Invalid 'as' clause!")
4386                c_name = fields[0]
4387                if c_name.endswith(':'):
4388                    name += ':'
4389                    c_name = c_name[:-1]
4390                fields[0] = name
4391                line = ' '.join(fields)
4392
4393        base, equals, default = line.rpartition('=')
4394        if not equals:
4395            base = default
4396            default = None
4397
4398        module = None
4399        try:
4400            ast_input = "def x({}): pass".format(base)
4401            module = ast.parse(ast_input)
4402        except SyntaxError:
4403            try:
4404                # the last = was probably inside a function call, like
4405                #   c: int(accept={str})
4406                # so assume there was no actual default value.
4407                default = None
4408                ast_input = "def x({}): pass".format(line)
4409                module = ast.parse(ast_input)
4410            except SyntaxError:
4411                pass
4412        if not module:
4413            fail("Function " + self.function.name + " has an invalid parameter declaration:\n\t" + line)
4414
4415        function_args = module.body[0].args
4416
4417        if len(function_args.args) > 1:
4418            fail("Function " + self.function.name + " has an invalid parameter declaration (comma?):\n\t" + line)
4419        if function_args.defaults or function_args.kw_defaults:
4420            fail("Function " + self.function.name + " has an invalid parameter declaration (default value?):\n\t" + line)
4421        if function_args.vararg or function_args.kwarg:
4422            fail("Function " + self.function.name + " has an invalid parameter declaration (*args? **kwargs?):\n\t" + line)
4423
4424        parameter = function_args.args[0]
4425
4426        parameter_name = parameter.arg
4427        name, legacy, kwargs = self.parse_converter(parameter.annotation)
4428
4429        if not default:
4430            if self.parameter_state == self.ps_optional:
4431                fail("Can't have a parameter without a default (" + repr(parameter_name) + ")\nafter a parameter with a default!")
4432            value = unspecified
4433            if 'py_default' in kwargs:
4434                fail("You can't specify py_default without specifying a default value!")
4435        else:
4436            if self.parameter_state == self.ps_required:
4437                self.parameter_state = self.ps_optional
4438            default = default.strip()
4439            bad = False
4440            ast_input = "x = {}".format(default)
4441            bad = False
4442            try:
4443                module = ast.parse(ast_input)
4444
4445                if 'c_default' not in kwargs:
4446                    # we can only represent very simple data values in C.
4447                    # detect whether default is okay, via a blacklist
4448                    # of disallowed ast nodes.
4449                    class DetectBadNodes(ast.NodeVisitor):
4450                        bad = False
4451                        def bad_node(self, node):
4452                            self.bad = True
4453
4454                        # inline function call
4455                        visit_Call = bad_node
4456                        # inline if statement ("x = 3 if y else z")
4457                        visit_IfExp = bad_node
4458
4459                        # comprehensions and generator expressions
4460                        visit_ListComp = visit_SetComp = bad_node
4461                        visit_DictComp = visit_GeneratorExp = bad_node
4462
4463                        # literals for advanced types
4464                        visit_Dict = visit_Set = bad_node
4465                        visit_List = visit_Tuple = bad_node
4466
4467                        # "starred": "a = [1, 2, 3]; *a"
4468                        visit_Starred = bad_node
4469
4470                    blacklist = DetectBadNodes()
4471                    blacklist.visit(module)
4472                    bad = blacklist.bad
4473                else:
4474                    # if they specify a c_default, we can be more lenient about the default value.
4475                    # but at least make an attempt at ensuring it's a valid expression.
4476                    try:
4477                        value = eval(default)
4478                        if value == unspecified:
4479                            fail("'unspecified' is not a legal default value!")
4480                    except NameError:
4481                        pass # probably a named constant
4482                    except Exception as e:
4483                        fail("Malformed expression given as default value\n"
4484                             "{!r} caused {!r}".format(default, e))
4485                if bad:
4486                    fail("Unsupported expression as default value: " + repr(default))
4487
4488                expr = module.body[0].value
4489                # mild hack: explicitly support NULL as a default value
4490                if isinstance(expr, ast.Name) and expr.id == 'NULL':
4491                    value = NULL
4492                    py_default = '<unrepresentable>'
4493                    c_default = "NULL"
4494                elif (isinstance(expr, ast.BinOp) or
4495                    (isinstance(expr, ast.UnaryOp) and
4496                     not (isinstance(expr.operand, ast.Num) or
4497                          (hasattr(ast, 'Constant') and
4498                           isinstance(expr.operand, ast.Constant) and
4499                           type(expr.operand.value) in (int, float, complex)))
4500                    )):
4501                    c_default = kwargs.get("c_default")
4502                    if not (isinstance(c_default, str) and c_default):
4503                        fail("When you specify an expression (" + repr(default) + ") as your default value,\nyou MUST specify a valid c_default." + ast.dump(expr))
4504                    py_default = default
4505                    value = unknown
4506                elif isinstance(expr, ast.Attribute):
4507                    a = []
4508                    n = expr
4509                    while isinstance(n, ast.Attribute):
4510                        a.append(n.attr)
4511                        n = n.value
4512                    if not isinstance(n, ast.Name):
4513                        fail("Unsupported default value " + repr(default) + " (looked like a Python constant)")
4514                    a.append(n.id)
4515                    py_default = ".".join(reversed(a))
4516
4517                    c_default = kwargs.get("c_default")
4518                    if not (isinstance(c_default, str) and c_default):
4519                        fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.")
4520
4521                    try:
4522                        value = eval(py_default)
4523                    except NameError:
4524                        value = unknown
4525                else:
4526                    value = ast.literal_eval(expr)
4527                    py_default = repr(value)
4528                    if isinstance(value, (bool, None.__class__)):
4529                        c_default = "Py_" + py_default
4530                    elif isinstance(value, str):
4531                        c_default = c_repr(value)
4532                    else:
4533                        c_default = py_default
4534
4535            except SyntaxError as e:
4536                fail("Syntax error: " + repr(e.text))
4537            except (ValueError, AttributeError):
4538                value = unknown
4539                c_default = kwargs.get("c_default")
4540                py_default = default
4541                if not (isinstance(c_default, str) and c_default):
4542                    fail("When you specify a named constant (" + repr(py_default) + ") as your default value,\nyou MUST specify a valid c_default.")
4543
4544            kwargs.setdefault('c_default', c_default)
4545            kwargs.setdefault('py_default', py_default)
4546
4547        dict = legacy_converters if legacy else converters
4548        legacy_str = "legacy " if legacy else ""
4549        if name not in dict:
4550            fail('{} is not a valid {}converter'.format(name, legacy_str))
4551        # if you use a c_name for the parameter, we just give that name to the converter
4552        # but the parameter object gets the python name
4553        converter = dict[name](c_name or parameter_name, parameter_name, self.function, value, **kwargs)
4554
4555        kind = inspect.Parameter.KEYWORD_ONLY if self.keyword_only else inspect.Parameter.POSITIONAL_OR_KEYWORD
4556
4557        if isinstance(converter, self_converter):
4558            if len(self.function.parameters) == 1:
4559                if (self.parameter_state != self.ps_required):
4560                    fail("A 'self' parameter cannot be marked optional.")
4561                if value is not unspecified:
4562                    fail("A 'self' parameter cannot have a default value.")
4563                if self.group:
4564                    fail("A 'self' parameter cannot be in an optional group.")
4565                kind = inspect.Parameter.POSITIONAL_ONLY
4566                self.parameter_state = self.ps_start
4567                self.function.parameters.clear()
4568            else:
4569                fail("A 'self' parameter, if specified, must be the very first thing in the parameter block.")
4570
4571        if isinstance(converter, defining_class_converter):
4572            _lp = len(self.function.parameters)
4573            if _lp == 1:
4574                if (self.parameter_state != self.ps_required):
4575                    fail("A 'defining_class' parameter cannot be marked optional.")
4576                if value is not unspecified:
4577                    fail("A 'defining_class' parameter cannot have a default value.")
4578                if self.group:
4579                    fail("A 'defining_class' parameter cannot be in an optional group.")
4580            else:
4581                fail("A 'defining_class' parameter, if specified, must either be the first thing in the parameter block, or come just after 'self'.")
4582
4583
4584        p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group)
4585
4586        if parameter_name in self.function.parameters:
4587            fail("You can't have two parameters named " + repr(parameter_name) + "!")
4588        self.function.parameters[parameter_name] = p
4589
4590    def parse_converter(self, annotation):
4591        if (hasattr(ast, 'Constant') and
4592            isinstance(annotation, ast.Constant) and
4593            type(annotation.value) is str):
4594            return annotation.value, True, {}
4595
4596        if isinstance(annotation, ast.Str):
4597            return annotation.s, True, {}
4598
4599        if isinstance(annotation, ast.Name):
4600            return annotation.id, False, {}
4601
4602        if not isinstance(annotation, ast.Call):
4603            fail("Annotations must be either a name, a function call, or a string.")
4604
4605        name = annotation.func.id
4606        symbols = globals()
4607
4608        kwargs = {node.arg: eval_ast_expr(node.value, symbols) for node in annotation.keywords}
4609        return name, False, kwargs
4610
4611    def parse_special_symbol(self, symbol):
4612        if symbol == '*':
4613            if self.keyword_only:
4614                fail("Function " + self.function.name + " uses '*' more than once.")
4615            self.keyword_only = True
4616        elif symbol == '[':
4617            if self.parameter_state in (self.ps_start, self.ps_left_square_before):
4618                self.parameter_state = self.ps_left_square_before
4619            elif self.parameter_state in (self.ps_required, self.ps_group_after):
4620                self.parameter_state = self.ps_group_after
4621            else:
4622                fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".b)")
4623            self.group += 1
4624            self.function.docstring_only = True
4625        elif symbol == ']':
4626            if not self.group:
4627                fail("Function " + self.function.name + " has a ] without a matching [.")
4628            if not any(p.group == self.group for p in self.function.parameters.values()):
4629                fail("Function " + self.function.name + " has an empty group.\nAll groups must contain at least one parameter.")
4630            self.group -= 1
4631            if self.parameter_state in (self.ps_left_square_before, self.ps_group_before):
4632                self.parameter_state = self.ps_group_before
4633            elif self.parameter_state in (self.ps_group_after, self.ps_right_square_after):
4634                self.parameter_state = self.ps_right_square_after
4635            else:
4636                fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".c)")
4637        elif symbol == '/':
4638            if self.positional_only:
4639                fail("Function " + self.function.name + " uses '/' more than once.")
4640            self.positional_only = True
4641            # ps_required and ps_optional are allowed here, that allows positional-only without option groups
4642            # to work (and have default values!)
4643            if (self.parameter_state not in (self.ps_required, self.ps_optional, self.ps_right_square_after, self.ps_group_before)) or self.group:
4644                fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".d)")
4645            if self.keyword_only:
4646                fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.")
4647            # fixup preceding parameters
4648            for p in self.function.parameters.values():
4649                if (p.kind != inspect.Parameter.POSITIONAL_OR_KEYWORD and not isinstance(p.converter, self_converter)):
4650                    fail("Function " + self.function.name + " mixes keyword-only and positional-only parameters, which is unsupported.")
4651                p.kind = inspect.Parameter.POSITIONAL_ONLY
4652
4653    def state_parameter_docstring_start(self, line):
4654        self.parameter_docstring_indent = len(self.indent.margin)
4655        assert self.indent.depth == 3
4656        return self.next(self.state_parameter_docstring, line)
4657
4658    # every line of the docstring must start with at least F spaces,
4659    # where F > P.
4660    # these F spaces will be stripped.
4661    def state_parameter_docstring(self, line):
4662        stripped = line.strip()
4663        if stripped.startswith('#'):
4664            return
4665
4666        indent = self.indent.measure(line)
4667        if indent < self.parameter_docstring_indent:
4668            self.indent.infer(line)
4669            assert self.indent.depth < 3
4670            if self.indent.depth == 2:
4671                # back to a parameter
4672                return self.next(self.state_parameter, line)
4673            assert self.indent.depth == 1
4674            return self.next(self.state_function_docstring, line)
4675
4676        assert self.function.parameters
4677        last_parameter = next(reversed(list(self.function.parameters.values())))
4678
4679        new_docstring = last_parameter.docstring
4680
4681        if new_docstring:
4682            new_docstring += '\n'
4683        if stripped:
4684            new_docstring += self.indent.dedent(line)
4685
4686        last_parameter.docstring = new_docstring
4687
4688    # the final stanza of the DSL is the docstring.
4689    def state_function_docstring(self, line):
4690        if self.group:
4691            fail("Function " + self.function.name + " has a ] without a matching [.")
4692
4693        stripped = line.strip()
4694        if stripped.startswith('#'):
4695            return
4696
4697        new_docstring = self.function.docstring
4698        if new_docstring:
4699            new_docstring += "\n"
4700        if stripped:
4701            line = self.indent.dedent(line).rstrip()
4702        else:
4703            line = ''
4704        new_docstring += line
4705        self.function.docstring = new_docstring
4706
4707    def format_docstring(self):
4708        f = self.function
4709
4710        new_or_init = f.kind in (METHOD_NEW, METHOD_INIT)
4711        if new_or_init and not f.docstring:
4712            # don't render a docstring at all, no signature, nothing.
4713            return f.docstring
4714
4715        text, add, output = _text_accumulator()
4716        parameters = f.render_parameters
4717
4718        ##
4719        ## docstring first line
4720        ##
4721
4722        if new_or_init:
4723            # classes get *just* the name of the class
4724            # not __new__, not __init__, and not module.classname
4725            assert f.cls
4726            add(f.cls.name)
4727        else:
4728            add(f.name)
4729        add('(')
4730
4731        # populate "right_bracket_count" field for every parameter
4732        assert parameters, "We should always have a self parameter. " + repr(f)
4733        assert isinstance(parameters[0].converter, self_converter)
4734        # self is always positional-only.
4735        assert parameters[0].is_positional_only()
4736        parameters[0].right_bracket_count = 0
4737        positional_only = True
4738        for p in parameters[1:]:
4739            if not p.is_positional_only():
4740                positional_only = False
4741            else:
4742                assert positional_only
4743            if positional_only:
4744                p.right_bracket_count = abs(p.group)
4745            else:
4746                # don't put any right brackets around non-positional-only parameters, ever.
4747                p.right_bracket_count = 0
4748
4749        right_bracket_count = 0
4750
4751        def fix_right_bracket_count(desired):
4752            nonlocal right_bracket_count
4753            s = ''
4754            while right_bracket_count < desired:
4755                s += '['
4756                right_bracket_count += 1
4757            while right_bracket_count > desired:
4758                s += ']'
4759                right_bracket_count -= 1
4760            return s
4761
4762        need_slash = False
4763        added_slash = False
4764        need_a_trailing_slash = False
4765
4766        # we only need a trailing slash:
4767        #   * if this is not a "docstring_only" signature
4768        #   * and if the last *shown* parameter is
4769        #     positional only
4770        if not f.docstring_only:
4771            for p in reversed(parameters):
4772                if not p.converter.show_in_signature:
4773                    continue
4774                if p.is_positional_only():
4775                    need_a_trailing_slash = True
4776                break
4777
4778
4779        added_star = False
4780
4781        first_parameter = True
4782        last_p = parameters[-1]
4783        line_length = len(''.join(text))
4784        indent = " " * line_length
4785        def add_parameter(text):
4786            nonlocal line_length
4787            nonlocal first_parameter
4788            if first_parameter:
4789                s = text
4790                first_parameter = False
4791            else:
4792                s = ' ' + text
4793                if line_length + len(s) >= 72:
4794                    add('\n')
4795                    add(indent)
4796                    line_length = len(indent)
4797                    s = text
4798            line_length += len(s)
4799            add(s)
4800
4801        for p in parameters:
4802            if not p.converter.show_in_signature:
4803                continue
4804            assert p.name
4805
4806            is_self = isinstance(p.converter, self_converter)
4807            if is_self and f.docstring_only:
4808                # this isn't a real machine-parsable signature,
4809                # so let's not print the "self" parameter
4810                continue
4811
4812            if p.is_positional_only():
4813                need_slash = not f.docstring_only
4814            elif need_slash and not (added_slash or p.is_positional_only()):
4815                added_slash = True
4816                add_parameter('/,')
4817
4818            if p.is_keyword_only() and not added_star:
4819                added_star = True
4820                add_parameter('*,')
4821
4822            p_add, p_output = text_accumulator()
4823            p_add(fix_right_bracket_count(p.right_bracket_count))
4824
4825            if isinstance(p.converter, self_converter):
4826                # annotate first parameter as being a "self".
4827                #
4828                # if inspect.Signature gets this function,
4829                # and it's already bound, the self parameter
4830                # will be stripped off.
4831                #
4832                # if it's not bound, it should be marked
4833                # as positional-only.
4834                #
4835                # note: we don't print "self" for __init__,
4836                # because this isn't actually the signature
4837                # for __init__.  (it can't be, __init__ doesn't
4838                # have a docstring.)  if this is an __init__
4839                # (or __new__), then this signature is for
4840                # calling the class to construct a new instance.
4841                p_add('$')
4842
4843            name = p.converter.signature_name or p.name
4844            p_add(name)
4845
4846            if p.converter.is_optional():
4847                p_add('=')
4848                value = p.converter.py_default
4849                if not value:
4850                    value = repr(p.converter.default)
4851                p_add(value)
4852
4853            if (p != last_p) or need_a_trailing_slash:
4854                p_add(',')
4855
4856            add_parameter(p_output())
4857
4858        add(fix_right_bracket_count(0))
4859        if need_a_trailing_slash:
4860            add_parameter('/')
4861        add(')')
4862
4863        # PEP 8 says:
4864        #
4865        #     The Python standard library will not use function annotations
4866        #     as that would result in a premature commitment to a particular
4867        #     annotation style. Instead, the annotations are left for users
4868        #     to discover and experiment with useful annotation styles.
4869        #
4870        # therefore this is commented out:
4871        #
4872        # if f.return_converter.py_default:
4873        #     add(' -> ')
4874        #     add(f.return_converter.py_default)
4875
4876        if not f.docstring_only:
4877            add("\n" + sig_end_marker + "\n")
4878
4879        docstring_first_line = output()
4880
4881        # now fix up the places where the brackets look wrong
4882        docstring_first_line = docstring_first_line.replace(', ]', ',] ')
4883
4884        # okay.  now we're officially building the "parameters" section.
4885        # create substitution text for {parameters}
4886        spacer_line = False
4887        for p in parameters:
4888            if not p.docstring.strip():
4889                continue
4890            if spacer_line:
4891                add('\n')
4892            else:
4893                spacer_line = True
4894            add("  ")
4895            add(p.name)
4896            add('\n')
4897            add(textwrap.indent(rstrip_lines(p.docstring.rstrip()), "    "))
4898        parameters = output()
4899        if parameters:
4900            parameters += '\n'
4901
4902        ##
4903        ## docstring body
4904        ##
4905
4906        docstring = f.docstring.rstrip()
4907        lines = [line.rstrip() for line in docstring.split('\n')]
4908
4909        # Enforce the summary line!
4910        # The first line of a docstring should be a summary of the function.
4911        # It should fit on one line (80 columns? 79 maybe?) and be a paragraph
4912        # by itself.
4913        #
4914        # Argument Clinic enforces the following rule:
4915        #  * either the docstring is empty,
4916        #  * or it must have a summary line.
4917        #
4918        # Guido said Clinic should enforce this:
4919        # http://mail.python.org/pipermail/python-dev/2013-June/127110.html
4920
4921        if len(lines) >= 2:
4922            if lines[1]:
4923                fail("Docstring for " + f.full_name + " does not have a summary line!\n" +
4924                    "Every non-blank function docstring must start with\n" +
4925                    "a single line summary followed by an empty line.")
4926        elif len(lines) == 1:
4927            # the docstring is only one line right now--the summary line.
4928            # add an empty line after the summary line so we have space
4929            # between it and the {parameters} we're about to add.
4930            lines.append('')
4931
4932        parameters_marker_count = len(docstring.split('{parameters}')) - 1
4933        if parameters_marker_count > 1:
4934            fail('You may not specify {parameters} more than once in a docstring!')
4935
4936        if not parameters_marker_count:
4937            # insert after summary line
4938            lines.insert(2, '{parameters}')
4939
4940        # insert at front of docstring
4941        lines.insert(0, docstring_first_line)
4942
4943        docstring = "\n".join(lines)
4944
4945        add(docstring)
4946        docstring = output()
4947
4948        docstring = linear_format(docstring, parameters=parameters)
4949        docstring = docstring.rstrip()
4950
4951        return docstring
4952
4953    def state_terminal(self, line):
4954        """
4955        Called when processing the block is done.
4956        """
4957        assert not line
4958
4959        if not self.function:
4960            return
4961
4962        if self.keyword_only:
4963            values = self.function.parameters.values()
4964            if not values:
4965                no_parameter_after_star = True
4966            else:
4967                last_parameter = next(reversed(list(values)))
4968                no_parameter_after_star = last_parameter.kind != inspect.Parameter.KEYWORD_ONLY
4969            if no_parameter_after_star:
4970                fail("Function " + self.function.name + " specifies '*' without any parameters afterwards.")
4971
4972        # remove trailing whitespace from all parameter docstrings
4973        for name, value in self.function.parameters.items():
4974            if not value:
4975                continue
4976            value.docstring = value.docstring.rstrip()
4977
4978        self.function.docstring = self.format_docstring()
4979
4980
4981
4982
4983# maps strings to callables.
4984# the callable should return an object
4985# that implements the clinic parser
4986# interface (__init__ and parse).
4987#
4988# example parsers:
4989#   "clinic", handles the Clinic DSL
4990#   "python", handles running Python code
4991#
4992parsers = {'clinic' : DSLParser, 'python': PythonParser}
4993
4994
4995clinic = None
4996
4997
4998def main(argv):
4999    import sys
5000
5001    if sys.version_info.major < 3 or sys.version_info.minor < 3:
5002        sys.exit("Error: clinic.py requires Python 3.3 or greater.")
5003
5004    import argparse
5005    cmdline = argparse.ArgumentParser(
5006        description="""Preprocessor for CPython C files.
5007
5008The purpose of the Argument Clinic is automating all the boilerplate involved
5009with writing argument parsing code for builtins and providing introspection
5010signatures ("docstrings") for CPython builtins.
5011
5012For more information see https://docs.python.org/3/howto/clinic.html""")
5013    cmdline.add_argument("-f", "--force", action='store_true')
5014    cmdline.add_argument("-o", "--output", type=str)
5015    cmdline.add_argument("-v", "--verbose", action='store_true')
5016    cmdline.add_argument("--converters", action='store_true')
5017    cmdline.add_argument("--make", action='store_true',
5018                         help="Walk --srcdir to run over all relevant files.")
5019    cmdline.add_argument("--srcdir", type=str, default=os.curdir,
5020                         help="The directory tree to walk in --make mode.")
5021    cmdline.add_argument("filename", type=str, nargs="*")
5022    ns = cmdline.parse_args(argv)
5023
5024    if ns.converters:
5025        if ns.filename:
5026            print("Usage error: can't specify --converters and a filename at the same time.")
5027            print()
5028            cmdline.print_usage()
5029            sys.exit(-1)
5030        converters = []
5031        return_converters = []
5032        ignored = set("""
5033            add_c_converter
5034            add_c_return_converter
5035            add_default_legacy_c_converter
5036            add_legacy_c_converter
5037            """.strip().split())
5038        module = globals()
5039        for name in module:
5040            for suffix, ids in (
5041                ("_return_converter", return_converters),
5042                ("_converter", converters),
5043            ):
5044                if name in ignored:
5045                    continue
5046                if name.endswith(suffix):
5047                    ids.append((name, name[:-len(suffix)]))
5048                    break
5049        print()
5050
5051        print("Legacy converters:")
5052        legacy = sorted(legacy_converters)
5053        print('    ' + ' '.join(c for c in legacy if c[0].isupper()))
5054        print('    ' + ' '.join(c for c in legacy if c[0].islower()))
5055        print()
5056
5057        for title, attribute, ids in (
5058            ("Converters", 'converter_init', converters),
5059            ("Return converters", 'return_converter_init', return_converters),
5060        ):
5061            print(title + ":")
5062            longest = -1
5063            for name, short_name in ids:
5064                longest = max(longest, len(short_name))
5065            for name, short_name in sorted(ids, key=lambda x: x[1].lower()):
5066                cls = module[name]
5067                callable = getattr(cls, attribute, None)
5068                if not callable:
5069                    continue
5070                signature = inspect.signature(callable)
5071                parameters = []
5072                for parameter_name, parameter in signature.parameters.items():
5073                    if parameter.kind == inspect.Parameter.KEYWORD_ONLY:
5074                        if parameter.default != inspect.Parameter.empty:
5075                            s = '{}={!r}'.format(parameter_name, parameter.default)
5076                        else:
5077                            s = parameter_name
5078                        parameters.append(s)
5079                print('    {}({})'.format(short_name, ', '.join(parameters)))
5080            print()
5081        print("All converters also accept (c_default=None, py_default=None, annotation=None).")
5082        print("All return converters also accept (py_default=None).")
5083        sys.exit(0)
5084
5085    if ns.make:
5086        if ns.output or ns.filename:
5087            print("Usage error: can't use -o or filenames with --make.")
5088            print()
5089            cmdline.print_usage()
5090            sys.exit(-1)
5091        if not ns.srcdir:
5092            print("Usage error: --srcdir must not be empty with --make.")
5093            print()
5094            cmdline.print_usage()
5095            sys.exit(-1)
5096        for root, dirs, files in os.walk(ns.srcdir):
5097            for rcs_dir in ('.svn', '.git', '.hg', 'build', 'externals'):
5098                if rcs_dir in dirs:
5099                    dirs.remove(rcs_dir)
5100            for filename in files:
5101                if not (filename.endswith('.c') or filename.endswith('.h')):
5102                    continue
5103                path = os.path.join(root, filename)
5104                if ns.verbose:
5105                    print(path)
5106                parse_file(path, verify=not ns.force)
5107        return
5108
5109    if not ns.filename:
5110        cmdline.print_usage()
5111        sys.exit(-1)
5112
5113    if ns.output and len(ns.filename) > 1:
5114        print("Usage error: can't use -o with multiple filenames.")
5115        print()
5116        cmdline.print_usage()
5117        sys.exit(-1)
5118
5119    for filename in ns.filename:
5120        if ns.verbose:
5121            print(filename)
5122        parse_file(filename, output=ns.output, verify=not ns.force)
5123
5124
5125if __name__ == "__main__":
5126    sys.exit(main(sys.argv[1:]))
5127