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