Skip to content

Commit 35991d5

Browse files
committed
Support -c for plat spec dists in multiplat pexes.
Fixes pex-tool#537
1 parent 927433a commit 35991d5

File tree

3 files changed

+64
-10
lines changed

3 files changed

+64
-10
lines changed

pex/finders.py

+14-9
Original file line numberDiff line numberDiff line change
@@ -293,17 +293,22 @@ def get_script_from_distributions(name, dists):
293293

294294

295295
def get_entry_point_from_console_script(script, dists):
296-
# check all distributions for the console_script "script"
297-
entries = frozenset(filter(None, (
298-
dist.get_entry_map().get('console_scripts', {}).get(script) for dist in dists)))
296+
# Check all distributions for the console_script "script". De-dup by dist key to allow for a
297+
# duplicate console script IFF the distribution is platform-specific and this is a multi-platform
298+
# pex.
299+
def get_entrypoint(dist):
300+
script_entry = dist.get_entry_map().get('console_scripts', {}).get(script)
301+
if script_entry is not None:
302+
# Entry points are of the form 'foo = bar', we just want the 'bar' part.
303+
return dist.key, str(script_entry).split('=')[1].strip()
304+
305+
entries = frozenset(filter(None, (get_entrypoint(dist) for dist in dists)))
299306

300-
# if multiple matches, freak out
301307
if len(entries) > 1:
302308
raise RuntimeError(
303-
'Ambiguous script specification %s matches multiple entry points:%s' % (
304-
script, ' '.join(map(str, entries))))
309+
'Ambiguous script specification %s matches multiple entry points:\n\t%s' % (
310+
script, '\n\t'.join('%s from %s' % (entry_point, key) for key, entry_point in entries)))
305311

306312
if entries:
307-
entry_point = next(iter(entries))
308-
# entry points are of the form 'foo = bar', we just want the 'bar' part:
309-
return str(entry_point).split('=')[1].strip()
313+
_, entry_point = next(iter(entries))
314+
return entry_point

tests/test_finders.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,12 @@
44
import zipimport
55

66
import pkg_resources
7+
import pytest
78

89
from pex.finders import ChainedFinder
910
from pex.finders import _add_finder as add_finder
1011
from pex.finders import _remove_finder as remove_finder
11-
from pex.finders import find_eggs_in_zip, get_script_from_egg
12+
from pex.finders import find_eggs_in_zip, get_entry_point_from_console_script, get_script_from_egg
1213

1314
try:
1415
import mock
@@ -118,3 +119,32 @@ def test_get_script_from_egg():
118119

119120
assert location is None
120121
assert content is None
122+
123+
124+
class FakeDist(object):
125+
def __init__(self, key, console_script_entry):
126+
self.key = key
127+
script = console_script_entry.split('=')[0].strip()
128+
self._entry_map = {'console_scripts': {script: console_script_entry}}
129+
130+
def get_entry_map(self):
131+
return self._entry_map
132+
133+
134+
def test_get_entry_point_from_console_script():
135+
dists = [FakeDist(key='fake', console_script_entry='bob= bob.main:run'),
136+
FakeDist(key='fake', console_script_entry='bob =bob.main:run')]
137+
assert 'bob.main:run' == get_entry_point_from_console_script('bob', dists)
138+
139+
140+
def test_get_entry_point_from_console_script_conflict():
141+
dists = [FakeDist(key='bob', console_script_entry='bob= bob.main:run'),
142+
FakeDist(key='fake', console_script_entry='bob =bob.main:run')]
143+
with pytest.raises(RuntimeError):
144+
get_entry_point_from_console_script('bob', dists)
145+
146+
147+
def test_get_entry_point_from_console_script_dne():
148+
dists = [FakeDist(key='bob', console_script_entry='bob= bob.main:run'),
149+
FakeDist(key='fake', console_script_entry='bob =bob.main:run')]
150+
assert None is get_entry_point_from_console_script('jane', dists)

tests/test_integration.py

+19
Original file line numberDiff line numberDiff line change
@@ -981,3 +981,22 @@ def test_invalid_entry_point_verification_3rdparty():
981981
'-o', pex_out_path,
982982
'--validate-entry-point'])
983983
res.assert_failure()
984+
985+
986+
@pytest.mark.skipif(NOT_CPYTHON36)
987+
def test_multiplatform_entrypoint():
988+
with temporary_dir() as td:
989+
pex_out_path = os.path.join(td, 'p537.pex')
990+
991+
res = run_pex_command(['p537==1.0.1',
992+
'--no-build',
993+
'--interpreter-constraint=CPython>=3.6,<3.7',
994+
'--platform=linux-x86_64',
995+
'--platform=macosx-10.13-x86_64',
996+
'-c', 'p537',
997+
'-o', pex_out_path,
998+
'--validate-entry-point'])
999+
res.assert_success()
1000+
1001+
greeting = subprocess.check_output([pex_out_path])
1002+
assert b'Hello World!' == greeting.strip()

0 commit comments

Comments
 (0)