Skip to content

TST: adding marker and stricter warning checks #214

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

Merged
merged 4 commits into from
Nov 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,20 @@ strict = true
lines_between_types = 1
lines_after_imports = 2
multi_line_output = 5
known_first_party = "mesonpy"
known_first_party = 'mesonpy'


[tool.coverage.html]
show_contexts = true


[tool.pytest.ini_options]
minversion = "6.0"
addopts = ["-ra", "--strict-markers", "--strict-config"]
log_cli_level = "info"
norecursedirs = "tests/packages/*"
testpaths = ["tests"]
minversion = '6.0'
addopts = ['-ra', '--strict-markers', '--strict-config']
log_cli_level = 'info'
norecursedirs = 'tests/packages/*'
testpaths = ['tests']
xfail_strict = true
filterwarnings = [
'error',
]
25 changes: 15 additions & 10 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import subprocess
import sys
import tempfile
import warnings

from venv import EnvBuilder

Expand Down Expand Up @@ -61,17 +62,22 @@ def in_git_repo_context(path=os.path.curdir):


@pytest.fixture(scope='session')
def tmp_dir_session(tmpdir_factory):
def tmp_path_session(tmp_path_factory):
return pathlib.Path(tempfile.mkdtemp(
prefix='mesonpy-test-',
dir=tmpdir_factory.mktemp('test'),
dir=tmp_path_factory.mktemp('test'),
))


class VEnv(EnvBuilder):
def __init__(self, env_dir):
super().__init__(with_pip=True)
self.create(env_dir)
# This warning is mistakenly generated by CPython 3.11.0
# https://github.com/python/cpython/pull/98743
with warnings.catch_warnings():
if sys.version_info[:3] == (3, 11, 0):
warnings.filterwarnings('ignore', 'check_home argument is deprecated and ignored.', DeprecationWarning)
self.create(env_dir)

def ensure_directories(self, env_dir):
context = super().ensure_directories(env_dir)
Expand Down Expand Up @@ -101,17 +107,17 @@ def fixture():

def generate_sdist_fixture(package):
@pytest.fixture(scope='session')
def fixture(tmp_dir_session):
def fixture(tmp_path_session):
with cd_package(package), in_git_repo_context():
return tmp_dir_session / mesonpy.build_sdist(tmp_dir_session)
return tmp_path_session / mesonpy.build_sdist(tmp_path_session)
return fixture


def generate_wheel_fixture(package):
@pytest.fixture(scope='session')
def fixture(tmp_dir_session):
def fixture(tmp_path_session):
with cd_package(package), in_git_repo_context():
return tmp_dir_session / mesonpy.build_wheel(tmp_dir_session)
return tmp_path_session / mesonpy.build_wheel(tmp_path_session)
return fixture


Expand All @@ -132,8 +138,8 @@ def disable_pip_version_check():


@pytest.fixture(scope='session')
def pep518_wheelhouse(tmpdir_factory):
wheelhouse = tmpdir_factory.mktemp('wheelhouse')
def pep518_wheelhouse(tmp_path_factory):
wheelhouse = tmp_path_factory.mktemp('wheelhouse')
meson_python = str(package_dir.parent.parent)
# Populate wheelhouse with wheel for the following packages and
# their dependencies. Wheels are downloaded from PyPI or built
Expand All @@ -150,4 +156,3 @@ def pep518_wheelhouse(tmpdir_factory):
def pep518(pep518_wheelhouse, monkeypatch):
monkeypatch.setenv('PIP_FIND_LINKS', pep518_wheelhouse)
monkeypatch.setenv('PIP_NO_INDEX', 'true')
return pep518_wheelhouse
6 changes: 3 additions & 3 deletions tests/docs/examples/test_spam.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@
from .conftest import build_project_wheel, examples_dir


def test_build_and_import(venv, tmp_dir_session):
def test_build_and_import(venv, tmp_path_session):
"""Test that the wheel for the spam example builds, installs, and imports."""

if sys.version_info < (3, 8):
# The test project requires Python >= 3.8.
with pytest.raises(mesonpy.MesonBuilderError, match=r'Unsupported Python version `3.7.\d+`'):
build_project_wheel(package=examples_dir / 'spam', outdir=tmp_dir_session)
build_project_wheel(package=examples_dir / 'spam', outdir=tmp_path_session)

else:
wheel = build_project_wheel(package=examples_dir / 'spam', outdir=tmp_dir_session)
wheel = build_project_wheel(package=examples_dir / 'spam', outdir=tmp_path_session)

subprocess.run(
[venv.executable, '-m', 'pip', 'install', wheel],
Expand Down
15 changes: 9 additions & 6 deletions tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@


def test_no_pep621(sdist_library):
sdist = tarfile.open(sdist_library, 'r:gz')
with tarfile.open(sdist_library, 'r:gz') as sdist:
sdist_pkg_info = sdist.extractfile('library-1.0.0/PKG-INFO').read().decode()

assert sdist.extractfile('library-1.0.0/PKG-INFO').read().decode() == textwrap.dedent('''
assert sdist_pkg_info == textwrap.dedent('''
Metadata-Version: 2.1
Name: library
Version: 1.0.0
''').strip()


def test_pep621(sdist_full_metadata):
sdist = tarfile.open(sdist_full_metadata, 'r:gz')
with tarfile.open(sdist_full_metadata, 'r:gz') as sdist:
sdist_pkg_info = sdist.extractfile('full_metadata-1.2.3/PKG-INFO').read().decode()

assert sdist.extractfile('full_metadata-1.2.3/PKG-INFO').read().decode() == textwrap.dedent('''\
assert sdist_pkg_info == textwrap.dedent('''\
Metadata-Version: 2.1
Name: full-metadata
Version: 1.2.3
Expand Down Expand Up @@ -50,9 +52,10 @@ def test_pep621(sdist_full_metadata):


def test_dynamic_version(sdist_dynamic_version):
sdist = tarfile.open(sdist_dynamic_version, 'r:gz')
with tarfile.open(sdist_dynamic_version, 'r:gz') as sdist:
sdist_pkg_info = sdist.extractfile('dynamic_version-1.0.0/PKG-INFO').read().decode().strip()

assert sdist.extractfile('dynamic_version-1.0.0/PKG-INFO').read().decode().strip() == textwrap.dedent('''
assert sdist_pkg_info == textwrap.dedent('''
Metadata-Version: 2.1
Name: dynamic-version
Version: 1.0.0
Expand Down
6 changes: 3 additions & 3 deletions tests/test_pep517.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,10 @@ def run(cmd: List[str], *args: object, **kwargs: object) -> subprocess.Completed
assert set(mesonpy.get_requires_for_build_wheel()) == expected


def test_invalid_config_settings(package_pure, tmp_dir_session):
def test_invalid_config_settings(package_pure, tmp_path_session):
raises_error = pytest.raises(mesonpy.ConfigError, match='Unknown config setting: invalid')

with raises_error:
mesonpy.build_sdist(tmp_dir_session, {'invalid': ()})
mesonpy.build_sdist(tmp_path_session, {'invalid': ()})
with raises_error:
mesonpy.build_wheel(tmp_dir_session, {'invalid': ()})
mesonpy.build_wheel(tmp_path_session, {'invalid': ()})
3 changes: 2 additions & 1 deletion tests/test_pep518.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .conftest import cd_package, in_git_repo_context


@pytest.mark.usefixtures('pep518')
@pytest.mark.parametrize(
('package'),
[
Expand All @@ -15,7 +16,7 @@
@pytest.mark.parametrize(
'build_arg', ['', '--wheel'], ids=['sdist_to_wheel', 'wheel_directly']
)
def test_pep518(pep518, package, build_arg, tmp_path):
def test_pep518(package, build_arg, tmp_path):
dist = tmp_path / 'dist'

with cd_package(package), in_git_repo_context():
Expand Down
12 changes: 6 additions & 6 deletions tests/test_project.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def test_unsupported_python_version(package_unsupported_python_version):
sys.version_info < (3, 8),
reason="unittest.mock doesn't support the required APIs for this test",
)
def test_user_args(package_user_args, mocker, tmp_dir_session):
def test_user_args(package_user_args, mocker, tmp_path_session):
mocker.patch('mesonpy.Project._meson')

def last_two_meson_args():
Expand All @@ -64,7 +64,7 @@ def last_two_meson_args():
]

# create the build directory ourselves because Project._meson is mocked
builddir = str(tmp_dir_session / 'build')
builddir = str(tmp_path_session / 'build')
subprocess.run(['meson', 'setup', '.', builddir], check=True)

config_settings = {
Expand All @@ -76,9 +76,9 @@ def last_two_meson_args():
}

with contextlib.suppress(Exception):
mesonpy.build_sdist(tmp_dir_session / 'dist', config_settings)
mesonpy.build_sdist(tmp_path_session / 'dist', config_settings)
with contextlib.suppress(Exception):
mesonpy.build_wheel(tmp_dir_session / 'dist', config_settings)
mesonpy.build_wheel(tmp_path_session / 'dist', config_settings)

assert last_two_meson_args() == [
# sdist
Expand All @@ -92,6 +92,6 @@ def last_two_meson_args():


@pytest.mark.parametrize('package', ('top-level', 'meson-args'))
def test_unknown_user_args(package, tmp_dir_session):
def test_unknown_user_args(package, tmp_path_session):
with pytest.raises(mesonpy.ConfigError):
mesonpy.Project(package_dir / f'unknown-user-args-{package}', tmp_dir_session)
mesonpy.Project(package_dir / f'unknown-user-args-{package}', tmp_path_session)
33 changes: 18 additions & 15 deletions tests/test_sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@


def test_contents(sdist_library):
sdist = tarfile.open(sdist_library, 'r:gz')
with tarfile.open(sdist_library, 'r:gz') as sdist:
names = set(sdist.getnames())

assert set(sdist.getnames()) == {
assert names == {
'library-1.0.0/example.c',
'library-1.0.0/examplelib.c',
'library-1.0.0/examplelib.h',
Expand All @@ -27,9 +28,10 @@ def test_contents(sdist_library):


def test_contents_subdirs(sdist_subdirs):
sdist = tarfile.open(sdist_subdirs, 'r:gz')
with tarfile.open(sdist_subdirs, 'r:gz') as sdist:
names = set(sdist.getnames())

assert set(sdist.getnames()) == {
assert names == {
'subdirs-1.0.0/PKG-INFO',
'subdirs-1.0.0/meson.build',
'subdirs-1.0.0/pyproject.toml',
Expand All @@ -40,7 +42,7 @@ def test_contents_subdirs(sdist_subdirs):
}


def test_contents_unstaged(package_pure, tmpdir):
def test_contents_unstaged(package_pure, tmp_path):
new_data = textwrap.dedent('''
def bar():
return 'foo'
Expand All @@ -54,28 +56,27 @@ def bar():
with open('pure.py', 'w') as f, open('crap', 'x'):
f.write(new_data)

sdist_path = mesonpy.build_sdist(os.fspath(tmpdir))
sdist_path = mesonpy.build_sdist(os.fspath(tmp_path))
finally:
with open('pure.py', 'w') as f:
f.write(old_data)
os.unlink('crap')

sdist = tarfile.open(tmpdir / sdist_path, 'r:gz')
with tarfile.open(tmp_path / sdist_path, 'r:gz') as sdist:
names = set(sdist.getnames())
read_data = sdist.extractfile('pure-1.0.0/pure.py').read().replace(b'\r\n', b'\n')

assert set(sdist.getnames()) == {
assert names == {
'pure-1.0.0/PKG-INFO',
'pure-1.0.0/meson.build',
'pure-1.0.0/pure.py',
'pure-1.0.0/pyproject.toml',
}
read_data = sdist.extractfile('pure-1.0.0/pure.py').read().replace(b'\r\n', b'\n')
assert read_data == new_data.encode()


@pytest.mark.skipif(sys.platform in {'win32', 'cygwin'}, reason='Platform does not support executable bit')
def test_executable_bit(sdist_executable_bit):
sdist = tarfile.open(sdist_executable_bit, 'r:gz')

expected = {
'executable_bit-1.0.0/PKG-INFO': False,
'executable_bit-1.0.0/example-script.py': True,
Expand All @@ -84,12 +85,13 @@ def test_executable_bit(sdist_executable_bit):
'executable_bit-1.0.0/meson.build': False,
'executable_bit-1.0.0/pyproject.toml': False,
}
for member in sdist.getmembers():
assert bool(member.mode & stat.S_IXUSR) == expected[member.name]

with tarfile.open(sdist_executable_bit, 'r:gz') as sdist:
for member in sdist.getmembers():
assert bool(member.mode & stat.S_IXUSR) == expected[member.name]


def test_generated_files(sdist_generated_files):
sdist = tarfile.open(sdist_generated_files, 'r:gz')
expected = {
'executable_bit-1.0.0/PKG-INFO',
'executable_bit-1.0.0/example-script.py',
Expand All @@ -100,4 +102,5 @@ def test_generated_files(sdist_generated_files):
'executable_bit-1.0.0/_version_meson.py',
'executable_bit-1.0.0/generate_version.py',
}
assert set(tar.name for tar in sdist.getmembers()) == expected
with tarfile.open(sdist_generated_files, 'r:gz') as sdist:
assert set(tar.name for tar in sdist.getmembers()) == expected
12 changes: 6 additions & 6 deletions tests/test_wheel.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,20 +188,20 @@ def test_detect_wheel_tag_script(wheel_executable):


@pytest.mark.skipif(platform.system() != 'Linux', reason='Unsupported on this platform for now')
def test_rpath(wheel_link_against_local_lib, tmpdir):
def test_rpath(wheel_link_against_local_lib, tmp_path):
artifact = wheel.wheelfile.WheelFile(wheel_link_against_local_lib)
artifact.extractall(tmpdir)
artifact.extractall(tmp_path)

elf = mesonpy._elf.ELF(tmpdir / f'example{EXT_SUFFIX}')
elf = mesonpy._elf.ELF(tmp_path / f'example{EXT_SUFFIX}')
assert '$ORIGIN/.link_against_local_lib.mesonpy.libs' in elf.rpath


@pytest.mark.skipif(platform.system() != 'Linux', reason='Unsupported on this platform for now')
def test_uneeded_rpath(wheel_purelib_and_platlib, tmpdir):
def test_uneeded_rpath(wheel_purelib_and_platlib, tmp_path):
artifact = wheel.wheelfile.WheelFile(wheel_purelib_and_platlib)
artifact.extractall(tmpdir)
artifact.extractall(tmp_path)

elf = mesonpy._elf.ELF(tmpdir / f'plat{EXT_SUFFIX}')
elf = mesonpy._elf.ELF(tmp_path / f'plat{EXT_SUFFIX}')
if elf.rpath:
# elf.rpath is a frozenset, so iterate over it. An rpath may be
# present, e.g. when conda is used (rpath will be <conda-prefix>/lib/)
Expand Down
13 changes: 8 additions & 5 deletions tests/test_wheelfile.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import contextlib
import time

import wheel.wheelfile
Expand All @@ -8,16 +9,18 @@
def test_basic(tmp_path):
path = tmp_path / 'test-1.0-py3-any-none.whl'
bar = tmp_path / 'bar'
open(bar, 'wb').write(b'bar')
bar.write_bytes(b'bar')
with mesonpy._wheelfile.WheelFile(path, 'w') as w:
assert w.name == 'test'
assert w.version == '1.0'
w.writestr('foo', b'test')
w.write(bar, 'bar')
with wheel.wheelfile.WheelFile(path, 'r') as w:
with contextlib.closing(wheel.wheelfile.WheelFile(path, 'r')) as w:
assert set(w.namelist()) == {'foo', 'bar', 'test-1.0.dist-info/RECORD'}
w.open('foo').read() == b'test'
w.open('bar').read() == b'bar'
with w.open('foo') as foo:
assert foo.read() == b'test'
with w.open('bar') as bar:
assert bar.read() == b'bar'


def test_source_date_epoch(tmp_path, monkeypatch):
Expand All @@ -27,7 +30,7 @@ def test_source_date_epoch(tmp_path, monkeypatch):
assert epoch % 2 == 0
monkeypatch.setenv('SOURCE_DATE_EPOCH', str(epoch))
bar = tmp_path / 'bar'
open(bar, 'wb').write(b'bar')
bar.write_bytes(b'bar')
with mesonpy._wheelfile.WheelFile(path, 'w') as w:
w.writestr('foo', b'test')
w.write(bar, 'bar')
Expand Down