Skip to content
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

In show_file, use os.remove to remove temporary images #6010

Merged
merged 3 commits into from Feb 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 4 additions & 2 deletions Tests/test_imageshow.py
Expand Up @@ -85,11 +85,13 @@ def test_ipythonviewer():
not on_ci() or is_win32(),
reason="Only run on CIs; hangs on Windows CIs",
)
def test_file_deprecated():
def test_file_deprecated(tmp_path):
f = str(tmp_path / "temp.jpg")
for viewer in ImageShow._viewers:
hopper().save(f)
with pytest.warns(DeprecationWarning):
try:
viewer.show_file(file="test.jpg")
viewer.show_file(file=f)
except NotImplementedError:
pass
with pytest.raises(TypeError):
Expand Down
148 changes: 118 additions & 30 deletions src/PIL/ImageShow.py
Expand Up @@ -15,7 +15,6 @@
import shutil
import subprocess
import sys
import tempfile
import warnings
from shlex import quote

Expand Down Expand Up @@ -127,6 +126,16 @@ def show_file(self, path=None, **options):
os.system(self.get_command(path, **options))
return 1

def _remove_path_after_delay(self, path):
subprocess.Popen(
[
sys.executable,
"-c",
"import os, sys, time; time.sleep(20); os.remove(sys.argv[1])",
path,
]
)


# --------------------------------------------------------------------

Expand Down Expand Up @@ -180,16 +189,8 @@ def show_file(self, path=None, **options):
path = options.pop("file")
else:
raise TypeError("Missing required argument: 'path'")
fd, temp_path = tempfile.mkstemp()
with os.fdopen(fd, "w") as f:
f.write(path)
with open(temp_path) as f:
subprocess.Popen(
["im=$(cat); open -a Preview.app $im; sleep 20; rm -f $im"],
shell=True,
stdin=f,
)
os.remove(temp_path)
subprocess.call(["open", "-a", "Preview.app", path])
self._remove_path_after_delay(path)
return 1


Expand All @@ -205,6 +206,16 @@ def get_command(self, file, **options):
command = self.get_command_ex(file, **options)[0]
return f"({command} {quote(file)}; rm -f {quote(file)})&"


class XDGViewer(UnixViewer):
"""
The freedesktop.org ``xdg-open`` command.
"""

def get_command_ex(self, file, **options):
command = executable = "xdg-open"
return command, executable

def show_file(self, path=None, **options):
"""
Display given file.
Expand All @@ -223,28 +234,11 @@ def show_file(self, path=None, **options):
path = options.pop("file")
else:
raise TypeError("Missing required argument: 'path'")
fd, temp_path = tempfile.mkstemp()
with os.fdopen(fd, "w") as f:
f.write(path)
with open(temp_path) as f:
command = self.get_command_ex(path, **options)[0]
subprocess.Popen(
["im=$(cat);" + command + " $im; rm -f $im"], shell=True, stdin=f
)
os.remove(temp_path)
subprocess.Popen(["xdg-open", path])
self._remove_path_after_delay(path)
return 1


class XDGViewer(UnixViewer):
"""
The freedesktop.org ``xdg-open`` command.
"""

def get_command_ex(self, file, **options):
command = executable = "xdg-open"
return command, executable


class DisplayViewer(UnixViewer):
"""
The ImageMagick ``display`` command.
Expand All @@ -257,6 +251,32 @@ def get_command_ex(self, file, title=None, **options):
command += f" -name {quote(title)}"
return command, executable

def show_file(self, path=None, **options):
"""
Display given file.

Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
and ``path`` should be used instead.
"""
if path is None:
if "file" in options:
warnings.warn(
"The 'file' argument is deprecated and will be removed in Pillow "
"10 (2023-07-01). Use 'path' instead.",
DeprecationWarning,
)
path = options.pop("file")
else:
raise TypeError("Missing required argument: 'path'")
args = ["display"]
if "title" in options:
args += ["-name", options["title"]]
args.append(path)

subprocess.Popen(args)
os.remove(path)
return 1


class GmDisplayViewer(UnixViewer):
"""The GraphicsMagick ``gm display`` command."""
Expand All @@ -266,6 +286,27 @@ def get_command_ex(self, file, **options):
command = "gm display"
return command, executable

def show_file(self, path=None, **options):
"""
Display given file.

Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
and ``path`` should be used instead.
"""
if path is None:
if "file" in options:
warnings.warn(
"The 'file' argument is deprecated and will be removed in Pillow "
"10 (2023-07-01). Use 'path' instead.",
DeprecationWarning,
)
path = options.pop("file")
else:
raise TypeError("Missing required argument: 'path'")
subprocess.Popen(["gm", "display", path])
os.remove(path)
return 1


class EogViewer(UnixViewer):
"""The GNOME Image Viewer ``eog`` command."""
Expand All @@ -275,6 +316,27 @@ def get_command_ex(self, file, **options):
command = "eog -n"
return command, executable

def show_file(self, path=None, **options):
"""
Display given file.

Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
and ``path`` should be used instead.
"""
if path is None:
if "file" in options:
warnings.warn(
"The 'file' argument is deprecated and will be removed in Pillow "
"10 (2023-07-01). Use 'path' instead.",
DeprecationWarning,
)
path = options.pop("file")
else:
raise TypeError("Missing required argument: 'path'")
subprocess.Popen(["eog", "-n", path])
os.remove(path)
return 1


class XVViewer(UnixViewer):
"""
Expand All @@ -290,6 +352,32 @@ def get_command_ex(self, file, title=None, **options):
command += f" -name {quote(title)}"
return command, executable

def show_file(self, path=None, **options):
"""
Display given file.

Before Pillow 9.1.0, the first argument was ``file``. This is now deprecated,
and ``path`` should be used instead.
"""
if path is None:
if "file" in options:
warnings.warn(
"The 'file' argument is deprecated and will be removed in Pillow "
"10 (2023-07-01). Use 'path' instead.",
DeprecationWarning,
)
path = options.pop("file")
else:
raise TypeError("Missing required argument: 'path'")
args = ["xv"]
if "title" in options:
args += ["-name", options["title"]]
args.append(path)

subprocess.Popen(args)
os.remove(path)
return 1


if sys.platform not in ("win32", "darwin"): # unixoids
if shutil.which("xdg-open"):
Expand Down