diff --git a/testpath/commands.py b/testpath/commands.py index c40c18e..21e2430 100644 --- a/testpath/commands.py +++ b/testpath/commands.py @@ -74,8 +74,12 @@ def __init__(self, name, content=None, python=''): self.command_dir = tempfile.mkdtemp() if content is None: + # Shebangs have a limited length, so symlink the Python executable + # to a short name that can't conflict with the real command. + tmp_python = os.path.join(self.command_dir, 'python-' + name) + os.symlink(sys.executable, tmp_python) content = _record_run.format( - python=sys.executable, recording_file=self.recording_file, + python=tmp_python, recording_file=self.recording_file, extra_code=python, ) elif python: diff --git a/tests/test_commands.py b/tests/test_commands.py index 63955fb..34675e1 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -1,6 +1,9 @@ import os from subprocess import call, check_output import unittest +import shutil +import sys +import tempfile from testpath.commands import * @@ -35,6 +38,26 @@ def test_assert_calls_twice(self): with assert_calls('git'): pass + def test_assert_calls_long_python_path(self): + current_python = sys.executable + tmp = tempfile.mkdtemp() + try: + tmp_python_dir = tmp + for _ in range(10): + tmp_python_dir = os.path.join(tmp_python_dir, 'looooooooooooooooooooooooooooooooooooooooooong_segment') + os.makedirs(tmp_python_dir) + tmp_python = os.path.join(tmp_python_dir, 'python') + os.symlink(sys.executable, tmp_python) + sys.executable = tmp_python + + with assert_calls('i_dont_exist'): + call(['i_dont_exist']) + with assert_calls('git'): + call(['git']) + finally: + sys.executable = current_python + shutil.rmtree(tmp, ignore_errors=True) + def test_fixed_output(): t = 'Sat 24 Apr 17:11:58 BST 2021\n' with MockCommand.fixed_output('date', t) as mock_date: