Skip to content

Commit 9ca3542

Browse files
KOLANICHuranusjr
andcommitted
Fixed --editable install for setuptools projects without setup.py.
Co-Authored-By: Tzu-ping Chung <[email protected]>
1 parent 8365bc3 commit 9ca3542

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

Diff for: news/9547.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed the bug preventing the use of --editable installs for setup.cfg-only setuptools-based projects.

Diff for: src/pip/_internal/req/constructors.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,22 @@ def parse_editable(editable_req):
8282
url_no_extras, extras = _strip_extras(url)
8383

8484
if os.path.isdir(url_no_extras):
85-
if not os.path.exists(os.path.join(url_no_extras, 'setup.py')):
85+
if (
86+
not os.path.exists(os.path.join(url_no_extras, 'setup.py'))
87+
and
88+
not os.path.exists(os.path.join(url_no_extras, 'setup.cfg'))
89+
):
8690
msg = (
87-
'File "setup.py" not found. Directory cannot be installed '
88-
'in editable mode: {}'.format(os.path.abspath(url_no_extras))
91+
'File "setup.py" or "setup.cfg" not found. Directory cannot be '
92+
'installed in editable mode: {}'
93+
.format(os.path.abspath(url_no_extras))
8994
)
9095
pyproject_path = make_pyproject_path(url_no_extras)
9196
if os.path.isfile(pyproject_path):
9297
msg += (
9398
'\n(A "pyproject.toml" file was found, but editable '
94-
'mode currently requires a setup.py based build.)'
99+
'mode currently requires a setuptools-based build'
100+
' ("setup.py" or "setup.cfg" or both).)'
95101
)
96102
raise InstallationError(msg)
97103

Diff for: src/pip/_internal/utils/setuptools_build.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111
# invoking via the shim. This avoids e.g. the following manifest_maker
1212
# warning: "warning: manifest_maker: standard file '-c' not found".
1313
_SETUPTOOLS_SHIM = (
14-
"import sys, setuptools, tokenize; sys.argv[0] = {0!r}; __file__={0!r};"
15-
"f=getattr(tokenize, 'open', open)(__file__);"
16-
"code=f.read().replace('\\r\\n', '\\n');"
14+
"import io, os, sys, setuptools, tokenize; sys.argv[0] = {0!r}; __file__={0!r};"
15+
"f = getattr(tokenize, 'open', open)(__file__) "
16+
"if os.path.exists(__file__) "
17+
"else io.StringIO('from setuptools import setup; setup()');"
18+
"code = f.read().replace('\\r\\n', '\\n');"
1719
"f.close();"
1820
"exec(compile(code, __file__, 'exec'))"
1921
)

Diff for: tests/functional/test_install.py

+25-6
Original file line numberDiff line numberDiff line change
@@ -1028,15 +1028,13 @@ def test_install_package_with_prefix(script, data):
10281028
result.did_create(install_path)
10291029

10301030

1031-
def test_install_editable_with_prefix(script):
1031+
def _test_install_editable_with_prefix(script, files):
10321032
# make a dummy project
10331033
pkga_path = script.scratch_path / 'pkga'
10341034
pkga_path.mkdir()
1035-
pkga_path.joinpath("setup.py").write_text(textwrap.dedent("""
1036-
from setuptools import setup
1037-
setup(name='pkga',
1038-
version='0.1')
1039-
"""))
1035+
1036+
for fn, contents in files.items():
1037+
pkga_path.joinpath(fn).write_text(textwrap.dedent(contents))
10401038

10411039
if hasattr(sys, "pypy_version_info"):
10421040
site_packages = os.path.join(
@@ -1059,6 +1057,27 @@ def test_install_editable_with_prefix(script):
10591057
result.did_create(install_path)
10601058

10611059

1060+
def test_install_editable_with_prefix_setup_py(script):
1061+
setup_py = """from setuptools import setup
1062+
setup(name='pkga', version='0.1')"""
1063+
_test_install_editable_with_prefix(script, {"setup.py": setup_py})
1064+
1065+
1066+
def test_install_editable_with_prefix_setup_cfg(script):
1067+
setup_cfg = """[metadata]
1068+
name = pkga
1069+
version = 0.1"""
1070+
_test_install_editable_with_prefix(script, {"setup.cfg": setup_cfg})
1071+
1072+
1073+
def test_install_editable_with_prefix(script):
1074+
_test_install_editable_with_prefix(script, """
1075+
from setuptools import setup
1076+
setup(name='pkga',
1077+
version='0.1')
1078+
""")
1079+
1080+
10621081
def test_install_package_conflict_prefix_and_user(script, data):
10631082
"""
10641083
Test installing a package using pip install --prefix --user errors out

0 commit comments

Comments
 (0)