4 # Copyright (C) 2005-2024 EDF
6 # This library is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU Lesser General Public
8 # License as published by the Free Software Foundation; either
9 # version 2.1 of the License, or (at your option) any later version.
11 # This library is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 # Lesser General Public License for more details.
16 # You should have received a copy of the GNU Lesser General Public
17 # License along with this library; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 # this module sets python 2.3 compatibility
26 # python 2.4 now have set in __builtin__ module
32 # python 2.4 enhance sort method in list object with key and reverse parameters, and introduced sorted function which do the same as sort but on a copied list
33 # as it's far more difficult to modify sort method, we implement a sorted fuction for python 2.3
35 def sorted(iterable, cmp=None, key=None, reverse=False) :
55 # string.Template allow us to create templated command without problem :
56 # configparser use standard substitution, so an error in template can make the config file invalid. With the new template, we avoid this problem
57 # thoses classes are stollen from python 2.4 string module
59 class _TemplateMetaclass(type):
62 (?P<escaped>%(delim)s) | # Escape sequence of two delimiters
63 (?P<named>%(id)s) | # delimiter and a Python identifier
64 {(?P<braced>%(id)s)} | # delimiter and a braced identifier
65 (?P<invalid>) # Other ill-formed delimiter exprs
69 def __init__(cls, name, bases, dct):
70 super(_TemplateMetaclass, cls).__init__(name, bases, dct)
74 pattern = _TemplateMetaclass.pattern % {
75 'delim' : re.escape(cls.delimiter),
78 cls.pattern = re.compile(pattern, re.IGNORECASE | re.VERBOSE)
81 class Template(metaclass=_TemplateMetaclass):
82 """A string class for supporting $-substitutions."""
85 idpattern = r'[_a-z][_a-z0-9]*'
87 def __init__(self, template):
88 self.template = template
90 # Search for $$, $identifier, ${identifier}, and any bare $'s
92 def _invalid(self, mo):
93 i = mo.start('invalid')
94 lines = self.template[:i].splitlines(True)
99 colno = i - len(''.join(lines[:-1]))
101 raise ValueError('Invalid placeholder in string: line %d, col %d' %
104 def substitute(self, *args, **kws):
106 raise TypeError('Too many positional arguments')
110 mapping = _multimap(kws, args[0])
113 # Helper function for .sub()
115 # Check the most common path first.
116 named = mo.group('named') or mo.group('braced')
117 if named is not None:
119 # We use this idiom instead of str() because the latter will
120 # fail if val is a Unicode containing non-ASCII characters.
122 if mo.group('escaped') is not None:
123 return self.delimiter
124 if mo.group('invalid') is not None:
126 raise ValueError('Unrecognized named group in pattern',
128 return self.pattern.sub(convert, self.template)
130 def safe_substitute(self, *args, **kws):
132 raise TypeError('Too many positional arguments')
136 mapping = _multimap(kws, args[0])
139 # Helper function for .sub()
141 named = mo.group('named')
142 if named is not None:
144 # We use this idiom instead of str() because the latter
145 # will fail if val is a Unicode containing non-ASCII
146 return '%s' % mapping[named]
148 return self.delimiter + named
149 braced = mo.group('braced')
150 if braced is not None:
152 return '%s' % mapping[braced]
154 return self.delimiter + '{' + braced + '}'
155 if mo.group('escaped') is not None:
156 return self.delimiter
157 if mo.group('invalid') is not None:
158 return self.delimiter
159 raise ValueError('Unrecognized named group in pattern',
161 return self.pattern.sub(convert, self.template)