Skip to content

Multiple session decorators don't work when using a list for the python argument #1042

@RazerM

Description

@RazerM

Current Behavior

I'm trying to use the same function for multiple sessions, but this fails when python is a list:

Traceback (most recent call last):
  File "<frozen runpy>", line 198, in _run_module_as_main
  File "<frozen runpy>", line 88, in _run_code
  File "/.../.venv/lib/python3.11/site-packages/nox/__main__.py", line 34, in <module>
    main()
  File "/.../.venv/lib/python3.11/site-packages/nox/_cli.py", line 202, in nox_main
    _main(main_ep=True)
  File "/.../.venv/lib/python3.11/site-packages/nox/_cli.py", line 275, in _main
    exit_code = execute_workflow(args)
                ^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.11/site-packages/nox/_cli.py", line 55, in execute_workflow
    return workflow.execute(
           ^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.11/site-packages/nox/workflow.py", line 61, in execute
    return_value = function_(*args, **kwargs)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.11/site-packages/nox/tasks.py", line 176, in discover_manifest
    return Manifest(functions, global_config, module_docstring)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.11/site-packages/nox/manifest.py", line 77, in __init__
    for session in self.make_session(name, func):
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.11/site-packages/nox/manifest.py", line 335, in make_session
    single_func = func.copy()
                  ^^^^^^^^^^^
  File "/.../.venv/lib/python3.11/site-packages/nox/_decorators.py", line 105, in copy
    _copy_func(self.func, name),
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.11/site-packages/nox/_decorators.py", line 53, in _copy_func
    src.__code__,
    ^^^^^^^^^^^^
AttributeError: 'Func' object has no attribute '__code__'. Did you mean: '__call__'?

Expected Behavior

nox -l:

* tests-nocoverage-3.11
* tests-nocoverage-3.12
* tests-3.11
* tests-3.12

Steps To Reproduce

This noxfile:

import nox

PYTHON_VERSIONS = ["3.11", "3.12"]


@nox.session(python=PYTHON_VERSIONS)
@nox.session(name="tests-nocoverage", python=PYTHON_VERSIONS)
def tests(
    session: nox.Session,
) -> None:
    if session.name == "tests-nocoverage":
        print("pytest")
    else:
        print("coverage run -m pytest")

Environment

- OS: macOS
- Python: 3.10–3.14
- Nox: 2025.11.12

Anything else?

This example could trivially be split up into two functions, but can be useful with more variations, like where I first saw this pattern in cryptography.

A patch that seems to work is to inject the following snippet before this line, but maybe that's not the right approach.

    if isinstance(func, Func):
        func = func.func

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions