Home | History | Annotate | Download | only in clinic
      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 
      8 import abc
      9 import ast
     10 import collections
     11 import contextlib
     12 import copy
     13 import cpp
     14 import functools
     15 import hashlib
     16 import inspect
     17 import io
     18 import itertools
     19 import os
     20 import pprint
     21 import re
     22 import shlex
     23 import string
     24 import sys
     25 import tempfile
     26 import textwrap
     27 import traceback
     28 import types
     29 
     30 from types import *
     31 NoneType = 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 
     44 version = '1'
     45 
     46 _empty = inspect._empty
     47 _void = inspect._void
     48 
     49 NoneType = type(None)
     50 
     51 class Unspecified:
     52     def __repr__(self):
     53         return '<Unspecified>'
     54 
     55 unspecified = Unspecified()
     56 
     57 
     58 class Null:
     59     def __repr__(self):
     60         return '<Null>'
     61 
     62 NULL = Null()
     63 
     64 
     65 class Unknown:
     66     def __repr__(self):
     67         return '<Unknown>'
     68 
     69 unknown = Unknown()
     70 
     71 sig_end_marker = '--'
     72 
     73 
     74 _text_accumulator_nt = collections.namedtuple("_text_accumulator", "text append output")
     75 
     76 def _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 
     85 text_accumulator_nt = collections.namedtuple("text_accumulator", "text append")
     86 
     87 def 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 
    102 def 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 
    125 def warn(*args, filename=None, line_number=None):
    126     return warn_or_fail(False, *args, filename=filename, line_number=line_number)
    127 
    128 def fail(*args, filename=None, line_number=None):
    129     return warn_or_fail(True, *args, filename=filename, line_number=line_number)
    130 
    131 
    132 def 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 
    141 def c_repr(s):
    142     return '"' + s + '"'
    143 
    144 
    145 is_legal_c_identifier = re.compile('^[A-Za-z_][A-Za-z0-9_]*$').match
    146 
    147 def 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.
    153 c_keywords = set("""
    154 asm auto break case char const continue default do double
    155 else enum extern float for goto if inline int long
    156 register return short signed sizeof static struct switch
    157 typedef typeof union unsigned void volatile while
    158 """.strip().split())
    159 
    160 def 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 
    169 def 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 
    177 def 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 
    184 def 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 
    228 def 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 
    249 def 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 
    269 def 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 
    300 def 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 
    310 class 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 
    356 class 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 
    372 class 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 
    446 class 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 
    455 def 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 
    470 def 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 
    485 def 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 
    515 def 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()
    525 def 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 
    539 def 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 
    591 class 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
   1260 def 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 
   1270 def 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 
   1280 class 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 
   1346 class 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 
   1502 class 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 
   1550 class 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 
   1586 class 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").
   1632 languages = { 'C': CLanguage, 'Python': PythonLanguage }
   1633 extensions = { name: CLanguage for name in "c cc cpp cxx h hh hpp hxx".split() }
   1634 extensions['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.
   1643 converters = {}
   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.
   1648 legacy_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.
   1657 return_converters = {}
   1658 
   1659 clinic = None
   1660 class Clinic:
   1661 
   1662     presets_text = """
   1663 preset block
   1664 everything block
   1665 methoddef_ifndef buffer 1
   1666 docstring_prototype suppress
   1667 parser_prototype suppress
   1668 cpp_if suppress
   1669 cpp_endif suppress
   1670 
   1671 preset original
   1672 everything block
   1673 methoddef_ifndef buffer 1
   1674 docstring_prototype suppress
   1675 parser_prototype suppress
   1676 cpp_if suppress
   1677 cpp_endif suppress
   1678 
   1679 preset file
   1680 everything file
   1681 methoddef_ifndef file 1
   1682 docstring_prototype suppress
   1683 parser_prototype suppress
   1684 impl_definition block
   1685 
   1686 preset buffer
   1687 everything buffer
   1688 methoddef_ifndef buffer 1
   1689 impl_definition block
   1690 docstring_prototype suppress
   1691 impl_prototype suppress
   1692 parser_prototype suppress
   1693 
   1694 preset partial-buffer
   1695 everything buffer
   1696 methoddef_ifndef buffer 1
   1697 docstring_prototype block
   1698 impl_prototype suppress
   1699 methoddef_define block
   1700 parser_prototype block
   1701 impl_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 
   1900 def 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 
   1933 def 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 
   1943 class 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 
   1954 class 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 
   1966 class 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 
   1981 unsupported_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 
   2056 INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW = """
   2057 INVALID, CALLABLE, STATIC_METHOD, CLASS_METHOD, METHOD_INIT, METHOD_NEW
   2058 """.replace(",", "").strip().split()
   2059 
   2060 class 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 
   2148 class 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 
   2189 class 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 
   2204 def 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 
   2213 def 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 
   2222 def 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 
   2236 class CConverterAutoRegister(type):
   2237     def __init__(cls, name, bases, classdict):
   2238         add_c_converter(cls)
   2239         add_default_legacy_c_converter(cls)
   2240 
   2241 class 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 
   2538 class 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 
   2553 class 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)
   2565 class 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 
   2575 class byte_converter(unsigned_char_converter): pass
   2576 
   2577 class short_converter(CConverter):
   2578     type = 'short'
   2579     default_type = int
   2580     format_unit = 'h'
   2581     c_ignored_default = "0"
   2582 
   2583 class 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})
   2594 class 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 
   2608 class 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 
   2618 class long_converter(CConverter):
   2619     type = 'long'
   2620     default_type = int
   2621     format_unit = 'l'
   2622     c_ignored_default = "0"
   2623 
   2624 class 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 
   2634 class long_long_converter(CConverter):
   2635     type = 'long long'
   2636     default_type = int
   2637     format_unit = 'L'
   2638     c_ignored_default = "0"
   2639 
   2640 class 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 
   2651 class 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 
   2665 class 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 
   2677 class float_converter(CConverter):
   2678     type = 'float'
   2679     default_type = float
   2680     format_unit = 'f'
   2681     c_ignored_default = "0.0"
   2682 
   2683 class double_converter(CConverter):
   2684     type = 'double'
   2685     default_type = float
   2686     format_unit = 'd'
   2687     c_ignored_default = "0.0"
   2688 
   2689 
   2690 class 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 
   2697 class 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 
   2723 class buffer: pass
   2724 class rwbuffer: pass
   2725 class robuffer: pass
   2726 
   2727 def str_converter_key(types, encoding, zeroes):
   2728     return (frozenset(types), bool(encoding), bool(zeroes))
   2729 
   2730 str_converter_argument_map = {}
   2731 
   2732 class 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 #
   2771 def 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 
   2795 r('es',  encoding=True,              accept={str})
   2796 r('es#', encoding=True, zeroes=True, accept={str})
   2797 r('et',  encoding=True,              accept={bytes, bytearray, str})
   2798 r('et#', encoding=True, zeroes=True, accept={bytes, bytearray, str})
   2799 r('s',                               accept={str})
   2800 r('s#',                 zeroes=True, accept={robuffer, str})
   2801 r('y',                               accept={robuffer})
   2802 r('y#',                 zeroes=True, accept={robuffer})
   2803 r('z',                               accept={str, NoneType})
   2804 r('z#',                 zeroes=True, accept={robuffer, str, NoneType})
   2805 del r
   2806 
   2807 
   2808 class PyBytesObject_converter(CConverter):
   2809     type = 'PyBytesObject *'
   2810     format_unit = 'S'
   2811     # accept = {bytes}
   2812 
   2813 class PyByteArrayObject_converter(CConverter):
   2814     type = 'PyByteArrayObject *'
   2815     format_unit = 'Y'
   2816     # accept = {bytearray}
   2817 
   2818 class 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)
   2826 class 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})
   2841 class 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 
   2871 def 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 
   2882 def 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 
   2889 class 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 
   2994 def 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 
   3004 class CReturnConverterAutoRegister(type):
   3005     def __init__(cls, name, bases, classdict):
   3006         add_c_return_converter(cls)
   3007 
   3008 class 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 
   3053 add_c_return_converter(CReturnConverter, 'object')
   3054 
   3055 class NoneType_return_converter(CReturnConverter):
   3056     def render(self, function, data):
   3057         self.declare(data)
   3058         data.return_conversion.append('''
   3059 if (_return_value != Py_None) {
   3060     goto exit;
   3061 }
   3062 return_value = Py_None;
   3063 Py_INCREF(Py_None);
   3064 '''.strip())
   3065 
   3066 class 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 
   3074 class 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 
   3086 class int_return_converter(long_return_converter):
   3087     type = 'int'
   3088     cast = '(long)'
   3089 
   3090 class 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 
   3100 class unsigned_long_return_converter(long_return_converter):
   3101     type = 'unsigned long'
   3102     conversion_fn = 'PyLong_FromUnsignedLong'
   3103     unsigned_cast = '(unsigned long)'
   3104 
   3105 class unsigned_int_return_converter(unsigned_long_return_converter):
   3106     type = 'unsigned int'
   3107     cast = '(unsigned long)'
   3108     unsigned_cast = '(unsigned int)'
   3109 
   3110 class Py_ssize_t_return_converter(long_return_converter):
   3111     type = 'Py_ssize_t'
   3112     conversion_fn = 'PyLong_FromSsize_t'
   3113 
   3114 class size_t_return_converter(long_return_converter):
   3115     type = 'size_t'
   3116     conversion_fn = 'PyLong_FromSize_t'
   3117     unsigned_cast = '(size_t)'
   3118 
   3119 
   3120 class 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 
   3130 class float_return_converter(double_return_converter):
   3131     type = 'float'
   3132     cast = '(double)'
   3133 
   3134 
   3135 class 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 
   3145 def 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 
   3163 class 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 
   3243 class 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 #
   4317 parsers = {'clinic' : DSLParser, 'python': PythonParser}
   4318 
   4319 
   4320 clinic = None
   4321 
   4322 
   4323 def 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 
   4443 if __name__ == "__main__":
   4444     sys.exit(main(sys.argv[1:]))
   4445