How to use nox with poetry?

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.


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)