mirror of https://github.com/python/cpython
gh-112205: Support @getter annotation from AC (gh-112396)
This commit is contained in:
parent
0785c68559
commit
7eeea13403
|
@ -4951,6 +4951,27 @@ static PyObject *
|
||||||
Test_meth_coexist_impl(TestObj *self)
|
Test_meth_coexist_impl(TestObj *self)
|
||||||
/*[clinic end generated code: output=808a293d0cd27439 input=2a1d75b5e6fec6dd]*/
|
/*[clinic end generated code: output=808a293d0cd27439 input=2a1d75b5e6fec6dd]*/
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
@getter
|
||||||
|
Test.property
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
|
#define TEST_PROPERTY_GETTERDEF \
|
||||||
|
{"property", (getter)Test_property_get, NULL, NULL},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Test_property_get_impl(TestObj *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Test_property_get(TestObj *self, void *Py_UNUSED(context))
|
||||||
|
{
|
||||||
|
return Test_property_get_impl(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
Test_property_get_impl(TestObj *self)
|
||||||
|
/*[clinic end generated code: output=892b6fb351ff85fd input=2d92b3449fbc7d2b]*/
|
||||||
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
output push
|
output push
|
||||||
|
|
|
@ -638,7 +638,7 @@ class ClinicWholeFileTest(TestCase):
|
||||||
C.__init__ = C.meth
|
C.__init__ = C.meth
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
"""
|
"""
|
||||||
err = "'__init__' must be a normal method, not a class or static method"
|
err = "'__init__' must be a normal method; got 'FunctionKind.CLASS_METHOD'!"
|
||||||
self.expect_failure(block, err, lineno=8)
|
self.expect_failure(block, err, lineno=8)
|
||||||
|
|
||||||
def test_validate_cloned_new(self):
|
def test_validate_cloned_new(self):
|
||||||
|
@ -2180,14 +2180,22 @@ class ClinicParserTest(TestCase):
|
||||||
self.expect_failure(block, err, lineno=2)
|
self.expect_failure(block, err, lineno=2)
|
||||||
|
|
||||||
def test_init_must_be_a_normal_method(self):
|
def test_init_must_be_a_normal_method(self):
|
||||||
err = "'__init__' must be a normal method, not a class or static method!"
|
err_template = "'__init__' must be a normal method; got 'FunctionKind.{}'!"
|
||||||
block = """
|
annotations = {
|
||||||
|
"@classmethod": "CLASS_METHOD",
|
||||||
|
"@staticmethod": "STATIC_METHOD",
|
||||||
|
"@getter": "GETTER",
|
||||||
|
}
|
||||||
|
for annotation, invalid_kind in annotations.items():
|
||||||
|
with self.subTest(annotation=annotation, invalid_kind=invalid_kind):
|
||||||
|
block = f"""
|
||||||
module foo
|
module foo
|
||||||
class Foo "" ""
|
class Foo "" ""
|
||||||
@classmethod
|
{annotation}
|
||||||
Foo.__init__
|
Foo.__init__
|
||||||
"""
|
"""
|
||||||
self.expect_failure(block, err, lineno=3)
|
expected_error = err_template.format(invalid_kind)
|
||||||
|
self.expect_failure(block, expected_error, lineno=3)
|
||||||
|
|
||||||
def test_duplicate_coexist(self):
|
def test_duplicate_coexist(self):
|
||||||
err = "Called @coexist twice"
|
err = "Called @coexist twice"
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_bytesobject.h" // _PyBytes_Join()
|
#include "pycore_bytesobject.h" // _PyBytes_Join()
|
||||||
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
||||||
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION()
|
|
||||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||||
#include "pycore_pyerrors.h" // _Py_FatalErrorFormat()
|
#include "pycore_pyerrors.h" // _Py_FatalErrorFormat()
|
||||||
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
|
#include "pycore_pylifecycle.h" // _Py_IsInterpreterFinalizing()
|
||||||
|
@ -518,25 +517,20 @@ buffered_closed(buffered *self)
|
||||||
return closed;
|
return closed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
@critical_section
|
||||||
|
@getter
|
||||||
|
_io._Buffered.closed
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
buffered_closed_get_impl(buffered *self, void *context)
|
_io__Buffered_closed_get_impl(buffered *self)
|
||||||
|
/*[clinic end generated code: output=f08ce57290703a1a input=18eddefdfe4a3d2f]*/
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self)
|
CHECK_INITIALIZED(self)
|
||||||
return PyObject_GetAttr(self->raw, &_Py_ID(closed));
|
return PyObject_GetAttr(self->raw, &_Py_ID(closed));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
buffered_closed_get(buffered *self, void *context)
|
|
||||||
{
|
|
||||||
PyObject *return_value = NULL;
|
|
||||||
|
|
||||||
Py_BEGIN_CRITICAL_SECTION(self);
|
|
||||||
return_value = buffered_closed_get_impl(self, context);
|
|
||||||
Py_END_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
@critical_section
|
@critical_section
|
||||||
_io._Buffered.close
|
_io._Buffered.close
|
||||||
|
@ -662,44 +656,35 @@ _io__Buffered_writable_impl(buffered *self)
|
||||||
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable));
|
return PyObject_CallMethodNoArgs(self->raw, &_Py_ID(writable));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*[clinic input]
|
||||||
|
@critical_section
|
||||||
|
@getter
|
||||||
|
_io._Buffered.name
|
||||||
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
buffered_name_get_impl(buffered *self, void *context)
|
_io__Buffered_name_get_impl(buffered *self)
|
||||||
|
/*[clinic end generated code: output=d2adf384051d3d10 input=6b84a0e6126f545e]*/
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self)
|
CHECK_INITIALIZED(self)
|
||||||
return PyObject_GetAttr(self->raw, &_Py_ID(name));
|
return PyObject_GetAttr(self->raw, &_Py_ID(name));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
/*[clinic input]
|
||||||
buffered_name_get(buffered *self, void *context)
|
@critical_section
|
||||||
{
|
@getter
|
||||||
PyObject *return_value = NULL;
|
_io._Buffered.mode
|
||||||
|
[clinic start generated code]*/
|
||||||
Py_BEGIN_CRITICAL_SECTION(self);
|
|
||||||
return_value = buffered_name_get_impl(self, context);
|
|
||||||
Py_END_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
buffered_mode_get_impl(buffered *self, void *context)
|
_io__Buffered_mode_get_impl(buffered *self)
|
||||||
|
/*[clinic end generated code: output=0feb205748892fa4 input=0762d5e28542fd8c]*/
|
||||||
{
|
{
|
||||||
CHECK_INITIALIZED(self)
|
CHECK_INITIALIZED(self)
|
||||||
return PyObject_GetAttr(self->raw, &_Py_ID(mode));
|
return PyObject_GetAttr(self->raw, &_Py_ID(mode));
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
|
||||||
buffered_mode_get(buffered *self, void *context)
|
|
||||||
{
|
|
||||||
PyObject *return_value = NULL;
|
|
||||||
|
|
||||||
Py_BEGIN_CRITICAL_SECTION(self);
|
|
||||||
return_value = buffered_mode_get_impl(self, context);
|
|
||||||
Py_END_CRITICAL_SECTION();
|
|
||||||
|
|
||||||
return return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Lower-level APIs */
|
/* Lower-level APIs */
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
@ -2541,9 +2526,9 @@ static PyMemberDef bufferedreader_members[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyGetSetDef bufferedreader_getset[] = {
|
static PyGetSetDef bufferedreader_getset[] = {
|
||||||
{"closed", (getter)buffered_closed_get, NULL, NULL},
|
_IO__BUFFERED_CLOSED_GETTERDEF
|
||||||
{"name", (getter)buffered_name_get, NULL, NULL},
|
_IO__BUFFERED_NAME_GETTERDEF
|
||||||
{"mode", (getter)buffered_mode_get, NULL, NULL},
|
_IO__BUFFERED_MODE_GETTERDEF
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2601,9 +2586,9 @@ static PyMemberDef bufferedwriter_members[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyGetSetDef bufferedwriter_getset[] = {
|
static PyGetSetDef bufferedwriter_getset[] = {
|
||||||
{"closed", (getter)buffered_closed_get, NULL, NULL},
|
_IO__BUFFERED_CLOSED_GETTERDEF
|
||||||
{"name", (getter)buffered_name_get, NULL, NULL},
|
_IO__BUFFERED_NAME_GETTERDEF
|
||||||
{"mode", (getter)buffered_mode_get, NULL, NULL},
|
_IO__BUFFERED_MODE_GETTERDEF
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2719,9 +2704,9 @@ static PyMemberDef bufferedrandom_members[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyGetSetDef bufferedrandom_getset[] = {
|
static PyGetSetDef bufferedrandom_getset[] = {
|
||||||
{"closed", (getter)buffered_closed_get, NULL, NULL},
|
_IO__BUFFERED_CLOSED_GETTERDEF
|
||||||
{"name", (getter)buffered_name_get, NULL, NULL},
|
_IO__BUFFERED_NAME_GETTERDEF
|
||||||
{"mode", (getter)buffered_mode_get, NULL, NULL},
|
_IO__BUFFERED_MODE_GETTERDEF
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -327,6 +327,24 @@ _io__Buffered_simple_flush(buffered *self, PyObject *Py_UNUSED(ignored))
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define _IO__BUFFERED_CLOSED_GETTERDEF \
|
||||||
|
{"closed", (getter)_io__Buffered_closed_get, NULL, NULL},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_io__Buffered_closed_get_impl(buffered *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_io__Buffered_closed_get(buffered *self, void *Py_UNUSED(context))
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
|
||||||
|
Py_BEGIN_CRITICAL_SECTION(self);
|
||||||
|
return_value = _io__Buffered_closed_get_impl(self);
|
||||||
|
Py_END_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(_io__Buffered_close__doc__,
|
PyDoc_STRVAR(_io__Buffered_close__doc__,
|
||||||
"close($self, /)\n"
|
"close($self, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
|
@ -442,6 +460,42 @@ _io__Buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define _IO__BUFFERED_NAME_GETTERDEF \
|
||||||
|
{"name", (getter)_io__Buffered_name_get, NULL, NULL},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_io__Buffered_name_get_impl(buffered *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_io__Buffered_name_get(buffered *self, void *Py_UNUSED(context))
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
|
||||||
|
Py_BEGIN_CRITICAL_SECTION(self);
|
||||||
|
return_value = _io__Buffered_name_get_impl(self);
|
||||||
|
Py_END_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _IO__BUFFERED_MODE_GETTERDEF \
|
||||||
|
{"mode", (getter)_io__Buffered_mode_get, NULL, NULL},
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_io__Buffered_mode_get_impl(buffered *self);
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
_io__Buffered_mode_get(buffered *self, void *Py_UNUSED(context))
|
||||||
|
{
|
||||||
|
PyObject *return_value = NULL;
|
||||||
|
|
||||||
|
Py_BEGIN_CRITICAL_SECTION(self);
|
||||||
|
return_value = _io__Buffered_mode_get_impl(self);
|
||||||
|
Py_END_CRITICAL_SECTION();
|
||||||
|
|
||||||
|
return return_value;
|
||||||
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(_io__Buffered_fileno__doc__,
|
PyDoc_STRVAR(_io__Buffered_fileno__doc__,
|
||||||
"fileno($self, /)\n"
|
"fileno($self, /)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
|
@ -1164,4 +1218,4 @@ skip_optional_pos:
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=e8ad39a45531d7f2 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=f21ed03255032b43 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -846,6 +846,10 @@ class CLanguage(Language):
|
||||||
static PyObject *
|
static PyObject *
|
||||||
{c_basename}({self_type}{self_name}, PyObject *Py_UNUSED(ignored))
|
{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 *Py_UNUSED(context))
|
||||||
|
""")
|
||||||
METH_O_PROTOTYPE: Final[str] = normalize_snippet("""
|
METH_O_PROTOTYPE: Final[str] = normalize_snippet("""
|
||||||
static PyObject *
|
static PyObject *
|
||||||
{c_basename}({impl_parameters})
|
{c_basename}({impl_parameters})
|
||||||
|
@ -865,6 +869,10 @@ class CLanguage(Language):
|
||||||
#define {methoddef_name} \
|
#define {methoddef_name} \
|
||||||
{{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}},
|
{{"{name}", {methoddef_cast}{c_basename}{methoddef_cast_end}, {methoddef_flags}, {c_basename}__doc__}},
|
||||||
""")
|
""")
|
||||||
|
GETTERDEF_PROTOTYPE_DEFINE: Final[str] = normalize_snippet(r"""
|
||||||
|
#define {getter_name} \
|
||||||
|
{{"{name}", (getter){c_basename}, NULL, NULL}},
|
||||||
|
""")
|
||||||
METHODDEF_PROTOTYPE_IFNDEF: Final[str] = normalize_snippet("""
|
METHODDEF_PROTOTYPE_IFNDEF: Final[str] = normalize_snippet("""
|
||||||
#ifndef {methoddef_name}
|
#ifndef {methoddef_name}
|
||||||
#define {methoddef_name}
|
#define {methoddef_name}
|
||||||
|
@ -1161,6 +1169,9 @@ class CLanguage(Language):
|
||||||
methoddef_define = self.METHODDEF_PROTOTYPE_DEFINE
|
methoddef_define = self.METHODDEF_PROTOTYPE_DEFINE
|
||||||
if new_or_init and not f.docstring:
|
if new_or_init and not f.docstring:
|
||||||
docstring_prototype = docstring_definition = ''
|
docstring_prototype = docstring_definition = ''
|
||||||
|
elif f.kind is GETTER:
|
||||||
|
methoddef_define = self.GETTERDEF_PROTOTYPE_DEFINE
|
||||||
|
docstring_prototype = docstring_definition = ''
|
||||||
else:
|
else:
|
||||||
docstring_prototype = self.DOCSTRING_PROTOTYPE_VAR
|
docstring_prototype = self.DOCSTRING_PROTOTYPE_VAR
|
||||||
docstring_definition = self.DOCSTRING_PROTOTYPE_STRVAR
|
docstring_definition = self.DOCSTRING_PROTOTYPE_STRVAR
|
||||||
|
@ -1217,7 +1228,11 @@ class CLanguage(Language):
|
||||||
parsearg: str | None
|
parsearg: str | None
|
||||||
if not parameters:
|
if not parameters:
|
||||||
parser_code: list[str] | None
|
parser_code: list[str] | None
|
||||||
if not requires_defining_class:
|
if f.kind is GETTER:
|
||||||
|
flags = "" # This should end up unused
|
||||||
|
parser_prototype = self.PARSER_PROTOTYPE_GETTER
|
||||||
|
parser_code = []
|
||||||
|
elif not requires_defining_class:
|
||||||
# no parameters, METH_NOARGS
|
# no parameters, METH_NOARGS
|
||||||
flags = "METH_NOARGS"
|
flags = "METH_NOARGS"
|
||||||
parser_prototype = self.PARSER_PROTOTYPE_NOARGS
|
parser_prototype = self.PARSER_PROTOTYPE_NOARGS
|
||||||
|
@ -1670,6 +1685,8 @@ class CLanguage(Language):
|
||||||
methoddef_cast_end = ""
|
methoddef_cast_end = ""
|
||||||
if flags in ('METH_NOARGS', 'METH_O', 'METH_VARARGS'):
|
if flags in ('METH_NOARGS', 'METH_O', 'METH_VARARGS'):
|
||||||
methoddef_cast = "(PyCFunction)"
|
methoddef_cast = "(PyCFunction)"
|
||||||
|
elif f.kind is GETTER:
|
||||||
|
methoddef_cast = "" # This should end up unused
|
||||||
elif limited_capi:
|
elif limited_capi:
|
||||||
methoddef_cast = "(PyCFunction)(void(*)(void))"
|
methoddef_cast = "(PyCFunction)(void(*)(void))"
|
||||||
else:
|
else:
|
||||||
|
@ -1927,8 +1944,12 @@ class CLanguage(Language):
|
||||||
full_name = f.full_name
|
full_name = f.full_name
|
||||||
template_dict = {'full_name': full_name}
|
template_dict = {'full_name': full_name}
|
||||||
template_dict['name'] = f.displayname
|
template_dict['name'] = f.displayname
|
||||||
template_dict['c_basename'] = f.c_basename
|
if f.kind is GETTER:
|
||||||
|
template_dict['getter_name'] = f.c_basename.upper() + "_GETTERDEF"
|
||||||
|
template_dict['c_basename'] = f.c_basename + "_get"
|
||||||
|
else:
|
||||||
template_dict['methoddef_name'] = f.c_basename.upper() + "_METHODDEF"
|
template_dict['methoddef_name'] = f.c_basename.upper() + "_METHODDEF"
|
||||||
|
template_dict['c_basename'] = f.c_basename
|
||||||
|
|
||||||
template_dict['docstring'] = self.docstring_for_c_string(f)
|
template_dict['docstring'] = self.docstring_for_c_string(f)
|
||||||
|
|
||||||
|
@ -2932,6 +2953,7 @@ class FunctionKind(enum.Enum):
|
||||||
CLASS_METHOD = enum.auto()
|
CLASS_METHOD = enum.auto()
|
||||||
METHOD_INIT = enum.auto()
|
METHOD_INIT = enum.auto()
|
||||||
METHOD_NEW = enum.auto()
|
METHOD_NEW = enum.auto()
|
||||||
|
GETTER = enum.auto()
|
||||||
|
|
||||||
@functools.cached_property
|
@functools.cached_property
|
||||||
def new_or_init(self) -> bool:
|
def new_or_init(self) -> bool:
|
||||||
|
@ -2947,6 +2969,7 @@ STATIC_METHOD: Final = FunctionKind.STATIC_METHOD
|
||||||
CLASS_METHOD: Final = FunctionKind.CLASS_METHOD
|
CLASS_METHOD: Final = FunctionKind.CLASS_METHOD
|
||||||
METHOD_INIT: Final = FunctionKind.METHOD_INIT
|
METHOD_INIT: Final = FunctionKind.METHOD_INIT
|
||||||
METHOD_NEW: Final = FunctionKind.METHOD_NEW
|
METHOD_NEW: Final = FunctionKind.METHOD_NEW
|
||||||
|
GETTER: Final = FunctionKind.GETTER
|
||||||
|
|
||||||
ParamDict = dict[str, "Parameter"]
|
ParamDict = dict[str, "Parameter"]
|
||||||
ReturnConverterType = Callable[..., "CReturnConverter"]
|
ReturnConverterType = Callable[..., "CReturnConverter"]
|
||||||
|
@ -3033,7 +3056,8 @@ class Function:
|
||||||
case FunctionKind.STATIC_METHOD:
|
case FunctionKind.STATIC_METHOD:
|
||||||
flags.append('METH_STATIC')
|
flags.append('METH_STATIC')
|
||||||
case _ as kind:
|
case _ as kind:
|
||||||
assert kind is FunctionKind.CALLABLE, f"unknown kind: {kind!r}"
|
acceptable_kinds = {FunctionKind.CALLABLE, FunctionKind.GETTER}
|
||||||
|
assert kind in acceptable_kinds, f"unknown kind: {kind!r}"
|
||||||
if self.coexist:
|
if self.coexist:
|
||||||
flags.append('METH_COEXIST')
|
flags.append('METH_COEXIST')
|
||||||
return '|'.join(flags)
|
return '|'.join(flags)
|
||||||
|
@ -4678,7 +4702,7 @@ class Py_buffer_converter(CConverter):
|
||||||
def correct_name_for_self(
|
def correct_name_for_self(
|
||||||
f: Function
|
f: Function
|
||||||
) -> tuple[str, str]:
|
) -> tuple[str, str]:
|
||||||
if f.kind in (CALLABLE, METHOD_INIT):
|
if f.kind in {CALLABLE, METHOD_INIT, GETTER}:
|
||||||
if f.cls:
|
if f.cls:
|
||||||
return "PyObject *", "self"
|
return "PyObject *", "self"
|
||||||
return "PyObject *", "module"
|
return "PyObject *", "module"
|
||||||
|
@ -5310,6 +5334,9 @@ class DSLParser:
|
||||||
self.target_critical_section.extend(args)
|
self.target_critical_section.extend(args)
|
||||||
self.critical_section = True
|
self.critical_section = True
|
||||||
|
|
||||||
|
def at_getter(self) -> None:
|
||||||
|
self.kind = GETTER
|
||||||
|
|
||||||
def at_staticmethod(self) -> None:
|
def at_staticmethod(self) -> None:
|
||||||
if self.kind is not CALLABLE:
|
if self.kind is not CALLABLE:
|
||||||
fail("Can't set @staticmethod, function is not a normal callable")
|
fail("Can't set @staticmethod, function is not a normal callable")
|
||||||
|
@ -5419,14 +5446,20 @@ class DSLParser:
|
||||||
_, cls = self.clinic._module_and_class(fields)
|
_, cls = self.clinic._module_and_class(fields)
|
||||||
if name in unsupported_special_methods:
|
if name in unsupported_special_methods:
|
||||||
fail(f"{name!r} is a special method and cannot be converted to Argument Clinic!")
|
fail(f"{name!r} is a special method and cannot be converted to Argument Clinic!")
|
||||||
|
|
||||||
if name == '__new__':
|
if name == '__new__':
|
||||||
if (self.kind is not CLASS_METHOD) or (not cls):
|
if (self.kind is CLASS_METHOD) and cls:
|
||||||
fail("'__new__' must be a class method!")
|
|
||||||
self.kind = METHOD_NEW
|
self.kind = METHOD_NEW
|
||||||
|
else:
|
||||||
|
fail("'__new__' must be a class method!")
|
||||||
elif name == '__init__':
|
elif name == '__init__':
|
||||||
if (self.kind is not CALLABLE) or (not cls):
|
if (self.kind is CALLABLE) and cls:
|
||||||
fail("'__init__' must be a normal method, not a class or static method!")
|
|
||||||
self.kind = METHOD_INIT
|
self.kind = METHOD_INIT
|
||||||
|
else:
|
||||||
|
fail(
|
||||||
|
"'__init__' must be a normal method; "
|
||||||
|
f"got '{self.kind}'!"
|
||||||
|
)
|
||||||
|
|
||||||
def state_modulename_name(self, line: str) -> None:
|
def state_modulename_name(self, line: str) -> None:
|
||||||
# looking for declaration, which establishes the leftmost column
|
# looking for declaration, which establishes the leftmost column
|
||||||
|
|
Loading…
Reference in New Issue