21
21
22
22
import six
23
23
24
- import re , sys
25
- from pyparsing import Literal , ZeroOrMore , \
26
- Optional , Regex , StringEnd , ParseException , Suppress
24
+ import re
25
+ import sys
26
+ from pyparsing import (Literal , ZeroOrMore , Optional , Regex , StringEnd ,
27
+ ParseException , Suppress )
28
+
29
+ try :
30
+ from functools import lru_cache
31
+ except ImportError :
32
+ from backports .functools_lru_cache import lru_cache
27
33
28
34
family_punc = r'\\\-:,'
29
35
family_unescape = re .compile (r'\\([%s])' % family_punc ).sub
@@ -166,7 +172,13 @@ def _property(self, s, loc, tokens):
166
172
self ._properties .setdefault (key , []).extend (val )
167
173
return []
168
174
169
- parse_fontconfig_pattern = FontconfigPatternParser ().parse
175
+
176
+ # `parse_fontconfig_pattern` is a bottleneck during the tests because it is
177
+ # repeatedly called when the rcParams are reset (to validate the default
178
+ # fonts). In practice, the cache size doesn't grow beyond a few dozen entries
179
+ # during the test suite.
180
+ parse_fontconfig_pattern = lru_cache ()(FontconfigPatternParser ().parse )
181
+
170
182
171
183
def generate_fontconfig_pattern (d ):
172
184
"""
@@ -180,7 +192,8 @@ def generate_fontconfig_pattern(d):
180
192
val = getattr (d , 'get_' + key )()
181
193
if val is not None and val != []:
182
194
if type (val ) == list :
183
- val = [value_escape (r'\\\1' , str (x )) for x in val if x is not None ]
195
+ val = [value_escape (r'\\\1' , str (x )) for x in val
196
+ if x is not None ]
184
197
if val != []:
185
198
val = ',' .join (val )
186
199
props .append (":%s=%s" % (key , val ))
0 commit comments