It's not you. Python packaging has regressed into a worse mess than it was 20 years ago. I limit myself to simple scripts that only rely on builtins. Anything more complicated goes to a more dependable language.
I don't know about the difference between 20 years ago versus now, but it's certainly doesn't seem to be clear now.
e.g. poetry, venv and pyenv have been mentioned in just the next few comments below yours. and this is just one example. i have seen other such seeming confusion and different statements by different people about what package management approach to use for python.
I rarely run into issues when using Poetry. If you use pip, add packages to requirements.txt willy-nilly and don't pin versions then you are asking for trouble.
UV. Using it as the exec target for python (UV script) is great. Dependencies declared at the top, now I have executable files in something better than bash.
I no longer shy away from writing <500 LOC utility/glue scripts in python thanks to uv.
I can't recommend uv enough. It's so fast, and uvx is so useful to run a random Python CLI tool. If you want to do things like you're accustomed to with pip you just `uv pip ...`