66import sys
77from pathlib import Path
88from textwrap import dedent
9+ from tempfile import NamedTemporaryFile
910
1011import nox
11-
12-
13- try :
14- from nox_poetry import Session
15- from nox_poetry import session
16- except ImportError :
17- message = f"""\
18- Nox failed to import the 'nox-poetry' package.
19-
20- Please install it using the following command:
21-
22- { sys .executable } -m pip install nox-poetry"""
23- raise SystemExit (dedent (message )) from None
12+ from nox import Session
13+ from nox import session
2414
2515
2616package = "mdio"
3727)
3828
3929
40- def activate_virtualenv_in_precommit_hooks (session : Session ) -> None :
41- """Activate virtualenv in hooks installed by pre-commit.
42-
43- This function patches git hooks installed by pre-commit to activate the
44- session's virtual environment. This allows pre-commit to locate hooks in
45- that environment when invoked from git.
46-
47- Args:
48- session: The Session object.
49- """
50- assert session .bin is not None # noqa: S101
51-
52- # Only patch hooks containing a reference to this session's bindir. Support
53- # quoting rules for Python and bash, but strip the outermost quotes so we
54- # can detect paths within the bindir, like <bindir>/python.
55- bindirs = [
56- bindir [1 :- 1 ] if bindir [0 ] in "'\" " else bindir
57- for bindir in (repr (session .bin ), shlex .quote (session .bin ))
58- ]
59-
60- virtualenv = session .env .get ("VIRTUAL_ENV" )
61- if virtualenv is None :
62- return
63-
64- headers = {
65- # pre-commit < 2.16.0
66- "python" : f"""\
67- import os
68- os.environ["VIRTUAL_ENV"] = { virtualenv !r}
69- os.environ["PATH"] = os.pathsep.join((
70- { session .bin !r} ,
71- os.environ.get("PATH", ""),
72- ))
73- """ ,
74- # pre-commit >= 2.16.0
75- "bash" : f"""\
76- VIRTUAL_ENV={ shlex .quote (virtualenv )}
77- PATH={ shlex .quote (session .bin )} "{ os .pathsep } $PATH"
78- """ ,
79- # pre-commit >= 2.17.0 on Windows forces sh shebang
80- "/bin/sh" : f"""\
81- VIRTUAL_ENV={ shlex .quote (virtualenv )}
82- PATH={ shlex .quote (session .bin )} "{ os .pathsep } $PATH"
83- """ ,
84- }
85-
86- hookdir = Path (".git" ) / "hooks"
87- if not hookdir .is_dir ():
88- return
89-
90- for hook in hookdir .iterdir ():
91- if hook .name .endswith (".sample" ) or not hook .is_file ():
92- continue
93-
94- if not hook .read_bytes ().startswith (b"#!" ):
95- continue
96-
97- text = hook .read_text ()
98-
99- if not any (
100- Path ("A" ) == Path ("a" ) and bindir .lower () in text .lower () or bindir in text
101- for bindir in bindirs
102- ):
103- continue
104-
105- lines = text .splitlines ()
106-
107- for executable , header in headers .items ():
108- if executable in lines [0 ].lower ():
109- lines .insert (1 , dedent (header ))
110- hook .write_text ("\n " .join (lines ))
111- break
112-
113-
11430@session (name = "pre-commit" , python = python_versions [0 ])
11531def precommit (session : Session ) -> None :
11632 """Lint using pre-commit."""
@@ -120,7 +36,8 @@ def precommit(session: Session) -> None:
12036 "--hook-stage=manual" ,
12137 "--show-diff-on-failure" ,
12238 ]
123- session .install (
39+ session .run (
40+ "uv" , "pip" , "install" ,
12441 "black" ,
12542 "darglint" ,
12643 "flake8" ,
@@ -133,34 +50,45 @@ def precommit(session: Session) -> None:
13350 "pre-commit" ,
13451 "pre-commit-hooks" ,
13552 "pyupgrade" ,
53+ external = True
13654 )
13755 session .run ("pre-commit" , * args )
138- if args and args [0 ] == "install" :
139- activate_virtualenv_in_precommit_hooks (session )
14056
14157
14258@session (python = python_versions [0 ])
14359def safety (session : Session ) -> None :
14460 """Scan dependencies for insecure packages."""
145- requirements = session .poetry .export_requirements ()
146- session .install ("safety" )
147- # TODO(Altay): Remove the CVE ignore once its resolved. Its not critical, so ignoring now.
148- ignore = ["70612" ]
149- session .run (
150- "safety" ,
151- "check" ,
152- "--full-report" ,
153- f"--file={ requirements } " ,
154- f"--ignore={ ',' .join (ignore )} " ,
155- )
61+ with NamedTemporaryFile (delete = False ) as requirements :
62+ session .run (
63+ "uv" , "pip" , "compile" ,
64+ "pyproject.toml" ,
65+ "--output-file" , requirements .name ,
66+ external = True
67+ )
68+ session .run (
69+ "uv" , "pip" , "install" , "safety" ,
70+ external = True
71+ )
72+ # TODO(Altay): Remove the CVE ignore once its resolved. Its not critical, so ignoring now.
73+ ignore = ["70612" ]
74+ try :
75+ session .run (
76+ "safety" ,
77+ "check" ,
78+ "--full-report" ,
79+ f"--file={ requirements .name } " ,
80+ f"--ignore={ ',' .join (ignore )} " ,
81+ )
82+ finally :
83+ os .remove (requirements .name )
15684
15785
15886@session (python = python_versions )
15987def mypy (session : Session ) -> None :
16088 """Type-check using mypy."""
16189 args = session .posargs or ["src" , "tests" , "docs/conf.py" ]
162- session .install ( "." )
163- session .install ( " mypy" , "pytest" )
90+ session .run_always ( "uv" , "pip" , "install" , "-e" , "." , external = True )
91+ session .run ( "uv" , "pip" , "install" , " mypy" , "pytest" , external = True )
16492 session .run ("mypy" , * args )
16593 if not session .posargs :
16694 session .run ("mypy" , f"--python-executable={ sys .executable } " , "noxfile.py" )
@@ -169,8 +97,12 @@ def mypy(session: Session) -> None:
16997@session (python = python_versions )
17098def tests (session : Session ) -> None :
17199 """Run the test suite."""
172- session .install ("." )
173- session .install ("coverage[toml]" , "pytest" , "pygments" , "pytest-dependency" , "s3fs" )
100+ session .run_always ("uv" , "pip" , "install" , "-e" , ".[cloud]" , external = True )
101+ session .run (
102+ "uv" , "pip" , "install" ,
103+ "coverage[toml]" , "pytest" , "pygments" , "pytest-dependency" , "s3fs" ,
104+ external = True
105+ )
174106 try :
175107 session .run ("coverage" , "run" , "--parallel" , "-m" , "pytest" , * session .posargs )
176108 finally :
@@ -183,7 +115,7 @@ def coverage(session: Session) -> None:
183115 """Produce the coverage report."""
184116 args = session .posargs or ["report" ]
185117
186- session .install ( " coverage[toml]" )
118+ session .run ( "uv" , "pip" , "install" , " coverage[toml]", external = True )
187119
188120 if not session .posargs and any (Path ().glob (".coverage.*" )):
189121 session .run ("coverage" , "combine" )
@@ -194,8 +126,8 @@ def coverage(session: Session) -> None:
194126@session (python = python_versions [0 ])
195127def typeguard (session : Session ) -> None :
196128 """Runtime type checking using Typeguard."""
197- session .install ( "." )
198- session .install ( " pytest" , "typeguard" , "pygments" )
129+ session .run_always ( "uv" , "pip" , "install" , "-e" , "." , external = True )
130+ session .run ( "uv" , "pip" , "install" , " pytest" , "typeguard" , "pygments" , external = True )
199131 session .run ("pytest" , f"--typeguard-packages={ package } " , * session .posargs )
200132
201133
@@ -209,8 +141,8 @@ def xdoctest(session: Session) -> None:
209141 if "FORCE_COLOR" in os .environ :
210142 args .append ("--colored=1" )
211143
212- session .install ( "." )
213- session .install ( " xdoctest[colors]" )
144+ session .run_always ( "uv" , "pip" , "install" , "-e" , "." , external = True )
145+ session .run ( "uv" , "pip" , "install" , " xdoctest[colors]", external = True )
214146 session .run ("python" , "-m" , "xdoctest" , * args )
215147
216148
@@ -221,14 +153,16 @@ def docs_build(session: Session) -> None:
221153 if not session .posargs and "FORCE_COLOR" in os .environ :
222154 args .insert (0 , "--color" )
223155
224- session .install ("." )
225- session .install (
156+ session .run_always ("uv" , "pip" , "install" , "-e" , "." , external = True )
157+ session .run (
158+ "uv" , "pip" , "install" ,
226159 "sphinx" ,
227160 "sphinx-click" ,
228161 "sphinx-copybutton" ,
229162 "furo" ,
230163 "myst-nb" ,
231164 "linkify-it-py" ,
165+ external = True
232166 )
233167
234168 build_dir = Path ("docs" , "_build" )
@@ -242,15 +176,17 @@ def docs_build(session: Session) -> None:
242176def docs (session : Session ) -> None :
243177 """Build and serve the documentation with live reloading on file changes."""
244178 args = session .posargs or ["--open-browser" , "docs" , "docs/_build" ]
245- session .install ("." )
246- session .install (
179+ session .run_always ("uv" , "pip" , "install" , "-e" , "." , external = True )
180+ session .run (
181+ "uv" , "pip" , "install" ,
247182 "sphinx" ,
248183 "sphinx-autobuild" ,
249184 "sphinx-click" ,
250185 "sphinx-copybutton" ,
251186 "furo" ,
252187 "myst-nb" ,
253188 "linkify-it-py" ,
189+ external = True
254190 )
255191
256192 build_dir = Path ("docs" , "_build" )
0 commit comments