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

Make classmethod work in limited-api #5800

Merged
merged 1 commit into from
May 16, 2024

Conversation

da-woods
Copy link
Contributor

@da-woods da-woods commented Nov 5, 2023

Except for the case where binding=False, which I don't think we can easily do. I don't care that much given that binding=True works correctly.

Fixes #5797

Except for the class where binding=False, which I don't think
we can easily do. I don't care that much given that binding=True
works correctly.

Fixes cython#5797
@@ -1792,13 +1795,54 @@ static PyObject* __Pyx_Method_ClassMethod(PyObject *method) {
PyTypeObject *d_type = descr->d_common.d_type;
#endif
return PyDescr_NewClassMethod(d_type, descr->d_method);
#else
return PyErr_Format(
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect it would be possible to cover this case by setting METH_CLASS when the PyMethodDef is defined. I definitely don't think that's worth it for the first pass and may not be worth it in general.

Copy link
Contributor

@vyasr vyasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The implementation looks fine. I'm not sure if there are improvements that could be made but I do think it is correct.

method_type = PyObject_GetAttrString(types_module, "MethodType");
if (!method_type) goto bad;
if (__Pyx_TypeCheck(method, method_type)) {
func = PyObject_GetAttrString(method, "__func__");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sort of surprised that PyMethod_GetFunction isn't part of the limited API. I wonder if there's a plan to add it at some point. I had to write code like this in a couple of places and it made me wonder if getattr is really the intended way to access everything in limited API mode. I couldn't find any good alternatives, though.

Comment on lines +1833 to +1834
builtins = PyEval_GetBuiltins(); // borrowed
if (!builtins) goto bad;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to extract this logic into a macro? Every limited API branch is going to be repeating this pattern everywhere. I'm imagining something like

#define goto_if_null(var, expr, label) var=expr; if(!var) goto label;
...
goto_if_null(builtins, PyEval_GetBuiltins(), bad);

Having seen it written out I'm not as convinced of the benefit as I was in my head, but I'll leave the suggestion in case you find it helpful.

@da-woods
Copy link
Contributor Author

da-woods commented May 5, 2024

I'm going to treat this as low impact, unlikely to break anything, and merge it in the fairly near future unless I get any objections...

@da-woods da-woods merged commit d9dde8b into cython:master May 16, 2024
81 of 83 checks passed
@da-woods da-woods deleted the limited-api-classmethod branch May 16, 2024 07:51
@da-woods da-woods added this to the 3.1 milestone May 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[BUG] classmethods don't compile using the limited api
2 participants