Skip to content

Commit

Permalink
pythongh-116171: Argument Clinic: disallow overriding return converte…
Browse files Browse the repository at this point in the history
…r for __init__ methods
  • Loading branch information
erlend-aasland committed Mar 1, 2024
1 parent ca56c3a commit 0dcff42
Show file tree
Hide file tree
Showing 3 changed files with 10 additions and 41 deletions.
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

0 comments on commit 0dcff42

Please sign in to comment.