如何在诗歌中使用 nox?

How to use nox with poetry?

我想使用nox in my project managed with poetry

不顺利的是在 nox 会话中安装开发依赖项。

我有 noxfile.py 如下所示:

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")

如何在 nox 会话中安装开发依赖项?

目前,session.install 不支持 poetryinstall 仅支持 shell 中的 runs pip。您可以使用更通用的方法 session.run.

激活 poetry

示例:

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

设置会话时,您可以通过自己禁用 python virtualenv (python=False) 的创建并使用 poetry shell 激活 poetry 来完成所有操作.

经过一些试验和错误,与我在@Yann 的回答中评论的相反,poetry 似乎忽略了 nox 传递的 VIRTUAL_ENV 变量。

受到 Claudio Jolowicz 精彩系列 Hypermodern Python 的启发,我用以下方法解决了这个问题:

@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)

在这里,我只是使用 pip 安装一个 PEP517 包。

不幸的是,通过 pip 安装的 PEP517 不支持可编辑(“-e”)开关。

仅供参考:install_with_constraints 是我从 Claudio 那里借来的函数,经过编辑后可以在 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)

我想在没有诗歌的情况下使用 nox 会话,所以我使用诗歌为 session.install() 生成参数,如下所示:

@nox.session
def tests(session: nox.sessions.Sessio0n):
    """ Run all tests """
    session.install(*requirements_txt, '.', 'pytest')
    session.run('pytest', 'tests/')


# Get requirements.txt from poetry
import tempfile, subprocess
with tempfile.NamedTemporaryFile('w+') as f:
    subprocess.run(f'poetry export --no-interaction --dev --format requirements.txt --without-hashes --output={f.name}', shell=True, check=True)
    f.seek(0)
    requirements_txt = f.readlines()