-
Couldn't load subscription status.
- Fork 485
Python2 to 3 Compatibility Pitfalls
feeb edited this page May 1, 2018
·
8 revisions
This is a collection of surprising behavior changes important for writing python3 compatible code. Because of the presence of libfuture, these behaviors are also present when the codebase is run on python2.
Bytestrings
-
bytes()cannot take an iterator. Though python3'sbytes()handles this properly, libfuture'sbytes()doesn't. -
bytes(n)where n is a number returns a bytestring of length n, all zeroes. - Indexing into a bytestring returns an integer on python3 and a one-character string on python2. libfuture standardizes this to always return ints.
- Use the
hexlify/unhexlifymethods frombinasciimodule to convert things to/from hexadecimal representation.
Strings
- Use the string methods in
utils/helpers.pyto determine types of strings being passed around. Preferisbytestr/isunicodetoisstring, unless it really doesn't matter. - Functions that read in data (e,g,
readlines,popen) will returnstr. In python3stris basically a unicode string, and in python2 they're basically bytestrings. Use the helper methods to make sure you're ready for either case. - Use the string literals
u'foo'orb'foo'rather than'foo'to avoid ambiguities, if you can. -
io.StringIOsimilarly now handles unicode rather than bytestrings. -
popen()withuniversal_newlines=Truewill return a bytestring no matter which version of python you use, which can be helpful.
Other types
- Use the
is*methods inutils/helpers.pyfor checking types. Libfuture introduces python3 compatible replacement types for types likebytes,int,objectetc. This is largely good but can be a weird headache if you are doing literal typechecking. E.g., a string could potentially be anewstringif it came from manticore, orstrif it came from a different library. Most of the headaches have already been worked through. - Python3 doesn't have a concept of a long. If you need to check for
ints orlongs, useisint. There's no reason to uselongliterals.
Python object model / metaclasses
-
__hash__needs to be re-implemented if your class overrides__eq__. - Be careful with implementing custom
__hasattr__and__getattr__methods. The resolution behaviors of these vary between python2 and 3 in confusing ways. - Metaclass syntax and behavior is pretty significantly different in python3. Manticore doesn't use this much, but be aware of it.