3131import nox .command
3232import nox .virtualenv
3333from nox import _options , tasks , workflow
34+ from nox ._options import DefaultStr
3435from nox ._version import get_nox_version
3536from nox .logger import logger , setup_logging
3637from nox .project import load_toml
3738
3839if TYPE_CHECKING :
3940 from collections .abc import Generator
4041
41- __all__ = ["execute_workflow" , "main" ]
42+ __all__ = ["execute_workflow" , "main" , "nox_main" ]
4243
4344
4445def __dir__ () -> list [str ]:
@@ -136,7 +137,19 @@ def check_url_dependency(dep_url: str, dist: importlib.metadata.Distribution) ->
136137 return dep_purl .netloc == origin_purl .netloc and dep_purl .path == origin_purl .path
137138
138139
140+ def get_main_filename () -> str | None :
141+ main_module = sys .modules .get ("__main__" )
142+ if (
143+ main_module
144+ and (fname := getattr (main_module , "__file__" , "" ))
145+ and os .path .exists (main_filename := os .path .abspath (fname ))
146+ ):
147+ return main_filename
148+ return None
149+
150+
139151def run_script_mode (
152+ noxfile : str ,
140153 envdir : Path ,
141154 * ,
142155 reuse : bool ,
@@ -163,11 +176,12 @@ def run_script_mode(
163176 subprocess .run ([* cmd , * dependencies ], env = env , check = True )
164177 nox_cmd = shutil .which ("nox" , path = env ["PATH" ])
165178 assert nox_cmd is not None , "Nox must be discoverable when installed"
179+ args = [nox_cmd , "-f" , noxfile , * sys .argv [1 :]]
166180 # The os.exec functions don't work properly on Windows
167181 if sys .platform .startswith ("win" ):
168182 raise SystemExit (
169183 subprocess .run (
170- [ nox_cmd , * sys . argv [ 1 :]] ,
184+ args ,
171185 env = env ,
172186 stdout = None ,
173187 stderr = None ,
@@ -176,10 +190,18 @@ def run_script_mode(
176190 check = False ,
177191 ).returncode
178192 )
179- os .execle (nox_cmd , nox_cmd , * sys . argv [ 1 :] , env ) # pragma: nocover # noqa: S606
193+ os .execle (nox_cmd , * args , env ) # pragma: nocover # noqa: S606
180194
181195
182196def main () -> None :
197+ _main (main_ep = False )
198+
199+
200+ def nox_main () -> None :
201+ _main (main_ep = True )
202+
203+
204+ def _main (* , main_ep : bool ) -> None :
183205 args = _options .options .parse_args ()
184206
185207 if args .help :
@@ -198,7 +220,12 @@ def main() -> None:
198220 msg = f"Invalid NOX_SCRIPT_MODE: { nox_script_mode !r} , must be one of 'none', 'reuse', or 'fresh'"
199221 raise SystemExit (msg )
200222 if nox_script_mode != "none" :
201- toml_config = load_toml (os .path .expandvars (args .noxfile ), missing_ok = True )
223+ noxfile = (
224+ args .noxfile
225+ if main_ep or not isinstance (args .noxfile , DefaultStr )
226+ else (get_main_filename () or args .noxfile )
227+ )
228+ toml_config = load_toml (os .path .expandvars (noxfile ), missing_ok = True )
202229 dependencies = toml_config .get ("dependencies" )
203230 if dependencies is not None :
204231 valid_env = check_dependencies (dependencies )
@@ -235,6 +262,7 @@ def main() -> None:
235262
236263 envdir = Path (args .envdir or ".nox" )
237264 run_script_mode (
265+ noxfile ,
238266 envdir ,
239267 reuse = nox_script_mode == "reuse" ,
240268 dependencies = dependencies ,
0 commit comments