pycommons.dev.building package

Tools for building python projects.

Submodules

pycommons.dev.building.build_info module

The project build information.

class pycommons.dev.building.build_info.BuildInfo(base_dir, package_name, tests_dir=None, examples_dir=None, doc_source_dir=None, doc_dest_dir=None, dist_dir=None, timeout=3600)[source]

Bases: object

A class that represents information about building a project.

>>> b = BuildInfo(Path(__file__).up(4), "pycommons", "tests", "examples",
...         "docs/source", "docs/build", "dist")
>>> b.base_dir == Path(__file__).up(4)
True
>>> b.package_name
'pycommons'
>>> b.sources_dir.endswith('pycommons')
True
>>> b.examples_dir.endswith('examples')
True
>>> b.tests_dir.endswith('tests')
True
>>> b.doc_source_dir.endswith('source')
True
>>> b.doc_dest_dir.endswith('build')
True
>>> b.dist_dir.endswith('dist')
True
>>> try:
...     BuildInfo(None, "pycommons")
... except TypeError as te:
...     print(te)
descriptor '__len__' requires a 'str' object but received a 'NoneType'
>>> try:
...     BuildInfo(1, "pycommons")
... except TypeError as te:
...     print(te)
descriptor '__len__' requires a 'str' object but received a 'int'
>>> try:
...     BuildInfo(Path(__file__).up(4), None)
... except TypeError as te:
...     print(te)
descriptor 'strip' for 'str' objects doesn't apply to a 'NoneType' object
>>> try:
...     BuildInfo(Path(__file__).up(4), 1)
... except TypeError as te:
...     print(te)
descriptor 'strip' for 'str' objects doesn't apply to a 'int' object
>>> try:
...     BuildInfo(Path(__file__).up(4), "")
... except ValueError as ve:
...     print(ve)
Relative path must not be empty.
>>> try:
...     BuildInfo(Path(__file__).up(4), ".")
... except ValueError as ve:
...     print(str(ve)[:32])
Inconsistent directories ['.', '
>>> try:
...     BuildInfo(Path(__file__).up(4), "..")
... except ValueError as ve:
...     print("does not contain" in str(ve))
True
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", 1)
... except TypeError as te:
...     print(te)
descriptor 'strip' for 'str' objects doesn't apply to a 'int' object
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", "..")
... except ValueError as ve:
...     print("does not contain" in str(ve))
True
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", ".")
... except ValueError as ve:
...     print(str(ve)[:27])
Inconsistent directories ['
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", None, 1)
... except TypeError as te:
...     print(te)
descriptor 'strip' for 'str' objects doesn't apply to a 'int' object
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", None, "..")
... except ValueError as ve:
...     print("does not contain" in str(ve))
True
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", None, ".")
... except ValueError as ve:
...     print(str(ve)[:27])
Inconsistent directories ['
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", doc_source_dir=1)
... except TypeError as te:
...     print(te)
descriptor 'strip' for 'str' objects doesn't apply to a 'int' object
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", doc_dest_dir=1)
... except TypeError as te:
...     print(te)
descriptor 'strip' for 'str' objects doesn't apply to a 'int' object
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons", dist_dir=1)
... except TypeError as te:
...     print(te)
descriptor 'strip' for 'str' objects doesn't apply to a 'int' object
>>> try:
...     BuildInfo(Path(__file__).up(4), "pycommons",
...          doc_source_dir="docs", doc_dest_dir="docs/build")
... except ValueError as ve:
...     print(str(ve)[:20])
Nested directories '
base_dir: Path

the path to the project base directory

command(args)[source]

Create a typical build step command.

This command will receive an environment with all the Python-related environment variables that were also passed to the current process. This includes the Path, the Python interpreter’s name, as well as information about the virtual environment, if any. This is necessary if we use build tools that were installed in this virtual environment.

Parameters:
  • args (Iterable[str]) – the arguments of the command

  • env – the environment to be used with this command

Return type:

Command

>>> b = BuildInfo(Path(__file__).up(4), "pycommons")
>>> cmd = b.command(("cat", "README.txt"))
>>> cmd.working_dir == b.base_dir
True
>>> cmd.command
('cat', 'README.txt')
>>> cmd.timeout
3600
>>> cmd.stderr == STREAM_FORWARD
True
>>> cmd.stdout == STREAM_FORWARD
True
>>> cmd.timeout
3600
dist_dir: Path | None

the directory where the distribution files should be located

doc_dest_dir: Path | None

the destination directory for documentation

doc_source_dir: Path | None

the source directory for documentation

examples_dir: Path | None

the path to the examples directory, if any

package_name: str

the name of the project / package

sources_dir: Path

the path to the directory with the package sources

tests_dir: Path | None

the path to the tests directory, if any

timeout: int

the standard timeout

pycommons.dev.building.build_info.parse_project_arguments(parser, args=None)[source]

Load project information arguments from the command line.

Parameters:
Return type:

BuildInfo

>>> from pycommons.io.arguments import pycommons_argparser
>>> ap = pycommons_argparser(__file__, "a test program",
...     "An argument parser for testing this function.")
>>> ee = parse_project_arguments(ap, ["--root", Path(__file__).up(4),
...                              "--package", "pycommons"])
>>> ee.package_name
'pycommons'
>>> ee.sources_dir.endswith("pycommons")
True
>>> ee.dist_dir.endswith("dist")
True
>>> ee.doc_source_dir.endswith("docs/source")
True
>>> ee.doc_dest_dir.endswith("docs/build")
True
>>> ee.examples_dir.endswith("examples")
True
>>> ee.tests_dir.endswith("tests")
True
>>> try:
...     parse_project_arguments(None)
... except TypeError as te:
...     print(te)
parser should be an instance of argparse.ArgumentParser but is None.
>>> try:
...     parse_project_arguments(1)
... except TypeError as te:
...     print(str(te)[:40])
parser should be an instance of argparse
pycommons.dev.building.build_info.replace_in_cmd(orig, replace_with, replace_what='.')[source]

Replace the occurrences of replace_what with replace_with.

Parameters:
  • orig (Iterable[str]) – the original sequence

  • replace_with (str) – the string it is to be replace with

  • replace_what (str, default: '.') – the string to be replaced

Return type:

Iterable[str]

Returns:

the replaced sequence

>>> replace_in_cmd(('x', '.', 'y'), 'a', '.')
['x', 'a', 'y']
>>> replace_in_cmd(('x', '.', 'y'), 'a')
['x', 'a', 'y']
>>> try:
...     replace_in_cmd(None, 'a', '.')
... except TypeError as te:
...     print(te)
orig should be an instance of typing.Iterable but is None.
>>> try:
...     replace_in_cmd(1, 'a', '.')
... except TypeError as te:
...     print(te)
orig should be an instance of typing.Iterable but is int, namely 1.
>>> try:
...     replace_in_cmd([], 'a', '.')
... except ValueError as ve:
...     print(ve)
Did not find '.'.
>>> try:
...     replace_in_cmd(['x'], 'a', '.')
... except ValueError as ve:
...     print(ve)
Did not find '.'.
>>> try:
...     replace_in_cmd(['x'], 'a')
... except ValueError as ve:
...     print(ve)
Did not find '.'.
>>> try:
...     replace_in_cmd(['x'], None, '.')
... except TypeError as te:
...     print(te)
descriptor '__len__' requires a 'str' object but received a 'NoneType'
>>> try:
...     replace_in_cmd(['x'], 1, '.')
... except TypeError as te:
...     print(te)
descriptor '__len__' requires a 'str' object but received a 'int'
>>> try:
...     replace_in_cmd(['x'], '', '.')
... except ValueError as ve:
...     print(ve)
Invalid replace_with ''.
>>> try:
...     replace_in_cmd(['x'], 'y', None)
... except TypeError as te:
...     print(te)
descriptor '__len__' requires a 'str' object but received a 'NoneType'
>>> try:
...     replace_in_cmd(['x'], 'y', 1)
... except TypeError as te:
...     print(te)
descriptor '__len__' requires a 'str' object but received a 'int'
>>> try:
...     replace_in_cmd(['x'], 'x', '')
... except ValueError as ve:
...     print(ve)
Invalid replace_what ''.

pycommons.dev.building.make_dist module

Make the distribution.

pycommons.dev.building.make_dist.make_dist(info)[source]

Create the distribution files.

This code cannot really be unit tested, as it would run the itself recursively.

Parameters:

info (BuildInfo) – the build information

Return type:

None

>>> root = Path(__file__).up(4)
>>> bf = BuildInfo(root, "pycommons",
...     examples_dir=root.resolve_inside("examples"),
...     tests_dir=root.resolve_inside("tests"),
...     dist_dir=root.resolve_inside("dist"),
...     doc_source_dir=root.resolve_inside("docs/source"),
...     doc_dest_dir=root.resolve_inside("docs/build"))
>>> from contextlib import redirect_stdout
>>> with redirect_stdout(None):
...     make_dist(bf)
>>> try:
...     make_dist(None)
... except TypeError as te:
...     print(str(te)[:50])
info should be an instance of pycommons.dev.buildi
>>> try:
...     make_dist(1)
... except TypeError as te:
...     print(str(te)[:50])
info should be an instance of pycommons.dev.buildi

pycommons.dev.building.make_documentation module

Create the documentation.

pycommons.dev.building.make_documentation.make_documentation(info)[source]

Make the documentation of the project.

Parameters:

info (BuildInfo) – the build information

Return type:

None

>>> root = Path(__file__).up(4)
>>> bf = BuildInfo(root, "pycommons",
...     examples_dir=root.resolve_inside("examples"),
...     tests_dir=root.resolve_inside("tests"),
...     doc_source_dir=root.resolve_inside("docs/source"),
...     doc_dest_dir=root.resolve_inside("docs/build"))
>>> from io import StringIO
>>> from contextlib import redirect_stdout
>>> with redirect_stdout(None):
...     make_documentation(bf)

pycommons.dev.building.run_tests module

Run the pytest tests.

pycommons.dev.building.run_tests.run_tests(info)[source]

Perform the unit testing of the project.

This code cannot really be unit tested, as it would run the itself recursively.

Parameters:

info (BuildInfo) – the build information

Return type:

None

>>> try:
...     run_tests(None)
... except TypeError as te:
...     print(str(te)[:50])
info should be an instance of pycommons.dev.buildi
>>> try:
...     run_tests(1)
... except TypeError as te:
...     print(str(te)[:50])
info should be an instance of pycommons.dev.buildi

pycommons.dev.building.static_analysis module

Perform the static code analysis.

pycommons.dev.building.static_analysis.static_analysis(info)[source]

Perform the static code analysis for a Python project.

Parameters:

info (BuildInfo) – the build information

Return type:

None

>>> from contextlib import redirect_stdout
>>> with redirect_stdout(None):
...     static_analysis(BuildInfo(
...         Path(__file__).up(4), "pycommons", "tests",
...             "examples", "docs/source"))
>>> try:
...     static_analysis(None)
... except TypeError as te:
...     print(str(te)[:50])
info should be an instance of pycommons.dev.buildi
>>> try:
...     static_analysis(1)
... except TypeError as te:
...     print(str(te)[:50])
info should be an instance of pycommons.dev.buildi