pypa/pip · error · InstallationError
does not appear to be a Python project: neither 'setup.py'…
Error message
{req_name} does not appear to be a Python project: neither 'setup.py' nor 'pyproject.toml' found. What it means
Raised by load_pyproject_toml (pyproject.py:56) as InstallationError when neither a pyproject.toml nor a setup.py exists in the project directory pip was asked to build/install from. pip needs at least one of these to know how to build the project, so their absence means the target is not recognizable as a Python project.
Solutions
- Verify the directory actually contains the project's setup.py or pyproject.toml (ls the path).
- Point pip at the correct subdirectory: 'pip install ./path/to/real/package'.
- For monorepos use the subdirectory feature of your VCS URL or path.
- If the project legitimately lacks build config, add a minimal pyproject.toml with a build-backend.
Example fix
# before pip install ./ # cwd has no setup.py/pyproject.toml # after: point at the real package dir pip install ./src/myproject # or add minimal build config # pyproject.toml: # [build-system] # requires = ["setuptools>=61"] # build-backend = "setuptools.build_meta"
Defensive patterns
Strategy: validation
Validate before calling
import os, sys
def is_python_project_dir(path: str) -> bool:
return os.path.isfile(os.path.join(path, 'setup.py')) or os.path.isfile(os.path.join(path, 'pyproject.toml'))
if __name__ == '__main__':
target = sys.argv[1]
if not is_python_project_dir(target):
print(f'{target} has neither setup.py nor pyproject.toml'); sys.exit(1) Type guard
import os
def is_python_project(path: str) -> bool:
return (os.path.isdir(path)
and (os.path.isfile(os.path.join(path, 'setup.py'))
or os.path.isfile(os.path.join(path, 'pyproject.toml')))) Try / catch
from subprocess import run, CalledProcessError
try:
run(["pip", "install", target], check=True)
except CalledProcessError:
# Point at the correct subdirectory containing the build files.
run(["pip", "install", correct_subdir], check=True) Prevention
- Verify the directory contains setup.py or pyproject.toml before pip install.
- For monorepos, pass the package subdirectory explicitly.
- Ensure git submodules are initialized before installing from a checkout.
When it happens
Trigger: Installing/building from a path (local dir, sdist, or VCS checkout) that contains no pyproject.toml and no setup.py — e.g. pointing pip at a docs folder, an empty checkout, or the wrong subdirectory of a monorepo.
Common situations: Wrong path given to pip install; a Git submodule that wasn't initialized; a monorepo where the package lives in a subdirectory; a tarball missing its build files; a directory that is just data/notebooks.
Related errors
- Directory is not installable. Neither 'setup.py' nor…
- invalid-pyproject-build-system-requires
- missing-pyproject-build-system-requires
- [dependency-groups] resolution failed for
- [dependency-groups] table was missing from
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/6c6461d44a8ad040.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/pyproject.py:57
req_name - The name of the requirement we're processing (for
error reporting)
Returns:
None if we should use the legacy code path, otherwise a tuple
(
requirements from pyproject.toml,
name of PEP 517 backend,
requirements we should check are installed after setting
up the build environment
directory paths to import the backend from (backend-path),
relative to the project root.
)
"""
has_pyproject = os.path.isfile(pyproject_toml)
has_setup = os.path.isfile(setup_py)
if not has_pyproject and not has_setup:
raise InstallationError(
f"{req_name} does not appear to be a Python project: "
f"neither 'setup.py' nor 'pyproject.toml' found."
)
if has_pyproject:
with open(pyproject_toml, encoding="utf-8") as f:
pp_toml = tomllib.loads(f.read())
build_system = pp_toml.get("build-system")
else:
build_system = None
if build_system is None:
# In the absence of any explicit backend specification, we
# assume the setuptools backend that most closely emulates the
# traditional direct setup.py execution, and require wheel and
# a version of setuptools that supports that backend.
build_system = {View on GitHub (pinned to f399c37189)