Skip to content

Doesn't work with Cython3 #1

Open
@labeneator

Description

Thank you for the tutorial and the repo. I've verified that the project does work with cython 0.x series but fails on cython3.

$  /tmp/example-cython-poetry-pypi 
 ❯ poetry build -vvv                                                                                                                                                                                                               
Using virtualenv: /Users/lmwangi/Library/Caches/pypoetry/virtualenvs/poetry-pypi-example-wSzIWKA2-py3.9
Building poetry-pypi-example (0.0.1)
  - Building sdist
  - Adding: /private/tmp/example-cython-poetry-pypi/poetry_pypi_example/main.cpython-39-darwin.so
  - Adding: README.rst
  - Adding: pyproject.toml
  - Built poetry-pypi-example-0.0.1.tar.gz
  - Building wheel
  - Executing build script: build.py
[1/1] Cythonizing poetry_pypi_example/main.py
Traceback (most recent call last):
  File "/private/tmp/example-cython-poetry-pypi/build.py", line 80, in <module>
    build()
  File "/private/tmp/example-cython-poetry-pypi/build.py", line 30, in build
    build_ext_cmd.copy_extensions_to_source()
  File "/Users/lmwangi/Library/Caches/pypoetry/virtualenvs/poetry-pypi-example-wSzIWKA2-py3.9/lib/python3.9/site-packages/setuptools/_distutils/cmd.py", line 103, in __getattr__
    raise AttributeError(attr)
AttributeError: copy_extensions_to_source

On drilling down, it looks like the import for build_ext in cython3 does not have ** copy_extensions_to_source**. To be precise in line 14, build_ext is None when it is imported from setuptools. Please see below:

Python 3.9.13 (main, May 24 2022, 21:28:31)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.6.0 -- An enhanced Interactive Python. Type '?' for help.

# Injected an IPython shell just before the setuptools import in Cython/Distutils/build_ext.py
In [1]: _build_ext_module

# Should return the build_ext module. Hmm, we can't get the build_ext module. Let's check the parents.
In [2]:  sys.modules.get('setuptools.command.build_ext')

# We can get the setuptools module
In [3]:  sys.modules.get('setuptools')
Out[3]: <module 'setuptools' from '/Users/lmwangi/Library/Caches/pypoetry/virtualenvs/wallet-api-ZqjMZXwH-py3.9/lib/python3.9/site-packages/setuptools/__init__.py'>


# We can get the setuptools.command module
In [5]:  sys.modules.get('setuptools.command')
Out[5]: <module 'setuptools.command' from '/Users/lmwangi/Library/Caches/pypoetry/virtualenvs/wallet-api-ZqjMZXwH-py3.9/lib/python3.9/site-packages/setuptools/command/__init__.py'>

# On the filesystem, the module does exist.
In [6]: !ls /Users/lmwangi/Library/Caches/pypoetry/virtualenvs/wallet-api-ZqjMZXwH-py3.9/lib/python3.9/site-packages/setuptools/command
 __init__.py   alias.py       bdist_rpm.py    build_ext.py   develop.py     easy_install.py   install.py	    install_lib.py	'launcher manifest.xml'   register.py   saveopts.py   setopt.py   upload.py
 __pycache__   bdist_egg.py   build_clib.py   build_py.py    dist_info.py   egg_info.py       install_egg_info.py   install_scripts.py	 py36compat.py		  rotate.py     sdist.py      test.py	  upload_docs.py


# Hmm, import does work
In [8]: import setuptools.command.build_ext

# Now a get works....
In [9]:  sys.modules.get('setuptools.command.build_ext')
Out[9]: <module 'setuptools.command.build_ext' from '/Users/lmwangi/Library/Caches/pypoetry/virtualenvs/wallet-api-ZqjMZXwH-py3.9/lib/python3.9/site-packages/setuptools/command/build_ext.py'>

Digging further, it looks like this is the [breaking commit](https://github.com/cython/cython/commit/c6f5c5ddcc021099febae7cb1194fedea01fd056).

< # Always inherit from the "build_ext" in distutils since setuptools already imports
< # it from Cython if available, and does the proper distutils fallback otherwise.
< # https://github.com/pypa/setuptools/blob/9f1822ee910df3df930a98ab99f66d18bb70659b/setuptools/command/build_ext.py#L16
<
< # setuptools imports Cython's "build_ext", so make sure we go first.
< _build_ext_module = sys.modules.get('setuptools.command.build_ext')
< if _build_ext_module is None:
<     import distutils.command.build_ext as _build_ext_module
<
< # setuptools remembers the original distutils "build_ext" as "_du_build_ext"
< _build_ext = getattr(_build_ext_module, '_du_build_ext', None)
< if _build_ext is None:
<     _build_ext = getattr(_build_ext_module, 'build_ext', None)
< if _build_ext is None:
---
> if 'setuptools' in sys.modules:
>     try:
>         from setuptools.command.build_ext import build_ext as _build_ext
>     except ImportError:
>         # We may be in the process of importing setuptools, which tries
>         # to import this.
>         from distutils.command.build_ext import build_ext as _build_ext

If we revert the import in Cython/Distutils/build_ext.py with the one in cython 0.x, the build now works

 ❯  head -17 /Users/lmwangi/Library/Caches/pypoetry/virtualenvs/poetry-pypi-example-wSzIWKA2-py3.9/lib/python3.9/site-packages/Cython/Distutils/build_ext.py 
import sys
import os


import sys

if 'setuptools' in sys.modules:
    try:
        from setuptools.command.build_ext import build_ext as _build_ext
    except ImportError:
        # We may be in the process of importing setuptools, which tries
        # to import this.
        from distutils.command.build_ext import build_ext as _build_ext
else:
    from distutils.command.build_ext import build_ext as _build_ext


 ❯ poetry run Cython -V 
Cython version 3.0.0a10

  ❯ poetry build  
Building poetry-pypi-example (0.0.1)
  - Building sdist
  - Built poetry-pypi-example-0.0.1.tar.gz
  - Building wheel
[1/1] Cythonizing poetry_pypi_example/main.py
  - Built poetry_pypi_example-0.0.1-cp39-cp39-macosx_12_0_x86_64.whl

Activity

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

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions