tomerfiliba / plumbum

Plumbum: Shell Combinators
https://plumbum.readthedocs.io
MIT License
2.79k stars 182 forks source link

StdinDataRedirection commands fail upon modification (TEE, FG, etc.) #604

Closed jesteria closed 2 years ago

jesteria commented 2 years ago

Commands to which standard input has been supplied from a Python string – which are StdinDataRedirection commands – erroneously throw exception RedirectionError when combined with built-in modifiers –

stdin is already redirected

– even though stdin is only being redirected the one time.


>>> from plumbum import TEE, FG, local                                          

# this works

>>> local['ls']['-d', '/'] & FG                                                                                                                               
/                                                                              
>>> local['ls']['-d', '/'] & TEE                                                                                                                              
/                                     
(0, '/\n', '')

# this does not work

>>> (local['cat']['-'] << 'this breaks') & FG                                   
Traceback (most recent call last):                                                                                                                            
    …
    raise RedirectionError("stdin is already redirected")
plumbum.commands.base.RedirectionError: stdin is already redirected

Affected modifiers invoke cmd.run(stdin=None, …). It appears sufficient to change these to simply omit the keyword pair stdin=None.

However, it's unclear whether this would have unwanted side-effects; and, it seems rather that StdinDataRedirection is in the wrong, in throwing an exception over the value None.

BaseRedirection.popen permits either PIPE or None:

if self.KWARG in kwargs and kwargs[self.KWARG] not in (PIPE, None):
    raise RedirectionError(…)

StdinDataRedirection.popen only permits PIPE:

if "stdin" in kwargs and kwargs["stdin"] != PIPE:
    raise RedirectionError(…)

→ As such, the resolution is perhaps that the above check in StdinDataRedirection.popen be made to mirror BaseRedirection.popen.