API: Test Support¶
test_support
¶
This package includes helper code that is only used for testing setuptools-pyproject-migration
itself. The code is made available when testing by a
pytest configuration option
that extends sys.path
.
- class test_support.Project(root: Path)¶
Bases:
object
A Python project on which
setup.py pyproject
can be run. Test code should not normally construct instances ofProject()
directly; instead, they can get one through a fixture or some helper function.Once you have the
Project
object, create any files you need underneath the root by callingwrite()
or one of its convenience wrappers likesetup_py()
orsetup_cfg()
. If you need to do anything other than creating files or if there is some reason not to use thewrite()
method, you can work directly onroot
, but don’t change anything outside ofroot
. Finally, when all necessary files have been created, call one ofrun()
,run_cli()
, orgenerate()
to runsetup.py pyproject
(or an equivalent) on the project.- Parameters:
root – The root directory in which to create the project. It should already exist. Typically this might be a temporary directory created by pytest’s
tmp_path
fixture.
- generate() Pyproject ¶
Run the equivalent of
setup.py pyproject
but return the generated data structure that would go into pyproject.toml instead of writing it out.
- run(runner: ProjectRunner) ProjectRunResult ¶
Run
setup.py pyproject
on the created project and return the output.If the project doesn’t already have a
setup.py
file, a simple one will be automatically created by callingsetup_py()
with no arguments before running it.- Parameters:
runner – The callable to use to run the script
- run_cli(runner: ProjectRunner) ProjectRunResult ¶
Run the console script
setuptools-pyproject-migration
on the created project and return the output.In contrast to
run()
, ifsetup.py
doesn’t exist, it will not be created, because the script is supposed to work without it. If you want to test the script’s behavior with asetup.py
file, create it “manually” with a call tosetup_py()
.- Parameters:
runner – The callable to use to run the script
- setup_cfg(content: str) None ¶
Write a
setup.cfg
file in the project root directory.- Parameters:
content – Text content to write to the file.
- setup_py(content: str | None = None) None ¶
Write a
setup.py
file in the project root directory.- Parameters:
content – Text content to write to the file.
- write(filename: Path | str, content: str) None ¶
Write a file with the given content and the given filename relative to the project root. If the file already exists, it will be overwritten after issuing a warning.
- Parameters:
filename – A filename or
pathlib.Path
representing the file to write. This should be a relative path, which will be interpreted relative to the project root directory. If the referenced file is not inside the project root, a warning will be issued.content – Text content to write to the file.
- class test_support.ProjectRunner(*args, **kwargs)¶
Bases:
Protocol
A runner for an external command. This is basically an abstraction of
ScriptRunner.run()
from pytest-console-scripts, or at least the subset of its behavior which we use in this project.
test_support.distribution
¶
Support code for distribution package testing.
“Distribution package” means the same thing here that it does in
importlib-metadata:
basically a Python project that can be installed with pip
or a compatible
tool. Most distribution packages, of course, come from PyPI,
but it’s also possible to use raw source code as a distribution package. Since
this plugin only works on projects that use setuptools (and have not been
converted to take setuptools configuration from pyproject.toml
), we only
test with distribution packages that have setup.py
or setup.cfg
in their
source code.
- class test_support.distribution.DistributionPackage¶
Bases:
ABC
A “distribution package” in the sense used in importlib_metadata.
Basically, this is a Python project that can be installed with
pip
or a compatible tool, and that has asetup.py
orsetup.cfg
file.- abstract prepare(path: Path) DistributionPackagePreparation ¶
Populate a directory with the package’s source code. This might involve checking out a repository, extracting an archive, or something else, depending on the type of project.
This method will be given an empty, writable directory. It should put the distribution package’s source code somewhere inside that directory and return the path in which setuptools-pyproject-migration should be run, i.e. the parent directory of
setup.py
orsetup.cfg
(unless the distribution package does something extremely weird that involves a custom path to setuptools config files).- Parameters:
path – An empty, writable directory in which the package’s source code should be placed. Implementations can also use parts of this directory as temporary storage; everything put in here will be ignored except for the path returned.
- Returns:
The root directory of the package, which contains
setup.py
orsetup.cfg
. This may bepath
or a subdirectory ofpath
depending on how the source code is prepared.
- class test_support.distribution.DistributionPackagePreparation(make_importable: bool = False)¶
Bases:
object
A distribution package that has been prepared for testing. “Prepared” means the source code is downloaded/extracted/checked out/whatever in a local directory, in a state that allows setuptools-pyproject-migration to run on it to generate a
pyproject.toml
file.- Parameters:
make_importable – When running setuptools-pyproject-migration on the code of the distribution package, the code is in a “raw” form that may not be usable, since many distribution packages require a build step to go from their raw code to something that can be imported. So, in accordance with standard packaging conventions, by default we don’t make the distribution package’s own code available for import when running its
setup.py
. But some projects (that don’t have build steps) expect their own code to be importable straight from the filesystem when running theirsetup.py
file. This flag can be set toTrue
to make that happen during testing.
- abstract property core_metadata_reference: StandardMetadata¶
Return the known correct core metadata for the distribution package. Typically this comes from the package’s wheel, if a wheel is available.
- Returns:
The known correct core metadata for the distribution package
- abstract property project: Project¶
Return the
test_support.Project
instance which can be used to compute the metadata from the prepared source code.
- class test_support.distribution.HashChecker(algorithm: str, expected_hash: str)¶
Bases:
object
- check(data)¶
- class test_support.distribution.PackageInfo(package_url: str, package_hash_spec: str, metadata_hash_spec: str | None)¶
Bases:
object
- class test_support.distribution.PackageType(value, names=None, *values, module=None, qualname=None, type=None, start=1, boundary=None)¶
Bases:
Enum
- SDIST = 'sdist'¶
- WHEEL = 'bdist_wheel'¶
- class test_support.distribution.PyPiDistribution(name: str, version: str, *, project_root: Path | None = None, make_importable: bool = False)¶
Bases:
DistributionPackage
A distribution package obtained from PyPI.
- Parameters:
name – The name of the project as registered on PyPI, i.e. the name in the project’s URL:
https://pypi.org/project/<name>
version – The version string of the project as registered on PyPI
project_root – The relative path within the project’s sdist to the directory containing
setup.py
orsetup.cfg
. If omitted, this defaults to<name>-<version>
with<name>
normalized in the manner specified by the sdist specification. Because the spec was designed to match what the vast majority of build tools actually produce in sdist files, it should be extremely rare to have to specify a custom project root.make_importable – When running setuptools-pyproject-migration on the code of the distribution package, the code is in a “raw” form that may not be usable, since many distribution packages require a build step to go from their raw code to something that can be imported. So, in accordance with standard packaging conventions, by default we don’t make the distribution package’s own code available for import when running its
setup.py
. But some projects (that don’t have build steps) expect their own code to be importable straight from the filesystem when running theirsetup.py
file. This flag can be set toTrue
to make that happen during testing.
- prepare(path: Path) DistributionPackagePreparation ¶
Populate a directory with the package’s source code. This involves downloading the sdist and extracting it.
- class test_support.distribution.PyPiPackagePreparation(distribution: PyPiDistribution, path: Path)¶
Bases:
DistributionPackagePreparation
- Parameters:
distribution_package – The distribution package to prepare
path – A temporary directory to use in preparing the distribution package. Typically this would be provided by pytest’s
tmp_path
fixture.
- property core_metadata_reference: StandardMetadata¶
Return the known correct core metadata for the distribution package. Typically this comes from the package’s wheel, if a wheel is available.
- Returns:
The known correct core metadata for the distribution package
- property project: Project¶
Return the
test_support.Project
instance which can be used to compute the metadata from the prepared source code.
- class test_support.distribution.SimplePackageListingParser(name: str, version: str)¶
Bases:
HTMLParser
A bare-bones parser for the list of versions of a given package offered by the simple repository API. It will select releases of the given version of the package.