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