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

Passing a NamedTuple **class** rather than instance to .dumps results in an error #301

Closed
ng-henry opened this issue Nov 14, 2022 · 3 comments · Fixed by #302
Closed

Passing a NamedTuple **class** rather than instance to .dumps results in an error #301

ng-henry opened this issue Nov 14, 2022 · 3 comments · Fixed by #302

Comments

@ng-henry
Copy link

simplejson has functionality to encode namedtuple instances using their _asdict() method. However, when passing the underlying namedtuple type to json.dumps, there's an error: ._asdict() missing 1 required positional argument: 'self'

static int
_is_namedtuple(PyObject *obj)
{
int rval = 0;
/* We intentionally accept anything with a duck typed _asdict method rather
* than requiring it to pass PyTuple_Check(obj). */
PyObject *_asdict = PyObject_GetAttrString(obj, "_asdict");
if (_asdict == NULL) {
PyErr_Clear();
return 0;
}
rval = PyCallable_Check(_asdict);
Py_DECREF(_asdict);
return rval;
}

The reason is that _is_namedtuple only checks for the existence of a method named _asdict(). Calling _asdict() from the object instance requires no further arguments as self is already provided. However, calling _asdict() from the namedtuple class requires an additional argument, self.

To fix this, _is_namedtuple function should further check that the object is an instance rather than a class, or that the _asdict() function is indeed callable with zero arguments.

@etrepum
Copy link
Member

etrepum commented Nov 14, 2022

What is the intended use case of passing such a nametuple class through the encoder? What do you expect to happen here other than perhaps a different error message?

@ng-henry
Copy link
Author

I'm working on capturing all the arguments of a given function call and serializing them to JSON. Since the arguments can be anything, I'd expect simplejson to encode builtin objects and call the default function for all the other things it cannot encode.

For example, if I pass in a random class (not NamedTuple), then simplejson would call default and let user handle it themselves. But for NamedTuple, simplejson crashes and does not let user specify how to encode.

@etrepum
Copy link
Member

etrepum commented Nov 14, 2022

This is implemented in v3.18.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants