{"id":"6c6461d44a8ad040","repo":"pypa/pip","slug":"req-name-does-not-appear-to-be-a-python-project","errorCode":null,"errorMessage":"{req_name} does not appear to be a Python project: neither 'setup.py' nor 'pyproject.toml' found.","messagePattern":"(.+?) does not appear to be a Python project: neither 'setup\\.py' nor 'pyproject\\.toml' found\\.","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/pyproject.py","lineNumber":57,"sourceCode":"        req_name - The name of the requirement we're processing (for\n                   error reporting)\n\n    Returns:\n        None if we should use the legacy code path, otherwise a tuple\n        (\n            requirements from pyproject.toml,\n            name of PEP 517 backend,\n            requirements we should check are installed after setting\n                up the build environment\n            directory paths to import the backend from (backend-path),\n                relative to the project root.\n        )\n    \"\"\"\n    has_pyproject = os.path.isfile(pyproject_toml)\n    has_setup = os.path.isfile(setup_py)\n\n    if not has_pyproject and not has_setup:\n        raise InstallationError(\n            f\"{req_name} does not appear to be a Python project: \"\n            f\"neither 'setup.py' nor 'pyproject.toml' found.\"\n        )\n\n    if has_pyproject:\n        with open(pyproject_toml, encoding=\"utf-8\") as f:\n            pp_toml = tomllib.loads(f.read())\n        build_system = pp_toml.get(\"build-system\")\n    else:\n        build_system = None\n\n    if build_system is None:\n        # In the absence of any explicit backend specification, we\n        # assume the setuptools backend that most closely emulates the\n        # traditional direct setup.py execution, and require wheel and\n        # a version of setuptools that supports that backend.\n\n        build_system = {","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/pyproject.py#L39-L75","documentation":"Raised by load_pyproject_toml() when pip is asked to build/install a source tree that contains neither a setup.py nor a pyproject.toml. pip requires at least one of these metadata files to identify the directory as a valid Python project and to determine the build backend. Without them, pip has no way to know how to build the package, so it aborts before attempting any build.","triggerScenarios":"Calling pip install on a directory path (e.g. `pip install ./some_dir`) where neither ./some_dir/setup.py nor ./some_dir/pyproject.toml exists. Also triggered when pip resolves an sdist that unpacks to a tree missing both files, or when a relative/wrong directory path is passed. The check is literally `os.path.isfile(pyproject_toml)` AND `os.path.isfile(setup_py)` both returning False at pyproject.py:56.","commonSituations":"Pointing pip at the wrong directory (parent of the project, a src/ layout root without metadata, a build artifact dir). Cloning a repo and running install from repo root when the package lives in a subdirectory. A CI checkout that excluded metadata files. A corrupted or incomplete sdist tarball.","solutions":["Verify the directory you passed actually contains pyproject.toml or setup.py: run `ls <dir>` and confirm one of those filenames is present.","If the project uses a src/ layout, point pip at the directory that holds the metadata file, e.g. `pip install ./project-root` not `pip install ./project-root/src`.","If you cloned into a subdirectory, `cd` to the directory containing pyproject.toml (or pass its absolute path) before running pip install.","If installing from a tarball/zip, extract it fully first and install from the extracted top-level directory, not the archive's inner nested folder."],"exampleFix":"# before\npip install ./src\n# after (assuming pyproject.toml is in the repo root)\npip install .","handlingStrategy":"validation","validationCode":"import os\n\ndef is_installable_project(directory: str) -> bool:\n    return os.path.isfile(os.path.join(directory, \"pyproject.toml\")) or \\\n           os.path.isfile(os.path.join(directory, \"setup.py\"))\n\n# before calling pip / load_pyproject_toml:\nif not is_installable_project(target_dir):\n    raise SystemExit(f\"{target_dir} has no pyproject.toml or setup.py\")","typeGuard":"null","tryCatchPattern":"null","preventionTips":["Always verify a directory contains pyproject.toml or setup.py before passing it to pip.","In CI, assert the metadata file exists as an early step so failures are clear.","Use absolute paths to avoid ambiguity about which directory pip inspects."],"tags":["pyproject","build-system","packaging","filesystem"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}