Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Modules/_struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class cache_struct_converter(CConverter):
type = 'PyStructObject *'
converter = 'cache_struct_converter'
c_default = "NULL"
broken_limited_capi = True
Comment thread
erlend-aasland marked this conversation as resolved.

def parse_arg(self, argname, displayname):
return """
Expand All @@ -120,7 +121,7 @@ class cache_struct_converter(CConverter):
def cleanup(self):
return "Py_XDECREF(%s);\n" % self.name
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=d6746621c2fb1a7d]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=14e83804f599ed8f]*/

static int cache_struct_converter(PyObject *, PyObject *, PyStructObject **);

Expand Down
3 changes: 2 additions & 1 deletion PC/winreg.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,7 @@ class DWORD_converter(unsigned_long_converter):
class HKEY_converter(CConverter):
type = 'HKEY'
converter = 'clinic_HKEY_converter'
broken_limited_capi = True

def parse_arg(self, argname, displayname):
return """
Expand Down Expand Up @@ -249,7 +250,7 @@ class self_return_converter(CReturnConverter):
data.return_conversion.append(
'return_value = (PyObject *)_return_value;\n')
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=17e645060c7b8ae1]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=f8cb7034338aeaba]*/

#include "clinic/winreg.c.h"

Expand Down
23 changes: 13 additions & 10 deletions Tools/clinic/clinic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,14 @@ def parser_body(
add(field)
return linear_format(output(), parser_declarations=declarations)

limited_capi = clinic.limited_capi
if limited_capi and (requires_defining_class or pseudo_args or
(any(p.is_optional() for p in parameters) and
any(p.is_keyword_only() and not p.is_optional() for p in parameters)) or
any(c.broken_limited_capi for c in converters)):
print(f"Function {f.full_name} cannot use limited C API", file=sys.stderr)
Comment thread
serhiy-storchaka marked this conversation as resolved.
Outdated
limited_capi = False

parsearg: str | None
if not parameters:
parser_code: list[str] | None
Expand Down Expand Up @@ -1234,7 +1242,7 @@ def parser_body(
{c_basename}({self_type}{self_name}, PyObject *%s)
""" % argname)

if clinic.limited_capi:
if limited_capi:
parsearg = None
else:
displayname = parameters[0].get_displayname(0)
Expand All @@ -1258,7 +1266,7 @@ def parser_body(
parser_definition = parser_body(parser_prototype, ' {option_group_parsing}')

elif (not requires_defining_class and pos_only == len(parameters) and
not pseudo_args and clinic.limited_capi):
not pseudo_args and limited_capi):
# positional-only for the limited C API
flags = "METH_VARARGS"
parser_prototype = self.PARSER_PROTOTYPE_VARARGS
Expand Down Expand Up @@ -1393,9 +1401,6 @@ def parser_body(
)
nargs = f"Py_MIN(nargs, {max_pos})" if max_pos else "0"

limited_capi = clinic.limited_capi
if requires_defining_class or pseudo_args:
limited_capi = False
if limited_capi:
# positional-or-keyword arguments
flags = "METH_VARARGS|METH_KEYWORDS"
Expand Down Expand Up @@ -2640,10 +2645,6 @@ def parse_file(

if LIMITED_CAPI_REGEX.search(raw):
limited_capi = True
# XXX Temporary solution
if os.path.basename(filename) in ('_struct.c', 'winreg.c'):
print(f"{filename} cannot use limited C API")
limited_capi = False

assert isinstance(language, CLanguage)
clinic = Clinic(language,
Expand Down Expand Up @@ -2938,7 +2939,7 @@ def is_vararg(self) -> bool:
return self.kind == inspect.Parameter.VAR_POSITIONAL

def is_optional(self) -> bool:
return not self.is_vararg() and (self.default is not unspecified)
return not self.is_vararg() and self.default is not unspecified

def copy(
self,
Expand Down Expand Up @@ -3128,6 +3129,8 @@ class CConverter(metaclass=CConverterAutoRegister):
# "#include "name" // reason"
include: tuple[str, str] | None = None

broken_limited_capi: bool = False

# keep in sync with self_converter.__init__!
def __init__(self,
# Positional args:
Expand Down