From 8da80130dbc747f3954b4904247d26289fe722f9 Mon Sep 17 00:00:00 2001
From: Andrew Murray <radarhere@users.noreply.github.com>
Date: Mon, 17 Jan 2022 08:59:17 +1100
Subject: [PATCH] In show_file, use os.remove to remove temporary images

Conflict:NA
Reference:https://github.com/python-pillow/Pillow/pull/6010/commits/8da80130dbc747f3954b4904247d26289fe722f9

---
 Tests/test_imageshow.py |   6 +-
 src/PIL/ImageShow.py    | 124 ++++++++++++++++++++++++++++++----------
 2 files changed, 98 insertions(+), 32 deletions(-)

diff --git a/Tests/test_imageshow.py b/Tests/test_imageshow.py
index f79a531..5983ebf 100644
--- a/Tests/test_imageshow.py
+++ b/Tests/test_imageshow.py
@@ -69,11 +69,13 @@ def test_viewers():
     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):
diff --git a/src/PIL/ImageShow.py b/src/PIL/ImageShow.py
index b3b9a5b..e4eb2f8 100644
--- a/src/PIL/ImageShow.py
+++ b/src/PIL/ImageShow.py
@@ -15,7 +15,6 @@ import os
 import shutil
 import subprocess
 import sys
-import tempfile
 import warnings
 from shlex import quote
 
@@ -169,16 +168,15 @@ class MacViewer(Viewer):
                 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])
+        subprocess.Popen(
+            [
+                sys.executable,
+                "-c",
+                "import os, sys, time;time.sleep(20);os.remove(sys.argv[1])",
+                path,
+            ]
+        )
         return 1
 
 
@@ -194,6 +192,16 @@ class UnixViewer(Viewer):
         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"""
         if path is None:
@@ -206,27 +214,10 @@ class UnixViewer(Viewer):
                 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])
+        os.remove(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."""
@@ -235,6 +226,32 @@ class DisplayViewer(UnixViewer):
         command = executable = "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'")
+        args = ["display"]
+        if "title" in options:
+            args += ["-name", options["title"]]
+        args.append(path)
+
+        subprocess.Popen(args)
+        os.remove(path)
+        return 1
+
 
 class EogViewer(UnixViewer):
     """The GNOME Image Viewer ``eog`` command."""
@@ -243,6 +260,27 @@ class EogViewer(UnixViewer):
         command = executable = "eog"
         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):
     """
@@ -258,6 +296,32 @@ class XVViewer(UnixViewer):
             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"):
-- 
2.27.0

