Issue36947
Created on 2019-05-17 14:27 by Nicholas Matthews, last changed 2022-04-11 14:59 by admin. This issue is now closed.
| Pull Requests | |||
|---|---|---|---|
| URL | Status | Linked | Edit |
| PR 15319 | closed | python-dev, 2019-08-17 07:09 | |
| Messages (14) | |||
|---|---|---|---|
| msg342723 - (view) | Author: Nicholas Matthews (Nicholas Matthews) | Date: 2019-05-17 14:27 | |
Currently the final sentence of the second paragraph reads: "In the following example, both MyClass and MySubclass are instances of Meta:" It should read something like: "In the following example, both MyClass and MySubclass have the metaclass Meta, and new instances will be created using Meta:" Classes are created by their metaclass, but cannot be said to be instances of their metaclass, correct? |
|||
| msg342724 - (view) | Author: Stéphane Wirtel (matrixise) * ![]() |
Date: 2019-05-17 14:31 | |
Thank you for your report |
|||
| msg342725 - (view) | Author: Stéphane Wirtel (matrixise) * ![]() |
Date: 2019-05-17 14:48 | |
just one question, I don't find the paragraph with this text in the code. Could you share the link of this paragraph? Thank you |
|||
| msg342726 - (view) | Author: Stéphane Wirtel (matrixise) * ![]() |
Date: 2019-05-17 14:49 | |
Found here: https://docs.python.org/3/reference/datamodel.html#metaclasses Thank you |
|||
| msg342727 - (view) | Author: Stéphane Wirtel (matrixise) * ![]() |
Date: 2019-05-17 14:51 | |
If you want to modify the text, please create a PR for this file: https://github.com/python/cpython/blob/master/Doc/reference/datamodel.rst#metaclasses Don't forget to sign the CLA, Thank you |
|||
| msg342728 - (view) | Author: Nicholas Matthews (Nicholas Matthews) | Date: 2019-05-17 14:59 | |
Ok, I will create a PR soon and update the issue. |
|||
| msg342730 - (view) | Author: Josh Rosenberg (josh.r) * ![]() |
Date: 2019-05-17 15:27 | |
Clarification is fine, but "MyClass and MySubclass are instances of Meta:" is 100% true. Declaring a class to have a metaclass (or inheriting from a class with a metaclass) means that the class itself is an instance of the metaclass.
New instances of the classes with metaclass Meta are not "created using Meta"; Meta modifies the creation of the classes themselves, not instances of the classes.
Point is, your suggested change is half wrong (new instances of MyClass and MySubclass aren't directly created using Meta), and half misunderstanding the current documentation ("MyClass is an instance of Meta" already means "MyClass has the metaclass Meta").
|
|||
| msg342731 - (view) | Author: Nicholas Matthews (Nicholas Matthews) | Date: 2019-05-17 15:35 | |
Thanks for the clarification. For the first point on the correctness of the original text, that makes sense, could you link me to any relevant documentation for further reading? On the second point "Meta modifies the creation of the classes themselves, not instances of the classes." I think this is not 100% correct. When you create an instance of a class via "instance = MyClass()", the `__call__` method of the metaclass is invoked, so metaclasses can control both class definition and instance creation. |
|||
| msg342780 - (view) | Author: Josh Rosenberg (josh.r) * ![]() |
Date: 2019-05-18 00:56 | |
Ah, you're right on __call__; I've never bothered to override it on a metaclass, but yes, since a class using a metaclass is an instance of the metaclass, like all instances, calling it invokes the __call__ of its type (it's just that the default metaclass, type, has a __call__ that turns around and calls the __new__ and __init__ of the "instance", which is a class). The nomenclature is hard here. In any event, yes, overriding __call__ will let you hook into the construction of each individual instance of the classes using the metaclass. That's not generally true of all uses of metaclasses (if __call__ is inherited from type, then while new instances are technically created using the metaclass, the metaclass is just letting the normal __new__/__init__ calls take place without interference). There is very little in the way of Python official documentation on metaclasses; the line you proposed to change is one of the few places it's mentioned (most references to metaclasses are on that Data Model page). There are a couple of mentions in the PEPs, and a lot of off-site tutorials, but it's a poorly documented feature in general. It's pretty easy to demonstrate the current wording is correct though: >>> class Meta(type): ... pass ... >>> class MyMeta(metaclass=Meta): ... pass ... >>> isinstance(MyMeta, Meta) True Note that we're using isinstance, not issubclass, and we're not constructing a MyMeta instance. MyMeta itself is an instance of Meta. I really think the problem here is that the documentation is correct, but so bare it's easy to miss the implications of "MyClass and MySubclass are instances of Meta"; since the classes are instances of another class, the metaclass has the same power over them that normal classes have over their instances. That's why __call__ can hook the creation of instances, __new__ can hook the creation of the class itself, __getitem__ can be used to perform lookups on the child class (in at least of the few iterations of the typing framework, that's how List[int] and the like worked; not sure if it's still that way), and properties defined on the metaclass can be accessed on classes that use it, but not their instances. It's enormously powerful, but so complex that the Python docs tend to encourage simpler, more targeted ways of tweaking classes (e.g. decorators). |
|||
| msg344105 - (view) | Author: Chirag Garg (codevil_2o) | Date: 2019-05-31 18:52 | |
It should be written like "In the following example, both MyClass and MySubclass are instances of Meta and the type of MyClass is of metaclass Meta and type of MySubclass is MyClass:" |
|||
| msg352972 - (view) | Author: Ido Michael (Ido Michael) * | Date: 2019-09-22 12:06 | |
Hey, Is someone working on this issue? Can I take it? Ido |
|||
| msg353002 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * ![]() |
Date: 2019-09-23 10:05 | |
It is not good first issue. The referred documentation is complex and needs deep knowledge of Python for changing. The original report was wrong. The original documentation is correct. Josh, do you think the documentation needs other changes, and if yes, do you mind to create a PR? If no, I am inclined to close this issue. |
|||
| msg353134 - (view) | Author: Josh Rosenberg (josh.r) * ![]() |
Date: 2019-09-25 03:24 | |
The existing documentation is correct, just hard to understand if you don't already understand the point of metaclasses (metaclasses are hard, the language to describe them will be inherently a little klunky). At some point, it might be nice to write a proper metaclass tutorial, even if it's only targeted at advanced users (the only people who should really be considering writing their own metaclasses or even directly using existing ones; everyone else should be using more targeted tools and/or inheriting from classes that already implement the desired metaclass). The Data model docs aren't concerned with tutorials and examples though; they're just dry description, and they're doing their job here, so I think this issue can be closed. |
|||
| msg353149 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) * ![]() |
Date: 2019-09-25 06:57 | |
Thank you Josh. |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:59:15 | admin | set | github: 81128 |
| 2019-09-25 06:57:03 | serhiy.storchaka | set | status: open -> closed resolution: fixed messages: + msg353149 stage: patch review -> resolved |
| 2019-09-25 03:24:19 | josh.r | set | messages: + msg353134 |
| 2019-09-23 10:05:32 | serhiy.storchaka | set | status: pending -> open title: [Good first issue] Fix 3.3.3.1 Metaclasses Documentation -> Fix 3.3.3.1 Metaclasses Documentation |
| 2019-09-23 10:05:19 | serhiy.storchaka | set | status: open -> pending nosy:
+ serhiy.storchaka |
| 2019-09-22 12:06:23 | Ido Michael | set | nosy:
+ Ido Michael messages: + msg352972 |
| 2019-08-17 07:09:09 | python-dev | set | keywords:
+ patch stage: patch review pull_requests: + pull_request15037 |
| 2019-05-31 18:52:04 | codevil_2o | set | nosy:
+ codevil_2o messages: + msg344105 |
| 2019-05-18 00:56:43 | josh.r | set | messages: + msg342780 |
| 2019-05-17 15:35:13 | Nicholas Matthews | set | messages: + msg342731 |
| 2019-05-17 15:27:24 | josh.r | set | nosy:
+ josh.r messages: + msg342730 |
| 2019-05-17 14:59:21 | Nicholas Matthews | set | messages: + msg342728 |
| 2019-05-17 14:51:04 | matrixise | set | messages: + msg342727 |
| 2019-05-17 14:49:42 | matrixise | set | status: pending -> open messages: + msg342726 |
| 2019-05-17 14:48:35 | matrixise | set | status: open -> pending messages: + msg342725 |
| 2019-05-17 14:38:56 | matrixise | set | keywords:
+ easy title: Fix 3.3.3.1 Metaclasses Documentation -> [Good first issue] Fix 3.3.3.1 Metaclasses Documentation |
| 2019-05-17 14:31:52 | matrixise | set | nosy:
+ docs@python, matrixise messages: + msg342724 assignee: docs@python |
| 2019-05-17 14:27:51 | Nicholas Matthews | create | |

