Skip to content

Commit

Permalink
Support - when running as an interpreter. (#543)
Browse files Browse the repository at this point in the history
It's surprising when using a pex in python interpreter mode that `-` is
not recognized as a program coming from stdin as regular python
interpreter would. Add support for this with a test.

The surprise of this missing feature was rightly identified in the
context of pantsbuild/pants#6275.
  • Loading branch information
jsirois authored Aug 24, 2018
1 parent f125317 commit 927433a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
12 changes: 8 additions & 4 deletions pex/pex.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,13 +417,17 @@ def _execute(self):

def execute_interpreter(self):
if sys.argv[1:]:
program = sys.argv[1]
try:
with open(sys.argv[1]) as fp:
name, content = sys.argv[1], fp.read()
if program == '-':
content = sys.stdin.read()
else:
with open(program) as fp:
content = fp.read()
except IOError as e:
die("Could not open %s in the environment [%s]: %s" % (sys.argv[1], sys.argv[0], e))
die("Could not open %s in the environment [%s]: %s" % (program, sys.argv[0], e))
sys.argv = sys.argv[1:]
self.execute_content(name, content)
self.execute_content(program, content)
else:
import code
code.interact()
Expand Down
17 changes: 17 additions & 0 deletions tests/test_pex.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Licensed under the Apache License, Version 2.0 (see LICENSE).

import os
import subprocess
import sys
import textwrap
from contextlib import contextmanager
Expand Down Expand Up @@ -342,3 +343,19 @@ def test_activate_interpreter_different_from_current():
pex._activate()
except SystemExit as e:
pytest.fail('PEX activation of %s failed with %s' % (pex, e))


def test_execute_interpreter_stdin_program():
with temporary_dir() as pex_chroot:
pex_builder = PEXBuilder(path=pex_chroot)
pex_builder.freeze()
process = PEX(pex_chroot).run(args=['-', 'one', 'two'],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE,
blocking=False)
stdout, stderr = process.communicate(input=b'import sys; print(" ".join(sys.argv[1:]))')

assert 0 == process.returncode
assert b'one two\n' == stdout
assert b'' == stderr

0 comments on commit 927433a

Please sign in to comment.