Skip to content
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

gh-116171: Argument Clinic: disallow overriding return converter for __init__ methods #116172

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
41 changes: 0 additions & 41 deletions Lib/test/clinic.test.c
Expand Up @@ -5327,47 +5327,6 @@ Test__pyarg_parsestackandkeywords_impl(TestObj *self, PyTypeObject *cls,
/*[clinic end generated code: output=4fda8a7f2547137c input=fc72ef4b4cfafabc]*/


/*[clinic input]
Test.__init__ -> long
Test overriding the __init__ return converter
[clinic start generated code]*/

PyDoc_STRVAR(Test___init____doc__,
"Test()\n"
"--\n"
"\n"
"Test overriding the __init__ return converter");

static long
Test___init___impl(TestObj *self);

static int
Test___init__(PyObject *self, PyObject *args, PyObject *kwargs)
{
int return_value = -1;
PyTypeObject *base_tp = TestType;
long _return_value;

if ((Py_IS_TYPE(self, base_tp) ||
Py_TYPE(self)->tp_new == base_tp->tp_new) &&
!_PyArg_NoPositional("Test", args)) {
goto exit;
}
if ((Py_IS_TYPE(self, base_tp) ||
Py_TYPE(self)->tp_new == base_tp->tp_new) &&
!_PyArg_NoKeywords("Test", kwargs)) {
goto exit;
}
_return_value = Test___init___impl((TestObj *)self);
if ((_return_value == -1) && PyErr_Occurred()) {
goto exit;
}
return_value = PyLong_FromLong(_return_value);

exit:
return return_value;
}

static long
Test___init___impl(TestObj *self)
/*[clinic end generated code: output=daf6ee12c4e443fb input=311af0dc7f17e8e9]*/
Expand Down
8 changes: 8 additions & 0 deletions Lib/test/test_clinic.py
Expand Up @@ -2146,6 +2146,14 @@ class Foo "" ""
expected_error = err_template.format(invalid_kind)
self.expect_failure(block, expected_error, lineno=3)

def test_init_cannot_define_a_return_type(self):
block = """
class Foo "" ""
Foo.__init__ -> long
"""
expected_error = "__init__ methods cannot define a return type"
self.expect_failure(block, expected_error, lineno=1)

def test_invalid_getset(self):
annotations = ["@getter", "@setter"]
for annotation in annotations:
Expand Down
2 changes: 2 additions & 0 deletions Tools/clinic/clinic.py
Expand Up @@ -5092,6 +5092,8 @@ def resolve_return_converter(
if forced_converter:
if self.kind in {GETTER, SETTER}:
fail(f"@{self.kind.name.lower()} method cannot define a return type")
if self.kind is METHOD_INIT:
fail("__init__ methods cannot define a return type")
ast_input = f"def x() -> {forced_converter}: pass"
try:
module_node = ast.parse(ast_input)
Expand Down