def install_with_constraints(session: Session, *args: str, **kwargs: Any) -> None: """Install packages constrained by Poetry's lock file.""" with tempfile.NamedTemporaryFile() as requirements: session.run( "poetry", "export", "--dev", "--format=requirements.txt", f"--output={requirements.name}", external=True, ) session.install(f"--constraint={requirements.name}", *args, **kwargs)
def lint(session: Session) -> None: """Lint using flake8.""" args = session.posargs or locations session.install( "flake8", "flake8-annotations", "flake8-bandit", "flake8-black", "flake8-bugbear", "flake8-docstrings", "flake8-import-order", "darglint", ) session.run("flake8", *args)
def mypy(s: Session) -> None: """Type-check using mypy.""" args = s.posargs or ["src", "tests", "docs/source/conf.py"] s.install(".") s.install("mypy", "pytest", "types-setuptools") s.run("mypy", *args) if not s.posargs: s.run("mypy", f"--python-executable={sys.executable}", "noxfile.py")
def tests(s: Session) -> None: """Run the test suite.""" s.install(".") s.install("coverage[toml]", "pytest", "pygments") try: s.run("coverage", "run", "--parallel", "-m", "pytest", *s.posargs) finally: if s.interactive: s.notify("coverage", posargs=[])
def safety(s: Session) -> None: """Scan dependencies for insecure packages.""" args = s.posargs or ["--ignore", "44715"] # TODO dvp: remove the 'ignore' option above on numpy updating to # 1.22.1 and above # safety reports: # -> numpy, installed 1.22.1, affected >0, id 44715 # All versions of Numpy are affected by CVE-2021-41495: # A null Pointer Dereference vulnerability exists in numpy.sort, # in the PyArray_DescrNew function due to missing return-value validation, # which allows attackers to conduct DoS attacks by # repetitively creating sort arrays. # https://github.com/numpy/numpy/issues/19038 # numpy-1.22.2 - still does not work requirements = s.poetry.export_requirements() s.install("safety") s.run("safety", "check", "--full-report", f"--file={requirements}", *args)
def isort(s: Session) -> None: """Organize imports.""" s.install("isort") search_patterns = [ "*.py", "src/xpypact/*.py", "tests/*.py", "benchmarks/*.py", "profiles/*.py", # "adhoc/*.py", ] files_to_process: List[str] = sum( map(lambda p: glob(p, recursive=True), search_patterns), []) s.run( "isort", "--check", "--diff", *files_to_process, external=True, )
def precommit(s: Session) -> None: """Lint using pre-commit.""" args = s.posargs or ["run", "--all-files", "--show-diff-on-failure"] s.install( "black", "darglint", "flake8", "flake8-bandit", "flake8-bugbear", "flake8-docstrings", "flake8-rst-docstrings", "pep8-naming", "pre-commit", "pre-commit-hooks", "isort", "mypy", "types-setuptools", ) s.run("pre-commit", *args) if args and args[0] == "install": activate_virtualenv_in_precommit_hooks(s)
def tests(session: Session) -> None: """Run the test suite.""" args = session.posargs or ["--cov"] session.install(".") session.install("coverage[toml]", "pytest", "pytest-cov", "pytest-mock", "deepdiff") session.run( "pytest", "-rA", *args, )
def safety(session: Session) -> None: """Scan dependencies for insecure packages.""" with tempfile.NamedTemporaryFile() as requirements: session.run( "poetry", "export", "--dev", "--format=requirements.txt", "--without-hashes", f"--output={requirements.name}", external=True, ) session.install("safety") session.run("safety", "check", f"--file={requirements.name}", "--full-report")
def coverage(s: Session) -> None: """Produce the coverage report. To obtain html report run nox -rs coverage -- html """ args = s.posargs or ["report"] s.install("coverage[toml]") if not s.posargs and any(Path().glob(".coverage.*")): s.run("coverage", "combine") s.run("coverage", *args)
def docs_build(s: Session) -> None: """Build the documentation.""" args = s.posargs or ["docs/source", "docs/_build"] s.install(".") s.install( "sphinx", "sphinx-click", "sphinx-rtd-theme", # "sphinxcontrib-htmlhelp", # "sphinxcontrib-jsmath", "sphinxcontrib-napoleon", # "sphinxcontrib-qthelp", "sphinx-autodoc-typehints", # "sphinx_autorun", ) build_dir = Path("docs", "_build") if build_dir.exists(): shutil.rmtree(build_dir) s.run("sphinx-build", *args)
def docs(s: Session) -> None: """Build and serve the documentation with live reloading on file changes.""" args = s.posargs or ["--open-browser", "docs/source", "docs/_build"] s.install(".") s.install( "sphinx", "sphinx-autobuild", "sphinx-click", "sphinx-rtd-theme", # "sphinxcontrib-htmlhelp", # "sphinxcontrib-jsmath", # "sphinxcontrib-napoleon", # "sphinxcontrib-qthelp", # "sphinx-autodoc-typehints", # "sphinx_autorun", ) build_dir = Path("docs", "_build") if build_dir.exists(): shutil.rmtree(build_dir) s.run("sphinx-autobuild", *args)
def pytype(session: Session) -> None: """Run the static type checker using pytype.""" args = session.posargs or ["--disable=import-error", *locations] session.install("pytype") session.run("pytype", *args)
def mypy(session: Session) -> None: """Type-check using mypy.""" args = session.posargs or locations session.install("mypy") session.run("mypy", *args)
def black(session: Session) -> None: """Run black code formatter.""" args = session.posargs or locations session.install("black") session.run("black", *args)
def test_session_install(proxy: nox_poetry.Session) -> None: """It installs the package.""" proxy.install(".")
def coverage(session: Session) -> None: """Upload coverage data.""" session.install("coverage[toml]", "codecov") session.run("coverage", "xml", "--fail-under=0") session.run("codecov", *session.posargs)
def xdoctest(session: Session) -> None: """Run examples with xdoctest.""" args = session.posargs or ["all"] session.run("poetry", "install", "--no-dev", external=True) session.install("xdoctest") session.run("python", "-m", "xdoctest", package, *args)
def typeguard(s: Session) -> None: """Runtime type checking using Typeguard.""" s.install(".") s.install("pytest", "typeguard", "pygments") s.run("pytest", f"--typeguard-packages={package}", *s.posargs)
def tests(session: nox_poetry.Session, sphinx: str) -> None: session.install(f"sphinx=={sphinx}")
def docs(session: Session) -> None: """Build the documentation.""" session.run("poetry", "install", "--no-dev", external=True) session.install("sphinx", "sphinx_autodoc_typehints") session.run("sphinx-build", "docs", "docs/_build")
def lint(session: nox_poetry.Session): session.install('flakehell', 'flake8', 'pep8-naming', 'flake8-quotes') session.run('flakehell', 'lint', 'src', 'tests', 'examples')
def coverage(session: nox_poetry.Session): session.install('coverage[toml]') session.run('coverage', 'combine') session.run('coverage', 'html') session.run('coverage', 'xml')
def test_session_getattr(proxy: nox_poetry.Session) -> None: """It delegates to the real session.""" assert proxy.create_tmp()
def test(session: nox_poetry.Session): session.install('.') session.install('pytest', 'pytest-cov', 'pytest-timeout') session.env['COVERAGE_FILE'] = f'.coverage.{session.python}' session.run('python', '-m', 'pytest', '--cov', 'parsita')
def xdoctest(s: Session) -> None: """Run examples with xdoctest.""" args = s.posargs or ["all"] s.install(".") s.install("xdoctest[colors]") s.run("python", "-m", "xdoctest", package, *args)