user3579222
user3579222

Reputation: 1430

How Debug with Python

I am a Java developer and today I started with Python (v3.7, using PyCharm). I tried to create a "hello world" application with a single package (boto3):

import boto3

client = boto3.resource('ec2', region_name='eu-central-1')
client.  # unlike java, no suggestion (method or attribute of client object) from the IDE

I read PyCharm code completion not giving recommendations and I understand that due to the dynamic typing PyCharm is unable to determine the type of client and consequently it can not make any suggestion (e.g. methods or attributes of the object).

Hence, during debugging I was forced to look up the documentation to identify the attributes and methods of returned objects. This was error-prone and effort-full (e.g. typos or I assumed a different type of object resulting in attribute not found errors during execution).

Then, I was executing my code in the debug mode: I tried to identify attributes and methods of the returned objects in the evaluation box which is inconvenient too.

How do you handle such situations in Python? Do you have a good reference?

Upvotes: 4

Views: 370

Answers (2)

Peter Badida
Peter Badida

Reputation: 12179

If your editor behaves strangely (or if you don't have IDE e.g. on server) you can use the code itself because the maintainers might have included the documentation in the code and generate the webpage/PDF from the code itself. In those cases it's always worth trying help() on a particular object such as:

import boto3
client = boto3.resource('ec2', region_name='eu-central-1')
help(boto3)
help(client)

but that works only if there is a docstring (code documentation) present which is not guaranteed. For such cases use these functions:

  • type() to determine object's type
  • dir() to list all names (variables, functions, ...) in the object
  • vars() to list the object properties stored in __dict__ attribute

and in case you encounter something more tricky e.g. an object without __dict__ attribute, always check with dir() because such object might use __slots__ to be more efficient than basic __dict__. That's very common with C/C++/Cython extensions and will cause vars() function to fail with an error:

TypeError: vars() argument must have __dict__ attribute

This is also efficient on module level:

import boto3
dir(boto3)

which is handy for using directly in a console. That should your editor do and apparently does not for some reason.

There is also a case where a module behaves strangely (can't find the example, but happened to me in the past) and unlike importing under the containerized "variable" such as boto3 it'd leak other symbols to the global variables.

That can be easily debugged with globals() or even locals() if you import within a function.

Once the code becomes annoying enough, just jump into a pdb debugger which allows you to reexecute the code in much saner way than manually re-running the program and waiting for a message in the console which might not even show (e.g. condition not met or so).

Upvotes: 3

Iain Shelvington
Iain Shelvington

Reputation: 32244

You can use type annotations in Python to give your IDE hints

import boto3

client: boto3.Session = boto3.resource('ec2', region_name='eu-central-1')

Now when you type client. you should get hints

This is especially useful if you would like to perform static analysis of your code and have added type annotations to all of your methods

Upvotes: 3

Related Questions