Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1b31dbd

Browse files
committed
Delayed import of pyparsing for fontconfig pattern matching
1 parent 898fbaa commit 1b31dbd

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

lib/matplotlib/fontconfig_pattern.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@
1616
from functools import lru_cache
1717
import re
1818

19-
from pyparsing import (Literal, ZeroOrMore, Optional, Regex, StringEnd,
20-
ParseException, Suppress)
21-
2219
family_punc = r'\\\-:,'
2320
family_unescape = re.compile(r'\\([%s])' % family_punc).sub
2421
family_escape = re.compile(r'([%s])' % family_punc).sub
@@ -27,6 +24,14 @@
2724
value_unescape = re.compile(r'\\([%s])' % value_punc).sub
2825
value_escape = re.compile(r'([%s])' % value_punc).sub
2926

27+
_SIMPLE_PATTERN_CACHE = {
28+
'cursive': {'family': ['cursive']},
29+
'sans': {'family': ['sans']},
30+
'monospace': {'family': ['monospace']},
31+
'sans:italic': {'family': ['sans'], 'slant': ['italic']},
32+
'sans:bold': {'family': ['sans'], 'weight': ['bold']},
33+
}
34+
3035

3136
class FontconfigPatternParser(object):
3237
"""A simple pyparsing-based parser for fontconfig-style patterns.
@@ -64,6 +69,10 @@ class FontconfigPatternParser(object):
6469
}
6570

6671
def __init__(self):
72+
# delayed import. Only executed when needed
73+
from pyparsing import (Literal, ZeroOrMore, Optional, Regex, StringEnd,
74+
ParseException, Suppress)
75+
6776
family = Regex(r'([^%s]|(\\[%s]))*' %
6877
(family_punc, family_punc)) \
6978
.setParseAction(self._family)
@@ -162,11 +171,33 @@ def _property(self, s, loc, tokens):
162171
return []
163172

164173

174+
@lru_cache(maxsize=1)
175+
def _get_parser():
176+
"""Return a cached FontconfigPatternParser instance."""
177+
return FontconfigPatternParser()
178+
179+
165180
# `parse_fontconfig_pattern` is a bottleneck during the tests because it is
166181
# repeatedly called when the rcParams are reset (to validate the default
167182
# fonts). In practice, the cache size doesn't grow beyond a few dozen entries
168183
# during the test suite.
169-
parse_fontconfig_pattern = lru_cache()(FontconfigPatternParser().parse)
184+
@lru_cache()
185+
def parse_fontconfig_pattern(pattern):
186+
"""
187+
Parse the given fontconfig *pattern* and return a dictionary
188+
of key/value pairs useful for initializing a
189+
:class:`font_manager.FontProperties` object.
190+
"""
191+
192+
# Try a lookup on simple patterns first. This can prevent the need to
193+
# create a full parser and to import pyparsing. If only patterns from
194+
# _SIMPLE_PATTERN_CACHE are used in the matplotlibrc file, this will
195+
# speed up the import of matplotlib.
196+
parsed = _SIMPLE_PATTERN_CACHE.get(pattern)
197+
if parsed is not None:
198+
return parsed
199+
200+
return _get_parser().parse(pattern)
170201

171202

172203
def generate_fontconfig_pattern(d):

0 commit comments

Comments
 (0)