redbaron icon indicating copy to clipboard operation
redbaron copied to clipboard

bug: remove() doesn't perform well.

Open yhm138 opened this issue 2 years ago • 1 comments

I wrote one script with readbaron to remove code comments.

from redbaron import RedBaron

def remove_comments_with_redbaron(source_py_file):
    with open(source_py_file, 'r', encoding='utf-8') as file:
        red = RedBaron(file.read())
    comments = red.find_all('comment')
    for comment in comments:
        comment.parent.remove(comment)
    return red.dumps()


def main():
    source_py_file = input("Enter the path to the .py file to clean up: ")
    new_content = remove_comments_with_redbaron(source_py_file)
    new_file_name = source_py_file.replace('.py', '_nocmts.py')
    with open(new_file_name, 'w', encoding='utf-8') as new_file:
        new_file.write(new_content)
    print(f"Cleaned file has been saved as: {new_file_name}")

if __name__ == '__main__':
    main()

But there may be indentation errors in the output file.

.py file I used:

from collections import deque
from math import lcm

lines = [x for x in open('E:\\ExplorerDownload\input_day20.txt').read().strip().split('\n')]

adj = {}
conjs = {}
ffs = {}
rx_conj = ""

for line in lines:
    module, dests = line.split(" -> ")
    dests = dests.split(", ")
    t = module[0]
    if module == "broadcaster":
        adj["broadcaster"] = dests
    else:
        label = module[1:]
        adj[label] = dests

    if "rx" in dests:
        rx_conj = label

    if t == "&":
        conjs[label] = {}

    if t == "%":
        ffs[label] = False

for label, dests in adj.items():
    for dest in dests:
        if dest in conjs:
            conjs[dest][label] = 0


low_pulses = 0
high_pulses = 0
presses = 0
rx_conj_presses = {}


def press():
    global low_pulses, high_pulses, presses
    presses += 1

    low_pulses += 1 + len(adj["broadcaster"])
    queue = deque()
    for dest in adj["broadcaster"]:
        queue.append((0, "broadcaster", dest))

    while queue:
        pulse, src, label = queue.popleft()

        if label == "rx":
            continue

        # conjunction
        to_send = 0
        if label in conjs:
            conjs[label][src] = pulse
            if any(n == 0 for n in conjs[label].values()):
                to_send = 1

        # flip-flop
        if label in ffs:
            if pulse == 1:
                continue
            ffs[label] = not ffs[label]
            if ffs[label]:
                to_send = 1

        # increment low or high pulses
        if to_send == 1:
            high_pulses += len(adj[label])
        else:
            low_pulses += len(adj[label])

        # send pulse to destination modules
        for dest in adj[label]:
            queue.append((to_send, label, dest))

        # check if any of the inputs connected to the conjunction
        # connected to "rx" are one and record the number of presses
        for label, val in conjs[rx_conj].items():
            if val == 1 and label not in rx_conj_presses:
                rx_conj_presses[label] = presses


for _ in range(1000):
    press()

print(low_pulses * high_pulses)

while len(rx_conj_presses) < 4:
    press()

print(lcm(*rx_conj_presses.values()))

yhm138 avatar Dec 20 '23 07:12 yhm138

I have a similar issue, here is a small reproducible example:

from redbaron import RedBaron

code = """def foo():
    try:
        pass
    except:
        pass


def bar():
    pass

foo()
"""

tree = RedBaron(code)

for node in tree.find_all("def"):
    if node.name == "bar":
        tree.remove(node)
        
print(tree.dumps())

The output is:

def foo():
    try:
        pass
except:
        pass


foo()

which has an indentation error.

I'm using redbaron==0.9.2 and Python 3.10.12

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