This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: subprocess.run: add an extra_env kwarg to complement existing env kwarg
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.9
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: brandtbucher, cjrh, gregory.p.smith, vapier
Priority: normal Keywords:

Created on 2020-03-05 02:10 by vapier, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (7)
msg363413 - (view) Author: Mike Frysinger (vapier) Date: 2020-03-05 02:10
a common idiom i run into is wanting to add/set one or two env vars when running a command via subprocess.  the only thing the API allows currently is inherting the current environment, or specifying the complete environment.  this means a lot of copying & pasting of the pattern:

 env = os.environ.copy()
 env['FOO'] = ...
 env['BAR'] = ...
 subprocess.run(..., env=env, ...)

it would nice if we could simply express this incremental behavior:

 subprocess.run(..., extra_env={'FOO': ..., 'BAR': ...}, ...)

then the subprocess API would take care of copying & merging.

 if extra_env:
   assert env is None
   env = os.environ.copy()
   env.update(extra_env)

this is akin to subprocess.run's capture_output shortcut.

it's unclear to me whether this would be in both subprocess.Popen & subprocess.run, or only subprocess.run.  it seems like subprocess.Popen elides convenience APIs.
msg363621 - (view) Author: Caleb Hattingh (cjrh) * Date: 2020-03-08 01:30
dict syntax tools make it fairy easy to compose new dicts from old ones with overrides:

    subprocess.run(..., env={**os.environ, 'FOO': ..., 'BAR', ...}, ...)

Would this be sufficient to avoid the copy/pasting boilerplate?
msg363624 - (view) Author: Brandt Bucher (brandtbucher) * (Python committer) Date: 2020-03-08 02:33
Caleb's answer, using PEP 584's merge operator:

    newenv = os.environ | {'FOO': ..., 'BAR': ...}
    subprocess.run(..., env=new_env, ...)
msg363627 - (view) Author: Brandt Bucher (brandtbucher) * (Python committer) Date: 2020-03-08 03:19
Ah, I didn't realize that os.environ and os.environ b aren't dict subclasses. I've added a ticket to update them with the new operators!
msg363805 - (view) Author: Mike Frysinger (vapier) Date: 2020-03-10 06:57
personally i still like having the extra_env setting explicitly broken out, but i agree that those operators help ease the majority of the pain.  i hadn't come across them before as they aren't in Python 2.

i wouldn't be upset if people declined the FR considering those options will be available in Python 3.9+.  thx for the tips.
msg363818 - (view) Author: Caleb Hattingh (cjrh) * Date: 2020-03-10 09:31
The dict unpacking generalizations that I posted were added in Python 3.5, which is pretty old by now. (But, true, is in Python 3 and not Python 2). This is the PEP: https://www.python.org/dev/peps/pep-0448/

The new syntax that Brandt posted will indeed only be available from 3.9 on.
msg363843 - (view) Author: Gregory P. Smith (gregory.p.smith) * (Python committer) Date: 2020-03-10 20:32
I think those dict unpacking and merging options are sufficient that adding an extra_env= parameter would merely complicate the already over complex API.

Thanks for the suggestions folks!
History
Date User Action Args
2022-04-11 14:59:27adminsetgithub: 84038
2020-03-10 20:32:27gregory.p.smithsetstatus: open -> closed
resolution: rejected
messages: + msg363843

stage: resolved
2020-03-10 13:18:52xtreaksetnosy: + gregory.p.smith
2020-03-10 09:31:11cjrhsetmessages: + msg363818
2020-03-10 06:57:33vapiersetmessages: + msg363805
2020-03-08 03:19:28brandtbuchersetmessages: + msg363627
2020-03-08 02:33:17brandtbuchersetnosy: + brandtbucher
messages: + msg363624
2020-03-08 01:30:03cjrhsetnosy: + cjrh
messages: + msg363621
2020-03-05 02:10:18vapiercreate