Dawn17
Dawn17

Reputation: 8297

Detecting indentations in Python

def divide(x, y): 
    try: 
        # Floor Division : Gives only Fractional Part as Answer 
        result = x // y 
        print("Yeah ! Your answer is :", result) 
    except ZeroDivisionError: 
        print("Sorry ! You are dividing by zero ")

    try: 
        result = x // y 
        print("Yeah ! Your answer is :", result) 
    except: 
        print("An error occurred") 

    try: 
        # Floor Division : Gives only Fractional Part as Answer 
        result = x // y 
        print("Yeah ! Your answer is :", result) 
    except ZeroDivisionError: 
        print("Sorry ! You are dividing by zero ")
    except NameError: 
        print("Name Error")
    except MemoryError: 
        print("Memory Error")
    except AttributeError: 
        print("Here is some\
            long long error message\
            .....")

I have a function that has three try...except clauses. My goal is to detect how many separate try...except clauses it has (3 in this function) and how many except keyword it has in each clause (the first and second one has 1 and the third one has 4).

I tried to import this file by doing

with open("test.py", "r") as f:
    content = f.readlines()
    ... # getting each line

and try to divide the try...except clauses by detecting the indentation level. However, I feel like this is not an exhaustive way of doing it and there might be an easier way.

Any help?

Upvotes: 4

Views: 170

Answers (1)

sanyassh
sanyassh

Reputation: 8520

It is a starting point to use ast for your task. With your code example it detects except without any exception on line 12 and prints too broad except, line 12. Also I tested it with except Exception:, the message is the same and with except ZeroDivisionError: pass, the message is useless exception. You can take it and improve further (work with several functions in module, etc.).

import ast

with open('test.py') as f:
    data = f.read()
    module = ast.parse(data)
    function = module.body[0]
    for obj in function.body:
        if isinstance(obj, ast.Try):
            try_block = obj
            for handler in try_block.handlers:
                if handler.type is None:
                    print('too broad except, line {}'.format(handler.lineno))
                    continue
                if handler.type == 'Exception':
                    print('too broad except, line {}'.format(handler.lineno))
                    continue
                if len(handler.body) == 1 and isinstance(handler.body[0], ast.Pass):
                    print('useless except, line {}'.format(handler.lineno))

For your goals stated in the question (count try...except blocks and count except clauses in each block), it is easy, as you can see: len([obj for obj in function.body if isinstance(obj, ast.Try)]) and len(try_block.handlers) will do it.

Upvotes: 4

Related Questions