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

with_metaclass: check existence of __prepare__ attribute before calling it #252

Open
behnam opened this issue Aug 9, 2018 · 5 comments
Open

Comments

@behnam
Copy link

behnam commented Aug 9, 2018

https://github.com/prettier/plugin-python/blob/04dc40a40501a13eaec5fcb4d5c99829a31d3ffc/vendor/python/six.py#L831

The def with_metaclass() implementation assumes that all meta classes have __prepare__ defined.

The Python Reference says (https://docs.python.org/3/reference/datamodel.html#preparing-the-class-namespace):

If the metaclass has a __prepare__ attribute, it is called as [...].

If the metaclass has no __prepare__ attribute, then the class namespace is initialised as an empty ordered mapping.

Therefore, I think six should check existence of __prepare__ attribute before calling it, as __prepare__ is not defined on type in PY2.

behnam pushed a commit to behnam/python-qcore that referenced this issue Aug 9, 2018
Classes passed to `six.with_metaclass()` are expected to have a
`__prepare__` method to pass `tox` checks, which is not defined by
default in PY2 and not used.

See also <benjaminp/six#252>.
JelleZijlstra pushed a commit to quora/qcore that referenced this issue Aug 9, 2018
Classes passed to `six.with_metaclass()` are expected to have a
`__prepare__` method to pass `tox` checks, which is not defined by
default in PY2 and not used.

See also <benjaminp/six#252>.
@benjaminp
Copy link
Owner

Why is that a problem, though? Defining a __prepare__ method on Python 2 is useless but harmless, right?

@behnam
Copy link
Author

behnam commented Aug 13, 2018

Looks like Cython makes calls to __prepare__ even in Python 2. So, not 100% a bug here, but would be great to address it so application (like qcore here) don't have to special-case for it.

@benjaminp
Copy link
Owner

Is there a Cython bug filed for that behavior?

@behnam
Copy link
Author

behnam commented Aug 15, 2018

Here's the original report on Cython: cython/cython#1936

The issue was introduced in #178, already reported in #210, and an Open PR is out in #211. Unfortunately both the issue and PR have been open for 11 months, without much movement.

@benjaminp, can we please either merge in #211, or go with a quick (and simpler) fix, which would be calling hasattr() before calling __prepare__()?

@aaronchall
Copy link

This is a problem because Python accepts any callable with the right signature as a metaclass, and this assumes that you are subclassing type (or something with a __prepare__ method) - so this behavior could be considered buggy for that reason.

What I don't understand is why you're defining a metaclass in the decorator - why don't you just return

meta('temporary_class', bases, {})

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

No branches or pull requests

3 participants