[pypy-issue] Issue #3075: Class keywords are improperly passed in PyPy3 when using ancestors from the “abc” module (pypy/pypy)

Alexander Böhn issues-reply at bitbucket.org
Mon Sep 16 23:08:20 EDT 2019


New issue 3075: Class keywords are improperly passed in PyPy3 when using ancestors from the “abc” module
https://bitbucket.org/pypy/pypy/issues/3075/class-keywords-are-improperly-passed-in

Alexander Böhn:

I produced this fairly minimal example:

‌

```python
# -*- encoding: utf-8 -*-
from __future__ import print_function

import abc

class Metabase(abc.ABCMeta):
    
    def __new__(metacls, name, bases, attributes, **kwargs):
        # Call up:
        return super(Metabase, metacls).__new__(metacls, name,
                                                         bases,
                                                         attributes,
                                                       **kwargs)

class Metaclass(Metabase):
    
    def __new__(metacls, name, bases, attributes, metakeyword="meta", **kwargs):
        # Stow metaclass keyword in attributes:
        if 'metakeyword' not in attributes:
            attributes['metakeyword'] = metakeyword
        
        # Remove metaclass’ keyword and call up:
        return super(Metaclass, metacls).__new__(metacls, name,
                                                          bases,
                                                          attributes,
                                                        **kwargs)

class Mixin(abc.ABC, metaclass=Metabase):
    
    @classmethod
    def __init_subclass__(cls, mixinkeyword="mixin", **kwargs):
        # Remove mixins’ keyword and call up:
        super(Mixin, cls).__init_subclass__(**kwargs)
        
        # Stow mixin keyword on subclass:
        cls.mixinkeyword = mixinkeyword

class Base(Mixin, metaclass=Metaclass):
    pass

class Derived(Base, mixinkeyword="derived-mixin",
                    metakeyword="derived-meta"):
    pass

def test():
    d = Derived()
    print(d)
    print(d.mixinkeyword)
    print(d.metakeyword)

if __name__ == '__main__':
    test()
```

‌

… if this is run with `python3 class-kwargs.py` :grinning: 

… if this is run with `pypy3 class-kwargs.py` :sob: 

‌

```python
Traceback (most recent call last):
  File ".script-bin/class-kwargs.py", line 43, in <module>
    metakeyword="derived-meta"):
  File ".script-bin/class-kwargs.py", line 27, in __new__
    **kwargs)
  File ".script-bin/class-kwargs.py", line 14, in __new__
    **kwargs)
TypeError: __new__() got an unexpected keyword argument 'mixinkeyword'
```

‌

… the output of `python3 --version` is `Python 3.7.4`

… the output of `pypy3 --version` is:

```plaintext
Python 3.6.1 (784b254d669919c872a505b807db8462b6140973, Sep 04 2019, 12:08:51)
[PyPy 7.1.1-beta0 with GCC 4.2.1 Compatible Apple LLVM 10.0.1 (clang-1001.0.46.4)]
```

There were, as far as I have been able to see looking through the docs, no major changes made to the way `__init_subclass__(…)` or metaclass keyword arguments worked between Python 3.6.1 and Python 3.7.

The `class-kwargs.py` script is attached here.




More information about the pypy-issue mailing list