-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Decoration] Exporting of rendered plots fails on windows (#370)
* Create draft PR for #369 * Fix export_plot on windows * black * Move temporary file creation out of method * Add missed flush * add tests for png export * add graphviz to dockerfile requirements * Use CloseableNamedTemporaryFile.py * Remove unnecessary use of temporary file * Add missing file deletion for 'closeable_temporary_file' * Rename CloseableNamedTemporaryFile.py * test CloseableNamedTemporaryFile * close CloseableNamedTemporaryFile before removing * black --------- Co-authored-by: rihi <[email protected]> Co-authored-by: rihi <[email protected]> Co-authored-by: Manuel Blatt <[email protected]> Co-authored-by: Manuel Blatt <[email protected]>
- Loading branch information
1 parent
271b469
commit d66b606
Showing
6 changed files
with
137 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import os | ||
from contextlib import contextmanager | ||
from tempfile import NamedTemporaryFile | ||
|
||
|
||
@contextmanager | ||
def CloseableNamedTemporaryFile(**kwargs): | ||
""" | ||
Context manager wrapper for NamedTemporaryFile, which allows | ||
closing the file handle without deleting the underling file. | ||
Deletion is delegated to the context manager closing. | ||
Note: With Python 3.12, a new parameter 'delete_on_close' is introduced | ||
for NamedTemporaryFile which accomplishes the same thing. Consequently, | ||
this api should be replaced when the code is updated to 3.12. | ||
""" | ||
|
||
kwargs["delete"] = False | ||
with NamedTemporaryFile(**kwargs) as file: | ||
try: | ||
yield file | ||
finally: | ||
# Close the file to be sure that it can be removed. | ||
# It's ok if the file was already closed because NamedTemporaryFile's close method is idempotent. | ||
file.close() | ||
# If file was already deleted outside of this contextmanager, this will crash | ||
# (just like the original NamedTemporaryFile). | ||
# On NT, this might also crash if another handle to this file is still open | ||
os.remove(file.name) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import os | ||
|
||
from decompiler.util.closeable_named_temporary_file import CloseableNamedTemporaryFile | ||
|
||
|
||
class TestCloseableNamedTemporaryFile: | ||
def test_usage_after_closing(self): | ||
with CloseableNamedTemporaryFile(mode="w") as file: | ||
file.write("test") | ||
file.close() | ||
with open(file.name, "r") as reopened_file: | ||
assert reopened_file.read() == "test" | ||
|
||
def test_deletion_with_close(self): | ||
with CloseableNamedTemporaryFile(mode="w") as file: | ||
file.close() | ||
assert not os.path.exists(file.name) | ||
|
||
def test_deletion_without_close(self): | ||
with CloseableNamedTemporaryFile(mode="w") as file: | ||
pass | ||
assert not os.path.exists(file.name) | ||
|
||
def test_close_after_delete(self): | ||
with CloseableNamedTemporaryFile(mode="w") as file: | ||
pass | ||
file.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters