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

Implement PEP-487: customisation of class creation #2781

Closed
fduxiao opened this issue Jan 4, 2019 · 14 comments · Fixed by #3533
Closed

Implement PEP-487: customisation of class creation #2781

fduxiao opened this issue Jan 4, 2019 · 14 comments · Fixed by #3533

Comments

@fduxiao
Copy link

fduxiao commented Jan 4, 2019

class ABC:
    def __init_subclass__(cls):
        print(cls)


class SubClass(ABC):
    pass

If you run this with python directly, it gives:

<class '__main__.SubClass'>

But after I compile it with cython, it gives:

TypeError                                 Traceback (most recent call last)
<ipython-input-1-a0954f22e2a4> in <module>
----> 1 import test

test.pyx in init test()

TypeError: __init_subclass__() takes exactly one argument (0 given)

How to solve it?

@scoder scoder changed the title Wrong cythonization for __init_subclass Implement PEP-487 Jan 4, 2019
@scoder scoder added this to the 3.0 milestone Jan 4, 2019
@scoder
Copy link
Contributor

scoder commented Jan 4, 2019

The relevant bits of PEP-487 need to get implemented. Specifically, __init_subclass__() is an implicit class method and must be treated as such, and class creation should call the __init_subclass__() method in older Python versions (before 3.6).

I assume you were using Py3.6 or later for your tests, right?

@fduxiao
Copy link
Author

fduxiao commented Jan 4, 2019

@scoder Yes, and actually with the latest python 3.7.2. I need this feature because metaclass cannot be passed from an ancestor class, so I choose to use __init_subclass__ instead to control the behavior of a class.

@scoder
Copy link
Contributor

scoder commented Jan 4, 2019

PR welcome, seems relatively easy. If you want to give it a try, see the HackerGuide for hints how to get started, and ask on the cython-dev mailing list whenever you feel like needing help.

@scoder scoder changed the title Implement PEP-487 Implement PEP-487: customisation of class creation Jan 18, 2019
scoder added a commit that referenced this issue Apr 22, 2020
@rayzchen
Copy link

rayzchen commented Jul 2, 2021

Python 3.9 error still isn't fixed

@rayzchen
Copy link

rayzchen commented Jul 2, 2021

Test:

# subclass.py
class A:
    def __init_subclass__(cls):
        print(cls)
        return cls

class B(A):
    pass

Run:

cythonize -3 -q -i subclass.py

Python 3.9.4 (tags/v3.9.4:1f2e308, Apr  6 2021, 13:22:44) [MSC v.1928 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import subclass
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "subclass.py", line 5, in init subclass
    class B(A):
TypeError: __init_subclass__() takes exactly one argument (0 given)
$ ls
__pycache__  subclass.c  subclass.cp39-win32.def  subclass.cp39-win32.pyd  subclass.o  sub.py

@da-woods
Copy link
Contributor

da-woods commented Jul 2, 2021

Python 3.9 error still isn't fixed

No. Your example works fine on the current Cython 3 alpha version. You're probably using an older version where this feature isn't supported.

@rayzchen
Copy link

rayzchen commented Jul 2, 2021

I use AppVeyor for building wheels and it uses the latest Cython version (using pip install cython). Is the fix in a release that I need to specify manually?

@da-woods
Copy link
Contributor

da-woods commented Jul 2, 2021

It's in the 3.0 alpha release (since 3.0a2 I think). It isn't (and won't be) in the 0.29.x branch. Since the 3.0 branch is still an alpha branch you probably do need to specify it manually. The alpha branch is pretty usable at this stage and is where most new features are going, so it may be worth your while trying it.

@rayzchen
Copy link

rayzchen commented Jul 2, 2021

How do I install it with pip?

@da-woods
Copy link
Contributor

da-woods commented Jul 2, 2021

How do I install it with pip?

According to https://pypi.org/project/Cython/3.0.0a8/ pip install Cython==3.0.0a8

@rayzchen
Copy link

rayzchen commented Jul 2, 2021

What about just choosing the latest prerelease?

@rayzchen
Copy link

rayzchen commented Jul 2, 2021

Never mind, pip install --pre cython works!

@rayzchen
Copy link

rayzchen commented Jul 4, 2021

I don't know what is going on now, but the error is still there. Here is the build: https://ci.appveyor.com/project/rayzchen/pyunity/build/job/i011xbqufc0tj03o

Lines 39-533 are the main focus. Line 39 installs cython 3.0a8, line 57 creates the cython files (using cythonize -3 -q file.py) and the rest is just creating the bdist. However, when I install the wheel provided (tested on both python 3.9 win32 and win_amd64) and run an example, the error happens when subclassing from pyunity.Behaviour, which defines __init_subclass__. But for some reason, it works randomly on another computer that I have open. I really am too confused right now.

@rayzchen
Copy link

rayzchen commented Jul 4, 2021

I don't really know how I fixed it but its fixed now...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants