type() does not call __prepare__?
From stackoverflow [1] # metaprepare.py class Meta1(type): @classmethod def __prepare__(mcs, name, bases): print('call prepare') return {} def __new__(mcs, name, bases, parameters): return super().__new__(mcs, name, bases, parameters) class A(metaclass=Meta1): pass type('C', (A, ), {}) output is: call prepare (just the once, not twice) The behavior of `type()` not calling `__prepare__()` has been constant since 3.3. Is it a bug? -- ~Ethan~ [1] https://stackoverflow.com/q/62128254/208880
But on calling `type` in this way, you are passing the namespace as a
ready object, as the
3rdy parameter - what would `__prepare__` even do, besides print it's
been called?
For sometime (maybe Python 3.3, I forgot), some helper
callables where added to the `types` module to allow
one to have more freedom in imperatively created classes:
````python
In [20]: types.prepare_class?
Signature: types.prepare_class(name, bases=(), kwds=None)
Docstring:
Call the __prepare__ method of the appropriate metaclass.
Returns (metaclass, namespace, kwds) as a 3-tuple
*metaclass* is the appropriate metaclass
*namespace* is the prepared class namespace
*kwds* is an updated copy of the passed in kwds argument with any
'metaclass' entry removed. If no kwds argument is passed in, this will
be an empty dict.
File: ~/projetos/terminedia/env/lib64/python3.7/types.py
Type: function
In [21]: types.new_class?
Signature: types.new_class(name, bases=(), kwds=None, exec_body=None)
Docstring: Create a class object dynamically using the appropriate metaclass.
File: ~/projetos/terminedia/env/lib64/python3.7/types.py
Type: function
In [22]: types.resolve_bases?
Signature: types.resolve_bases(bases)
Docstring: Resolve MRO entries dynamically as specified by PEP 560.
File: ~/projetos/terminedia/env/lib64/python3.7/types.py
Type: function
```
On Mon, 1 Jun 2020 at 16:28, Ethan Furman
From stackoverflow [1]
# metaprepare.py class Meta1(type): @classmethod def __prepare__(mcs, name, bases): print('call prepare') return {} def __new__(mcs, name, bases, parameters): return super().__new__(mcs, name, bases, parameters)
class A(metaclass=Meta1): pass
type('C', (A, ), {})
output is:
call prepare
(just the once, not twice)
The behavior of `type()` not calling `__prepare__()` has been constant since 3.3.
Is it a bug?
-- ~Ethan~
[1] https://stackoverflow.com/q/62128254/208880 _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/CQTD7WFO... Code of Conduct: http://python.org/psf/codeofconduct/
It's not a bug, it's just bypassing steps in the Py3 dynamic class
definition process.
https://docs.python.org/3/library/types.html#types.new_class is the API to
use to invoke the full metaclass machinery, including namespace preparation.
https://docs.python.org/3/reference/datamodel.html#metaclasses goes into
more detail on how that works (calling the metaclass constructor is the
last step, after the namespace has already been prepared and populated).
Cheers,
Nick.
On Tue., 2 Jun. 2020, 5:22 am Ethan Furman,
From stackoverflow [1]
# metaprepare.py class Meta1(type): @classmethod def __prepare__(mcs, name, bases): print('call prepare') return {} def __new__(mcs, name, bases, parameters): return super().__new__(mcs, name, bases, parameters)
class A(metaclass=Meta1): pass
type('C', (A, ), {})
output is:
call prepare
(just the once, not twice)
The behavior of `type()` not calling `__prepare__()` has been constant since 3.3.
Is it a bug?
-- ~Ethan~
[1] https://stackoverflow.com/q/62128254/208880 _______________________________________________ Python-Dev mailing list -- python-dev@python.org To unsubscribe send an email to python-dev-leave@python.org https://mail.python.org/mailman3/lists/python-dev.python.org/ Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/CQTD7WFO... Code of Conduct: http://python.org/psf/codeofconduct/
participants (3)
-
Ethan Furman
-
Joao S. O. Bueno
-
Nick Coghlan