{"id":"8ea6b09fd2b67472","repo":"pypa/pip","slug":"directory-name-r-is-not-installable-neither-se","errorCode":null,"errorMessage":"Directory {name!r} is not installable. Neither 'setup.py' nor 'pyproject.toml' found.","messagePattern":"Directory (.+?) is not installable\\. Neither 'setup\\.py' nor 'pyproject\\.toml' found\\.","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/req/constructors.py","lineNumber":315,"sourceCode":"        return True\n    return False\n\n\ndef _get_url_from_path(path: str, name: str) -> str | None:\n    \"\"\"\n    First, it checks whether a provided path is an installable directory. If it\n    is, returns the path.\n\n    If false, check if the path is an archive file (such as a .whl).\n    The function checks if the path is a file. If false, if the path has\n    an @, it will treat it as a PEP 440 URL requirement and return the path.\n    \"\"\"\n    if _looks_like_path(name) and os.path.isdir(path):\n        if is_installable_dir(path):\n            return path_to_url(path)\n        # TODO: The is_installable_dir test here might not be necessary\n        #       now that it is done in load_pyproject_toml too.\n        raise InstallationError(\n            f\"Directory {name!r} is not installable. Neither 'setup.py' \"\n            \"nor 'pyproject.toml' found.\"\n        )\n    if not is_archive_file(path):\n        return None\n    if os.path.isfile(path):\n        return path_to_url(path)\n    urlreq_parts = name.split(\"@\", 1)\n    if len(urlreq_parts) >= 2 and not _looks_like_path(urlreq_parts[0]):\n        # If the path contains '@' and the part before it does not look\n        # like a path, try to treat it as a PEP 440 URL req instead.\n        return None\n    logger.warning(\n        \"Requirement %r looks like a filename, but the file does not exist\",\n        name,\n    )\n    return path_to_url(path)\n","sourceCodeStart":297,"sourceCodeEnd":333,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/req/constructors.py#L297-L333","documentation":"Raised by _get_url_from_path() when the path passed to install_req_from_line looks like a path and resolves to a directory, but is_installable_dir() returns False — meaning the directory lacks both setup.py and pyproject.toml. pip will not treat a metadata-less directory as an installable project (constructors.py:315).","triggerScenarios":"Running `pip install ./some_dir` where some_dir exists and is a directory but contains neither setup.py nor pyproject.toml. Distinct from error 120 (which fires later in load_pyproject_toml); this one fires earlier during path-based requirement parsing.","commonSituations":"Pointing at a documentation/ or tests/ directory by mistake. A monorepo where the installable package is nested deeper. An empty scaffold directory created by a generator that was never populated.","solutions":["Confirm the target directory contains pyproject.toml or setup.py: `ls <dir>`.","Point pip at the directory that actually holds the project metadata (often one level up or down).","If the project is elsewhere, pass the correct absolute path.","If you intended to install a package by name from PyPI, remove the path prefix and use the distribution name instead."],"exampleFix":"# before\npip install ./docs\n# after\npip install ./pkg","handlingStrategy":"validation","validationCode":"import os\nfrom pip._internal.utils.misc import is_installable_dir\n\ndef assert_dir_installable(path: str) -> None:\n    if os.path.isdir(path) and not is_installable_dir(path):\n        raise ValueError(\n            f\"{path!r} is a directory but lacks setup.py and pyproject.toml\"\n        )","typeGuard":"import os\n\ndef dir_has_project_metadata(path: str) -> bool:\n    return os.path.exists(os.path.join(path, \"pyproject.toml\")) or \\\n           os.path.exists(os.path.join(path, \"setup.py\"))","tryCatchPattern":"null","preventionTips":["Before `pip install ./dir`, confirm the dir has pyproject.toml or setup.py.","Avoid pointing pip at documentation, test, or build-output directories.","Use `pip show` or directory listing to verify project roots in monorepos."],"tags":["filesystem","packaging","requirements","pyproject"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}