redbaron icon indicating copy to clipboard operation
redbaron copied to clipboard

[BUG] `return` on the 1-2 indent levels levels inside of `try`/`except` resets the closes `except` level

Open webknjaz opened this issue 6 years ago • 5 comments

While checking some code related to #190 I've discovered another bug.

Let me start with a demo:

from pathlib import Path
from redbaron import RedBaron

src = Path('demo.py').read_text()
fst = RedBaron(src)

fimp1, = fst.find_all('from_import')
fimp1.insert_after(fimp1)

Path('out.demo.py').write_text(fst.dumps())

demo.py:

from x import y


def func(x, y, z):
    try:
        return
        c()
    except:
        smth()

class A:
    try:
        return
        c()
    except:
        smth()

try:
    try:
        return
        c()
    except:
        smth()
except:
    pass

try:
    try:
        try:
            return
            c()
        except:
            smth()
        return
    except:
        pass
except:
    pass

out.demo.py:

from x import y
from x import y


def func(x, y, z):
    try:
        return
        c()
except:
        smth()

class A:
    try:
        return
        c()
except:
        smth()

try:
    try:
        return
        c()
except:
        smth()
except:
    pass

try:
    try:
        try:
            return
            c()
        except:
            smth()
        return
except:
        pass
except:
    pass

What's wrong?

If you look closer, you'll notice that some of the except: lines don't have any indentation at all after dumping. It looks like this only happens when the return statement is present in the try part and from ... import ... statement is inserted into FST (top level?). Also, it doesn't seem to affect try/return/except on the third level of nesting.

N.B. Along with this issue, I also observe #190.

webknjaz avatar Nov 19 '19 22:11 webknjaz

Can confirm! Also seeing this under similar circumstances.

wyattanderson avatar Dec 13 '19 20:12 wyattanderson

I was wrong. It's not a workaround.

Found a workaround: use the replace() method instead.

  from pathlib import Path

  from redbaron import RedBaron

  src = Path('original_module.py').read_text()
  fst = RedBaron(src)

  fimp1, *_ = fst.find_all('from_import')
- fimp1.insert_after(fimp1)
+ fimp1.replace(f'{fimp1.dumps()!s}\n{fimp1.dumps()!s}')

  Path('converted_module.py').write_text(fst.dumps())                                 

webknjaz avatar Jan 15 '20 23:01 webknjaz

hi, Is there any update or workaround for this issue?

DorConnecteam avatar May 14 '22 15:05 DorConnecteam

Has this issue been solved or is there a reliable workaround?

tanaymeh avatar Sep 09 '23 15:09 tanaymeh

I have a similar issue that may have common causes: https://github.com/PyCQA/redbaron/issues/222#issuecomment-2302415656

hoorelbeke-jimmy avatar Aug 21 '24 15:08 hoorelbeke-jimmy