From 188338007fa5f9d11538056c1a86ae45d997a34a Mon Sep 17 00:00:00 2001 From: Thomas A Caswell Date: Mon, 5 Oct 2020 17:48:21 -0400 Subject: [PATCH] MNT: make certifi actually optional In #18636 we removed certifi as a runtime dependency, but it turns out we do try to use it if you read from a url in a handful of places. This makes us fail gracefully and log if we can not import certifi. --- lib/matplotlib/__init__.py | 13 +++++++++++-- lib/matplotlib/image.py | 8 ++++++-- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/__init__.py b/lib/matplotlib/__init__.py index fc4c0e1de0d7..6362edafe02c 100644 --- a/lib/matplotlib/__init__.py +++ b/lib/matplotlib/__init__.py @@ -717,7 +717,11 @@ def is_url(filename): @functools.lru_cache() def _get_ssl_context(): - import certifi + try: + import certifi + except ImportError: + _log.debug("Could not import certifi.") + return None import ssl return ssl.create_default_context(cafile=certifi.where()) @@ -726,7 +730,12 @@ def _get_ssl_context(): def _open_file_or_url(fname): if not isinstance(fname, Path) and is_url(fname): import urllib.request - with urllib.request.urlopen(fname, context=_get_ssl_context()) as f: + ssl_ctx = _get_ssl_context() + if ssl_ctx is None: + _log.debug( + "Could not get certifi ssl context, https may not work." + ) + with urllib.request.urlopen(fname, context=ssl_ctx) as f: yield (line.decode('utf-8') for line in f) else: fname = os.path.expanduser(fname) diff --git a/lib/matplotlib/image.py b/lib/matplotlib/image.py index 0dc4449b4abc..23ee9f8b3e7d 100644 --- a/lib/matplotlib/image.py +++ b/lib/matplotlib/image.py @@ -1478,8 +1478,12 @@ def imread(fname, format=None): if len(parsed.scheme) > 1: # Pillow doesn't handle URLs directly. # hide imports to speed initial import on systems with slow linkers from urllib import request - with request.urlopen(fname, - context=mpl._get_ssl_context()) as response: + ssl_ctx = mpl._get_ssl_context() + if ssl_ctx is None: + _log.debug( + "Could not get certifi ssl context, https may not work." + ) + with request.urlopen(fname, context=ssl_ctx) as response: import io try: response.seek(0)