How to write python polyglot unittest for method using type function?

Viewed 39

I am trying to write python2 and python3 compatible code which uses type function. Both return different strings in 2 v/s 3, which I have to assert in my unit tests.

Python 3.7.4 (default, Oct 18 2019, 15:58:40)
>>> type(2)
<class 'int'>

Python 2.7.16 (default, Jul 24 2019, 16:45:12)
>>> type(2)
<type 'int'>

The intention here is to validate the exception messages raised from my function. For example,

def func(arg1):
    if not isinstance(arg1, int):
        raise TypeError('Expected type %s but got %s' % (type(int), type(arg1)))
        
    print("Function executed")
    
try:
    func('str')
except TypeError as e:
    assert e.args[0]== "Expected type <type 'type'> but got <type 'str'>"
    print("Correct exception was raised")

Assertion here passes in python2 but fails in python3.

2 Answers

Variations like this are the motivation for the assertRaisesRegexp function from the standard unittest module (which you should probably be using). (Note the spelling: Python 3 supports the only spelling from 2 (with the p), so that’s what you’d want here.)

Using type() in python for almost anything is not flexible. Instead you should use isinstance(var, type). It is almost the same in both versions of python 2.7 and 3:

isinstance(2, int)

This returns True in both versions every time.

Make sure you do not accidentally put the type in a string:

INCORRECT: 'int'

CORRECT: int

OR:

print(type(2) is int)

will output:

True

Related