Skip to content

Commit 7c93e3f

Browse files
authored
Support out-of-source builds and remove pkg_resources (#77)
1 parent 5d19775 commit 7c93e3f

File tree

6 files changed

+31
-79
lines changed

6 files changed

+31
-79
lines changed

.github/workflows/python-test.yml

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
# This workflow will install Python dependencies and run tests with a variety of Python versions
2-
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
3-
41
name: Test
52

63
on:
@@ -14,12 +11,13 @@ jobs:
1411
build:
1512
runs-on: ${{ matrix.os }}
1613
strategy:
17-
fail-fast: true
14+
fail-fast: false
1815
matrix:
19-
os: [ubuntu-latest, windows-latest]
20-
python-version: ["3.10", "3.11", "3.12", "pypy3.10"]
21-
pytest-version: ["8"]
22-
cython-version: ["0.29", "3"]
16+
os: [ubuntu-latest, windows-latest, macos-latest]
17+
python-version: ["3.11", "3.12", "3.13", "3.14"]
18+
pytest-version: ["9"]
19+
cython-version: ["3"]
20+
editable-install: ["true", "false"]
2321

2422
steps:
2523
- uses: actions/checkout@v6
@@ -38,6 +36,15 @@ jobs:
3836
python -m pip install cython==${{ matrix.cython-version }}.*
3937
python -m pip install -e .
4038
39+
- name: Install example-project (editable)
40+
run: python -m pip install -e tests/example-project
41+
if: ${{ matrix.editable-install == 'true' }}
42+
43+
- name: Install example-project (non-editable)
44+
run: python -m pip install tests/example-project
45+
if: ${{ matrix.editable-install == 'false' }}
46+
4147
- name: Test with pytest
42-
run: |
43-
pytest -vv tests src
48+
env:
49+
PY_IGNORE_IMPORTMISMATCH: "1"
50+
run: pytest -vv tests

src/pytest_cython/__init__.py

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
from importlib.metadata import version, PackageNotFoundError
1+
from importlib.metadata import version
22

3-
try:
4-
__version__ = version("pytest-cython")
5-
except PackageNotFoundError:
6-
import warnings
7-
warnings.warn('could not get pytest-cython version')
8-
__version__ = '0.0.0'
3+
__version__ = version('pytest-cython')
4+
5+
del version

src/pytest_cython/plugin.py

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99

1010
from typing import Any, Iterable, Union
1111

12-
from _pytest.nodes import Collector
13-
from _pytest.doctest import skip, DoctestModule, DoctestItem
12+
from _pytest.doctest import DoctestModule, DoctestItem
1413
from _pytest.pathlib import resolve_package_path, ImportMode
1514

1615

@@ -33,15 +32,11 @@ def pytest_addoption(parser: pytest.Parser):
3332
)
3433

3534

36-
def pytest_collect_file(file_path: pathlib.Path, path, parent: pytest.Collector) -> pytest.Module:
35+
def pytest_collect_file(file_path: pathlib.Path, parent: pytest.Collector) -> pytest.Module:
3736
config = parent.config
3837
if file_path.suffix not in CYTHON_SUFFIXES or not config.getoption('--doctest-cython'):
3938
return
4039

41-
bin_path = file_path.with_suffix(EXT_SUFFIX)
42-
if not bin_path.exists():
43-
return
44-
4540
# only run test if matching .so and .pyx files exist
4641
return _PatchedDoctestModule.from_parent(parent, path=file_path)
4742

@@ -62,15 +57,6 @@ def collect(self) -> Iterable[DoctestItem]:
6257
os.environ[IGNORE_IMPORTMISMATCH_KEY] = IGNORE_IMPORTMISMATCH
6358

6459
module = self.obj # module already imported
65-
66-
try:
67-
_check_module_import(module, self.path, mode)
68-
except Collector.CollectError:
69-
if self.config.getvalue("doctest_ignore_import_errors"):
70-
skip("unable to import module %r" % self.path)
71-
else:
72-
raise
73-
7460
return _add_line_numbers(module, items)
7561

7662

@@ -94,30 +80,6 @@ def _get_module_name(path: pathlib.Path) -> str:
9480
return module_name
9581

9682

97-
def _check_module_import(module: Any, path: pathlib.Path, mode: ImportMode) -> None:
98-
# double check that the only difference is the extension else raise an exception
99-
100-
if mode is ImportMode.importlib or IGNORE_IMPORTMISMATCH == "1":
101-
return
102-
103-
module_name = _get_module_name(path)
104-
module_file = _without_suffixes(module.__file__)
105-
import_file = _without_suffixes(path)
106-
107-
if module_file == import_file:
108-
return
109-
110-
raise Collector.CollectError(
111-
"import file mismatch:\n"
112-
"imported module %r has this __file__ attribute:\n"
113-
" %s\n"
114-
"which is not the same as the test file we want to collect:\n"
115-
" %s\n"
116-
"HINT: remove __pycache__ / .pyc files and/or use a "
117-
"unique basename for your test file modules" % (module_name, module_file, import_file)
118-
)
119-
120-
12183
def _add_line_numbers(module: Any, items: Iterable[DoctestItem]) -> Iterable[DoctestItem]:
12284
# handle tests from Cython's internal __test__ dict generated by
12385
# the autotestdict directive; we exclude the tests from __test__,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[build-system]
2+
requires = ["setuptools>=74.1", "Cython", "wheel"]

tests/example-project/setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
]
2323

2424
setup(
25-
name='pytest-cython',
25+
name='pytest-cython-example',
2626
version='0.3.1',
2727
description="Example Cython project for pytest-cython tests",
2828
package_dir={'': 'src'},

tests/test_pytest_cython.py

Lines changed: 5 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,19 @@
22

33
import pathlib
44
import pytest
5-
import shutil
5+
from pathlib import Path
66

7-
from setuptools.sandbox import run_setup
8-
9-
# import pytest_cython as a quite check to ensure it was installed before running tests
7+
# Check imports to ensure packages are installed before running tests
108
import pytest_cython.plugin
9+
import pypackage
1110

1211

1312
ROOT_PATH = pathlib.Path(__file__).parent
1413
PROJECT_PATH = ROOT_PATH.joinpath('example-project')
1514
PACKAGE_PATH = PROJECT_PATH.joinpath('src', 'pypackage')
1615

17-
IMPORT_MODES = ["append", "prepend", "importlib"]
18-
16+
# TODO: Figure out if importlib can be supported.
17+
IMPORT_MODES = ["append", "prepend"]
1918

2019
def get_module(basename: str, suffix='.pyx') -> pathlib.Path:
2120
return PACKAGE_PATH.joinpath(basename + suffix)
@@ -25,21 +24,6 @@ def run_pytest(pytester: pytest.Pytester, module: pathlib.Path, import_mode) ->
2524
return pytester.runpytest('-vv', '--doctest-cython', '--import-mode', import_mode, str(module))
2625

2726

28-
@pytest.fixture(scope='module', autouse=True)
29-
def build_example_project():
30-
shutil.rmtree(PROJECT_PATH.joinpath('build'), True)
31-
shutil.rmtree(PACKAGE_PATH.joinpath('__pycache__'), True)
32-
33-
for file in PACKAGE_PATH.glob('*.pyd'):
34-
file.unlink()
35-
36-
for file in PACKAGE_PATH.glob('*.c'):
37-
file.unlink()
38-
39-
setup_py = PROJECT_PATH.joinpath('setup.py')
40-
run_setup(str(setup_py), ['build_ext', '--inplace'])
41-
42-
4327
@pytest.mark.parametrize('import_mode', IMPORT_MODES)
4428
def test_cython_ext_module(pytester, import_mode):
4529
module = get_module('cython_ext_module')

0 commit comments

Comments
 (0)