Hacker News new | past | comments | ask | show | jobs | submit login

I'll add a 4th rationale: 4. It will create work for countless developers which is completely consistent with the python core value of disdain for other people's time.

If this pep were implemented I suspect it would result in forcing thousands of not tens of thousands of people to spend hours modifying perfectly working code and destroying the ability to run old scientific code without modification. Extremely effective industrial sabotage if it were to be accepted.

It is hard for me to articulate how much peps like this reinforce my desire to never start another python project. Even if this pep is rejected the fact that there are people who would put in the time and effort to write and submit such a PEP tells me that they will do it again, and eventually they might succeed.






> It is hard for me to articulate how much peps like this reinforce my desire to never start another python project

I completely understand this sentiment. Recent python events have made me wonder if there are some people intent on sabotaging the management of the language.

I loved the incremental improvements and thoughtful process involved up until a couple of years ago but it feels like python will become brittle and break badly if things continue the way they are. It feels like the adults have been driven out the room when it comes to stewardship. I'm not sure how recoverable the situation is.


As someone who doesn't follow the language, which recent events are you referring to?

It wasn't recent by Internet time but when the debate on walrus operator drove out the BDFL that was the obvious break. Python has been circling the drain ever since. A lot of motion, yes, but to what end?

- - - -

Oh! How could I forget!? The creeps actually banned Tim Peters!


Just as a reminder, the BDFL supported the "walrus operator" and co-authored the PEP for it.

Yes? and as GP said, he stepped down because (as explained in the first line of his email) "Now that PEP 572 is done, I don't ever want to have to fight so hard for a PEP and find that so many people despise my decisions."

A lot of the time, people say things like "Python has been circling the drain ever since." referring to the implementation of the "walrus operator", to imply that they don't like the feature and that it was the first of a series of changes to the language that have made it progressively worse; and they often further imply that if only we still had the original leadership then we could avoid such damage to the language.

I was, in a sense, in that camp at the time, before I looked it up. I felt that the operator went against the spirit of the language by trampling on what was previously a strong, and clearly very conscious, separation between statements and expressions. And I misguidedly imagined, and lamented, that GvR was unable to keep it out of the language, being overruled by consensus.

I just want to make sure it's clear that things are not like that. Rather, the Python envisioned (nowadays, though not originally) by the original leadership includes PEP 572 - and probably also the large majority of what's been added since.


Very good point and 'cheers!' for raising it.

It's not the "walrus operator" per se that's the problem, it's the change in project governance.

Python has been captured by bureaucracy and corporate interests. The way it's being improved-to-death is a symptom. The unceremonious eviction of Tim Peters indicates to me that the take-over is complete: the new guard feels comfortable throwing out the old guard, they expect that their power is such that no one will blink, and no one did. (No corporation withdrew support for them, the blow-back was all hot air.)

It would be interesting to know GvR's opinions of some of the new cruft, but it's not really relevant.


Using "|" to merge dictionaries (which was possible in other ways before) instead of offering pipes as in bash and Elixir (a feature that's actually useful).

The “|” operator was already used for set unions and binary OR, so it’s a little late to reserve it for control flow. Personally I don’t mind having a “dict union” operator at all.

https://peps.python.org/pep-0584/ is the PEP for merging dictionaries; sadly, it barely mentions pipes as a consideration.

To be fair, the notion that pipes are lower-priority than other syntax needs is not exclusive to Python: in the JS world, discussion in https://github.com/tc39/proposal-pipeline-operator and specifically https://github.com/tc39/proposal-pipeline-operator/wiki/Bike... has been going on since 2018, with things like Tuple Literals taking precedence.

On the Python side, though, at least you can build your own pipes! You can define various helper classes that have, say, an `__rrshift__` method, to let you do the following with full type-checking support:

load_iterable_from_db() >> to_dict_by("id") >> tee(logger) >> call_(dict.values) >> to_dataframe

(With great apologies to FP folks who see a bind operator, and C++ folks who have seen enough operator overloading for a lifetime!)

Not necessarily something you want to use unless you want to confuse your team, but quite useful for fluent code in notebooks!


Like all of python, `a | b` operator is just `a.__or__(b)`. If you want that operator to do something different in a different context, just override __or__.

Nothing prevents you from defining the | operator for other user-defined types where that would actually make sense. A dictionary doesn't represent an ongoing process or stream. Lots of things are possible; that isn't a reason not to find better ways to do them (cf. Raymond Hettinger).

Elixir's 'pipes' always felt very hacky to me. (But so does most of the language, compared to Erlang.)

In what ways does Elixir feel "hacky"? I get that it can be inconsistent at times but the whole language is really a Lisp-2 in disguise.

Any Lisp-ness comes from Elixir being a skin on Erlang, and so comes almost anything else good to say about Elixir. (And my comment was explicitly comparing Elixir to Erlang.)

The 'pipe' is hacky, for example, because it's just syntactic sugar that only works in one specific case, and not in general.


I feel like as a scripting language Python excels. Glad to have this PEP, but it would be more pythonic have except be optional.

The reason I pick up Python for projects is because it grows with the application; opportunities to add typing etc. Who knows maybe in a few years Python will enforce all the types and it will be as verbose as Java. Personally I’d like to see how they handle declaring a method or function throws exceptions.

Pretty narly we have compiled Python apps with poetry, it’s starting to punch out of its weight class.


So it doesn't matter if it goes through or not, just that someone proposed a change like this is enough to steer you away from Python?

If the change goes through, couldn't you just use older Python versions for those specific projects, or has the Python ecosystem still not figured out how to do this without huge hassles?


That version will eventually become EOL, stop getting security patches, eventually stop compiling with the latest OpenSSL, etc. Bitrot.

Either software is updated or it isn't. If you're worried about "bitrot" then you bear the responsibility for your end of keeping the system up to date. (Or finding a third party to do it.) API Changes occur for a reason, and it isn't reasonable to expect other developers to make security fixes to their older versions of code in perpetuity while guaranteeing that stable interface in perpetuity. They'd never get to fix anything that isn't a security issue that way. Programmer resources are limited - especially for Python, which doesn't pay the overwhelming majority of its devs (although it can afford to pay several PSF staff).

Python is open source. Nothing prohibits you from forking the 2.7 codebase and adding your own security patches (or more substantial things like back-porting new OpenSSL support, or even cherry-picking backwards-compatible features from 3.x that you do like), for example.

I'm happy when people criticize new features in Python. But I expect to read criticism of features based on their actual merits and consequences, not on the principle that it's new or backwards-incompatible or would cause "churn".


So we have this proposed change which will cause a bunch of needless churn.

Then we have people saying "just don't upgrade anything if you don't want to deal with the churn" but that too is a very large burden for all the reasons I mentioned.

All the reasonable adults in the room want option 3: don't do the thing that causes needless churn.

> But I expect to read criticism of features based on their actual merits and consequences, not on the principle that it's new or backwards-incompatible or would cause "churn".

I am honestly shocked to see this attitude. Churn is a very real consequence. Do you have no respect for the time of the countless devs who use python?


The entire point is that proponents of the change disagree that it's "needless churn".

It's bizarre to me that expecting people to improve their code incrementally is considered a disrespect for their time.

The proposed change is not arbitrary - which can be seen by trying to imagine the alternate universe in which the reverse change were proposed. One can imagine a world in which `except:` were added to a Python that didn't support it, but certainly not one where it were made mandatory (whether for the `except BaseException:` case or the `except Exception:` case).

I assume there are people out there who would, similarly, argue that it was "needless" to make `print` into a function (and thereby break users of the `>>file` syntax). But it demonstrably and significantly makes the language better.


If you want to talk incrementalism, then the right approach is making this an error in other parts of the Python ecosystem. Linters, mypy, pyright, etc, without make a source-breaking language change.

Imagine whatever universe you want, but we live in this one. In this universe, there is a shitload of old python. Python 2.7 isn't even completely gone. Literal lifetimes of collective time would be spent on the fallout of this change, which does not seem worth the reward.


Does that matter when you just want to run "old scientific code"? Old version of libraries like OpenSSL can still be run in that context, granted you don't expose that code to the internet at large.

Old scientific code broke for many people with the introduction of the mac m1. I would think this would be a continuing trend in the future. Staying on old versions simply isn't possible over a long period without keeping the hardware going with it too.

> Old scientific code broke for many people with the introduction of the mac m1.

How could the people maintaining Python possibly avoid that? It would be up to Apple to proactively reach out to affected projects, if Apple cares about that.


The way to "avoid" it is to make it easier to upgrade to the latest version of python rather than making it harder.

When the qualifier is "granted you don't expose that code to the internet" then yes, it matters.

Who finds "old scientific code" and then exposes a server running that code to the internet without any changes? Sounds like asking for trouble, but I guess we all use computers differently...

I don't know why people do things without thinking them through, but they do. Regarding trouble, I don't think we've covered anything here that wouldn't be asking for trouble.

> destroying the ability to run old scientific code

TBH that kind of code barely survives minor Python version upgrades in my experience.


Perhaps in a few years we can have another PEP, to require "except BaseException" to be replaced with bare "except:". Then we can all change our code back again.

If someone on my team or in my company proposed to break most of our python code for no substantial reason, unless they were pretty junior I would count that as a real red flag against their judgement.

How do people land on the python steering council exactly?


From the PEP:

> A tool will be provided to automatically update code to replace bare except: with except BaseException:.


That's besides the point. I don't want to muck about with tools on my Python scripts.

I have sometimes not run a Python script for a few years, and then when I need it, it stopped working and I need to track down what changed/broke or run some tool or whatnot. I don't keep track of the latest greatest Python changes – like most Python programmers it's not my "day job" to write Python code so I now need to track what changed between "the Python version I used about 3 years ago, whatever that was" and now. It's pretty annoying.

And that's assuming said tool will be fool-proof. Never mind of course that all my dependencies (if any) will need updating too.

What will happen in practice is that people will write "except Exception:" rather than "except:" and do nothing different. Basically nothing will change.

Meanwhile, I have C and Go programs that have worked without modification for about 10 years. Not that nothing ever breaks in C or Go, but it's the exception (hah!) rather than the rule.


> like most Python programmers it's not my "day job" to write Python code

I’d love to know whether that’s true, and to what extreme. I believe you’re right - that people using Python for a few hours a week (or less) greatly outnumber software developers using it as their primary language.

I think that’s a real issue for the evolution of Python, because updates to the language design (e.g. the makeup of the Steering Council) come almost entirely from the second group.


> I think that’s a real issue for the evolution of Python, because updates to the language design (e.g. the makeup of the Steering Council) come almost entirely from the second group.

Yes I agree, and it's disappointing to see some take such a narrow view of things.

A big part of maintaining and evolving a language is saying "no" a lot. There are a lot of people with ideas, almost always reasoned from their own use-case. That's okay, everyone does that to some degree, but there almost always trade-offs and such to consider.

Your job as Steering Council or Core Dev or BFDL or whatever governance you have is to consider all use cases and make a balanced decision. Reading that thread, some do. But unfortunately others don't.

Even for Python 3, Guido spent most of his time saying "no" to proposals. There were a lot of pretty wild ideas for Python 3000.


Which just underscores the point that this is mostly software engineering theater. If your goal is a system in which all exceptions are explicitly and appropriately handled, your first mistake was picking Python.

I propose a rider to the PEP in which implementation will be deferred until its proponents can correctly affirm that the library reference lists, for each function and method, every exception it might throw.


>If your goal is a system in which all exceptions are explicitly and appropriately handled, your first mistake was picking Python.

No, the goal is a system in which the code correctly indicates which exceptions it's intended to handle, and doesn't accidentally handle the wrong exceptions because the developer was either lazy or misinformed about the semantics (perhaps due to experience with a different programming language).


> ...and doesn't accidentally handle the wrong exceptions...

What support does Python offer, to the author of a function, for determining what would be the wrong exceptions for it to handle? How, in Python, does the author of a function signal, to the functions she is calling, which exceptions they should not handle? As I alluded to in my previous post, the Python language and documentation does not even give programmers a good accounting of what exceptions the library functions might throw.


The point was about how the set of exceptions handled by `except:` might not match what the programmer expects, especially a programmer coming from a different language. It's not about knowing what kinds of exception the code in the `try` could raise and it isn't about telling a called function what to do.

Other languages, notably Java, have tried the "functions document what they can raise" idea. Everyone seems to hate the result.


Thank goodness there was 2to3 tool in the past. It made the migration to Python 3 so smooth and quick. /partial-s

I know it is not nearly on the same level, but people seriously overestimate the effort needed between not doing anything at all and even the slightest work, no matter how reliable and easy. The difference between nothing and anything is huge.


I feel like I've heard this argument countless times, and yet I'm never swayed by it. I've been using Python for about 20 years and I've never felt put out by the need to change anything to work with a new version of Python (or of a library). It simply hasn't caused significant pain - my memories are more filled with painful debugging sessions caused by overly-clever designs or trying to refactor too much at once.

will there be a tool to upgrade all direct and transitive dependencies of your project to make them work in that new interpreter?

I propose to call this tool 3to760, in memory of 2to3.

Anything popular is going to attract an increasingly high-variance group of engineers. With such variance comes such PEPS.

Eh, while I sympathize with what you’re saying, PEPs get written and rejected all the time. I’ve gotten the impression that some were written for the main goal of documenting the reasons why a common request is a bad idea.

Like, I don’t know if there’s a PEP to use braces, but it wouldn’t surprise me if someone had made one so that from then on there’d be an official doc you could point people at when they ask about it.

Not saying this is one of those, and I see Brett Cannon’s on this one. I am saying not to get too worked up over the existence of a draft PEP.


PEP 666 was supposedly written to be rejected so as to document the community stance on indentation.

The rejection of braces isn't in a PEP to my knowledge; it's only in the __future__ Easter egg.


I think emitting a warning every time an unspecific exception is caught might be a better balance. That way, you could still do a quick “try: … except: …” when drafting new code, but the code might warn you if the bare except block is ever used (including what exception was caught, and a suggestion for how to catch only that specific exception).

With that PEP you can still do a quick "try: except:" it's just spelled "try: except Exception:"

> warning every time an unspecific exception is caught

Caught and not re-raised


I often find discussions of these sorts, whether for python or other open source projects, get so focused on purity of concept that they totally forget practicality

Quickly read the thread, isn't "hours" a bit much for what is basically a

  sed -Ei 's/^([\t ]*except):/\1 BaseException:/' **/*.py

now try delivering that change to all of your dependencies before being able to deploy your software with a new interpreter.

Not that I support the PEP but they could easily add an interpreter flag or environment variable to disable the behavior.

Will this command be automatically run by venv, or poetry, or whatever, on every package update?

Definitely going to want to use Tree-sitter, not regex. That regex just broke my docstrings.

Multi-line strings don't exist.

On the bright side, turning bare exceptions into types exceptions is the kind of thing an llm is great for. It's also basically zero cost for new code.

On the other hand, I completely agree that it's not worth a breaking change.


Does that even require an LLM? It should be possible through traditional static analysis.

> It should be possible through traditional static analysis

Even better/worse, could do it with regex on text streams.


There's some space for interpretation in picking exactly which exception type to use depending on context (value error vs runtime error vs not implemented error), and there may be package specific exceptions available.

Everything requires an LLM nowadays.

Especially if you want to get funding



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: