The Python team needs not feel any pressure to change to compete, Python has already done quite well and found its niche.
The Python team needs not feel any pressure to change to compete, Python has already done quite well and found its niche.
I am a user of pip binaries. Every few years one of them breaks.
As far as I understand, developers never cared about pinning their dependencies and python is fast to deprecate stuff.
$ uvx remt
Built pygobject==3.54.5
Built remt==0.11.0
Built pycairo==1.28.0
Installed 12 packages in 9ms
Traceback (most recent call last):
File "/home/user/.cache/uv/archive-v0/BLXjdwASU_oMB-R4bIMnQ/bin/remt", line 27, in <module>
import remt
File "/home/user/.cache/uv/archive-v0/BLXjdwASU_oMB-R4bIMnQ/lib/python3.13/site-packages/remt/__init__.py", line 20, in <module>
import pkg_resources
ModuleNotFoundError: No module named 'pkg_resources'
$ uvx maybe
× Failed to build `blessings==1.6`
├─▶ The build backend returned an error
╰─▶ Call to `setuptools.build_meta:__legacy__.build_wheel` failed (exit status:
1)
[stderr]
/home/user/.cache/uv/builds-v0/.tmpsdhgNf/lib/python3.13/site-packages/setuptools/_distutils/dist.py:289:
UserWarning: Unknown distribution option: 'tests_require'
warnings.warn(msg)
/home/user/.cache/uv/builds-v0/.tmpsdhgNf/lib/python3.13/site-packages/setuptools/_distutils/dist.py:289:
UserWarning: Unknown distribution option: 'test_suite'
warnings.warn(msg)
error in blessings setup command: use_2to3 is invalid.
hint: This usually indicates a problem with the package or the build
environment.
help: `blessings` (v1.6) was included because `maybe` (v0.4.0) depends on
`blessings==1.6`
I heard rumors from computer vision developers that even libraries deprecate that fast.Having said that, our team is having to do a bunch of work to move to a new python version for our AWS serverless stuff, which is not something I'd have to worry about with Go (for example). So I agree, there is a problem here.
If so, you also cannot attribute to Python the virtues of Python lib developers either (in particular, a large library ecosystem).
Also, the syntax of layout is bad. I am not talking about layout itself, I do like Haskell syntax (despite being weird about parens). But if I write `a = b +` in Python on one line, then I get a syntax error, although the parser could instead assume that the expression is not terminated and must (obviously) continue on the next (indented) line. I hate that I need to use `\` or `(...)` to make this clear to the parser. I wrote parsers myself, and I know that it knows what needs to follow, and Python itself shows me that it knows: by raising a completely unnecessary syntax error.
It feels to me that the Python language design confuses `simple and easy` with `primitive`. If feels like a design without the knowledge of programming language research and ergonomy. It feels to me like a dangerous toy language, and I am never sure which of my stupid mistakes will be found by the compiler/interpreter, and which will just silently misinterpreted. And which of my perfectly valid requests will be rejected with an exception. In some aspects it feels less safe than C, particularly due to the lack of scoping and the danger of reuse of variables or introduction of new function local variables when actually, outer 'scope' variables were intended to be written.
This is not really meant as a rant, but it is a personal opinion, and I try to lay out my reasons. I am not trying to shame anyone who loves Python, but I just want to clarify that there are people who hate Python.
What would that even do? Is that the equivalent of `a = a or (i > 0)`? Python does not have a "||" operator.
> the `a if b else c` confusion
I'll agree that Python really dropped the ball on implementing a ternary operator, but I guess Guido really didn't want the C version.
> the weirdness of comprehensions (particularly nested `for`s)
If a comprehension is getting weird because of nesting, then I'd change it to not be a comprehension. I'd rather have nested `for` loops than nested comprehensions.
> the exceptions that are raised for non-exceptional cases
I'd be interested in an example of this.
> like trying to delete a non-existing dict entry (need an additional `if` or a `try` block) or access a non-existing map entry (need to use `.get()` instead of `[]` or a `try` block)
I suggest thinking more about the Zen of Python. Specifically, explicit is better than implicit, and errors should never pass silently. If you're trying to delete a non-existing dict entry, or trying to access a non-existing entry, then in most cases, you have a bug somewhere. Basically, Python believes that your code is expecting that dict entry to exist. Forcing you to use .get or use an `if` is a measure to make your code explicitly declare that it's expected that the dict entry might not exist.
> But if I write `a = b +` in Python on one line, then I get a syntax error [..]
Yeah, the parser could certainly be written to handle this case, but it was deliberately written not to.
> It feels to me like a dangerous toy language
Toy language, I could see. Dangerous? Not at all. I could call it opinionated, though.
> and I am never sure which of my stupid mistakes will be found by the compiler/interpreter, and which will just silently misinterpreted.
Meanwhile, I'd look at C and think "I'm not sure which of my mistakes will lead to a memory leak or an exploitable buffer overflow."
> In some aspects it feels less safe than C, particularly due to the lack of scoping and the danger of reuse of variables or introduction of new function local variables when actually, outer 'scope' variables were intended to be written.
I'd argue the exact opposite: It's more dangerous to allow you to accidentally clobber a global variable when you meant to create a local one.
> This is not really meant as a rant, but it is a personal opinion, and I try to lay out my reasons.
I think the core issue is that Python tries to adopt a different paradigm than languages like C, and it's a paradigm that you just strongly disagree with. Personally, I love it. What's funny is that when I first saw Python, I was like "This language sucks, it makes things too easy and it holds your hand." After using it extensively at work though, I find myself saying "This language is great! It makes things so easy and holds your hand!"
> ... the Zen of Python ... > ... was deliberately written not to ... > ... Guido really didn't want ...
Yes, sure, I do not question that. I am merely saying that I hate many of the outcomes of that. I also hate discussions about that -- it is so quickly sacrilege to hate Python. I know that it's futile to discuss religion, and I am not trying to do that. But someone said that no-one hates Python -- well, I do, and this is why!
> ... explicit is better than implicit ...
Except for variable declarations, apparently. I would very much like them to be explicit, and it would be a start to fix the scoping problem.
> ... Dangerous? Not at all ...
I perceive a danger when the compiler/interpreter does not tell me that I am doing unintended things. Obviously, it cannot know what I intend. But proper and smaller scopes are generally regarded as helping humans to track the visibility of a variable. I certainly cope better with explicit variable declarations and with smaller scopes. I feel a danger that I accidentally misuse (or reuse) variables, e.g. by missing a `nonlocal` or `global` declaration or by using a variable after an `if` that was meant to be only valid local to that `if` block.
> ... Meanwhile, I'd look at C and think "I'm not sure which of my mistakes will lead to a memory leak or an exploitable buffer overflow." ...
Of course C is dangerous, that's why I cited it. But in at least one aspect, the scoping and related lack of explicit syntax to introduce new variables, I think Python is more dangerous than C. In most other aspect, C is definitely worse.
Comparing another language, and how it is possible to improve: JavaScript managed to fix scoping by introducing `let`. If you don't use `var`, then this particular problem is solved in JavaScript.
> ... the exceptions that are raised for non-exceptional cases ...
E.g., 'file not found' in open(). That's not exceptional, because it potentially happens with every usage of open(). You can never seriously use `open` without handling the case that the file is not found. Therefore, it's not exceptional, but it should be encoded in the return value.
> ... then I'd change it to not be a comprehension. ...
That's not the point. I don't want imperative, I want functional. I like list comprehension. I am not complaining about imperative `for`, but I am complaining about the confusing syntax of nested `for` in comprehensions. I am complaining of being forced to use imperative `for` by the weirdly confusing syntax of functional `for`.
Every python codebase i’ve had to look after has rotten to the point it doesn’t even build and is a maintenance nightmare.
I also hate whitespace instead of {}
like with everything else these days, it's about living with it and try to make the best of the good parts of it
i remember getting told in the 00s that i would get used to and love the whitespace-based block definition, and boy i hate it now more than ever with 1000s of hours spent looking at and coding in python
but it is what it is, for whatever reason it has become a must in many particular industries a lot like Java took over some earlier on although it seems to be fading, and javascript is a must in others
it really isn't just about programming languages that these days you either learn to live with some massive annoyances and practices you may hate, or withdraw entirely from society
Given the choice though I typically don’t teach for python unless there’s an obvious reason to (some good library for my task or a team i am helping is only python people / devops etc)
Other platforms like Java and .NET enjoy one to two decades of life for source before it becomes mildly challenging to build.
Java enjoys months of life for source before it becomes impossible to build, because some prehistoric version of Gradle with shitty Groovy script stopped working.
It's why projects use so many packages in the first place.
Why?