Title: problem with ABCMeta.__prepare__ when called after types.new_class
Type: behavior Stage: patch review
Components: Library (Lib) Versions: Python 3.8, Python 3.7
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: Ricyteach, levkivskyi
Priority: normal Keywords: patch

Created on 2018-03-30 20:43 by Ricyteach, last changed 2018-03-31 02:58 by Ricyteach.

File name Uploaded Description Edit Ricyteach, 2018-03-30 20:43 demo of issue
Pull Requests
URL Status Linked Edit
PR 6317 closed Ricyteach, 2018-03-31 02:38
Messages (5)
msg314714 - (view) Author: Rick Teachey (Ricyteach) * Date: 2018-03-30 20:43
I am pretty sure this is a bug. If not I apologize.

Say I want to dynamically create a new `C` class, with base class `MyABC` (and dynamically assigned abstract method `m`). This works fine if I use `type`, but if I use `new_class`, the keyword argument to the `m` method implementation gets lost somewhere in the call to `ABCMeta.__prepare___`.

I've attached a file to demo. Thanks.
msg314716 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-03-30 21:02
This is not a bug, but a misunderstanding:

* First, ABCMeta doesn't have `__prepare__`, it is just `type.__prepare__`
* Second, the third argument to `types.new_class` is called `kwds` for a reason. It is not a namespace like in `type` but the set of keywords in the equivalent class definition. For example:

types.new_class('Test', (A, B), {'metaclass': Meta, 'foo': 42})

id equivalent to

class Test(A, B, metaclass=Meta, foo=42):

If you want to populate the namespace, then you should use the fourth argument `exec_body` which should be a callable that takes newly created dictionary and populates it with items. For your case it should be:

C = new_class("C", (MyABC,), {}, exec_body=lambda ns: ns.update(namespace))

If you want to clarify the corresponding docstring, then please open a PR. Otherwise you can close the issue.
msg314717 - (view) Author: Rick Teachey (Ricyteach) * Date: 2018-03-30 21:06
Excellent; thank you very much for the explanation.

I have never done a PR on a project this size but I'll give it a try.
msg314718 - (view) Author: Ivan Levkivskyi (levkivskyi) * (Python committer) Date: 2018-03-30 21:07 will help you.
msg314731 - (view) Author: Rick Teachey (Ricyteach) * Date: 2018-03-31 02:58
Thank you; I gave it a go. Hopefully didn't cause too much additional work for someone.
Date User Action Args
2018-03-31 02:58:22Ricyteachsetmessages: + msg314731
2018-03-31 02:38:37Ricyteachsetkeywords: + patch
stage: patch review
pull_requests: + pull_request6033
2018-03-30 21:07:25levkivskyisetmessages: + msg314718
2018-03-30 21:06:20Ricyteachsetmessages: + msg314717
2018-03-30 21:02:10levkivskyisetmessages: + msg314716
2018-03-30 20:43:02Ricyteachcreate