diff --git a/.travis.yml b/.travis.yml index 56901a44412d..c6971c322498 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,22 +19,25 @@ addons: - result_images.tar.bz2 apt: packages: + - cm-super + - dvipng + - gdb + - gir1.2-gtk-3.0 + - graphviz - inkscape - libav-tools - - gdb + - libcairo2 + - libgeos-dev + - libgirepository-1.0.1 + - lmodern - mencoder - - dvipng + - otf-freefont - pgf - - lmodern - - cm-super + - texlive-fonts-recommended - texlive-latex-base - texlive-latex-extra - - texlive-fonts-recommended - texlive-latex-recommended - texlive-xetex - - graphviz - - libgeos-dev - - otf-freefont env: global: @@ -123,6 +126,10 @@ install: # install was successful by trying to import the toolkit (sometimes, the # install appears to be successful but shared libraries cannot be loaded at # runtime, so an actual import is a better check). + pip install cairocffi pgi && + python -c 'import pgi as gi; gi.require_version("Gtk", "3.0"); from pgi.repository import Gtk' && + echo 'pgi is available' || + echo 'pgi is not available' pip install pyqt5 && python -c 'import PyQt5.QtCore' && echo 'PyQt5 is available' || diff --git a/doc/glossary/index.rst b/doc/glossary/index.rst index a4713567726a..487caed10f4a 100644 --- a/doc/glossary/index.rst +++ b/doc/glossary/index.rst @@ -8,8 +8,8 @@ Glossary .. glossary:: AGG - The Anti-Grain Geometry (`Agg `_) rendering engine, capable of rendering - high-quality images + The Anti-Grain Geometry (`Agg `_) rendering + engine, capable of rendering high-quality images Cairo The `Cairo graphics `_ engine @@ -20,7 +20,8 @@ Glossary provides extensions to the standard datetime module EPS - Encapsulated Postscript (`EPS `_) + Encapsulated Postscript (`EPS + `_) FreeType `FreeType `_ is a font rasterization @@ -32,7 +33,8 @@ Glossary The Gimp Drawing Kit for GTK+ GTK - The GIMP Toolkit (`GTK `_) graphical user interface library + The GIMP Toolkit (`GTK `_) graphical user interface + library JPG The Joint Photographic Experts Group (`JPEG @@ -47,13 +49,14 @@ Glossary deviation, fourier transforms, and convolutions. PDF - Adobe's Portable Document Format (`PDF `_) + Adobe's Portable Document Format (`PDF + `_) PNG Portable Network Graphics (`PNG - `_), a raster graphics format - that employs lossless data compression which is more suitable - for line art than the lossy jpg format. Unlike the gif format, + `_), a raster + graphics format that employs lossless data compression which is more + suitable for line art than the lossy jpg format. Unlike the gif format, png is not encumbered by requirements for a patent license. PS @@ -64,12 +67,24 @@ Glossary channel. PDF was designed in part as a next-generation document format to replace postscript + pgi + `pgi ` exists as a relatively + new Python wrapper to GTK3 and acts as a pure python alternative to + PyGObject. pgi still exists in its infancy, currently missing many + features of PyGObject. However Matplotlib does not use any of these + missing features. + pygtk `pygtk `_ provides python wrappers for the :term:`GTK` widgets library for use with the GTK or GTKAgg backend. Widely used on linux, and is often packages as 'python-gtk2' + PyGObject + Like :term:`pygtk`, `PyGObject ` provides + python wrappers for the :term:`GTK` widgets library; unlike pygtk, + PyGObject wraps GTK3 instead of the now obsolete GTK2. + pyqt `pyqt `_ provides python wrappers for the :term:`Qt` widgets library and is required by @@ -82,14 +97,12 @@ Glossary language widely used for scripting, application development, web application servers, scientific computing and more. - pytz `pytz `_ provides the Olson tz database in Python. it allows accurate and cross platform timezone calculations and solves the issue of ambiguous times at the end of daylight savings - Qt `Qt `__ is a cross-platform application framework for desktop and embedded development. diff --git a/doc/users/next_whats_new/2017-12-04-AL-pgi.rst b/doc/users/next_whats_new/2017-12-04-AL-pgi.rst new file mode 100644 index 000000000000..4f774bef6989 --- /dev/null +++ b/doc/users/next_whats_new/2017-12-04-AL-pgi.rst @@ -0,0 +1,19 @@ +PGI bindings for gtk3 +--------------------- + +The GTK3 backends can now use PGI_ instead of PyGObject_. PGI is a fairly +incomplete binding for GObject, thus its use is not recommended; its main +benefit is its availability on Travis (thus allowing CI testing for the gtk3agg +and gtk3cairo backends). + +The binding selection rules are as follows: +- if ``gi`` has already been imported, use it; else +- if ``pgi`` has already been imported, use it; else +- if ``gi`` can be imported, use it; else +- if ``pgi`` can be imported, use it; else +- error out. + +Thus, to force usage of PGI when both bindings are installed, import it first. + +.. _PGI: https://pgi.readthedocs.io/en/latest/ +.. _PyGObject: http://pygobject.readthedocs.io/en/latest/# diff --git a/lib/matplotlib/backends/_gtk3_compat.py b/lib/matplotlib/backends/_gtk3_compat.py new file mode 100644 index 000000000000..825fa2341c80 --- /dev/null +++ b/lib/matplotlib/backends/_gtk3_compat.py @@ -0,0 +1,41 @@ +""" +GObject compatibility loader; supports ``gi`` and ``pgi``. + +The binding selection rules are as follows: +- if ``gi`` has already been imported, use it; else +- if ``pgi`` has already been imported, use it; else +- if ``gi`` can be imported, use it; else +- if ``pgi`` can be imported, use it; else +- error out. + +Thus, to force usage of PGI when both bindings are installed, import it first. +""" + +from __future__ import (absolute_import, division, print_function, + unicode_literals) + +import six + +import importlib +import sys + + +if "gi" in sys.modules: + import gi +elif "pgi" in sys.modules: + import pgi as gi +else: + try: + import gi + except ImportError: + try: + import pgi as gi + except ImportError: + raise ImportError("The Gtk3 backend requires PyGObject or pgi") + + +gi.require_version("Gtk", "3.0") +globals().update( + {name: + importlib.import_module("{}.repository.{}".format(gi.__name__, name)) + for name in ["GLib", "GObject", "Gtk", "Gdk"]}) diff --git a/lib/matplotlib/backends/backend_gtk3.py b/lib/matplotlib/backends/backend_gtk3.py index 3e1225b8a0b1..606b01977cdd 100644 --- a/lib/matplotlib/backends/backend_gtk3.py +++ b/lib/matplotlib/backends/backend_gtk3.py @@ -7,39 +7,20 @@ import os import sys -try: - import gi -except ImportError: - raise ImportError("Gtk3 backend requires pygobject to be installed.") - -try: - gi.require_version("Gtk", "3.0") -except AttributeError: - raise ImportError( - "pygobject version too old -- it must have require_version") -except ValueError: - raise ImportError( - "Gtk3 backend requires the GObject introspection bindings for Gtk 3 " - "to be installed.") - -try: - from gi.repository import Gtk, Gdk, GObject, GLib -except ImportError: - raise ImportError("Gtk3 backend requires pygobject to be installed.") - import matplotlib +from matplotlib import ( + backend_tools, cbook, colors as mcolors, lines, rcParams) from matplotlib._pylab_helpers import Gcf from matplotlib.backend_bases import ( _Backend, FigureCanvasBase, FigureManagerBase, GraphicsContextBase, - NavigationToolbar2, RendererBase, TimerBase, cursors) -from matplotlib.backend_bases import ToolContainerBase, StatusbarBase + NavigationToolbar2, RendererBase, StatusbarBase, TimerBase, + ToolContainerBase, cursors) from matplotlib.backend_managers import ToolManager from matplotlib.cbook import is_writable_file_like from matplotlib.figure import Figure from matplotlib.widgets import SubplotTool +from ._gtk3_compat import GLib, GObject, Gtk, Gdk -from matplotlib import ( - backend_tools, cbook, colors as mcolors, lines, rcParams) _log = logging.getLogger(__name__) diff --git a/lib/matplotlib/backends/backend_gtk3agg.py b/lib/matplotlib/backends/backend_gtk3agg.py index a8bce0c4e6fc..5d175ec7eccc 100644 --- a/lib/matplotlib/backends/backend_gtk3agg.py +++ b/lib/matplotlib/backends/backend_gtk3agg.py @@ -42,7 +42,7 @@ def on_draw_event(self, widget, ctx): else: bbox_queue = self._bbox_queue - if HAS_CAIRO_CFFI: + if HAS_CAIRO_CFFI and not isinstance(ctx, cairo.Context): ctx = cairo.Context._from_pointer( cairo.ffi.cast('cairo_t **', id(ctx) + object.__basicsize__)[0], diff --git a/lib/matplotlib/backends/backend_gtk3cairo.py b/lib/matplotlib/backends/backend_gtk3cairo.py index 79ba1fc2d24d..f27d38ecdb26 100644 --- a/lib/matplotlib/backends/backend_gtk3cairo.py +++ b/lib/matplotlib/backends/backend_gtk3cairo.py @@ -12,7 +12,7 @@ class RendererGTK3Cairo(backend_cairo.RendererCairo): def set_context(self, ctx): - if HAS_CAIRO_CFFI: + if HAS_CAIRO_CFFI and not isinstance(ctx, cairo.Context): ctx = cairo.Context._from_pointer( cairo.ffi.cast( 'cairo_t **', diff --git a/lib/matplotlib/tests/test_backends_interactive.py b/lib/matplotlib/tests/test_backends_interactive.py index 0a8b7d80276c..07d5759bbe0c 100644 --- a/lib/matplotlib/tests/test_backends_interactive.py +++ b/lib/matplotlib/tests/test_backends_interactive.py @@ -17,17 +17,22 @@ def _get_testable_interactive_backends(): - return [ - pytest.mark.skipif( - not os.environ.get("DISPLAY") - or sys.version_info < (3,) - or importlib.util.find_spec(module_name) is None, - reason="No $DISPLAY or could not import {!r}".format(module_name))( - backend) - for module_name, backend in [ - ("PyQt5", "qt5agg"), - ("tkinter", "tkagg"), - ("wx", "wxagg")]] + backends = [] + for deps, backend in [(["cairocffi", "pgi"], "gtk3agg"), + (["cairocffi", "pgi"], "gtk3cairo"), + (["PyQt5"], "qt5agg"), + (["tkinter"], "tkagg"), + (["wx"], "wxagg")]: + reason = None + if sys.version_info < (3,): + reason = "Py3-only test" + elif not os.environ.get("DISPLAY"): + reason = "No $DISPLAY" + elif any(importlib.util.find_spec(dep) is None for dep in deps): + reason = "Missing dependency" + backends.append(pytest.mark.skip(reason=reason)(backend) if reason + else backend) + return backends _test_script = """\ pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy