Skip to content

Commit 3f8220c

Browse files
dwighthubbardDwight Hubbard
andauthored
Add flag to interpreter the command as a module passed as the -m flag to the interpreter running the command. (#41)
* Add flag to interpreter the command as a module passed as the `-m` flag to the interpreter running the command. * Add flag to interpreter the command as a module passed as the `-m` flag to the interpreter running the command. * Add flag to interpreter the command as a module passed as the `-m` flag to the interpreter running the command. * Add flag to interpreter the command as a module passed as the `-m` flag to the interpreter running the command. --------- Co-authored-by: Dwight Hubbard <[email protected]>
1 parent be9413d commit 3f8220c

File tree

7 files changed

+51
-12
lines changed

7 files changed

+51
-12
lines changed

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,20 @@ $ pip install pypirun
6969
The following will run the command `serviceping -c 1 yahoo.com` from the [serviceping](https://pypi.org/project/serviceping/) package:
7070

7171
```console
72-
dhubbard@mac:~$ pypirun serviceping serviceping -c 1 yahoo.com
72+
$ pypirun serviceping serviceping -c 1 yahoo.com
7373
SERVICEPING yahoo.com:80 (72.30.35.10:80).
7474
from yahoo.com:80 (72.30.35.10:80): time=65.50 ms --- yahoo.com ping statistics ---
7575
1 packages transmitted, 1 received, 0.0% package loss, time 73.038ms
7676
rtt min/avg/max/dev = 65.50/65.50/65.50/0.00 ms
7777
```
7878

79+
### Run the screwdrivercd.installdeps module from the screwdrivercd package as a script
80+
81+
```console
82+
$ pypirun -m screwdrivercd screwdrivercd.installdeps
83+
$
84+
```
85+
7986
## Screwdriver V4 pypirun command
8087

8188
The pypirun package publishes a screwdriver v4 shared command called `python/pypirun`.

screwdriver.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ version: 4
22
shared:
33
environment:
44
PACKAGE_DIRECTORY: src
5+
TOX_ENVLIST: py39,py310,py311
56

67
jobs:
78
validate_test:

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ packages=
2929
package_dir=
3030
=src
3131

32-
python_requires = >= 3.8
32+
python_requires = >= 3.9
3333
zip_safe = True
3434

3535
[options.entry_points]

src/pypirun/arguments.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ def parse_arguments() -> argparse.Namespace:
4040
parser.add_argument('--no-cache-dir', default=False, action='store_true', help="Disable the pip cache when installing")
4141
parser.add_argument('--upgrade_pip', default=False, action='store_true', help='Upgrade the pip before installing packages')
4242
parser.add_argument('--upgrade_setuptools', default=False, action='store_true', help="Upgrade setuptools before installing packages")
43+
parser.add_argument('--module', '-m', default=False, action='store_true', help='Run library module as a script')
4344
parser.add_argument('package', type=str, help='Package the command is in')
4445
parser.add_argument('command', nargs='*', help='Command to run')
4546

@@ -51,7 +52,7 @@ def parse_arguments() -> argparse.Namespace:
5152
command = []
5253
in_command = False
5354
for argument in sys.argv[1:]:
54-
if not in_command and argument.startswith('--'):
55+
if not in_command and argument.startswith('-'):
5556
argv.append(argument)
5657
continue
5758
in_command = True
@@ -64,7 +65,11 @@ def parse_arguments() -> argparse.Namespace:
6465
raise ParseError('Insufficient arguments provided')
6566

6667
args = parser.parse_args(args=argv)
67-
args.package = command[0]
68-
args.command = command[1:]
6968

69+
args.package = command[0]
70+
if args.module:
71+
args.module = command[1]
72+
args.command = command[2:]
73+
else:
74+
args.command = command[1:]
7075
return args

src/pypirun/cli.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ def interpreter_parent(interpreter):
4545
return interpreter
4646

4747

48-
def install_and_run(package, command, interpreter, debug=False, no_cache_dir=False, upgrade_setuptools=False, upgrade_pip=False):
48+
def install_and_run(package, command, interpreter, module='', debug=False, no_cache_dir=False, upgrade_setuptools=False, upgrade_pip=False):
4949
"""
5050
Install a package and run a command in a temporary Python virtualenv
5151
@@ -59,7 +59,10 @@ def install_and_run(package, command, interpreter, debug=False, no_cache_dir=Fal
5959
6060
interpreter: str
6161
The python interpreter executable to use to create the virtualenv
62-
62+
63+
module: str
64+
Python module for the interpreter to run
65+
6366
debug: bool, optional
6467
Print more useful debug output. Default: False
6568
@@ -125,8 +128,14 @@ def install_and_run(package, command, interpreter, debug=False, no_cache_dir=Fal
125128
print(f'Installed files: {list(venv_bin_after-venv_bin_before)}')
126129

127130
# Run the command
131+
if module:
132+
command = f'{venv_dir}/bin/python3 -m {module} {command}'
133+
else:
134+
command = f'{venv_dir}/bin/{command}'
135+
if debug:
136+
print(f'Running: {command}')
128137
try:
129-
subprocess.check_call(f'{venv_dir}/bin/{command}', shell=True) # nosec
138+
subprocess.check_call(command, shell=True) # nosec
130139
except subprocess.CalledProcessError as error: # pragma: no cover
131140
return error.returncode
132141
return exit_ok() # pragma: no cover
@@ -151,7 +160,10 @@ def main():
151160
except ParseError:
152161
return 1
153162
interpreter = args.interpreter
154-
command_file = args.command[0]
163+
if args.module:
164+
command_file = ''
165+
else:
166+
command_file = args.command[0]
155167
command = ' '.join(args.command)
156168
if not interpreter: # pragma: no cover
157169
interpreter = interpreter_parent(sys.executable)
@@ -161,8 +173,8 @@ def main():
161173
print('Unable to find python3 interpreter')
162174
return 1
163175

164-
if args.always_install or not shutil.which(command_file):
165-
return install_and_run(package=args.package, command=command, interpreter=interpreter, debug=args.debug, no_cache_dir=args.no_cache_dir, upgrade_setuptools=args.upgrade_setuptools, upgrade_pip=args.upgrade_pip)
176+
if args.always_install or args.module or not shutil.which(command_file):
177+
return install_and_run(package=args.package, command=command, interpreter=interpreter, module=args.module, debug=args.debug, no_cache_dir=args.no_cache_dir, upgrade_setuptools=args.upgrade_setuptools, upgrade_pip=args.upgrade_pip)
166178

167179
try:
168180
subprocess.check_call(command, shell=True) # nosec

tests/test_arguments.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,17 @@ def test_parse_arguments_defaults__package_command(self):
3939
self.assertFalse(result.upgrade_setuptools)
4040
self.assertEqual(result.package, 'foo')
4141
self.assertEqual(result.command, ['bar'])
42+
43+
def test_parse_arguments_module(self):
44+
sys.argv = ['parse_arguments', '-m', 'foo', 'bar']
45+
default_interpreter = os.environ.get('BASE_PYTHON', None)
46+
result = pypirun.arguments.parse_arguments()
47+
self.assertIsInstance(result, argparse.Namespace)
48+
self.assertEqual(result.interpreter, default_interpreter)
49+
self.assertFalse(result.debug)
50+
self.assertFalse(result.always_install)
51+
self.assertFalse(result.upgrade_pip)
52+
self.assertFalse(result.upgrade_setuptools)
53+
self.assertEqual(result.module, 'bar')
54+
self.assertEqual(result.package, 'foo')
55+
self.assertEqual(result.command, [])

tox.ini

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ package_dir = src/pypirun
55
package_name = pypirun
66

77
[tox]
8-
envlist = py38,py39,py310,py311
8+
envlist = py39,py310,py311
99
isolated_build = True
1010
skip_missing_interpreters = true
1111

0 commit comments

Comments
 (0)