Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use nox with poetry?

I want to use nox in my project managed with poetry.

What is not going well is that installing dev dependency in nox session.

I have the noxfile.py as shown below:

import nox
from nox.sessions import Session
from pathlib import Path

__dir__ = Path(__file__).parent.absolute()


@nox.session(python=PYTHON)
def test(session: Session):
    session.install(str(__dir__))  # I want to use dev dependency here
    session.run("pytest")

How can I install dev dependency in nox session?

like image 879
Yohei Avatar asked Jan 16 '20 11:01

Yohei


2 Answers

Currently, session.install doesn't support poetry and install just runs pip in the shell. You can activate poetry with a more general method session.run.

Example:

@nox.session(python=False)
def tests(session):
    session.run('poetry', 'shell')
    session.run('poetry', 'install')
    session.run('pytest')

When you set up session, you can do everything by your own disabling creation of python virtualenv (python=False) and activating poetry's one with poetry shell.

like image 115
Yann Avatar answered Nov 20 '22 04:11

Yann


After some trials and errors and contrary to what I commented in @Yann's answer, it seems that poetry ignores the VIRTUAL_ENV variable passed by nox.

Inspired by the wonderful series Hypermodern Python by Claudio Jolowicz, I solved the problem with the following:

@nox.session(python=PYTHON)
def test(session: Session) -> None:
    """
    Run unit tests.

    Arguments:
        session: The Session object.
    """
    args = session.posargs or ["--cov"]
    session.install(".")
    install_with_constraints(
        session,
        "coverage[toml]",
        "pytest",
        "pytest-cov",
        "pytest-mock",
        "pytest-flask",
    )
    session.run("pytest", *args)

Here, I'm just using pip to install a PEP517 package.

Unfortunately PEP517 installs via pip don't support the editable ("-e") switch.

FYI: install_with_constraints is the function I borrowed from Claudio, edited to work on Windows:

def install_with_constraints(
    session: Session, *args: str, **kwargs: Any
) -> None:
    """
    Install packages constrained by Poetry's lock file.

    This function is a wrapper for nox.sessions.Session.install. It
    invokes pip to install packages inside of the session's virtualenv.
    Additionally, pip is passed a constraints file generated from
    Poetry's lock file, to ensure that the packages are pinned to the
    versions specified in poetry.lock. This allows you to manage the
    packages as Poetry development dependencies.

    Arguments:
        session: The Session object.
        args: Command-line arguments for pip.
        kwargs: Additional keyword arguments for Session.install.
    """
    req_path = os.path.join(tempfile.gettempdir(), os.urandom(24).hex())
    session.run(
        "poetry",
        "export",
        "--dev",
        "--format=requirements.txt",
        f"--output={req_path}",
        external=True,
    )
    session.install(f"--constraint={req_path}", *args, **kwargs)
    os.unlink(req_path)
like image 3
sanzoghenzo Avatar answered Nov 20 '22 03:11

sanzoghenzo