How Best to Coerce Python Objects to Integers?

Steve D'Aprano steve+python at pearwood.info
Tue Jan 3 18:26:08 EST 2017


On Wed, 4 Jan 2017 10:09 am, Ethan Furman wrote:

> And, of course, whether or not "except Exception" is too broad depends on
> the use-case.

I'm having trouble thinking of *any* use-case where this would be useful. His 
intention, it seems, is to write a function which simply cannot fail, 
presumably so that he can write code which consumes the output and just keeps 
going no matter what he throws at it:

graph = make_graph()
incoming_data = [1, 12, 7, "hello", None, [], {}, 5] for obj in incoming_data:
    graph.draw_point(int_or_else(obj))


But of course that's impossible:

class Evil:
    def __int__(self):
        os.abort()

Or for that matter:

class Evil:
    def __int__(self):
        time.sleep(2147483647)



So his code still can fail under some circumstances. And so it should. Why is 
my input data including such evil objects? I should find out why. I'm having 
trouble seeing how it could be anything but a programming bug.


He gives the rationale for this function:

    A scenario thatâ Ös more realistic than the Unintable class might
    be a class that wraps an industrial sensor. Calling int() on an
    instance normally returns a value representing pressure or
    temperature. However, it might reasonably raise a
    SensorNotReadyError.

Okay. Let's suppose it can return either an integer as a string, some arbitrary 
non-numeric string to indicate a sensor error, or raises SensorNotReadyError. 
Then this would be an appropriate function to use:

def int_or_else(value):
    try:
        return int(value)
    except ValueError:
        assert isinstance(value, str)
        # consider logging the error?
        return None
    except SensorNotReadyError:
        return None


Now when he connects up to the sensor and starts reading values, it will work, 
but if his input gets contaminated with arbitrary junk objects (a sign of a 
programming bug in his code) he will find out about it.


One possible use-case might be something like Excel, where there are two data 
types: numbers, and text, and numeric operations on text will just skip them 
altogether. If you were to build an object-oriented spreadsheet, where the 
cells can contain any object not just numbers and text, then you could 
potentially have a situation like:

        Column A
Row 1:  1
Row 2:  ftp_server()
Row 3:  2
Row 4:  3
Row 5:  =sum(A1:A4)

and you (arguably) want the result to be 6 rather than some error. Or do you? I 
can make a good case for skipping text cells, as Excel does, but I'm not sure 
that ftp_server should be skipped. So I'll count that as a use-case, but a 
dubious one.

Another possible use-case might be the REPL for an interpreter, where you want 
the REPL to keep going no matter what exceptions take place. But I don't think 
this is the right way to do that, and it's not how the Python REPL works 
either.

Other than that, I'm not seeing any use-case where this sort of thing is 
anything but a bad idea.





--
Steve
â £Cheer up,â Ø they said, â £things could be worse.â Ø So I cheered up, and
sure
enough, things got worse.




More information about the Python-list mailing list