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