From cb48387f66a7fe9c2450b740a84c3c5af3712895 Mon Sep 17 00:00:00 2001 From: Thorsten Behrens Date: Wed, 29 Dec 2010 13:21:05 -0500 Subject: PY3K _fastmath support o _fastmath now builds and runs on PY3K o Changes to setup.py to allow /usr/include for gmp.h o Changes to setup.py to allow linking fastmath w/ static mpir on Windows without warning messages o Changes to test_DSA/test_RSA to throw an exception if _fastmath is present but cannot be imported (due to an issue building _fastmath or the shared gmp/mpir libraries not being reachable) o number.py has the code to flag a failing _fastmath, but that code is commented out for a better runtime experience o Clean up the if for py21compat import - should have been == not is o Clean up some '== None' occurences, now 'is None' instead --- python-3-changes.txt | 109 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 73 insertions(+), 36 deletions(-) (limited to 'python-3-changes.txt') diff --git a/python-3-changes.txt b/python-3-changes.txt index 51f9455..2b7b164 100755 --- a/python-3-changes.txt +++ b/python-3-changes.txt @@ -1,75 +1,112 @@ Py code: -setup.py invokes 2to3 automatically. This handles int/long and print issues, among others. -setup.py will touch nt.py on win32 after build and build again. This is necessary so 2to3 can do its magic on that file. - -There are still a lot of places in the code that need manual attention even with 2to3. They mostly have to do with string (2.x) vs. byte/unicode (3.x) representation - -Use "if sys.version_info[0] is 2:" where needed. Ideally, most of the conditional code can be in py3compat. - -Replace str(x) with bstr(x) if bytes were intended. Becomes str(x) in 2.x and bytes(x) in 3.x through py3compat module. -Replace chr(x) with bchr(x) if bytes were intended. Becomes chr(x) in 2.x and bytes([x]) in 3.x through py3compat module. -Replace ord(x) with bord(x) if bytes were intended. Becomes ord(x) in 2.x and x in 3.x through py3compat module. - -Comparing a string index to a string literal needs to be changed in 3.x, as b'string'[0] returns an integer, not b's'. -The comparison can be fixed by indexing the right side, too: "if s[0]==b('\x30')[0]:" or "if self.typeTag!=self.typeTags['SEQUENCE'][0]:" +setup.py invokes 2to3 automatically. This handles int/long and print issues, + among others. +setup.py will touch nt.py on win32 after build and build again. This is + necessary so 2to3 can do its magic on that file. + +There are still a lot of places in the code that need manual attention even + with 2to3. They mostly have to do with string (2.x) vs. byte/unicode (3.x) + representation + +Use "if sys.version_info[0] == 2:" where needed. Ideally, most of the + conditional code can be in py3compat. + +Replace str(x) with bstr(x) if bytes were intended. Becomes str(x) in 2.x and + bytes(x) in 3.x through py3compat module. +Replace chr(x) with bchr(x) if bytes were intended. Becomes chr(x) in 2.x and + bytes([x]) in 3.x through py3compat module. +Replace ord(x) with bord(x) if bytes were intended. Becomes ord(x) in 2.x and + x in 3.x through py3compat module. + +Comparing a string index to a string literal needs to be changed in 3.x, as + b'string'[0] returns an integer, not b's'. +The comparison can be fixed by indexing the right side, too: + "if s[0]==b('\x30')[0]:" or "if self.typeTag!=self.typeTags['SEQUENCE'][0]:" String literals need to be bytes if bytes were intended. -Replace "x" with b("x") if bytes were intended. Becomes "x" in 2.x, and s.encode("x","latin-1") in 3.x through py3compat module. -For example, '"".join' is replaced by 'b("").join', and 's = ""' becomes 's = b("")'. +Replace "x" with b("x") if bytes were intended. Becomes "x" in 2.x, and + s.encode("x","latin-1") in 3.x through py3compat module. +For example, '"".join' is replaced by 'b("").join', and 's = ""' becomes + 's = b("")'. Search for \x to find literals that may have been intended as byte strings -!! However, where a human-readable ASCII text string output was intended, such as in AllOrNothing.undigest(), leave as a string literal !! +!! However, where a human-readable ASCII text string output was intended, + such as in AllOrNothing.undigest(), leave as a string literal !! -Only load python_compat.py "if sys.version_info[0] is 2 and sys.version_info[1] is 1:" . -The assignment to True, False generates syntax errors in 3.x, and >= 2.2 don't need the compatibility code. +Only load py21compat.py + "if sys.version_info[0] == 2 and sys.version_info[1] == 1:" . + The assignment to True, False generates syntax errors in 3.x, and >= 2.2 don't + need the compatibility code. -Where print is used with >> to redirect, use a separate function instead. See setup.py for an example +Where print is used with >> to redirect, use a separate function instead. + See setup.py for an example -The string module has been changed in 3.x. It lost join and split, maketrans now expects bytes, and so on. +The string module has been changed in 3.x. It lost join and split, maketrans + now expects bytes, and so on. Replace string.join(a,b) with b.join(a). Replace string.split(a) with a.split(). Replace body of white-space-stripping functions with 'return "".join(s.split())' -Integer division via the "/" operator can return a float in 3.x. This causes issues in Util.number.getStrongPrime. As 2.1 does not support -the "//" operator, divmod(a,b)[0] is used instead, to conform with an existing practice throughout the rest of the pycrypto code base. +Integer division via the "/" operator can return a float in 3.x. This causes + issues in Util.number.getStrongPrime. As 2.1 does not support the "//" + operator, divmod(a,b)[0] is used instead, to conform with an existing practice + throughout the rest of the pycrypto code base. -Do not use assert_/failUnless or failIf. These are deprecated and are scheduled to be removed in Python 3.3 and 3.4. -Use instead assertEqual(expr,True) for assert_ and assertEqual(expr,False) for failIf +Do not use assert_/failUnless or failIf. These are deprecated and are scheduled + to be removed in Python 3.3 and 3.4. +Use instead assertEqual(expr,True) for assert_ and assertEqual(expr,False) for + failIf C code: -Extended "pycrypto_compat.h". It handles #define's for Python 3.x forward compatibility +Extended "pycrypto_compat.h". It handles #define's for Python 3.x forward + compatibility #include "pycrypto_compat.h" -// All other local includes after this, so they can benefit from the definitions in pycrypto_compat.h +// All other local includes after this, so they can benefit from the +// definitions in pycrypto_compat.h The compat header #defines IS_PY3K if compiling on 3.x -The compat header #defines PyBytes_*, PyUnicode_*, PyBytesObject to resolve to their PyString* counterparts if compiling on 2.x. -PyLong_* can be dangerous depending on code construct (think an if that runs PyInt_* with else PyLong_*), +The compat header #defines PyBytes_*, PyUnicode_*, PyBytesObject to resolve to + their PyString* counterparts if compiling on 2.x. +PyLong_* can be dangerous depending on code construct (think an if that runs + PyInt_* with else PyLong_*), therefore it is #defined in each individual module if needed and safe to do so. PyString_* has been replaced with PyBytes_* or PyUnicode_* depending on intent -PyStringObject has been replaced with PyBytesObject or PyUnicodeObject depending on intent. +PyStringObject has been replaced with PyBytesObject or PyUnicodeObject + depending on intent. PyInt_* has been replaced with PyLong_*, where safe to do (in all cases so far) The C code uses "#ifdef IS_PY3K" liberally. Code duplication has been avoided. -Module initialization and module structure differ significantly in 3.x. Conditionals take care of it. +Module initialization and module structure differ significantly in 3.x. + Conditionals take care of it. myModuleType.ob_type assignment conditionally becomes PyTypeReady for 3.x. -getattr cannot be used to check against custom attributes in 3.x. For 3.x, conditional code uses getattro -and PyUnicode_CompareWithASCIIString instead of strcmp +getattr cannot be used to check against custom attributes in 3.x. For 3.x, + conditional code uses getattro and PyUnicode_CompareWithASCIIString instead + of strcmp hexdigest() needed to be changed to return a Unicode object with 3.x TODO: -- Check for type of string in functions and throw an error when it's not correct. While at it, ensure that functions observe the guidelines below re type. +- Check for type of string in functions and throw an error when it's not + correct. While at it, ensure that functions observe the guidelines below + re type. This is friendlier than just relying on Python's errors. -- Document the expected types for functions. The cipher, the key and the input texts are byte-strings. Plaintext decodes are byte-strings currently, this needs review. - In keeping with how Python 3.x's hash functions work, the input MODE is a text string. hexdigest() returns a text string, and digest() returns a byte-string. +- Document the expected types for functions. + The cipher, the key and the input texts are byte-strings. + Plaintext decodes are byte-strings. (?? Not true for all functions ??) + In keeping with how Python 3.x's hash functions work, the input MODE is a + text string. + hexdigest() returns a text string + digest() returns a byte-string. - Look into LIBPATH/%LIB% and /NODEFAULTLIB:LIBCMT in setup.py for libgmp/libmpir - Go through test cases and see which modules are not covered -- Look into exclusions in setup.py +- Make sure DerSequence slicing is tested, since I took the explicit slice functions + away in 3.x +- Test install on all tested Python versions -- cgit v1.2.1