@@ -2030,10 +2030,18 @@ def csnames(group: str, names: Iterable[str]) -> Regex:
2030
2030
# elements is important for speed.)
2031
2031
p .auto_delim = Forward ()
2032
2032
p .placeable = Forward ()
2033
+ p .named_placeable = Forward ()
2033
2034
p .required_group = Forward ()
2034
2035
p .optional_group = Forward ()
2035
2036
p .token = Forward ()
2036
2037
2038
+ # Workaround for placable being part of a cycle of definitions
2039
+ # calling `p.placeable("name")` results in a copy, so not guaranteed
2040
+ # to get the definition added after it is used.
2041
+ # ref https://github.com/matplotlib/matplotlib/issues/25204
2042
+ # xref https://github.com/pyparsing/pyparsing/issues/95
2043
+ p .named_placeable <<= p .placeable
2044
+
2037
2045
set_names_and_parse_actions () # for mutually recursive definitions.
2038
2046
2039
2047
p .optional_group <<= "{" + ZeroOrMore (p .token )("group" ) + "}"
@@ -2043,7 +2051,7 @@ def csnames(group: str, names: Iterable[str]) -> Regex:
2043
2051
2044
2052
p .accent = (
2045
2053
csnames ("accent" , [* self ._accent_map , * self ._wide_accents ])
2046
- - p .placeable ("sym" ))
2054
+ - p .named_placeable ("sym" ))
2047
2055
2048
2056
p .function = csnames ("name" , self ._function_names )
2049
2057
@@ -2089,7 +2097,7 @@ def csnames(group: str, names: Iterable[str]) -> Regex:
2089
2097
+ OneOrMore (oneOf (["_" , "^" ]) - p .placeable )("subsuper" )
2090
2098
+ Regex ("'*" )("apostrophes" ))
2091
2099
| Regex ("'+" )("apostrophes" )
2092
- | (p .placeable ("nucleus" ) + Regex ("'*" )("apostrophes" ))
2100
+ | (p .named_placeable ("nucleus" ) + Regex ("'*" )("apostrophes" ))
2093
2101
)
2094
2102
2095
2103
p .simple = p .space | p .customspace | p .font | p .subsuper
0 commit comments