What's the tidy/elegant way to protect this against null/empty parameters?

Jean-Michel Pichavant jeanmichel at sequans.com
Tue Oct 16 05:22:32 EDT 2012



----- Original Message -----
> I want to fix an error in some code I have installed, however I don't
> really want to just bodge it.
> 
> The function producing the error is:-
> 
>     def get_text(self, idx):               # override !
>         node = self.items[idx]
> 
>         a= [
>             ", ".join(node.tags),
>             node.comment,
>             node.folderName,
>             cd2rd(node.date),
>             node.name,
>             '[' + self.rating_stars[node.rating] + ']'
>             ] [self.select]
> 
>         return a
> 
> 
> The error occurs when node[] (or at least its members) turn out to be
> empty, you get a Traceback that ends with:-
> 
>   File "/usr/lib/jbrout/jbrout/listview.py", line 608, in draw_cell
>   layout.set_text(self.get_text(thumbnail_num))
>   File "/usr/lib/jbrout/jbrout.py", line 325, in get_text ",
>   ".join(node.tags),
>   TypeError: sequence item 0: expected string, NoneType found
> 
> Now its *probably* something higher up the tree causing the problem
> (it's only one particular image in 20 thousand or so that breaks
> things) but I really want to just get things working.  So, what's the
> neatest way to protect the get_text() method from empty data?
> 
> 
> --
> Chris Green
> --
> http://mail.python.org/mailman/listinfo/python-list

Hi Chris,

Usually, you want to keep your variable types consistent. For instance, if node.tags is supposed to be a string, then make it so that it is always a string.
However NoneType may be one inconsistent type that is acceptable for any variable. It depends on the situation, and your personal preferences.

To go back to your example, None may have a different meaning that an empty string. Here's a way to redefine locally a None object into an empty string:

", ".join(node.tags or '')

if node itself can be None, here's a way to protect against None attribute access:

", ".join(node and node.tags)

you can combine the 2 methods:

", ".join((node and node.tags) or '')


This method uses the fact that:
A and B returns B if bool(A) and bool(B) are True, returns the first non True between A and B.
A or B returns B if bool(A) is False, returns A if bool(A) is True.

JM



More information about the Python-list mailing list