asciimoo/exrex

Python 3.6 issue with groups

Closed this issue · 3 comments

vwyu commented

With Python 3.6, the command exrex "(a|b)" results in error:

Traceback (most recent call last):
  File "~/.local/bin/exrex", line 11, in <module>
    load_entry_point('exrex==0.10.4', 'console_scripts', 'exrex')()
  File "~/.local/bin/exrex.py", line 512, in __main__
    args['output'].write(next(g))
  File "~/.local/bin/exrex.py", line 144, in ggen
    g2 = f(*args, **kwargs)
  File "~/.local/bin/exrex.py", line 167, in _gen
    for i in d:
TypeError: 'int' object is not iterable

I expect to see:

a
b

It seems that the problem is due to a change in what is returned from the parse function in Python 3.6.

I tried the following in both Python 3.5.2 and Python 3.6:

from re import sre_parse
print(sre_parse.parse("(a|b)"))

The result for Python 3.5.2:

[(SUBPATTERN, (1, [(IN, [(LITERAL, 97), (LITERAL, 98)])]))]

The result for Python 3.6:

[(SUBPATTERN, (1, 0, 0, [(IN, [(LITERAL, 97), (LITERAL, 98)])]))]

I just downloaded the module, and am having the same problem.

I am not familiar with the output of module re.sre_parse, however, the following seems to remedy the problem for at least i[0] == sre_parse.SUBPATTERN.

line 209      ret = ggen(ret, _gen, i[1][
line 210 -                1], limit=limit, count=False, grouprefs=grouprefs, groupref=i[1][0])
line 210 +                3], limit=limit, count=False, grouprefs=grouprefs, groupref=i[1][0])

Line 208 should probably also change the index key from i[1][1] to i[1][3].

EDIT: i[0] == sre_parse.ASSERT fails; i[1] = (1, [(LITERAL, 120)]).
Changed to x = i[1][1] if i[0] == sre_parse.ASSERT else i[1][3], however, tests.py

[+] generation test passed
[+] count test passed
[E] Assertion error! "(foo|bar)(20|)16"
        2 not match
[-] random generation test failed

@vwyu @bunnyamin thank you the report and the detailed description. Hopefully the bug is fixed on the latest master. Could you verify?

    exrex.getone('(a|(b|(c|d)))', 11) -> 'd'

    exrex.generate('(a|(b|(c|d)))', 11)) ->
        'a'
        'b'
        'c'
        'd'

    []$ ./exrex/tests.py
        [+] generation test passed
        [+] count test passed
        [+] random generation test passed
        [+] simplification test passed