Gets a C expression as used in PO files for plural forms and returns a Python function that implements an equivalent expression.
(plural)
| 194 | |
| 195 | |
| 196 | def c2py(plural): |
| 197 | """Gets a C expression as used in PO files for plural forms and returns a |
| 198 | Python function that implements an equivalent expression. |
| 199 | """ |
| 200 | |
| 201 | if len(plural) > 1000: |
| 202 | raise ValueError('plural form expression is too long') |
| 203 | try: |
| 204 | result, nexttok = _parse(_tokenize(plural)) |
| 205 | if nexttok: |
| 206 | raise _error(nexttok) |
| 207 | |
| 208 | depth = 0 |
| 209 | for c in result: |
| 210 | if c == '(': |
| 211 | depth += 1 |
| 212 | if depth > 20: |
| 213 | # Python compiler limit is about 90. |
| 214 | # The most complex example has 2. |
| 215 | raise ValueError('plural form expression is too complex') |
| 216 | elif c == ')': |
| 217 | depth -= 1 |
| 218 | |
| 219 | ns = {'_as_int': _as_int, '__name__': __name__} |
| 220 | exec('''if True: |
| 221 | def func(n): |
| 222 | if not isinstance(n, int): |
| 223 | n = _as_int(n) |
| 224 | return int(%s) |
| 225 | ''' % result, ns) |
| 226 | return ns['func'] |
| 227 | except RecursionError: |
| 228 | # Recursion error can be raised in _parse() or exec(). |
| 229 | raise ValueError('plural form expression is too complex') |
| 230 | |
| 231 | |
| 232 | def _expand_lang(loc): |