Why Python sucks – why I hate Python: a Python rant

Suck #1

I started following a super-basic tutorial on Python as I’d learned the basics over the years and wanted to learn again from scratch.

The very first thing they do is:


>> import requests

Simple, right?


I got:

So now I’m spending half an hour trying to debug the most basic thing in a Python tutorial. This is clearly a sign of things to come.

Various StackOverflow answers describing complicated solutions that did not help:



Turns out the solution was to do:

pip install requests 


Fortunately, I had pip installed. But basically a complete beginner would have that as an additional hurdle to overcome.


''=> current working directory

then searches through directories.

/usr/local/lib/python2.7/site-packages => third party packages

Note: on Debian this is called dist-packages.

Suck #2

Following a script that mentions os.environ I get:

NameError: global name 'os' is not defined

Turns out I need to import os. Python folks – can’t this be done automatically? It’s not hard. Just see a variable that matches a package you know and import it. DONE. Kind of like the Mac’s AutoSave. Let’s get out of the ’80s here…


Suck #3

Again, following that script I copy and paste part into a REPL to try it out. As the indentation is different I get:

IndentationError: unexpected indent

Groan. So, I have to go through the script manually adding indents. Again, let’s get rid of indent restrictions. Stupid.

Suck #4

Gibberish logs and debug output.

A method I had copied was clearly wrong. When I attempted to use it from the REPL with ec2 = get_client("ec2") I got:

What a pile of gibberish. To be clear – 21 lines and 1629 characters of gibberish.

Why not print it out in Assembly just to make it less clear?! Has anyone made any effort whatsoever on making this more user-friendly?


or  a line like:

testing = os.environ['testing']


Why not just output:

testing = os.environ['testing'] # Error generated. No such key "testing" 

Suck #5

I’ve got an object that’s been returned using a pretty standard library. i.e.

client = boto3.client('ec2')

There is no output when I run it from the REPL. Sounds OK.

Let’s inspect this object. Looking for introspectionI find:


Ooh. Python has a strong set of introspection features. OK, let’s try


Jeez! Another 6 lines of gibberish.

How about client.getattr()? Surely that’s got to return something?!

Why can’t they just return messages like: AttributeError: 'EC2' object has no attribute 'getattr' and get it over with. Then you could have some debug parameter to find out more if any of the additional text above is actually useful.

At least the very user-friendly underscore underscore dict underscore underscore method (i.e. __dict__) helps figure out what’s going on behind the scenes. That was an easy one to figure out without digging through Stackoverflow. Not.

Suck #6

Let’s follow the 4 simple steps here:


1. Download or clone the repository.

No problem.

2. Open terminal and point to root of repository. Type: pip install -r requirements.txt

I get (in red):

awscli 1.15.53 has requirement botocore==1.10.52, but you’ll have botocore 1.12.23 which is incompatible.

I’ve no idea now whether I need to upgrade awscli, downgrade botocore. Or even why I’m getting this message.

It also fails with:

Could not install packages due to an EnvironmentError: [Errno 13] Permission denied: ‘/usr/local/man’
Consider using the --user option or check the permissions.

Why on earth didn’t the maintainers bother to mention that you might need to use --user in the install instructions.

I run:

pip install --user -r requirements.txt

and no longer see the red fails. I’ve no idea why the awscli, botocore errors have disappeared.

3. Run server with: python3 application.py. Alternatively: ./manage.py runserver

Great. 2 options to fail.

Let’s try the second:

./manage.py runserver

and the nice simple error message:

I don’t understand why they couldn’t make this less simple to understand. Perhaps another 1500 lines of gibberish to reduce legibility would have helped. E.g. they could have thrown in some random characters to help confuse the end user.

Given that the instructions say:

Python 3.4+

and I find this issue buried on github:


which helpfully suggests ignoring the official (faulty) install instructions and using (the also incorrect):

pip3 install -r requirements.txt

The correct install instructions are:

pip3 install --user -r requirements.txt


Handily there’s also no mention that:

python3 application.py

will take 10 seconds before it starts generating output and so appearing it’s not working.

4. Access HQ with: http://localhost:5000


Did I say I hate Python?


Suck #7

Why on earth use 4 spaces?!

Let me rephrase it. If you use one less or more of an invisible character your code will break. Or if you swap it out for another invisible character that looks exactly the same (i.e. the tab) it will also break.

Brilliant design idea.

Let’s find something analogous in the real world.

If you reach for the right glass you can have a drink of water.

But if you reach for the wrong glass (that looks exactly the same) it breaks.


Suck #8

Strong typing.

I refuse to believe strong typing is the future of coding. All the talk about catching bugs earlier is guff. Adding pre-compilation gates just slows down the coding process. The compiler and interpreter should be the ones doing the heavy lifting – not the programmer.


print(“URL: + some_url)

if some_url is None then you get:



Suck #9

Stuff breaking.

I’m fed up of junk like this:


Leave a Reply

Your email address will not be published. Required fields are marked *