-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent util.execute from reading output files #296
base: master
Are you sure you want to change the base?
Changes from 6 commits
03f672b
01a7425
335817e
2df24d3
132f5f8
f66a88b
2a78064
02b9432
4a3e389
3308c0a
a3d0ace
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -377,6 +377,7 @@ def execute( | |
infiles: Optional[Dict[str, str]] = None, | ||
outfiles: Optional[List[str]] = None, | ||
*, | ||
outfiles_track: Optional[List[str]] = [], | ||
as_binary: Optional[List[str]] = None, | ||
scratch_name: Optional[str] = None, | ||
scratch_directory: Optional[str] = None, | ||
|
@@ -404,6 +405,11 @@ def execute( | |
outfiles : List[str] = None | ||
Output file names to be collected after execution into | ||
values. May be {}. | ||
outfiles_track: List[str], optional | ||
Keys of `outfiles` to keep track of without loading their contents in memory. | ||
For specified filename in `outfiles_track`, the file path instead of contents | ||
is stored in `outfiles`. To ensure tracked files are not deleted after execution, | ||
you must set `scratch_messy=True`. | ||
as_binary : List[str] = None | ||
Keys of `infiles` or `outfiles` to be treated as bytes. | ||
scratch_name : str, optional | ||
|
@@ -428,7 +434,6 @@ def execute( | |
Run command through the shell. | ||
exit_code: int, optional | ||
The exit code above which the process is considered failure. | ||
|
||
Raises | ||
------ | ||
FileExistsError | ||
|
@@ -471,7 +476,9 @@ def execute( | |
) as scrdir: | ||
popen_kwargs["cwd"] = scrdir | ||
popen_kwargs["shell"] = shell | ||
with disk_files(infiles, outfiles, cwd=scrdir, as_binary=as_binary) as extrafiles: | ||
with disk_files( | ||
infiles, outfiles, cwd=scrdir, as_binary=as_binary, outfiles_track=outfiles_track | ||
) as extrafiles: | ||
with popen(command, popen_kwargs=popen_kwargs) as proc: | ||
# Wait for the subprocess to complete or the timeout to expire | ||
if interupt_after is None: | ||
|
@@ -562,7 +569,8 @@ def disk_files( | |
*, | ||
cwd: Optional[str] = None, | ||
as_binary: Optional[List[str]] = None, | ||
) -> Dict[str, Union[str, bytes]]: | ||
outfiles_track: Optional[List[str]] = [], | ||
) -> Dict[str, Union[str, bytes, Path]]: | ||
"""Write and collect files. | ||
|
||
Parameters | ||
|
@@ -577,10 +585,13 @@ def disk_files( | |
Directory to which to write and read files. | ||
as_binary : List[str] = None | ||
Keys in `infiles` (`outfiles`) to be written (read) as bytes, not decoded. | ||
|
||
outfiles_track: List[str], optional | ||
Keys of `outfiles` to keep track of (i.e. file contents not loaded in memory). | ||
For specified filename in `outfiles_track`, the file path instead of contents | ||
is stored in `outfiles`. | ||
Yields | ||
------ | ||
Dict[str] = str | ||
Dict[str, Union[str, bytes, Path]] | ||
outfiles with RHS filled in. | ||
|
||
""" | ||
|
@@ -604,19 +615,33 @@ def disk_files( | |
|
||
finally: | ||
for fl in outfiles.keys(): | ||
omode = "rb" if fl in as_binary else "r" | ||
try: | ||
filename = lwd / fl | ||
with open(filename, omode) as fp: | ||
outfiles[fl] = fp.read() | ||
LOGGER.info(f"... Writing ({omode}): {filename}") | ||
except (OSError, FileNotFoundError): | ||
if "*" in fl: | ||
filename = lwd / fl | ||
if fl not in outfiles_track: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are you handling the case when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, this will not work (bigfile will be loaded in memory). For {
...
"outfiles": ["*"],
"outfiles_track": ["bigfile"],
...
} or the opposite: {
...
"outfiles": ["bigfile", ...],
"outfiles_track": ["*"],
...
}
I guess the main advantage in setting |
||
omode = "rb" if fl in as_binary else "r" | ||
try: | ||
with open(filename, omode) as fp: | ||
outfiles[fl] = fp.read() | ||
LOGGER.info(f"... Reading ({omode}): {filename}") | ||
except (OSError, FileNotFoundError): | ||
if "*" in fl: | ||
gfls = {} | ||
for gfl in lwd.glob(fl): | ||
with open(gfl, omode) as fp: | ||
gfls[gfl.name] = fp.read() | ||
LOGGER.info(f"... Reading ({omode}): {gfl}") | ||
if not gfls: | ||
gfls = None | ||
outfiles[fl] = gfls | ||
else: | ||
outfiles[fl] = None | ||
else: | ||
if filename.is_file(): | ||
outfiles[fl] = filename | ||
elif "*" in fl: | ||
gfls = {} | ||
for gfl in lwd.glob(fl): | ||
with open(gfl, omode) as fp: | ||
gfls[gfl.name] = fp.read() | ||
LOGGER.info(f"... Writing ({omode}): {gfl}") | ||
if gfl.is_file(): | ||
gfls[gfl.name] = gfl | ||
if not gfls: | ||
gfls = None | ||
outfiles[fl] = gfls | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably better to have
None
here, likeas_binary
. https://stackoverflow.com/questions/26320899/why-is-the-empty-dictionary-a-dangerous-default-value-in-pythonThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point but shouldn't matter here since
outfiles_track
should never be modified, but if you're concerned someone might I could change its type to an immutable object like aTuple
OR if you prefer a list for consistency that is by defaultNone
, I could add a single line todisk_files
:that would make the current code work with no additional changes.