0

I'm trying to add a player to a board in python, but am struggling with the implmentation.

The player object's attributes gets validated when a player is initiated via the operator library. I want to show the exceptions as they occur; ie. put the initiation of each player in a try-except.

Problem is that when I do it as I am bellow I get an error saying:

Traceback (most recent call last): File "./main.py", line 88, in move r.forward() AttributeError: 'NoneType' object has no attribute 'forward'

During handling of the above exception, another exception occurred:

Traceback (most recent call last): File "./main.py", line 161, in main() File "./main.py", line 141, in main move(choice, player) # Peform the moves on the player File "./main.py", line 91, in move Try again!\n>>> ".format(err, r.initial[0], r.initial[1], r.initial[2])) AttributeError: 'NoneType' object has no attribute 'initial'

The operations mentioned above are movements handled by the player class (player.py). It's clear that I am somehow returning a NoneType, but I'm not sure why this is occuring.

It happens when I have entered an incorrect player-position during initiation and then add a correct one.

So basically this is what I do:

  1. Initiate the board
  2. Initiate a player outside of bounds (or on another player)
  3. Initiate a correct player position.
  4. Error occurs.

However, there are no errors if I add players correctly (ie. step 3 doesn't occur).

def add_player(board):

    try:
        choice = input("Please enter the current player's initial position.\nRemember to keep inside board's limits!\n>>> ").split()
        if len(choice) == 3 and validate_player(choice[0], choice[1], choice[2]): # Check the length of supplied input and check type-integrity

            return Player(int(choice[0]), int(choice[1]), choice[2], board)       # Initiate a player with the supplied input. Each player is assigned to a Board (many-to-one relation).

    except Exception as err:
        print(err)
        add_player(board)
geostocker
  • 1,190
  • 2
  • 17
  • 29
  • 1
    Without seeing the code that calls `forward`, we aren't going to be able to diagnose the problem. Please provide a [mcve]. – Kevin Apr 05 '17 at 13:02
  • 1
    This doesn't directly answer your question, but [Asking the user for input until they give a valid response](http://stackoverflow.com/q/23294658/953482) may give you ideas on how to validate user input without using recursion, which may make your stack traces more comprehensible. – Kevin Apr 05 '17 at 13:13

1 Answers1

1

There are several possible problems here. Firstly, if the if statement does not evaluate to True, nothing is returned from the function. No exception would be raised so the except block wouldn't be entered, but nothing else is returned either; None is the default return value when nothing else is returned.

Secondly, even if there was an exception, you are not returning the result from the recursive call to add_player in the except block. However you should not be using recursion here, you should loop until the right values are entered.

Unrelated, but you should never catch the base Exception; you should only catch the things that you might expect, which in this case are ValueError (from the int call, if something other than a number is entered) and IndexError (from the indexing into list, if less than three items are entered). Catch those exceptions only.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895