-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
gh-112205: Support @getter annotation from AC #112396
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
72d9018
ea83973
969adf9
716b8d9
c5fe2b2
2d9800d
442c575
e0fb271
0778eb7
d5b1751
7f4bfa8
fe46de0
0892d0d
769f6cd
dde933e
d381b5e
351ba08
f53a035
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -846,6 +846,10 @@ class CLanguage(Language): | |||||||||||||||||||||||
static PyObject * | ||||||||||||||||||||||||
{c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored)) | ||||||||||||||||||||||||
""") | ||||||||||||||||||||||||
PARSER_PROTOTYPE_GETTER: Final[str] = normalize_snippet(""" | ||||||||||||||||||||||||
static PyObject * | ||||||||||||||||||||||||
{c_basename}({self_type}{self_name}, void *context) | ||||||||||||||||||||||||
""") | ||||||||||||||||||||||||
METH_O_PROTOTYPE: Final[str] = normalize_snippet(""" | ||||||||||||||||||||||||
static PyObject * | ||||||||||||||||||||||||
{c_basename}({impl_parameters}) | ||||||||||||||||||||||||
|
@@ -865,6 +869,10 @@ class CLanguage(Language): | |||||||||||||||||||||||
#define {methoddef_name} \ | ||||||||||||||||||||||||
{{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}}, | ||||||||||||||||||||||||
""") | ||||||||||||||||||||||||
GETTERDEF_PROTOTYPE_DEFINE: Final[str] = normalize_snippet(r""" | ||||||||||||||||||||||||
#define {methoddef_name} \ | ||||||||||||||||||||||||
{{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, NULL, NULL}}, | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We may need to reform the template for the setter case too. But not sure we should handle this at this PR :) |
||||||||||||||||||||||||
""") | ||||||||||||||||||||||||
METHODDEF_PROTOTYPE_IFNDEF: Final[str] = normalize_snippet(""" | ||||||||||||||||||||||||
#ifndef {methoddef_name} | ||||||||||||||||||||||||
#define {methoddef_name} | ||||||||||||||||||||||||
|
@@ -1161,6 +1169,9 @@ def output_templates( | |||||||||||||||||||||||
methoddef_define = self.METHODDEF_PROTOTYPE_DEFINE | ||||||||||||||||||||||||
if new_or_init and not f.docstring: | ||||||||||||||||||||||||
docstring_prototype = docstring_definition = '' | ||||||||||||||||||||||||
elif f.getter: | ||||||||||||||||||||||||
methoddef_define = self.GETTERDEF_PROTOTYPE_DEFINE | ||||||||||||||||||||||||
docstring_prototype = docstring_definition = '' | ||||||||||||||||||||||||
else: | ||||||||||||||||||||||||
docstring_prototype = self.DOCSTRING_PROTOTYPE_VAR | ||||||||||||||||||||||||
docstring_definition = self.DOCSTRING_PROTOTYPE_STRVAR | ||||||||||||||||||||||||
|
@@ -1217,7 +1228,11 @@ def parser_body( | |||||||||||||||||||||||
parsearg: str | None | ||||||||||||||||||||||||
if not parameters: | ||||||||||||||||||||||||
parser_code: list[str] | None | ||||||||||||||||||||||||
if not requires_defining_class: | ||||||||||||||||||||||||
if f.getter: | ||||||||||||||||||||||||
flags = "NULL" | ||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks strange to me; AFAICS, we don't use Ideally we should not have to specify
Suggested change
Suggested change
This comment was marked as resolved.
Sorry, something went wrong. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah please ignore my previous comment, now I understood what you want to say :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You may already know: the reason I don't use Lines 11 to 17 in a194938
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're not creating a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
We need to refactor some of the code while implementing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dde933e There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure my suggested comment is good enough :) Wording it more explicit might be better (cc. @AlexWaygood). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is fine... or, at least, I can't think of anything better :) Looking at this function gives me a headache; this change doesn't really make my head hurt significantly more tbh :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, the urge to refactor is growing. I suggest we take a stab at it pretty soon, Alex :) |
||||||||||||||||||||||||
parser_prototype = self.PARSER_PROTOTYPE_GETTER | ||||||||||||||||||||||||
parser_code = [] | ||||||||||||||||||||||||
elif not requires_defining_class: | ||||||||||||||||||||||||
# no parameters, METH_NOARGS | ||||||||||||||||||||||||
flags = "METH_NOARGS" | ||||||||||||||||||||||||
parser_prototype = self.PARSER_PROTOTYPE_NOARGS | ||||||||||||||||||||||||
|
@@ -1670,6 +1685,8 @@ def parser_body( | |||||||||||||||||||||||
methoddef_cast_end = "" | ||||||||||||||||||||||||
if flags in ('METH_NOARGS', 'METH_O', 'METH_VARARGS'): | ||||||||||||||||||||||||
methoddef_cast = "(PyCFunction)" | ||||||||||||||||||||||||
elif f.getter: | ||||||||||||||||||||||||
methoddef_cast = "(getter)" | ||||||||||||||||||||||||
elif limited_capi: | ||||||||||||||||||||||||
methoddef_cast = "(PyCFunction)(void(*)(void))" | ||||||||||||||||||||||||
else: | ||||||||||||||||||||||||
|
@@ -1928,7 +1945,10 @@ def render_function( | |||||||||||||||||||||||
template_dict = {'full_name': full_name} | ||||||||||||||||||||||||
template_dict['name'] = f.displayname | ||||||||||||||||||||||||
template_dict['c_basename'] = f.c_basename | ||||||||||||||||||||||||
template_dict['methoddef_name'] = f.c_basename.upper() + "_METHODDEF" | ||||||||||||||||||||||||
if f.getter: | ||||||||||||||||||||||||
template_dict['methoddef_name'] = f.c_basename.upper() + "_GETTERDEF" | ||||||||||||||||||||||||
else: | ||||||||||||||||||||||||
template_dict['methoddef_name'] = f.c_basename.upper() + "_METHODDEF" | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
template_dict['docstring'] = self.docstring_for_c_string(f) | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
|
@@ -2932,6 +2952,7 @@ class FunctionKind(enum.Enum): | |||||||||||||||||||||||
CLASS_METHOD = enum.auto() | ||||||||||||||||||||||||
METHOD_INIT = enum.auto() | ||||||||||||||||||||||||
METHOD_NEW = enum.auto() | ||||||||||||||||||||||||
GETTER = enum.auto() | ||||||||||||||||||||||||
erlend-aasland marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
@functools.cached_property | ||||||||||||||||||||||||
def new_or_init(self) -> bool: | ||||||||||||||||||||||||
|
@@ -2947,6 +2968,7 @@ def __repr__(self) -> str: | |||||||||||||||||||||||
CLASS_METHOD: Final = FunctionKind.CLASS_METHOD | ||||||||||||||||||||||||
METHOD_INIT: Final = FunctionKind.METHOD_INIT | ||||||||||||||||||||||||
METHOD_NEW: Final = FunctionKind.METHOD_NEW | ||||||||||||||||||||||||
GETTER: Final = FunctionKind.GETTER | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
ParamDict = dict[str, "Parameter"] | ||||||||||||||||||||||||
ReturnConverterType = Callable[..., "CReturnConverter"] | ||||||||||||||||||||||||
|
@@ -2983,6 +3005,7 @@ class Function: | |||||||||||||||||||||||
docstring_only: bool = False | ||||||||||||||||||||||||
critical_section: bool = False | ||||||||||||||||||||||||
target_critical_section: list[str] = dc.field(default_factory=list) | ||||||||||||||||||||||||
getter: bool = False | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
def __post_init__(self) -> None: | ||||||||||||||||||||||||
self.parent = self.cls or self.module | ||||||||||||||||||||||||
|
@@ -3032,6 +3055,8 @@ def methoddef_flags(self) -> str | None: | |||||||||||||||||||||||
flags.append('METH_CLASS') | ||||||||||||||||||||||||
case FunctionKind.STATIC_METHOD: | ||||||||||||||||||||||||
flags.append('METH_STATIC') | ||||||||||||||||||||||||
case FunctionKind.GETTER: | ||||||||||||||||||||||||
pass | ||||||||||||||||||||||||
case _ as kind: | ||||||||||||||||||||||||
assert kind is FunctionKind.CALLABLE, f"unknown kind: {kind!r}" | ||||||||||||||||||||||||
if self.coexist: | ||||||||||||||||||||||||
|
@@ -4678,7 +4703,7 @@ def parse_arg(self, argname: str, displayname: str, *, limited_capi: bool) -> st | |||||||||||||||||||||||
def correct_name_for_self( | ||||||||||||||||||||||||
f: Function | ||||||||||||||||||||||||
) -> tuple[str, str]: | ||||||||||||||||||||||||
if f.kind in (CALLABLE, METHOD_INIT): | ||||||||||||||||||||||||
if f.kind in (CALLABLE, METHOD_INIT, GETTER): | ||||||||||||||||||||||||
corona10 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||
if f.cls: | ||||||||||||||||||||||||
return "PyObject *", "self" | ||||||||||||||||||||||||
return "PyObject *", "module" | ||||||||||||||||||||||||
|
@@ -5140,6 +5165,7 @@ class DSLParser: | |||||||||||||||||||||||
preserve_output: bool | ||||||||||||||||||||||||
critical_section: bool | ||||||||||||||||||||||||
target_critical_section: list[str] | ||||||||||||||||||||||||
getter: bool | ||||||||||||||||||||||||
from_version_re = re.compile(r'([*/]) +\[from +(.+)\]') | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
def __init__(self, clinic: Clinic) -> None: | ||||||||||||||||||||||||
|
@@ -5176,6 +5202,7 @@ def reset(self) -> None: | |||||||||||||||||||||||
self.preserve_output = False | ||||||||||||||||||||||||
self.critical_section = False | ||||||||||||||||||||||||
self.target_critical_section = [] | ||||||||||||||||||||||||
self.getter = False | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
def directive_version(self, required: str) -> None: | ||||||||||||||||||||||||
global version | ||||||||||||||||||||||||
|
@@ -5310,6 +5337,9 @@ def at_critical_section(self, *args: str) -> None: | |||||||||||||||||||||||
self.target_critical_section.extend(args) | ||||||||||||||||||||||||
self.critical_section = True | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
def at_getter(self) -> None: | ||||||||||||||||||||||||
self.getter = True | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
def at_staticmethod(self) -> None: | ||||||||||||||||||||||||
if self.kind is not CALLABLE: | ||||||||||||||||||||||||
fail("Can't set @staticmethod, function is not a normal callable") | ||||||||||||||||||||||||
|
@@ -5427,6 +5457,9 @@ def update_function_kind(self, fullname: str) -> None: | |||||||||||||||||||||||
if (self.kind is not CALLABLE) or (not cls): | ||||||||||||||||||||||||
fail("'__init__' must be a normal method, not a class or static method!") | ||||||||||||||||||||||||
corona10 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||
self.kind = METHOD_INIT | ||||||||||||||||||||||||
elif self.getter and cls: | ||||||||||||||||||||||||
self.kind = GETTER | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
corona10 marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||
|
||||||||||||||||||||||||
def state_modulename_name(self, line: str) -> None: | ||||||||||||||||||||||||
# looking for declaration, which establishes the leftmost column | ||||||||||||||||||||||||
|
@@ -5500,6 +5533,8 @@ def state_modulename_name(self, line: str) -> None: | |||||||||||||||||||||||
line, _, returns = line.partition( 77C1 9;->') | ||||||||||||||||||||||||
returns = returns.strip() | ||||||||||||||||||||||||
full_name, c_basename = self.parse_function_names(line) | ||||||||||||||||||||||||
if self.getter: | ||||||||||||||||||||||||
c_basename += '_get' | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
return_converter = None | ||||||||||||||||||||||||
if returns: | ||||||||||||||||||||||||
|
@@ -5534,7 +5569,8 @@ def state_modulename_name(self, line: str) -> None: | |||||||||||||||||||||||
self.function = Function(name=function_name, full_name=full_name, module=module, cls=cls, c_basename=c_basename, | ||||||||||||||||||||||||
return_converter=return_converter, kind=self.kind, coexist=self.coexist, | ||||||||||||||||||||||||
critical_section=self.critical_section, | ||||||||||||||||||||||||
target_critical_section=self.target_critical_section) | ||||||||||||||||||||||||
target_critical_section=self.target_critical_section, | ||||||||||||||||||||||||
getter=self.getter) | ||||||||||||||||||||||||
self.block.signatures.append(self.function) | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
# insert a self converter automatically | ||||||||||||||||||||||||
|
Uh oh!
There was an error while loading. Please reload this page.