Skip to content

Commit

Permalink
gh-38135: Use magick command instead of the deprecated convert if…
Browse files Browse the repository at this point in the history
… available

The `convert` command is deprecated and throws a warning at runtime.

URL: #38135
Reported by: Antonio Rojas
Reviewer(s): Dima Pasechnik
  • Loading branch information
Release Manager committed Jul 12, 2024
2 parents 7982725 + 64eaf5a commit 7411980
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 59 deletions.
4 changes: 2 additions & 2 deletions build/pkgs/configure/checksums.ini
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
tarball=configure-VERSION.tar.gz
sha1=1451031f1325bb7d31929b92415ee25795ed7022
sha256=a5c2064d5c792d32bbfa6c97a72aab395764ed7882f9bcadb8f04ca34c42c6b4
sha1=2fe177f49970106f210c9afca8668efad5b985df
sha256=9c6d24b778a4c805c91e58263265dbd4214e1215c6e90246a10637c83500d552
2 changes: 1 addition & 1 deletion build/pkgs/configure/package-version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
812a1160c06c055f74f9fcc86a7678c5a7a8788c
3243fc5218a7fb9f29493ce1fd35e6aa120c8c86
2 changes: 1 addition & 1 deletion src/sage/doctest/external.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ def has_ffmpeg():

def has_imagemagick():
"""
Test if ImageMagick (command convert) is available.
Test if ImageMagick (command magick or convert) is available.
EXAMPLES::
Expand Down
40 changes: 22 additions & 18 deletions src/sage/features/imagemagick.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
r"""
Feature for testing the presence of ``imagemagick``
Currently we only check for the presence of ``convert``. When needed, other
commands like ``magick``, ``magick-script``, ``convert``, ``mogrify``,
Currently we only check for the presence of ``convert`` or ``magick``. When needed, other
commands like ``magick-script``, ``mogrify``,
``identify``, ``composite``, ``montage``, ``compare``, etc. could be also
checked in this module.
"""
Expand All @@ -21,35 +21,39 @@
from . import Executable, FeatureTestResult
from .join_feature import JoinFeature

class Convert(Executable):
class Magick(Executable):
r"""
A :class:`~sage.features.Feature` describing the presence of ``convert``.
A :class:`~sage.features.Feature` describing the presence of ``magick`` or the deprecated ``convert``.
EXAMPLES::
sage: from sage.features.imagemagick import Convert
sage: Convert().is_present() # optional - imagemagick
FeatureTestResult('convert', True)
sage: from sage.features.imagemagick import Magick
sage: Magick().is_present() # optional - imagemagick
FeatureTestResult('magick', True)
"""
def __init__(self):
r"""
TESTS::
sage: from sage.features.imagemagick import Convert
sage: isinstance(Convert(), Convert)
sage: from sage.features.imagemagick import Magick
sage: isinstance(Magick(), Magick)
True
"""
Executable.__init__(self, "convert", executable="convert")
Executable.__init__(self, "magick", executable="magick")
try:
_ = self.absolute_filename()
except RuntimeError:
Executable.__init__(self, "magick", executable="convert")

def is_functional(self):
r"""
Return whether command ``convert`` in the path is functional.
Return whether command ``magick`` or ``convert`` in the path is functional.
EXAMPLES::
sage: from sage.features.imagemagick import Convert
sage: Convert().is_functional() # optional - imagemagick
FeatureTestResult('convert', True)
sage: from sage.features.imagemagick import Magick
sage: Magick().is_functional() # optional - imagemagick
FeatureTestResult('magick', True)
"""
# Create the content of 1-pixel png file
Expand Down Expand Up @@ -78,9 +82,9 @@ def is_functional(self):
filename, _png = os.path.splitext(filename_png)
filename_gif = filename + '.gif'

# running command convert (taken from sage/plot/animate.py)
# running command magick/convert (taken from sage/plot/animate.py)
from subprocess import run
cmd = ['convert', '-dispose', 'Background', '-delay', '20',
cmd = [self.executable, '-dispose', 'Background', '-delay', '20',
'-loop', '0', filename_png, filename_gif]

try:
Expand Down Expand Up @@ -110,7 +114,7 @@ class ImageMagick(JoinFeature):
A :class:`~sage.features.Feature` describing the presence of
:ref:`ImageMagick <spkg_imagemagick>`
Currently, only the availability of the :class:`convert` program is checked.
Currently, only the availability of the :class:`magick` (or :class:`convert`) program is checked.
EXAMPLES::
Expand All @@ -127,7 +131,7 @@ def __init__(self):
True
"""
JoinFeature.__init__(self, "imagemagick",
[Convert()],
[Magick()],
spkg="imagemagick",
url="https://www.imagemagick.org/")

Expand Down
4 changes: 2 additions & 2 deletions src/sage/graphs/graph_latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
the four compass points
To use LaTeX in Sage you of course need a working TeX installation and it will
work best if you have the ``dvipng`` and ``convert`` utilities. For graphs you
work best if you have the ``dvipng`` and ``magick`` utilities. For graphs you
need the ``tkz-graph.sty`` and ``tkz-berge.sty`` style files of the tkz-graph
package. TeX, dvipng, and convert should be widely available through package
managers or installers. You may need to install the tkz-graph style files in
Expand All @@ -69,7 +69,7 @@
- TeX: http://ctan.org/
- dvipng: http://sourceforge.net/projects/dvipng/
- convert: http://www.imagemagick.org (the ImageMagick suite)
- magick: http://www.imagemagick.org (the ImageMagick suite)
- tkz-graph: https://www.ctan.org/pkg/tkz-graph
Customizing the output is accomplished in several ways. Suppose ``g`` is a
Expand Down
41 changes: 21 additions & 20 deletions src/sage/misc/latex.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,22 +681,22 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i
else:
raise ValueError("Unsupported LaTeX engine.")

# if png output + latex, check to see if dvipng or convert is installed.
# if png output + latex, check to see if dvipng or magick/convert is installed.
from sage.features.imagemagick import ImageMagick
from sage.features.dvipng import dvipng
if png:
if ((not engine or engine == "latex")
and not (dvipng().is_present() or ImageMagick().is_present())):
print()
print("Error: neither dvipng nor convert (from the ImageMagick suite)")
print("Error: neither dvipng nor magick/convert (from the ImageMagick suite)")
print("appear to be installed. Displaying LaTeX, PDFLaTeX output")
print("requires at least one of these programs, so please install")
print("and try again.")
print()
print("Go to http://sourceforge.net/projects/dvipng/ and")
print("http://www.imagemagick.org to download these programs.")
return "Error"
# if png output + [pdf|xe|lua]latex, check to see if convert is installed.
# if png output + [pdf|xe|lua]latex, check to see if magick/convert is installed.
elif engine in ["pdflatex", "xelatex", "lualatex"]:
ImageMagick().require()
# check_validity: check to see if the dvi file is okay by trying
Expand All @@ -705,7 +705,7 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i
# function.
#
# thus if not png output, check validity of dvi output if dvipng
# or convert is installed.
# or magick/convert is installed.
else:
check_validity = dvipng().is_present()
# set up filenames, other strings:
Expand Down Expand Up @@ -733,10 +733,11 @@ def _run_latex_(filename, debug=False, density=150, engine=None, png=False, do_i

ps2pdf = ['ps2pdf', filename + '.ps']

# We seem to need a larger size when using convert compared to
# We seem to need a larger size when using magick/convert compared to
# when using dvipng:
density = int(1.4 * density / 1.3)
convert = ['convert', '-density',
from sage.features.imagemagick import Magick
magick = [Magick().executable, '-density',
'{0}x{0}'.format(density), '-trim', filename + '.' + suffix,
filename + '.png']

Expand All @@ -754,10 +755,10 @@ def subpcall(x):
if debug:
print(lt)
if png:
print(convert)
print(magick)
e = subpcall(lt)
if png:
e = e and subpcall(convert)
e = e and subpcall(magick)
else: # latex
if (png or check_validity):
if dvipng().is_present():
Expand All @@ -768,19 +769,19 @@ def subpcall(x):
dvipng_error = not os.path.exists(os.path.join(base, filename + '.png'))
# If there is no png file, then either the latex
# process failed or dvipng failed. Assume that dvipng
# failed, and try running dvips and convert. (If the
# latex process failed, then dvips and convert will
# failed, and try running dvips and magick/convert. (If the
# latex process failed, then dvips and magick/convert will
# fail also, so we'll still catch the error.)
if dvipng_error:
if png:
if ImageMagick().is_present():
if debug:
print("'dvipng' failed; trying 'convert' instead...")
print("'dvipng' failed; trying 'magick/convert' instead...")
print(dvips)
print(convert)
e = subpcall(dvips) and subpcall(convert)
print(magick)
e = subpcall(dvips) and subpcall(magick)
else:
print("Error: 'dvipng' failed and 'convert' is not installed.")
print("Error: 'dvipng' failed and 'magick/convert' is not installed.")
return "Error: dvipng failed."
else: # not png, i.e., check_validity
return_suffix = "pdf"
Expand All @@ -796,12 +797,12 @@ def subpcall(x):
print("error running dvips and ps2pdf; trying pdflatex instead...")
print(pdflt)
e = subpcall(pdflt)
else: # do not have dvipng, so must have convert. run latex, dvips, convert.
else: # do not have dvipng, so must have magick/convert. run latex, dvips, magick/convert.
if debug:
print(lt)
print(dvips)
print(convert)
e = subpcall(lt) and subpcall(dvips) and subpcall(convert)
print(magick)
e = subpcall(lt) and subpcall(dvips) and subpcall(magick)
if not e:
print("An error occurred.")
try:
Expand Down Expand Up @@ -902,7 +903,7 @@ class Latex(LatexCall):
.. WARNING::
You must have dvipng (or dvips and convert) installed
You must have dvipng (or dvips and magick/convert) installed
on your operating system, or this command will not work.
EXAMPLES::
Expand Down Expand Up @@ -1013,9 +1014,9 @@ def eval(self, x, globals, strip=False, filename=None, debug=None,
.. WARNING::
When using ``'latex'`` (the default), you must have ``dvipng`` (or
``dvips`` and ``convert``) installed on your operating system, or
``dvips`` and ``magick/convert``) installed on your operating system, or
this command will not work. When using ``'pdflatex'``, ``'xelatex'``
or ``'lualatex'``, you must have ``convert`` installed.
or ``'lualatex'``, you must have ``magick/convert`` installed.
OUTPUT:
Expand Down
26 changes: 13 additions & 13 deletions src/sage/plot/animate.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
object, creating a sequence of PNG files.
These are then assembled to various target formats using different
tools.
In particular, the ``convert`` program from ImageMagick_ can be used to
In particular, the ``magick/convert`` program from ImageMagick_ can be used to
generate an animated GIF file.
FFmpeg_ (with the command line program ``ffmpeg``) provides support for
various video formats, but also an alternative method of generating
Expand All @@ -20,7 +20,7 @@
Note that ``ImageMagick`` and ``FFmpeg`` are not included with Sage, and
must be installed by the user. On unix systems, type ``which
convert`` at a command prompt to see if ``convert`` (part of the
magick`` at a command prompt to see if ``magick`` (part of the
``ImageMagick`` suite) is installed. If it is, you will be given its
location. Similarly, you can check for ``ffmpeg`` with ``which
ffmpeg``. See the websites of ImageMagick_ or FFmpeg_ for
Expand Down Expand Up @@ -567,11 +567,11 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False,
objects in self.
This method will only work if either (a) the ImageMagick
software suite is installed, i.e., you have the ``convert``
software suite is installed, i.e., you have the ``magick/convert``
command or (b) ``ffmpeg`` is installed. See the web sites of
ImageMagick_ and FFmpeg_ for more details. By default, this
produces the gif using ``convert`` if it is present. If this
can't find ``convert`` or if ``use_ffmpeg`` is True, then it
produces the gif using Imagemagick if it is present. If this
can't find ImageMagick or if ``use_ffmpeg`` is True, then it
uses ``ffmpeg`` instead.
INPUT:
Expand All @@ -589,7 +589,7 @@ def gif(self, delay=20, savefile=None, iterations=0, show_path=False,
print the path to the saved file
- ``use_ffmpeg`` -- boolean (default: ``False``); if True, use
'ffmpeg' by default instead of 'convert'.
'ffmpeg' by default instead of ImageMagick
If ``savefile`` is not specified: in notebook mode, display the
animation; otherwise, save it to a default file name.
Expand Down Expand Up @@ -651,7 +651,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False,
the frames in ``self``.
This method will only work if ``imagemagick`` is installed (command
``convert``). See https://www.imagemagick.org for information
``magick`` or ``convert``). See https://www.imagemagick.org for information
about ``imagemagick``.
INPUT:
Expand Down Expand Up @@ -690,12 +690,12 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False,
like this::
FeatureNotPresentError: imagemagick is not available.
Executable 'convert' not found on PATH.
Executable 'magick' not found on PATH.
Further installation instructions might be available at
https://www.imagemagick.org/.
"""
from sage.features.imagemagick import ImageMagick
from sage.features.imagemagick import ImageMagick, Magick
ImageMagick().require()

if not savefile:
Expand All @@ -706,7 +706,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False,

# running the command
directory = self.png()
cmd = ['convert', '-dispose', 'Background',
cmd = [Magick().executable, '-dispose', 'Background',
'-delay', '%s' % int(delay), '-loop', '%s' % int(iterations),
'*.png', savefile]
from subprocess import run
Expand All @@ -721,7 +721,7 @@ def _gif_from_imagemagick(self, savefile=None, show_path=False,
result.stderr.strip(),
result.stdout.strip()))
raise OSError("Error: Cannot generate GIF animation. "
"The convert command (ImageMagick) is present but does "
"The magick/convert command (ImageMagick) is present but does "
"not seem to be functional. Verify that the objects "
"passed to the animate command can be saved in PNG "
"image format. "
Expand Down Expand Up @@ -825,7 +825,7 @@ def show(self, delay=None, iterations=None, **kwds):
Currently this is done using an animated gif, though this
could change in the future. This requires that either
ffmpeg or the ImageMagick suite (in particular, the
``convert`` command) is installed.
``magick/convert`` command) is installed.
See also the :meth:`ffmpeg` method.
Expand Down Expand Up @@ -1121,7 +1121,7 @@ def save(self, filename=None, show_path=False, use_ffmpeg=False, **kwds):
print the path to the saved file
- ``use_ffmpeg`` -- boolean (default: ``False``); if True, use
'ffmpeg' by default instead of 'convert' when creating GIF
'ffmpeg' by default instead of ImageMagick when creating GIF
files.
If filename is None, then in notebook mode, display the
Expand Down
4 changes: 2 additions & 2 deletions src/sage/plot/plot3d/tachyon.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@
sage: fname_png = tmp_filename(ext='.png')
sage: fname_ppm = tmp_filename(ext='.ppm')
sage: T.save(fname_png)
sage: r2 = os.system('convert '+fname_png+' '+fname_ppm) # optional -- ImageMagick
sage: from sage.features.imagemagick import Magick
sage: r2 = os.system(Magick().executable+' '+fname_png+' '+fname_ppm) # optional -- ImageMagick
sage: # optional - imagemagick
sage: T = Tachyon(xres=800, yres=600,
....: camera_position=(-2.0,-.1,.3),
Expand Down

0 comments on commit 7411980

Please sign in to comment.