News for hackers. Stuff that matters.
Re:I'm Switching to Python and Actually Liking It by bobbylarrybobby on Wednesday July 16, 2025 @12:28PM (#44584142)
This isn't really unique to the walrus operator, it's just a general python quirk (albeit one I find incredibly annoying). `for i in range(5): ...` will leave `i` bound to 4 after the loop.
Re:I'm Switching to Python and Actually Liking It by nomel on Wednesday July 16, 2025 @02:36PM (#44585468)
Oddly enough, "except" variables don't remain bound!

    try:
        x = int('cat')
    except Exception as e:
        pass
    print(e)  # <- NameError: name 'e' is not defined
So, it appears Python actually has three variable scopes (global, local, exception block)?
Re:I'm Switching to Python and Actually Liking It by mananaysiempre on Wednesday July 16, 2025 @03:46PM (#44586076)
Also true of JavaScript pre-ES5, another language that on first glance seems to only have function scope: it actually does have block scope, but only for variables introduced in `catch` blocks. AFAIU that was the standard way for a dumb transpiler to emulate `let`.
Re:I'm Switching to Python and Actually Liking It by SerpentJoe on Wednesday July 16, 2025 @04:41PM (#44586584)
I wonder if that was ever popular, considering the deoptimization effects of try/catch, and given that block scope can also be managed by renaming variables.
Re:I'm Switching to Python and Actually Liking It by agumonkey on Wednesday July 16, 2025 @02:43PM (#44585544)
exceptions being the exception is funny somehow
Re:I'm Switching to Python and Actually Liking It by tough on Wednesday July 16, 2025 @03:45PM (#44586067)
very recursive
Re:I'm Switching to Python and Actually Liking It by fuzztester on Thursday July 17, 2025 @12:54AM (#44589795)
you can say that again.
Re:I'm Switching to Python and Actually Liking It by suspended_state on Wednesday July 16, 2025 @04:40PM (#44586574)
> Oddly enough

It's not that odd, since it's the only situation where you cannot keep it bounded, unless you enjoy having variables that may or may not be defined (Heisenberg variable?), depending on whether the exception has been raised or not?

Compare with the if statement, where the variable in the expression being tested will necessarily be defined.

Re:I'm Switching to Python and Actually Liking It by MyOutfitIsVague on Wednesday July 16, 2025 @05:12PM (#44586835)
> Compare with the if statement, where the variable in the expression being tested will necessarily be defined.

    if False:
        x = 7
    print(x)

    print(x)
          ^
    NameError: name 'x' is not defined
Ruby does this sort of stuff, where a variable is defined more or less lexically (nil by default). Python doesn't do this. You can have local variables that only maybe exist in Python.
Re:I'm Switching to Python and Actually Liking It by NekkoDroid on Wednesday July 16, 2025 @04:46PM (#44586613)
While somewhat true, what would this be bound to?

    for i in range(0):
        pass
Re:I'm Switching to Python and Actually Liking It by suspended_state on Wednesday July 16, 2025 @04:59PM (#44586718)
Well, after writing my comment, I realized that a python interpreter could define the variable and set it to None between the guarded block and the except block, and implicitly assign it to the raised exception right before evaluating the except block, when the exception as been raised. So technically, it would be possible to define the variable e in GP example and have it scoped to "whatever is after the guarded block", just like what is done with for blocks.

Is there any chance this would cause trouble though? Furthermore, what would be the need of having this variable accessible after the except block? In the case of a for block, it could be interesting to know at which point the for block was "passed".

So, maybe "None" answers your question?

Re:I'm Switching to Python and Actually Liking It by NekkoDroid on Thursday July 17, 2025 @10:24AM (#44593797)
The answer is: it is unbound. Intellisense will most likely tell you it is `Unbound | <type>` when you try to use the value from a for loop. Would it be possible that it could be default initialized to `None`? Sure, but `None` is a destinctivly different value than a still unbound variable and may result in different handling.
Re:I'm Switching to Python and Actually Liking It by fuzztester on Thursday July 17, 2025 @12:56AM (#44589816)
Heisenbug is the word you are looking but may not find.
Re:I'm Switching to Python and Actually Liking It by nomel on Thursday July 17, 2025 @12:56AM (#44589817)
Are you saying that this should result in a name error?

   if <true comparison here>:
       x = 5
   print(x)  # <- should give name error?
Re:I'm Switching to Python and Actually Liking It by suspended_state on Thursday July 17, 2025 @02:43AM (#44590416)
I stand corrected, the exception case is definitely an oddity, both as being an outlier and as a strange behaviour wrt Python's semantics. Or is it a strange behaviour?

In the case of an if like in your example, no provision is made about the existence of x. It could have been defined earlier, and this line would simply update its value.

Your example:

   if True:
       x = 5
   print(x)  # 5

Same with x defined prior:

   x = 1
   if False:
       x = 5
   print(x)  # 1
What about this one?

   if False:
       x = 5
   print(x)  # ???


On the other hand, the notation "<exception value> as <name>" looks like it introduces a new name; what if that name already existed before? Should it just replace the content of the variable? Why the "as" keyword then? Why not something like "except <name> = <exception value>" or the walrus operator?

While investigating this question, I tried the following:

    x = 3
    try:
        raise Exception()
    except Exception as x:
        pass
    print(x)  # <- what should that print?
Re:I'm Switching to Python and Actually Liking It by fc417fc802 on Friday July 18, 2025 @12:56AM (#44601347)
In any sane language it would, yes.
Re:I'm Switching to Python and Actually Liking It by MyOutfitIsVague on Wednesday July 16, 2025 @05:09PM (#44586801)
Nope, it's more complicated than that:

    e = 'before'
    try:
        x = int('cat')
    except Exception as e:
        e2 = e
        print(e)
    print(e2) # <- This works!
    print(e)  # <- NameError: name 'e' is not defined
It's not a scoping thing, the bound exception variable is actually deleted after the exception block, even if it was already bound before!
Re:I'm Switching to Python and Actually Liking It by librasteve on Thursday July 17, 2025 @02:36AM (#44590372)
lol - raku maybe weird, but at least it has sane variable scoping
Re:I'm Switching to Python and Actually Liking It by rolandog on Wednesday July 16, 2025 @06:11PM (#44587361)
I may be rusty, but wasn't there a "finally" scope for those situations?

edit: writing from phone on couch and the laptop... looks far, far away...

Re:I'm Switching to Python and Actually Liking It by zahlman on Wednesday July 16, 2025 @08:43PM (#44588486)
Exception blocks don't create a different scope. Instead, the name is explicitly (well, implicitly but deliberately) deleted from the scope after the try/except block runs. This happens because it would otherwise produce a reference cycle and delay garbage collection.

https://stackoverflow.com/questions/24271752

https://docs.python.org/3/reference/compound_stmts.html#exce...

Re:I'm Switching to Python and Actually Liking It by afiori on Thursday July 17, 2025 @05:28AM (#44591390)
This is the type of things that make me roll my eyes at all the wtf JavaScript posts[0], yes there are a lot of random things that happen with type conversions and quite a few idiosyncrasies (my favourite is that document.all is a non empty collection that is != from false but convert to false in an if)

But the language makes sense at a lower level, scopes, values, bindings have their mostly reasonable rules that are not hard to follow.

In comparison python seems like an infinite tower of ad-hoc exceptions over ad-hoc rules, sure it looks simpler but anywhere you look you discover an infinite depth of complexity [1]

[0] and how half of the complaints are a conjugation of "I don't like that NaNs exist

[1] my favourite example is how dunder methods are a "synchronized view" of the actual object behaviour, that is in a + b a.__add__ is never inspected, instead at creation time a's add behaviour is defined as its __add__ method but the association is purely a convention, eg any c extension type need to reimplement all these syncs to expose the correct behaviour and could for funzies decide that a type will use __add__ for repr and __repr__ for add

Re:I'm Switching to Python and Actually Liking It by zahlman on Friday July 18, 2025 @11:23PM (#44612315)
> yes there are a lot of random things that happen with type conversions and quite a few idiosyncrasies... the language makes sense at a lower level, scopes, values, bindings have their mostly reasonable rules

The "random things" make it practically impossible to figure out what will happen without learning a whole bunch of seemingly arbitrary, corner-case-specific rules (consider the jsdate.wtf test currently making the rounds). And no, nobody is IMX actually simply complaining about NaNs existing (although the lack of a separate integer type does complicate things).

Notice that tests showcasing JavaScript WTFery can work just by passing user data to a builtin type constructor. Tests of Python WTFery generally rely on much more advanced functionality (see e.g. https://discuss.python.org/t/quiz-how-well-do-you-know-pytho...). The only builtin type constructor in Python that I'd consider even slightly surprising is the one for `bytes`/`bytearray`.

Python's scoping is simple and makes perfect sense, it just isn't what you're used to. (It also, unlike JavaScript, limits scope by default, so your code isn't littered with `var` for hygiene.) Variables are names for objects with reference semantics, which are passed by value - exactly like `class` types in C# (except you don't have to worry about `ref`/`in`/`out` keywords) or non-primitives in Java (notwithstanding the weird hybrid behaviour of arrays). Bindings are late in most places, except notably default arguments to functions.

I have no idea what point you're trying to make about __add__; in particular I can't guess what you think it should mean to "inspect" the method. Of course things work differently when you use the C API than when you actually write Python code; you're interacting with C data structures that aren't directly visible from Python.

When you work at the Python level, __add__/__iadd__/__radd__ implement addition, following a well-defined protocol. Nothing happens "at creation time"; methods are just attributes that are looked up at runtime. It is true that the implementation of addition will overlook any `__add__` attribute attached directly to the object, and directly check the class (unlike code that explicitly looks for an attribute). But there's no reason to do that anyway. And on the flip side, you can replace the `__add__` attribute of the class and have it used automatically; it was not set in stone when the class was created.

I'll grant you that the `match` construct is definitely not my favourite piece of language design.

Re:I'm Switching to Python and Actually Liking It by afiori on Monday July 21, 2025 @09:23AM (#44634801)
> methods are just attributes that are looked up at runtime

At runtime when evaluating a + b no dunder method is looked up and there is no guarantee that a + b === a.__anydunder__(b) https://youtu.be/qCGofLIzX6g

What i mean with weird scoping is

    def foo():
      e = 'defined'
      try:
        raise ValueError
      except Exception as e:
        print(e)
      print(e) # this will error out

    foo()
I also dislike how local/global scopes work in python but that is more of a personal preference.

I agree that that Javascripts standard library is horrible the jsdate.wtf is an extreme but apt example, IMO most of these are solved with some "defensive programming" but I respect other opinions here.

> And no, nobody is IMX actually simply complaining about NaNs existing

I watched many Javascript WTF! videos on youtube and NaNs and [2] == "2" were usually 90% of the content.

Re:I'm Switching to Python and Actually Liking It by afiori on Tuesday July 22, 2025 @04:52AM (#44644667)
Anyway actually my biggest gripe with python is that i find the module/impor/export system counterintuitive
Re:I'm Switching to Python and Actually Liking It by tyrust on Wednesday July 16, 2025 @02:43PM (#44585539)
Oh yeah, that's a good point.

Python really is a bit of a mess haha.

Re:I'm Switching to Python and Actually Liking It by yread on Wednesday July 16, 2025 @02:07PM (#44585201)
Maybe Python will get a let one day
Re:I'm Switching to Python and Actually Liking It by dec0dedab0de on Wednesday July 16, 2025 @05:03PM (#44586748)
I find it incredibly intuitive and useful that it does that. sometimes it drives me nuts that it doesn't do it for comprehensions but I can see why.

But if something fails in a loop running in the repl or jupyter I already have access to the variables.

If I want to do something with a loop of data that is roughly the same shape, I already have access to one of the the items at the end.

Short circuiting/breaking out of a loop early doesn't require an extra assignment.

I really can't see the downside.

Re:I'm Switching to Python and Actually Liking It by bobbylarrybobby on Wednesday July 16, 2025 @05:07PM (#44586777)
Python 2 actually did let comprehension variables leak out into the surrounding scope. They changed it for Python 3, presumably because it was too surprising to overwrite an existing variable with a comprehension variable.
Re:I'm Switching to Python and Actually Liking It by dapperdrake on Wednesday July 16, 2025 @11:33PM (#44589443)
That almost sounds like having the "variables" eax, ebx, ecx, and edx.
Re:I'm Switching to Python and Actually Liking It by dec0dedab0de on Thursday July 17, 2025 @10:04AM (#44593583)
Oh wow, maybe that's why I expect it to work that way! I can't believe it's been long enough since I used 2 that I'm forgetting it's quirks.
Re:I'm Switching to Python and Actually Liking It by pletnes on Wednesday July 16, 2025 @05:22PM (#44586924)
It would be utterly nuts otherwise. For loops over all elements in a sequence. If the sequence is a list of str, as an example, what would the «item after the last item» be?
Re:I'm Switching to Python and Actually Liking It by setr on Wednesday July 16, 2025 @05:29PM (#44586982)
the issue isn't the value of i, the issue is that i is still available after the loop ends. in most other languages, if it was instantiated by the for-each loop, it'd die with the for-each loop
Re:I'm Switching to Python and Actually Liking It by all2 on Wednesday July 16, 2025 @06:38PM (#44587600)
I cannot tell you how many times I've hit issues debugging and it was something like this. "You should know better" -- I know, I know, but I still snag on this occasionally.
Re:I'm Switching to Python and Actually Liking It by Alex3917 on Wednesday July 16, 2025 @11:14PM (#44589337)
> `for i in range(5): ...` will leave `i` bound to 4 after the loop. reply

This "feature" was responsible for one of the worst security issues I've seen in my career. I love Python, but the scope leakage is a mess. (And yes, I know it's common in other languages, but that shouldn't excuse it.)

Re:I'm Switching to Python and Actually Liking It by anitil on Thursday July 17, 2025 @12:16AM (#44589658)
I would love to hear about the security issue if you're able to talk about it
Re:I'm Switching to Python and Actually Liking It by Alex3917 on Thursday July 17, 2025 @09:24AM (#44593137)
I don't remember the exact details, but it basically involved something along the lines of:

1) Loop through a list of permissions in a for list

2) After the loop block, check if the user had a certain permission. The line of code performing the check was improperly indented and should have failed, but instead succeeded because the last permission from the previous loop was still in scope.

Fortunately there was no real impact because it only affected users within the same company, but it was still pretty bad.

Re:I'm Switching to Python and Actually Liking It by anitil on Thursday July 17, 2025 @07:43PM (#44599576)
Oof that's a near miss. That's the sort of hard-to-find issue that keeps me up at night. Although maybe these days some ai tool would be able to pick them up