Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make PoetrySession public #277

Draft
wants to merge 18 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .darglint
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[darglint]
strictness = short
strictness = long
14 changes: 10 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,16 @@ This works because session functions are passed instances of ``nox_poetry.Sessio
a proxy for ``nox.Session`` adding Poetry-related functionality.
Behind the scenes, nox-poetry uses Poetry to export a `constraints file`_ and build the package.

For more fine-grained control, additional utilities are available under the ``session.poetry`` attribute:
You can also create a ``PoetrySession`` from a ``session``;
this works both in plain Nox sessions, and in nox-poetry sessions.
The ``PoetrySession`` class provides the same ``install`` method as ``nox_poetry.Session``,
as well as these additional utilities:

- ``session.poetry.installroot(distribution_format=[WHEEL|SDIST])``
- ``session.poetry.build_package(distribution_format=[WHEEL|SDIST])``
- ``session.poetry.export_requirements()``
- ``installroot(distribution_format=[WHEEL|SDIST])``
- ``build_package(distribution_format=[WHEEL|SDIST])``
- ``export_requirements()``

For more details, please see the API reference in the documentation_.


Why?
Expand Down Expand Up @@ -187,6 +192,7 @@ This project was generated from `@cjolowicz`_'s `Hypermodern Python Cookiecutter
.. _Nox: https://nox.thea.codes/
.. _Poetry: https://python-poetry.org/
.. _constraints file: https://pip.pypa.io/en/stable/user_guide/#constraints-files
.. _documentation: https://nox-poetry.readthedocs.io/
.. _file an issue: https://github.com/cjolowicz/nox-poetry/issues
.. _nox.sessions.Session.install: https://nox.thea.codes/en/stable/config.html#nox.sessions.Session.install
.. _nox.sessions.Session.run: https://nox.thea.codes/en/stable/config.html#nox.sessions.Session.run
Expand Down
8 changes: 4 additions & 4 deletions docs/reference.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ Classes
.......

.. autoclass:: Session
.. automethod:: nox_poetry.sessions._PoetrySession.install
.. automethod:: nox_poetry.sessions._PoetrySession.installroot
.. automethod:: nox_poetry.sessions._PoetrySession.export_requirements
.. automethod:: nox_poetry.sessions._PoetrySession.build_package
:members:

.. autoclass:: PoetrySession
:members:

Constants
.........
Expand Down
5 changes: 4 additions & 1 deletion noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import nox

from nox_poetry import PoetrySession
from nox_poetry import Session
from nox_poetry import session

Expand Down Expand Up @@ -98,7 +99,9 @@ def precommit(session: Session) -> None:
@session(python="3.9")
def safety(session: Session) -> None:
"""Scan dependencies for insecure packages."""
requirements = session.poetry.export_requirements()
poetry = PoetrySession(session)
requirements = poetry.export_requirements()

session.install("safety")
# Ignore CVE-2020-28476 affecting all versions of tornado
# https://github.com/tornadoweb/tornado/issues/2981
Expand Down
20 changes: 10 additions & 10 deletions src/nox_poetry/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,22 @@

This package provides a drop-in replacement for the :func:`session` decorator,
and for the :class:`Session` object passed to user-defined session functions.
This enables :meth:`session.install
<nox_poetry.sessions._PoetrySession.install>` to install packages at the
versions specified in the Poetry lock file.
This enables :meth:`session.install <nox_poetry.PoetrySession.install>` to
install packages at the versions specified in the Poetry lock file.

Example:
>>> @session(python=["3.8", "3.9"])
... def tests(session: Session) -> None:
... session.install("pytest", ".")
... session.run("pytest")

It also provides helper functions that allow more fine-grained control:
The :class:`PoetrySession` class provides utilities that allow more fine-grained
control:

- :meth:`session.poetry.installroot
<nox_poetry.sessions._PoetrySession.installroot>`
- :meth:`session.poetry.build_package
<nox_poetry.sessions._PoetrySession.build_package>`
- :meth:`session.poetry.export_requirements
<nox_poetry.sessions._PoetrySession.export_requirements>`
- :meth:`PoetrySession.install`
- :meth:`PoetrySession.installroot`
- :meth:`PoetrySession.build_package`
- :meth:`PoetrySession.export_requirements`

Two constants are defined to specify the format for distribution archives:

Expand All @@ -31,6 +29,7 @@
from nox_poetry.core import install
from nox_poetry.core import installroot
from nox_poetry.poetry import DistributionFormat
from nox_poetry.sessions import PoetrySession
from nox_poetry.sessions import Session
from nox_poetry.sessions import session

Expand All @@ -46,6 +45,7 @@
"export_requirements",
"install",
"installroot",
"PoetrySession",
"Session",
"session",
"SDIST",
Expand Down
91 changes: 51 additions & 40 deletions src/nox_poetry/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
import functools
import hashlib
import re
import warnings
from pathlib import Path
from typing import Any
from typing import Iterable
from typing import Optional
from typing import Tuple
from typing import Union

import nox

Expand Down Expand Up @@ -41,6 +43,52 @@ def wrapper(session: nox.Session, *_args, **_kwargs) -> None:
return nox.session(wrapper, **kwargs) # type: ignore[call-overload]


class _SessionProxy:
"""Proxy for :class:`nox.sessions.Session`."""

def __init__(self, session: nox.Session) -> None:
"""Initialize."""
self._session = session

def __getattr__(self, name: str) -> Any:
"""Delegate attribute access to nox.Session."""
return getattr(self._session, name)


class Session(_SessionProxy):
"""Proxy for :class:`nox.sessions.Session`, passed to session functions.

This class overrides :meth:`nox.sessions.Session.install` with
:meth:`PoetrySession.install`.
"""

def __init__(self, session: nox.Session) -> None:
"""Initialize."""
super().__init__(session)
self._poetry = PoetrySession(session)

@property
def poetry(self) -> "PoetrySession":
"""Provide access to Poetry-related functionality.

.. deprecated:: 0.9
Use :class:`PoetrySession` instead.
""" # noqa: DAR
warnings.warn(
"nox_poetry.Session.poetry is deprecated"
", use nox_poetry.PoetrySession instead",
category=FutureWarning,
)
return self._poetry

def install(self, *args: str, **kwargs: Any) -> None:
"""Install packages into a Nox session using Poetry.

See :meth:`PoetrySession.install` for details.
"""
return self.poetry.install(*args, **kwargs)


_EXTRAS_PATTERN = re.compile(r"^(.+)(\[[^\]]+\])$")


Expand All @@ -52,12 +100,12 @@ def _split_extras(arg: str) -> Tuple[str, Optional[str]]:
return arg, None


class _PoetrySession:
class PoetrySession:
"""Poetry-related utilities for session functions."""

def __init__(self, session: nox.Session) -> None:
def __init__(self, session: Union[nox.Session, Session]) -> None:
"""Initialize."""
self.session = session
self.session = session if isinstance(session, nox.Session) else session._session
self.poetry = Poetry(session)

def install(self, *args: str, **kwargs: Any) -> None:
Expand Down Expand Up @@ -199,40 +247,3 @@ def build_package(
url += f"#egg={self.poetry.config.name}"

return url


class _SessionProxy:
"""Proxy for :class:`nox.sessions.Session`."""

def __init__(self, session: nox.Session) -> None:
"""Initialize."""
self._session = session

def __getattr__(self, name: str) -> Any:
"""Delegate attribute access to nox.Session."""
return getattr(self._session, name)


class Session(_SessionProxy):
"""Proxy for :class:`nox.sessions.Session`, passed to session functions.

This class overrides :meth:`session.install
<nox_poetry.sessions._PoetrySession.install>`, and provides Poetry-related
utilities:

- :meth:`Session.poetry.installroot
<nox_poetry.sessions._PoetrySession.installroot>`
- :meth:`Session.poetry.build_package
<nox_poetry.sessions._PoetrySession.build_package>`
- :meth:`Session.poetry.export_requirements
<nox_poetry.sessions._PoetrySession.export_requirements>`
"""

def __init__(self, session: nox.Session) -> None:
"""Initialize."""
super().__init__(session)
self.poetry = _PoetrySession(session)

def install(self, *args: str, **kwargs: Any) -> None:
"""Install packages into a Nox session using Poetry."""
return self.poetry.install(*args, **kwargs)
5 changes: 3 additions & 2 deletions src/nox_poetry/sessions.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ import nox.virtualenv

Python = Optional[Union[str, Sequence[str], bool]]

class _PoetrySession:
class PoetrySession:
def __init__(self, session: Union[nox.Session, "Session"]) -> None: ...
def install(self, *args: str, **kwargs: Any) -> None: ...
def installroot(
self, *, distribution_format: str = ..., extras: Iterable[str] = ...
Expand All @@ -27,7 +28,7 @@ class _PoetrySession:
def build_package(self, *, distribution_format: str = ...) -> str: ...

class Session:
poetry: _PoetrySession
poetry: PoetrySession
_session: nox.Session
def __init__(self, session: nox.Session) -> None: ...
def install(self, *args: str, **kwargs: Any) -> None: ...
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ def __init__(self, path: Path) -> None:
"""Initialize."""
self.virtualenv = FakeVirtualenv(path)

@property
def _session(self) -> "FakeSession":
"""Allow passing this instance to PoetrySession."""
return self

def run_always(self, *args: str, **kargs: Any) -> str:
"""Run."""
path = Path("dist") / "example.whl"
Expand Down