I am migrating one big project from Python 2 -> Python 3, the issue with comparison between "bytes" and "str" only found when the old code run into it and fail explicitly. If it falsely pass, i will not be aware. One example:
def read_var_startaddr(self, var_name):
#__get_var_name() will return bytes
if self.__get_var_name() == var_name:
print("do something")
return self.__get_startaddr()
So i would like to fix this for the whole project, instead of waiting until something happens, there are twos things in my mind:
My Question: With option 2, Is it possible to do wrap the basic operator, how to do it and what are the impacts it may cause? Is there better way?
Thanks a lot!
Perhaps give 2to3
a try first (a tag you selected I assume unassumingly). It's built in with Python 3, and might save you a lot of time.
For number 2 specifically, you can overwrite the dunder method __eq__
in objects, and use that instead. Something like so:
class Item:
def __init__(self, item):
if isinstance(item, bytes):
self._item = item
elif isinstance(item, str):
self._item = bytes(item, 'utf-8')
elif isinstance(item, int):
self._item = bytes(str(item), 'utf-8')
else:
raise Exception("Item must be of type bytes, str, or int.")
def __eq__(self, other):
if isinstance(other, bytes):
return self._item == other
elif isinstance(other, str):
return self._item.decode("utf-8") == other
elif isinstance(other, int):
if self._item.isdigit():
return int(self._item) == other
else:
raise Exception("Cannot compare non-int to int.")
Then all of the following would work:
item = Item("hello")
item == "hello" # True
item == b"hello" # True
item = Item(100)
item == 100 # True
item == "100" # True
item == b"100" # True
Do note that all objects Item
will now be comparable with respect to the new __eq__
we wrote. If you are wondering "is there a way to modify ALL ==
comparison signs", the answer is... technically yes, but I promise you it is not worth it. You would have to deal with the ast
module and create some very confusing code.
You could also more simply create a function compare_str_bytes()
that uses some of the code above to compare bytes and strings accordingly.