Skip to content

Commit

Permalink
Fix getargs argument passing (#18350)
Browse files Browse the repository at this point in the history
Fixes mypyc/mypyc#1078

Introduced in #17930

See the first commit to see the bug (wrong condition)

---------

Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
  • Loading branch information
2 people authored and svalentin committed Dec 30, 2024
1 parent b9fa8ee commit 3755abb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 12 deletions.
21 changes: 9 additions & 12 deletions mypyc/lib-rt/getargs.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,12 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
current_arg = Py_NewRef(PyTuple_GET_ITEM(args, i));
}
else if (nkwargs && i >= pos) {
int res = PyDict_GetItemStringRef(kwargs, kwlist[i], &current_arg);
if (res == 1) {
--nkwargs;
}
else if (res == -1) {
if (unlikely(PyDict_GetItemStringRef(kwargs, kwlist[i], &current_arg) < 0)) {
return 0;
}
if (current_arg) {
--nkwargs;
}
}
else {
current_arg = NULL;
Expand Down Expand Up @@ -371,11 +370,12 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
Py_ssize_t j;
/* make sure there are no arguments given by name and position */
for (i = pos; i < bound_pos_args && i < len; i++) {
int res = PyDict_GetItemStringRef(kwargs, kwlist[i], &current_arg);
if (res == 1) {
Py_DECREF(current_arg);
PyObject *current_arg;
if (unlikely(PyDict_GetItemStringRef(kwargs, kwlist[i], &current_arg) < 0)) {
goto latefail;
}
else if (unlikely(res == 0)) {
if (unlikely(current_arg != NULL)) {
Py_DECREF(current_arg);
/* arg present in tuple and in dict */
PyErr_Format(PyExc_TypeError,
"argument for %.200s%s given by name ('%s') "
Expand All @@ -385,9 +385,6 @@ vgetargskeywords(PyObject *args, PyObject *kwargs, const char *format,
kwlist[i], i+1);
goto latefail;
}
else if (unlikely(res == -1)) {
goto latefail;
}
}
/* make sure there are no extraneous keyword arguments */
j = 0;
Expand Down
15 changes: 15 additions & 0 deletions mypyc/test-data/run-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,21 @@ a = A(10)
assert a.foo() == 11
assert foo() == 21

[case testClassKwargs]
class X:
def __init__(self, msg: str, **variables: int) -> None:
pass
[file driver.py]
import traceback
from native import X
X('hello', a=0)
try:
X('hello', msg='hello')
except TypeError as e:
print(f"{type(e).__name__}: {e}")
[out]
TypeError: argument for __init__() given by name ('msg') and position (1)

[case testGenericClass]
from typing import TypeVar, Generic, Sequence
T = TypeVar('T')
Expand Down

0 comments on commit 3755abb

Please sign in to comment.