I think Python has a place in many developers toolkits. I've never met anyone who hates Python (though I'm sure they exist), whereas for pretty much any other language one could mention there are much more polarizing viewpoints. (as the saying goes "Python is everyone's second favorite programming language").

The Python team needs not feel any pressure to change to compete, Python has already done quite well and found its niche.

raises hand I hate python.

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.

Be careful of attributing to python what is really the fault of python lib developers.

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.

> Be careful of attributing to python what is really the fault of python lib developers.

If so, you also cannot attribute to Python the virtues of Python lib developers either (in particular, a large library ecosystem).

Yip. What you are talking about is the language ecosystem.

I've been mostly not using Python since it's arrival in the early 90s. Meaning I tinker with it but don't use it professionally.

Well, I hate Python. Main points for me: the scoping (or lack of it), the lack of declaration of new identifiers (linked to lack of scoping), the lack of update operators (like `a ||= (i > 0)`), the general lack of conciseness, the `a if b else c` confusion, the weirdness of comprehensions (particularly nested `for`s), the exceptions that are raised for non-exceptional cases. The heaviness of handling exception, 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).

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.

> the lack of update operators (like `a ||= (i > 0)`)

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!"

Yes, all your points are valid for yourself. It's OK. I did not try to convince you that Python is bad. I only tried to explain why I hate it. In the hope that maybe you better understand why. It's too easy to say 'I hate XYZ', so I tried to explain myself. I am perfectly fine with you loving it. Let's see whether I can explain myself better:

> ... 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`.

raises hand I hate python.

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 {}

i resist saying that i hate python because that implies that i don't hate aspects of basically all alternatives (or all that are popular anyway)

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

Oh, don’t get me wrong i don’t refuse to work with it or anything so extreme. These days I end up writing code in any of a handful of languages.

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)

These issues are true of most legacy codebases I've worked on in other languages, but I think language design can be a factor here. Do you have any thoughts on if and how Python has led to this rot?

Another comment has explained this already, but the lack of dependency pinning and the general "it's just a script" attitude isn't conducive to long-term stability. During the early days of the llama local LLM runner, I was shocked to discover that releases weren't buildable mere days after being tagged in Git! Days!

Other platforms like Java and .NET enjoy one to two decades of life for source before it becomes mildly challenging to build.

> 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.

I think that is a totally fair criticism. There is something to be said about a language being too easy to hack something together with, it's something that makes backend JavaScript coding a long term pain as well I think.

uv helps a lot with the first problem. Not so much with the second, though.

I hate python and I use it everyday because I work in the data space. Its a toy scripting / glue language that has gotten used for far too much that it was not designed for. The usual suspects are also really annoying, such as white space instead of {}, no types, its so damn slow and all projects use so many packages and the packages use packages etc. That last one could just be a personal preference thing to I will admit, but the rest are just almost objectively bad. Especially when building infrastructure like a data platform.

"white space instead of braces" is "just almost objectively bad"?

Why?

usually packages use packages in any worthwhile language with useful packages and desire for code reuse...

It's also funny to hear this about Python which, arguably, has biggest std and amount batteries included out of the box.

Python's stdlib is not really something to brag about. Very inconsistent, multiple ways of doing the same thing, a lot stuff in there people recommend against actually using...so much cruft acquired over decades.

It's why projects use so many packages in the first place.

Indeed. The standard library was primarily designed in, and for, an era where you couldn't just download multiple megabytes of third-party code on a whim.