2

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.

5
  • Why check the string representations of the types at all? Commented Jun 24, 2020 at 13:38
  • @AbhinavGupta Does my answer help you? Commented Jun 24, 2020 at 14:03
  • @Davis I have updated my question for better clarity. Please have a re-look. Thanks for the help :) Commented Jun 24, 2020 at 14:06
  • I ran the code and got this error message AttributeError: 'TypeError' object has no attribute 'message' in python 3. This is because the attribute message from errors has been deprecated since python 2.6 according to: github.com/google/yapf/issues/564 It has been deprecated since python 2.6 and to look to: python.org/dev/peps/pep-0352 for further information. It seems like using e.message will not allow for the code to work in both versions. Commented Jun 24, 2020 at 14:18
  • 1
    @Eno Thanks for pointing that out. I've updated the line to be compatible with both versions. Commented Jun 24, 2020 at 22:43

2 Answers 2

2

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.)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks @Davis, this is what I was looking for. However, I've decided to wrap the error and override the message string for now. It would require simple changes in the unit tests.
0

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

2 Comments

Hi @Eno, I have updated my question. Can you please have a re-look? Thanks for helping out :)
Yes sure I will update my answer as soon as I find out a solution with this new information you have provided.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.