user2237405
user2237405

Reputation: 31

Python 'if x is None' not catching NoneType

The below snippet of code keeps returning a "NoneType isn't iterable" error. Why doesn't the if statement catch this?

inset = set()
for x in node.contacted:
    print type(x)
    if x.is_converted() is True:
        nset.add(x)
        if x.contacted is None:
            memotable[node.gen][node.genind] = nset
        else:
            nset.union(self.legacy(x, memotable))
            memotable[node.gen][node.genind] = nset

Full traceback as requested:

Traceback (most recent call last):

File "F:\Dropbox\CS\a4\skeleton\trialtest.py", line 142, in test_legacy_and_frac()

File "F:\Dropbox\CS\a4\skeleton\trialtest.py", line 125, in test_legacy_and_frac cunittest2.assert_equals(set([n10,n12,n21]), t.legacy(n00,mtable))

File "F:\Dropbox\CS\a4\skeleton\trial.py", line 138, in legacy nset.union(self.legacy(x, memotable))

File "F:\Dropbox\CS\a4\skeleton\trial.py", line 138, in legacy nset.union(self.legacy(x, memotable))

TypeError: 'NoneType' object is not iterable

Upvotes: 2

Views: 1818

Answers (3)

Janne Karila
Janne Karila

Reputation: 25207

The exception occurs because the function call self.legacy(x, memotable) returns None.

The traceback indicates the error occurs in nset.union(self.legacy(x, memotable)), and set.union() raises that exception when its argument is None. (I'm assuming nset is a set. Your code defines inset = set(), but does not show where nset comes from)

>>> set().union(None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'NoneType' object is not iterable

Upvotes: 0

abarnert
abarnert

Reputation: 366073

The if statement guarantees that x.contacted isn't None.

But x.contacted isn't what you're trying to iterate or index, so it isn't guarding anything.

There's no reason memotable or memotable[node.gen] can't be None even though x.contacted is something else. For that matter, we have no idea of what the code inside self.legacy(x, memotable) does—maybe it tries to iterate x, or other_table[x], or who knows what, any of which could be None.

This is why you need to look at the entire traceback, not just the error string. It will tell you exactly which statement failed, and why.


And now that you've pasted the traceback:

File "F:\Dropbox\CS\a4\skeleton\trial.py", line 138, in legacy nset.union(self.legacy(x, memotable))

Yep, it's something that happens inside that self.legacy line, and it has absolutely nothing to do with x.contacted. The problem is almost certainly that your self.legacy method is returning None, so you're doing nset.union(None).

Again, whether x.contacted is or is not None is completely irrelevant here, so your check doesn't guard you here.

If you want us to debug the problem in that function, you will have to give us the code to that function, instead of code that has nothing to do with the error. Maybe it's something silly, like doing a + b instead of return a + b at the end, or maybe it's some deep logic error, but there's really no way we can guess.

Upvotes: 3

pradyunsg
pradyunsg

Reputation: 19466

Check the value of memotable and memotable[node.gen] as it can not be said to guaranteed that they are not None if x.contacted is not None (without the code).

If you mention the values of the variables here and Post the Full Traceback, we may be able to point out the problem more precisely.

Upvotes: 0

Related Questions