diff --git a/news/9547.bugfix.rst b/news/9547.bugfix.rst new file mode 100644 index 00000000000..1dd74d25286 --- /dev/null +++ b/news/9547.bugfix.rst @@ -0,0 +1 @@ +When --editable install is used for setup.cfg-only setuptools-based projects it doesn't work. diff --git a/src/pip/_internal/req/constructors.py b/src/pip/_internal/req/constructors.py index cfb1951b6b8..4c921607ceb 100644 --- a/src/pip/_internal/req/constructors.py +++ b/src/pip/_internal/req/constructors.py @@ -82,16 +82,17 @@ def parse_editable(editable_req): url_no_extras, extras = _strip_extras(url) if os.path.isdir(url_no_extras): - if not os.path.exists(os.path.join(url_no_extras, 'setup.py')): + if not os.path.exists(os.path.join(url_no_extras, 'setup.py')) and not os.path.exists(os.path.join(url_no_extras, 'setup.cfg')): msg = ( - 'File "setup.py" not found. Directory cannot be installed ' + 'File "setup.py" or "setup.cfg" not found. Directory cannot be installed ' 'in editable mode: {}'.format(os.path.abspath(url_no_extras)) ) pyproject_path = make_pyproject_path(url_no_extras) if os.path.isfile(pyproject_path): msg += ( '\n(A "pyproject.toml" file was found, but editable ' - 'mode currently requires a setup.py based build.)' + 'mode currently requires a setuptools-based build' + ' ("setup.py" or "setup.cfg" or both).)' ) raise InstallationError(msg) diff --git a/src/pip/_internal/utils/setuptools_build.py b/src/pip/_internal/utils/setuptools_build.py index 2a664b00703..20d1517b486 100644 --- a/src/pip/_internal/utils/setuptools_build.py +++ b/src/pip/_internal/utils/setuptools_build.py @@ -12,8 +12,8 @@ # invoking via the shim. This avoids e.g. the following manifest_maker # warning: "warning: manifest_maker: standard file '-c' not found". _SETUPTOOLS_SHIM = ( - "import sys, setuptools, tokenize; sys.argv[0] = {0!r}; __file__={0!r};" - "f=getattr(tokenize, 'open', open)(__file__);" + "import sys, setuptools.build_meta, tokenize; sys.argv[0] = {0!r}; __file__={0!r};" + "f = setuptools.build_meta._open_setup_script(__file__) if hasattr(setuptools.build_meta, '_open_setup_script') else getattr(tokenize, 'open', open)(__file__);" "code=f.read().replace('\\r\\n', '\\n');" "f.close();" "exec(compile(code, __file__, 'exec'))"