Search code examples
pythonbox2dcollisionnonetype

PyBox2D - NoneType is not subscriptable during collision filtering


I have a Box2D world where I need to filter collision I have three entities there, a Car, a Pedestrian and a Building. Details can be found here where I was told to ask a new question. I finally managed to filter the collision, when a car hits a pedestrian it does something, but when the car hits building I get an error that "NoneType is not subscriptable" how can I fix it? Thank you

CAR_CATEGORY = 0x0002
PEDESTRIAN_CATEGORY = 0x0004
BUILDING_CATEGORY = 0x0008

CAR_GROUP = 2
PEDESTRIAN_GROUP = -4 
BUILDING_GROUP = 8

class myContactListener(b2ContactListener):
    def handle_contact(self, contact, began):
        # A contact happened -- see if a wheel hit a
        # ground area
        fixture_a = contact.fixtureA
        fixture_b = contact.fixtureB

        body_a, body_b = fixture_a.body, fixture_b.body
        ud_a, ud_b = body_a.userData, body_b.userData


        pedestrian_contact = None
        car_contact = None
        building_contact = None
        for ud in (ud_a, ud_b):
            obj = ud['obj']          
            if isinstance(obj, Car):
                car_contact = obj
            elif isinstance(obj, Pedestrian):
                pedestrian_contact = obj
            elif isinstance(obj, Building):
                building_contact = obj

        if car_contact is not None and pedestrian_contact is not None:
            if began:
                print("Shame on you, you killed an innocent pedestrian!!!")

        elif car_contact is not None and building_contact is not None:
            if began:
                print("BOOMMM")
    def __init__(self):
        b2ContactListener.__init__(self)
    def BeginContact(self, contact):
        self.handle_contact(contact, True)
    def EndContact(self, contact):
        pass
    def PreSolve(self, contact, oldManifold):
        pass
    def PostSolve(self, contact, impulse):
        pass

box2world = world(contactListener=myContactListener(),gravity =(0.0, 0.0), doSleep =True)

How can I fix the error? Any help appreciated


Solution

  • As your code has only one subscription (one use of [] brackets), the error message means you may need to check the ud object for None before doing ud['obj'], like so:

    if ud is None:
        continue
    

    The same error message can be triggered in any python interpreter like so:

    >>> a = None[0]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: 'NoneType' object is not subscriptable
    >>> 
    

    The official documentation defines subscriptions:

    6.3.2. Subscriptions

    A subscription selects an item of a sequence (string, tuple or list) or mapping (dictionary) object:

    subscription ::= primary "[" expression_list "]"

    The primary must evaluate to an object that supports subscription (lists or dictionaries for example). User-defined objects can support subscription by defining a getitem() method.

    ... and goes on to define the built-in types of objects that do support subscription.