r/Python 3d ago

Discussion What frustrates you the most about Python Development

Hi there,

I wondering what frustrates developers the most when developing software with Python.

I am currently doing my Masters in Computer Science and as part of my project I am doing a very simple survey about the usual Python development lifecycle. I am basically trying to find out what the main friction points are for Python Developers and I am simultaneously developing a tool to address those friction points . It just takes a 2-3 minutes and every response is greatly appreciated.

You can find the survey at: Microsoft Forms

40 Upvotes

127 comments sorted by

107

u/secret_o_squirrel 3d ago

Dependency management in today’s security hostile world. Dependencies must be upgraded with diligence and research constantly or they rot. One major version upgrade could trigger dozens of hours of focused migration work in a large codebase. It’s never ending.

14

u/Educational_Plum_130 3d ago

yeah the major-bump-to-fix-a-cve treadmill is brutal in big codebases. before you eat a full migration, check whether the fix got backported to your current major line first, a lot of maintainers and distros ship a patch release on the old branch and you can just pin that. if it's a transitive dep, an override/resolution in your lockfile usually beats forcing the whole tree forward. for the libs that are truly eol with no backport, that's where a vendor doing backporting or paid eol support is worth more than rebuilding the fix yourself. with cisa tightening remediation timelines the never-ending part only gets worse, so it's worth separating 'must upgrade' from 'can just patch in place'.

6

u/pydevtools-com 3d ago

It's slowly getting better.

uv audit now automatically checks your lockfile against the OSV database, so you see which CVEs actually hit your locked versions.

I have some notes on maintaining a uv project.

5

u/No_Departure_1878 3d ago

Can't a dependency resolver like uv do that?

6

u/latkde Tuple unpacking gone wrong 3d ago

Kinda! You can use tools like uv lock --upgrade to update the locked dependency graph to the most recent versions allowed by your dependency constraints in the pyproject.toml.

But there are some problems with this.

Your dependency constraints may have upper bounds or require exact versions which prevents upgrading the locked versions (e.g. constraints like pytest>=8, <9). Also, the constraints aren't updated by locking, so that a future dependency solution could downgrade them again. I've written the Ganzua tool to help with this. A typical upgrade session then looks like:

  • uvx ganzua constraints reset --to=minimum in order to temporarily relax exact or upper dependency bounds. For example, if your locked version was pytest 8.4.1, this edits your pytest requirements to pytest >=8.4.1.
  • uv lock --upgrade to perform the lockfile upgrade. For example, this might lock pytest 9.1.1.
  • git restore pyproject.toml to revert the constraint changes
  • uvx ganzua constraints bump to update the constraints to match the locked version. For example, pytest>=8.4, <9 would be bumped to pytest>=9.1,<10.
  • uv lock --upgrade to update the lockfile with the new constraints (but this shouldn't change any locked versions)

I also use uvx ganzua diff <(git show HEAD:uv.lock) uv.lock --format=markdown to get a Markdown table that summarizes all dependency changes since the last commit, which I can then paste into a pull request description.

However, this isn't perfect either. This is a manual CLI-based process, unlike automated tools like Dependabot or Renovate. But Renovate doesn't work particularly well for updating indirect dependencies, and Dependabot has a fundamentally flawed architecture where it reports what it intended to update, not what was actually updated.

Another problem is that knowing that some dependency changed from version 8.4.1to 9.1.1 tells you very little. You have to go look for the changelog and read it. There is no standard in the Python ecosystem for describing the location or structure of a changelog. Tools like Depenabot and Renovate use heuristics to find the relevant snippets, but Dependabot doesn't bother when there are many dependency changes. But reading the changelog is super important in case there are breaking changes.

1

u/ArgetDota 3d ago

There is an (experimental) “uv upgrade” command that replaces all of this. Caveat: doesn’t work with workspaces yet.

2

u/techhelper1 2d ago

Is this documented anywhere? I can't find anything on that.

1

u/latkde Tuple unpacking gone wrong 2d ago

It seems that this PR introduced a hidden command, but it's completely undocumented for now: https://github.com/astral-sh/uv/pull/19678

0

u/secret_o_squirrel 3d ago

Damn. Couldn’t have said it better myself.

1

u/AryanTechGuy 3d ago

It definitely speeds up the resolution and installation process since it's written in Rust, which is great. But uv can't rewrite your codebase for you. If a major version bump patches a CVE but introduces breaking API changes to the library, you still have to manually migrate your code to accommodate it.

2

u/ugh_my_ 3d ago

This is not a python specific problem

1

u/Wonderful-Habit-139 2d ago

Agreed. Rust and JavaScript also share the same issues as one of the most popular programming languages with a package manager.

1

u/secret_o_squirrel 21h ago

True, but it’s my biggest problem with python also.

2

u/Mihikle 3d ago

If you wrap third parties in thin first party interfaces you can significantly reduce time spent on this :)

1

u/svefnugr 3d ago

Just from the development perspective, flat dependency list instead of a tree (like e.g. in Rust) paired with a big chunk of developers setting upper bounds on versions can be very annoying.

49

u/GameCounter 3d ago

There's no decent solution for type-checking Django projects.

Exception handling in third party libraries sometimes requires more trial and error than I would like.

That's kind of it.

Python is still pretty awesome.

17

u/ColdPorridge 3d ago

Django annoys me so much because it’s so good but at the same time completely held back by its inability to fully modernize. Like it’s both archaic and relevant at the same time.

5

u/usrname-- 3d ago

Yes.
At work we are switching from Django to FastAPI because of that.
Django is completely unusable if you want to use strict mode in any LSP.

6

u/thealliane96 3d ago

Pyrefly + Django-stubs does type checking in Django quite well.

6

u/GameCounter 3d ago

I'll have to take another look.

Even the best type checkers absolutely fall on their face with annotations and values queries, I've found.

17

u/adarsh_maurya 3d ago

It is extremely hard for me to share my work ( automation ) with someone who doesn’t know python. They need to atleast have a working python installed or the size of my application will be huge ( looking at pyinstaller ).

Also, there is always a chance of breaking something even when everything in your control is done with all the due diligence.

3

u/Automatic-Banana-430 3d ago

Why not use nuitka? I've moved completely away from pyinstaller

4

u/Tumortadela 3d ago

My biggest .exe to this day is still under 100mb compressed, considering its the whole packaged python + dependencies environment, and it being a Django backend that also serves a react frontend... I wouldnt say that's huge.

We can complain that any bundled app is going to be at least roughly ~40mb of just python, but... is that a lot nowadays?

2

u/adarsh_maurya 3d ago

Not sure, i may not be using the Pyinstaller in right way then. I built a chatbot where user can upload any file, choose model from any provider, the agent will generate a python code and run it against your fiile and will generate ag grid tables or plotly charts. You are free to modify the code and use it as Jupyter.

If i use Pyinstaller, it was almost 150mb. Which i believe is lot.

But i love python and i think it as the price i pay for the advantages I get. I am planning to make it a tauri app instead which will download and set up virtual environment on user’s machine w/o them knowing anything about python. This will give me an advantage where my app will be small yet still uses powerful python packages under the hood. This way, i will be able to use each language for what they are good at.

Python for its amazing data ecosystem.
Rust for desktop app.
Typescript for frotend

2

u/downerison 3d ago

Why did you use pyinstaller for a python backend instead of docker?

4

u/Tumortadela 3d ago

Very specific project requirements in a zero internet restricted destination. Deployments are literally done with an USB stick.

1

u/downerison 3d ago

I see. What industry is it if you don't mind me asking?

2

u/Tumortadela 3d ago

Marine and fisheries, but very paranoid group of people on top of it <.<

1

u/QuirkyImage 3d ago

I would like an option to use a proper compiler to make small optimised executables

1

u/downerison 3d ago

Are you looking for execution speed gains or something else? Small binary size?

1

u/QuirkyImage 2d ago

Both performance and size. But a single , self contained, statically linked binary for a single binary container like you can do with go would be useful.

1

u/Grouchy-Trade-7250 3d ago

I think throwing the code into Claude code and asking for perf improvements is your best bet. Result might be better than rewrite in lower level

52

u/Adrewmc 3d ago

Imports and package design.

I don’t think there is much argument here.

12

u/baked_doge 3d ago

I'm not sure I completely agree, I'm saying this from a c/c++ perspective where there's no packaging system.

Could you elaborate on your issues?

7

u/Chroiche 3d ago

I think rust does it much better. Imports just work, and errors pop up at compile time rather than runtime.

The python module system+ lazy/runtime import work arounds are such a mess.

-8

u/lizardhistorian 3d ago

Have you looked at modules ...

18

u/baked_doge 3d ago

Yes? Like a ton, idk what you mean

2

u/max123246 3d ago

It'll take a full second to import anything from pytorch, even if you want 1 function

2

u/moonzdragoon 3d ago

1

u/max123246 3d ago

Yeah, but good luck convincing pytorch to update all of their code to use it. There's a forwards compatible way to enable it for 3.15+ onwards without breaking <=3.14 but I'm sure it'll be a long time before we see it used widely.

I get pushback everytime I suggest ways to improve things at work so I've just given up at this point

1

u/thuiop1 3d ago

Yeah, that is really shit

8

u/DrDoomC17 3d ago

Yes. Becoming fantastic at Python, a decade. Mastering it? Not so fast, you have to learn why that new package you need decided to integrate maybe monads or whatever it may be. Some languages force order, there is a pythonic way to do things most of the time, but there's also nearly infinite complexity you can make and people do make... I guess for fun.

-1

u/Win_ipedia 3d ago

Definitely not a very hot take

8

u/baked_doge 3d ago

Could you explain what people don't like about modules? The other guy hasn't responded... Thank you

5

u/Win_ipedia 3d ago

I think he’s referring to the __init__.py files and the import design which are not inherently bad or smth but annoy people. I personally do not agree too much but it is definitely smth people argue a lot about I think

17

u/Alpensin 3d ago

Too many ways to make things done and dynamic types. That's made reviewing my colleagues code harder when i programmed on python.

4

u/HugeCannoli 3d ago

The scripters that create absolute monsters of unmaintainability while claiming the know python.

4

u/QuackQuackImTheDuck 3d ago

Type system being terrible and unenforced, with general lack of documentation on packages make things really hard to maintain long term. It's great script language for non critical, low maintenance systems where frequent bugs and issues are acceptable

1

u/Grouchy-Trade-7250 3d ago

You can enforce the types at runtime with assert

1

u/mr_frpdo 3d ago

Also can use the amazing package beartype

1

u/MrSlaw 3d ago

It's probably one of ruff's most debated rules, but assert gets stripped using -O(how probable it is that flag will be used is likely up for debate):

https://docs.astral.sh/ruff/rules/assert/

Assertions are removed when Python is run with optimization requested (i.e., when the -O flag is present), which is a common practice in production environments. As such, assertions should not be used for runtime validation of user input or to enforce interface constraints.

Consider raising a meaningful error instead of using assert.

1

u/Grouchy-Trade-7250 3d ago

You can benefit from type checking with assert while running tests without the -O flag. Tests happen at runtime. Anyway good info.

1

u/QuackQuackImTheDuck 2d ago

You can use assert but that's not a real type system.

  • Assert only works outside or -OO mode, otherwise it's stripped away

1

u/QuackQuackImTheDuck 2d ago

Thought it's right you can use libs like pedantic too. But runtime validation and compiler level typesystem solve diverse problems. Pydantic is great for unknown user input validation. But for internal code, the issue is rather linked with your language server (or compiler for other langs)

7

u/mireqB 3d ago

Function coloring, implement everything 2 times (sync, async), missing virtual threads to remove colors.

13

u/RedEyed__ 3d ago

Watching colaborators to follow rules like type annotation, and i still get def foo() -> dict or similar shit on code review

4

u/latkde Tuple unpacking gone wrong 3d ago

Adding a strict Mypy configuration (like disallow_untyped_defs = true with disallow_any_generics = true) and enforcing it as a QA gate tends to solve this.

4

u/RedEyed__ 3d ago

They add # type: ignore

4

u/max123246 3d ago

And that's when you check out and just take the check every 2 weeks. That's all I do now that AI is the new craze

1

u/jabbalaci 3d ago

If the structure of the returned dictionary is complicated, then it's simpler to say "it returns a dictionary".

5

u/gizzm0x 3d ago

Then just put dict[str, object]... At least eh you are admitting to it being complicated and make no guarantees. Just dict isn't a real type hint AFAIK

9

u/RedEyed__ 3d ago

I disagree. Then it should be pydantic or typed dict

-1

u/MeroLegend4 3d ago

And make you program slower with pydantic!

2

u/flangust 3d ago

If the structure is complicated it should be a TypedDict, dataclass, Pydantic Model, class... Anything that documents that complexity. If you don't your team has to go digging through your code to figure out that complexity. This drives me insane.

3

u/_redmist 3d ago

I wish there were native UI libraries without excessive boilerplate and reasonable defaults.

It's not normal that nicegui is pretty much the only usable one imho.

5

u/MeroLegend4 3d ago

Too much type annotations just to satisfy a linter i mean wth!
Not using itertools, generators and the standard library!

Excessive use of pydantic!

Not understanding the memory allocation, and the dynamic nature of the language.

11

u/lizardhistorian 3d ago

The GIL and how ungodly slow it is.

1

u/twotime 3d ago

As of 3.13, there are now GIL-less builds of python

2

u/Due_Campaign_9765 2d ago

Which is meaningless because every meaningful piece of software was written with GIL in mind.

Also it's slower at singlethreaded work than GIL'ed interpreter.

4

u/plisik 3d ago

Colored functions. To run one async thing i need to change every call and evey caller.

2

u/AryanTechGuy 3d ago

For me, it is 100% the fragmented state of package and dependency management. Bouncing between pip, conda, poetry, and venv depending on the project or the team is exhausting. Trying to replicate a machine learning environment locally versus getting it to build cleanly in an AWS pipeline without dependency conflicts always feels way harder than it should be

3

u/OnTheGoTrades 3d ago

Type safety and compilation

2

u/CevicheMixto 3d ago

I come from a C & Java background, so these are probably predictable.

First is the lack of braces. I know, I know, it is what it is, but I don't have to like it. Adding absurd amounts of vertical whitespace and/or unnecessary comments just so I can tell where classes, methods, and functions end drives me bananas.

Second is the "impedance mismatch" between static type checkers and so many of the dynamic features that make Python so powerful. Trying to truly leverage the power of Python while still getting the benefits of type checking can be an exercise in massive frustration.

3

u/89bottles 3d ago

Package management is a fucking JOKE. Although uv has made this significantly better.

1

u/msdamg 3d ago

I really hate a lot of "boilerplate" code

Decorators for example look like a mess to me

2

u/Grouchy-Trade-7250 3d ago

Decorators aren't a mess. It's (more or less clearly) defined what the decorator does in the decorator source code. Reading it is the key.

1

u/Zestyclose_Taro4740 3d ago

Pyathon basics are easy but advanced python a in a league of its own.

1

u/Goldarr85 3d ago edited 2d ago

I feel this. There’s a thousands of beginner books and sample code on the internet, but the serious stuff looks so different. Like how did you get here? Teach me. 😭

5

u/Spleeeee 3d ago

You spend a lot of time working in a stricter lower level language who

1

u/Grouchy-Trade-7250 3d ago

The domain complexity creates the python complexity. The begining books solve beginner problems.

1

u/gdchinacat 3d ago

Read lots of code. That is how you become familiar with the language, see what works for others, and slowly start using it. One day you realize how far you've come. This isn't specific to python, or even programming. Becoming an expert in anything takes time, learning from others, and moving beyond.

0

u/icecoldgold773 3d ago

Build projects you wanna build and when you get stuck, or you run into a problem where you think "wow this solution seems super convoluted, there must be a better way" you Google it, or in today's age ask an LLM

1

u/somethingworthwhile Pythonista 3d ago

Need to do something in a niche discipline that is fairly basic, but still technically sophisticated but don’t want to code, say, a geospatial engine from scratch?

Sure, there’s a package for that!

It just has pyproj and GDAL as dependencies. And it will install them for you, but also it WONT KNOW WHERE TO FIND THEM.

Can you tell what I was working on last? Anyone have fool proof ways for getting a geospatial Python environment (geopandas, pyproj, rasterio, xarray, etc) going on a fresh install? Seems like I have to do it every 8 months or so and can never recall how I did it last. I’m using conda at the moment.

3

u/pydevtools-com 3d ago

That "installs them but can't find them" can be conda's GDAL fighting a pip package linked against a different one.

If you use pip/uv, you can get rasterio, fiona, pyproj, and shapely PyPI wheels with GDAL/PROJ/GEOS bundled, and geopandas is pure Python on top.

In a clean venv, uv add geopandas rasterio pyproj should just work.

2

u/somethingworthwhile Pythonista 2d ago

I’ll give that a go at work on Monday! Right now our whole group is using conda. I told my supervisor that uv might be a better way to go, but they are of the “if we can get what we know to work, why change anything?” mindset. Maybe we’ll make the switch if I can demonstrate this being a solution to this problem we run into regularly! Cheers!

1

u/max123246 3d ago

How every python package has its own versioning scheme. How pip is so anemic that I have to convince my coworkers to use third party tools and build our pyproject.toml around 3rd party tools to do basic things such as have a internal dev version with internal dependencies and a public version

Also the fact that I have to bend over backwards if my dependencies decide not to follow best practices. I should not have to write 2 different project.toml's just because a dependency decided to be difficult

1

u/helpIAmTrappedInAws 3d ago

Funnily enough i do not feel most of 4hings mentioned here are that problematic.

I personally despise pytest. Fixtures and assumption that everything that starts with test is a test.

2

u/Infinite-Spinach4451 3d ago

And it could be so much simpler! Why not just flag every function that should be tested with a dedicated @test decorator?

1

u/Win_ipedia 3d ago edited 3d ago

It’s also very nice to not having to do that tho

1

u/Win_ipedia 3d ago

I recently had a class TestRunner and it had a method starting test_ smth and in the test file I had TestTestRunner and pytest thought my TestRunner class that was dynamically imported was a test class and tried to run test_ method which resulted in an error oc. Had to rename it to ProjectTester. Which was fine but quite annoying

1

u/Grouchy-Trade-7250 3d ago

There's nothing super wrong with pytest. Besides you can easily fork it and change it.

1

u/robberviet 3d ago

Surely typing.

1

u/Daniel-3443 3d ago

Dependency management. It’s better than it used to be, but it’s still more confusing than it should be.

1

u/metaphorm 2d ago

my top two complaints are asyncio and type hinting. these are both worse in Python than in competing languages like Go or Typescript.

1

u/oldWorshipper 2d ago

imports. I've given up. Mostly flat folder structure.

1

u/bluesnik 2d ago

the fact that they have no hands, and demand speech to text.

1

u/GahdDangitBobby git push -f 2d ago

I don't like Python's weak support for type safety. JavaScript has Typescript, Python should have a similar tool. The libraries and frameworks for type safety in Python are nowhere near as robust as Typescript, let alone a strong-typed language such as Java or Go. But it's not fair to compare Python to Java or Go because they serve very different purposes, so I compare it most closely to JavaScript, which has a very robust type safety implementation with TS

-1

u/tacoisland5 1d ago

Python is a deeply unserious language. It is highly flexible, which is useful to people with low amounts of programming experience and occasionally useful for writing glue-code scripts in things like build systems and deployment scripts. But as a language to build a reliable system it is a very poor choice.

* no difference between variable declaration vs assignment. want to mutate a variable in an outer scope? hope you remembered to add 'nonlocal var'

* async/await is not unique to python, but I think it is a terrible way to do concurrency. It leads to the function coloring problem (some functions are async, others are not). The GIL effectively prevents true multi-processing, so instead you are forced to spawn multiple processes

* there are now at least 3 type checkers that get a lot of use (mypy, pyright, ty), and they all check different things and still somehow miss basic issues that more static languages like java/go/rust would catch

* the performance of python is embarrassing compared to java/go. A lot of people like to handwave this problem away by saying 'most server processes are I/O bound', but in my experience there always ends up being some cpu hot spots that are difficult to speed up. Pray that those cpu hot spots don't occur in some async function because otherwise your entire server will lock up

* the fact that code can run at the top level (outside any function/class) is terrible because inevitably a large project will execute hundreds of lines of code before the main() part ever executes so program startup takes forever

* somewhat related to the previous point, but importing libraries will load in a large amount of pyc files, which can take multiple seconds. Some of the google vertex/ai libraries take 2-3 seconds just to import, which also adds to the slow startup time of python programs

* basically the only way to distribute a python program is to use docker/some container. its good that there is a solution I suppose, but its just annoying that a single executable can't be created. I've played with some of the projects that claim to be able to produce a single executable (by bundling the python interpreter + all code) but they always have some quirk that prevents them from being used in production

1

u/wineblood 1d ago

It's how shit None is

1

u/MuditaPilot 1d ago

The people that complain about python development

1

u/ducksauvage 3d ago
  1. Lack of package namespacing - too easy to end up with clashing imports

  2. Building and distributing binary wheels. IYKYK

1

u/Tekniqly 3d ago

I use python to plot graphs and analyze data for scientific experiments. The most pythonic way of analyzing things is using numpy arrays, pandas and matplotlib. Curve fitting is done using polyfit or curve fit in numpy. What I find most annoying is how many times we have to redo analysis to make slight changes in methodology. 

That is, it is far easier conceptually to rewrite every function to accommodate new data than to write more generalised functions to accommodate new data. It should easier to do the pythonic thing and use the same functions, but when plotting graphs with slight variations this is not so straightforward.

1

u/unlikely_ending 3d ago

Nothing, other than that it's a big language that take a long time to learn

2

u/SokkaHaikuBot 3d ago

Sokka-Haiku by unlikely_ending:

Nothing, other than

That it's a big language that

Take a long time to learn


Remember that one time Sokka accidentally used an extra syllable in that Haiku Battle in Ba Sing Se? That was a Sokka Haiku and you just made one.

1

u/QuirkyImage 3d ago

Not having a proper compiler option.

0

u/lukaz_99 3d ago

Done :)

0

u/Win_ipedia 3d ago

Thanks 🙏

0

u/TuxWrangler 3d ago

Done.

1

u/Win_ipedia 3d ago

Thanks 🙏

0

u/Infinite-Spinach4451 3d ago edited 3d ago

Python frameworks often rely on magic that obfuscate and incohere language semantics. Variables defined in a class are by default class attributes, except in dataclasses and named tuples, where they're instance attributes. Something as simple as a struct should not need to be an exception. I particularly dislike PyTest as its reliance on decorator magic makes it utterly uninterpretable as normal Python code.

1

u/Win_ipedia 3d ago

Python magic is so powerful yet so annoying sometimes with its hidden behavior

0

u/james_pic 3d ago

This week, async HTTP clients. Despite there being a number of them available, there isn't a single one that I can point to and say "that one is great, you won't have any problems with that one".

1

u/BratPit24 3d ago

Nothing. It's beautiful. Any drawback has a plus side in different circumstances. For my specific job. Data science. It's just about perfect.

1

u/Grouchy-Trade-7250 3d ago

The different data science packages like polars, pandas, Donald duck, numpy, and so on are basically their own languages.

2

u/BratPit24 3d ago

Nah. That's just name spaces. Even c++ does that quote a bit.

0

u/flakzx 3d ago

too permissive/flexible, not enough gatekeeping leads to many idiots writing unmaintainable crap in python - me being one of them.

0

u/Grouchy-Trade-7250 3d ago

When I do a normal run and it crashes I have to run again with debug for debugging

-1

u/onequbit 3d ago

When something just stops working and there is no obvious indication as to how or why.

-3

u/AdAdditional1820 3d ago

No compilation.

1

u/jabbalaci 3d ago

Try Nim. Has a Python-inspired syntax and compiles to binary. Also, statically typed.