(self, clang: CLanguage)
| 650 | self.parser_body(*parser_code) |
| 651 | |
| 652 | def parse_general(self, clang: CLanguage) -> None: |
| 653 | parsearg: str | None |
| 654 | deprecated_positionals: dict[int, Parameter] = {} |
| 655 | deprecated_keywords: dict[int, Parameter] = {} |
| 656 | for i, p in enumerate(self.parameters): |
| 657 | if p.deprecated_positional: |
| 658 | deprecated_positionals[i] = p |
| 659 | if p.deprecated_keyword: |
| 660 | deprecated_keywords[i] = p |
| 661 | |
| 662 | has_optional_kw = ( |
| 663 | max(self.pos_only, self.min_pos) + self.min_kw_only |
| 664 | < len(self.converters) |
| 665 | ) |
| 666 | |
| 667 | use_parser_code = True |
| 668 | if self.limited_capi: |
| 669 | parser_code = [] |
| 670 | use_parser_code = False |
| 671 | self.fastcall = False |
| 672 | else: |
| 673 | self.codegen.add_include('pycore_modsupport.h', |
| 674 | '_PyArg_UnpackKeywords()') |
| 675 | if not self.varpos: |
| 676 | nargs = "nargs" |
| 677 | else: |
| 678 | nargs = f"Py_MIN(nargs, {self.max_pos})" if self.max_pos else "0" |
| 679 | |
| 680 | if self.fastcall: |
| 681 | self.flags = "METH_FASTCALL|METH_KEYWORDS" |
| 682 | self.parser_prototype = PARSER_PROTOTYPE_FASTCALL_KEYWORDS |
| 683 | self.declarations = declare_parser(self.func, codegen=self.codegen) |
| 684 | self.declarations += "\nPyObject *argsbuf[%s];" % (len(self.converters) or 1) |
| 685 | if self.varpos: |
| 686 | self.declarations += "\nPyObject * const *fastargs;" |
| 687 | argsname = 'fastargs' |
| 688 | argname_fmt = 'fastargs[%d]' |
| 689 | else: |
| 690 | argsname = 'args' |
| 691 | argname_fmt = 'args[%d]' |
| 692 | if has_optional_kw: |
| 693 | self.declarations += "\nPy_ssize_t noptargs = %s + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - %d;" % (nargs, self.min_pos + self.min_kw_only) |
| 694 | unpack_args = 'args, nargs, NULL, kwnames' |
| 695 | else: |
| 696 | # positional-or-keyword arguments |
| 697 | self.flags = "METH_VARARGS|METH_KEYWORDS" |
| 698 | self.parser_prototype = PARSER_PROTOTYPE_KEYWORD |
| 699 | argsname = 'fastargs' |
| 700 | argname_fmt = 'fastargs[%d]' |
| 701 | self.declarations = declare_parser(self.func, codegen=self.codegen) |
| 702 | self.declarations += "\nPyObject *argsbuf[%s];" % (len(self.converters) or 1) |
| 703 | self.declarations += "\nPyObject * const *fastargs;" |
| 704 | self.declarations += "\nPy_ssize_t nargs = PyTuple_GET_SIZE(args);" |
| 705 | if has_optional_kw: |
| 706 | self.declarations += "\nPy_ssize_t noptargs = %s + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - %d;" % (nargs, self.min_pos + self.min_kw_only) |
| 707 | unpack_args = '_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL' |
| 708 | parser_code = [libclinic.normalize_snippet(f""" |
| 709 | {argsname} = _PyArg_UnpackKeywords({unpack_args}, &_parser, |
no test coverage detected