Skip to content

NameError: name '_DISTUTILS_PATCH' is not defined #2969

@losnappas

Description

@losnappas

Issue

I'm using uv and initialized my venv with uv venv, I'm not sure I should report here or in uv.

I'm using a marimo notebook, and I occasionally run into this error:

Process Process-1:
Traceback (most recent call last):
  File "/nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/lib/python3.12/multiprocessing/process.py", line 314, in _bootstrap
    self.run()
  File "/nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/lib/python3.12/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 3071, in launch_kernel
    asyncio.run(control_loop(kernel))
  File "/nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/lib/python3.12/asyncio/runners.py", line 195, in run
    return runner.run(main)
           ^^^^^^^^^^^^^^^^
  File "/nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/lib/python3.12/asyncio/runners.py", line 118, in run
    return self._loop.run_until_complete(task)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/lib/python3.12/asyncio/base_events.py", line 691, in run_until_complete
    return future.result()
           ^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 3065, in control_loop
    await kernel.handle_message(request)
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 2257, in handle_message
    await self.request_handler.handle(request)
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 2878, in handle
    return await handler(request)
           ^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 2139, in handle_execute_multiple
    await self.run(request.execution_requests)
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 1563, in run
    await _run_with_uninstantiated_requests(execution_requests)
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 1552, in _run_with_uninstantiated_requests
    await self._run_cells(
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 1357, in _run_cells
    while cell_ids := await self._run_cells_internal(cell_ids):
                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runtime.py", line 1442, in _run_cells_internal
    await runner.run_all()
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runner/cell_runner.py", line 692, in run_all
    post_hook(cell, self, run_result)
  File "/nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/lib/python3.12/contextlib.py", line 81, in inner
    return func(*args, **kwds)
           ^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.12/site-packages/marimo/_runtime/runner/hooks_post_execution.py", line 191, in _broadcast_duckdb_datasource
    if not DependencyManager.duckdb.has():
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.12/site-packages/marimo/_dependencies/dependencies.py", line 22, in has
    has_dep = importlib.util.find_spec(self.pkg) is not None
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen importlib.util>", line 100, in find_spec
  File "<frozen importlib._bootstrap>", line 1262, in _find_spec
  File "/.../.venv/lib/python3.12/site-packages/marimo/_output/formatters/formatters.py", line 122, in find_spec
    spec = original_find_spec(fullname, path, target)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/.../.venv/lib/python3.12/site-packages/_virtualenv.py", line 51, in find_spec
    if fullname in _DISTUTILS_PATCH and self.fullname is None:
                   ^^^^^^^^^^^^^^^^
NameError: name '_DISTUTILS_PATCH' is not defined

Seems to me to be stemming from this file

_DISTUTILS_PATCH = "distutils.dist", "setuptools.dist"

I asked gpt5 and it gave me this response:

You're right that in your posted code _DISTUTILS_PATCH appears above the class. The NameError happens because import machinery can call your find_spec while the module is still being executed, before the name binding is visible to the finder closure — a form of circular-import/timing issue with import hooks.

Concretely:

• If the import system asks your finder about some module while this module is still importing, Python may execute find_spec in that partially-initialized state where module-level names are not yet visible to the running code path, producing NameError when you reference a free global.

Two safe fixes — pick one:

1. Ensure the name is read only after module initialization (recommended)
  • Change the check to look up the name at runtime via globals():
  if globals().get("_DISTUTILS_PATCH") and fullname in globals()["_DISTUTILS_PATCH"] and self.fullname is None:
This avoids a free-variable lookup that can raise NameError during partial initialization.
2. Make the patch list an attribute on the finder or otherwise tightly coupled
  • e.g. set _Finder.DISTUTILS_PATCH = ("distutils.dist", "setuptools.dist") and use:
  if fullname in self.DISTUTILS_PATCH and self.fullname is None:
3. Ensure ordering: guarantee _DISTUTILS_PATCH is defined before you ever install the finder into sys.meta_path. (Insert sys.meta_path.insert(...) only after all module-level names are set.) This usually fixes it if the insertion currently happens earlier in your real file.

Also fix the unrelated bug: VIRTUALENV_PATCH_FILE = os.path.join(file) is wrong — use VIRTUALENV_PATCH_FILE = os.path.abspath(file) or just file.

Pick (1) or (2) to make the finder robust against import-time races.

Environment

Provide at least:

  • OS: NixOS / Linux
  • Shell: bash
  • Python version and path: Python 3.12.11 / /[project_dir]/.venv/bin/python -> /nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/bin/python3.12
  • pip list of the host python where virtualenv is installed:

I ran uv pip list:

Using Python 3.12.11 environment at: /nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11

Output of the virtual environment creation

Make sure to run the creation with -vvv --with-traceback:

DEBUG uv 0.8.14
DEBUG Found project root: `/[project_root...]`
DEBUG No workspace root found, using project root
DEBUG Using Python request `/nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/bin/python3.12` from explicit request
DEBUG Checking for Python interpreter at path `/nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/bin/python3.12`
TRACE Found cached interpreter info for Python 3.12.11, skipping query of: /nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/bin/python3.12
DEBUG Using base executable for virtual environment: /nix/store/zsbkvanzzx4dd5va9ivsx83rs12d4dsv-python3-3.12.11/bin/python3.12
DEBUG Allowing existing virtual environment due to `--allow-existing`

I ran uv -q venv --allow-existing -vvv -- --allow-traceback there.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions