24
Find the bug (a classic) (programming.dev)
class Node:
    def __init__(self, edges = set()):
        self.edges = edges


def main():
    foo = Node()
    bar = Node()
    quz = Node()

    foo.edges.add(bar)
    bar.edges.add(foo)

    assert(foo is not bar) # assertion succeeds
    assert(foo is not quz) # assertion succeeds
    assert(bar is not quz) # assertion succeeds
    assert(len(quz.edges) == 0) # assertion fails??


main()

spoilerMutable default values are shared across objects. The set in this case.

all 12 comments
sorted by: hot top new old
[-] technohacker@programming.dev 10 points 2 years ago* (last edited 2 years ago)

Oh I had a similar bug but with defaulted dicts. Default args are constructed once and reused. Not a problem for immutable args, but mutables like dicts (and sets I'd also assume) are all shared.

EDIT: whoops, didn't see you spoilered the answer, my bad! If it helps, i found my bug when dealing with cross-thread stuff, so that was a fun moment to bisect

[-] joyjoy@lemm.ee 4 points 2 years ago

You may like collections.defaultdict. Pass the constructor a factory function to be run when a key is missing.

dd = defaultdict(list)
dd['key'].append("value")
print(dd['key'])  # ["value"]
[-] technohacker@programming.dev 1 points 2 years ago

Ah sorry I meant a default argument which was a dict, thanks for the tip tho!

[-] m_f@discuss.online 3 points 2 years ago* (last edited 2 years ago)

Yeah, I discovered this when a coworker wrote code like def foo(timestamp = now()) and had fun debugging why there were a bunch of duplicate timestamps.

PEP 671 would add new syntax to ease the pain, but it's not accepted yet. It would allow for writing function definitions like one of these:

def bisect_right(a, x, lo=0, hi=>len(a), *, key=None):
def connect(timeout=>default_timeout):
def add_item(item, target=>[]):
def format_time(fmt, time_t=>time.time()):
[-] FizzyOrange@programming.dev 2 points 2 years ago

Yeah Pylint catches this. If you aren't using Pylint you are writing bad Python.

[-] milkisklim@lemm.ee 6 points 2 years ago

That's a funny way to spell Ruff

[-] FizzyOrange@programming.dev 3 points 2 years ago

Yeah I tried Ruff about a year ago and it only had really trivial lints so it wasn't a good replacement for Pylint. Is it on par yet?

[-] milkisklim@lemm.ee 2 points 2 years ago* (last edited 2 years ago)

What do you mean by trivial? I am not necessarily the most experienced coder, but it does a great job yelling at me to keep methods short and simple.

I'd suggest taking five minutes whenever and look up the ruff ruleset to see if it would be helpful for you.

Also maybe because I don't know how to use pylint in vs code, but the only semi useful thing it catches for me is if my venv doesn't have a library the code imports.

Edit: For example, Ruff has caught this bug (mutable argument defaults) in my code before.

[-] FizzyOrange@programming.dev 1 points 2 years ago

it does a great job yelling at me to keep methods short and simple

Yes style things like that are what I would consider trivial. I also think those are actively bad lints. Yes methods should be short in general, but making it a hard enforced limit means you end up getting sidetracked by refactoring when you only wanted to add one line to a method.

[-] Michal@programming.dev 2 points 2 years ago

Static set argument?

[-] waz@lemmy.world 1 points 2 years ago* (last edited 2 years ago)

Wow, I learned this bug during a job interview I had this week. I'm not much of a Python guy, but I was givin a Python coding challenge and I tried default initializing a parameter to an empty list. The guy interviewing me looked horrified and explained the problem and sent me an article about it to read later. It's a odd coincidence coming across it twice in one week.

this post was submitted on 26 Feb 2025
24 points (96.2% liked)

Python

8019 readers
3 users here now

Welcome to the Python community on the programming.dev Lemmy instance!

📅 Events

PastNovember 2023

October 2023

July 2023

August 2023

September 2023

🐍 Python project:
💓 Python Community:
✨ Python Ecosystem:
🌌 Fediverse
Communities
Projects
Feeds

founded 3 years ago
MODERATORS