diff options
| author | yum <yum.food.vr@gmail.com> | 2023-01-23 14:28:53 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2023-01-23 14:32:09 -0800 |
| commit | 9fff496394dcd94c4084694ca96a5e07ab836274 (patch) | |
| tree | d89b78e16ecb6011bdd74555da79f7a8c1d90752 /FOSS/Python/Dependencies/future-0.18.2/docs/compatible_idioms.rst | |
| parent | 9329d64f991b8b3289af22e4c2eedb09a97c5640 (diff) | |
package.ps1 now fetches all dependencies
Don't literally check in Python since it looks dodgy (rightfully so).
Instead the build script just fetches it.
* Update README, simplifying language and documenting other projects
Diffstat (limited to 'FOSS/Python/Dependencies/future-0.18.2/docs/compatible_idioms.rst')
| -rw-r--r-- | FOSS/Python/Dependencies/future-0.18.2/docs/compatible_idioms.rst | 1457 |
1 files changed, 0 insertions, 1457 deletions
diff --git a/FOSS/Python/Dependencies/future-0.18.2/docs/compatible_idioms.rst b/FOSS/Python/Dependencies/future-0.18.2/docs/compatible_idioms.rst deleted file mode 100644 index b0cb05a..0000000 --- a/FOSS/Python/Dependencies/future-0.18.2/docs/compatible_idioms.rst +++ /dev/null @@ -1,1457 +0,0 @@ -.. _compatible-idioms: - -Cheat Sheet: Writing Python 2-3 compatible code -=============================================== - -- **Copyright (c):** 2013-2019 Python Charmers Pty Ltd, Australia. -- **Author:** Ed Schofield. -- **Licence:** Creative Commons Attribution. - -A PDF version is here: http://python-future.org/compatible\_idioms.pdf - -This notebook shows you idioms for writing future-proof code that is -compatible with both versions of Python: 2 and 3. It accompanies Ed -Schofield's talk at PyCon AU 2014, "Writing 2/3 compatible code". (The -video is here: http://www.youtube.com/watch?v=KOqk8j11aAI&t=10m14s.) - -Minimum versions: - -- Python 2: 2.7+ -- Python 3: 3.4+ - -Setup ------ - -The imports below refer to these ``pip``-installable packages on PyPI: - -:: - - import future # pip install future - import builtins # pip install future - import past # pip install future - import six # pip install six - -The following scripts are also ``pip``-installable: - -:: - - futurize # pip install future - pasteurize # pip install future - -See http://python-future.org and https://pythonhosted.org/six/ for more -information. - -Essential syntax differences ----------------------------- - -print -~~~~~ - -.. code:: python - - # Python 2 only: - print 'Hello' -.. code:: python - - # Python 2 and 3: - print('Hello') -To print multiple strings, import ``print_function`` to prevent Py2 from -interpreting it as a tuple: - -.. code:: python - - # Python 2 only: - print 'Hello', 'Guido' -.. code:: python - - # Python 2 and 3: - from __future__ import print_function # (at top of module) - - print('Hello', 'Guido') -.. code:: python - - # Python 2 only: - print >> sys.stderr, 'Hello' -.. code:: python - - # Python 2 and 3: - from __future__ import print_function - - print('Hello', file=sys.stderr) -.. code:: python - - # Python 2 only: - print 'Hello', -.. code:: python - - # Python 2 and 3: - from __future__ import print_function - - print('Hello', end='') -Raising exceptions -~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - raise ValueError, "dodgy value" -.. code:: python - - # Python 2 and 3: - raise ValueError("dodgy value") -Raising exceptions with a traceback: - -.. code:: python - - # Python 2 only: - traceback = sys.exc_info()[2] - raise ValueError, "dodgy value", traceback -.. code:: python - - # Python 3 only: - raise ValueError("dodgy value").with_traceback() -.. code:: python - - # Python 2 and 3: option 1 - from six import reraise as raise_ - # or - from future.utils import raise_ - - traceback = sys.exc_info()[2] - raise_(ValueError, "dodgy value", traceback) -.. code:: python - - # Python 2 and 3: option 2 - from future.utils import raise_with_traceback - - raise_with_traceback(ValueError("dodgy value")) -Exception chaining (PEP 3134): - -.. code:: python - - # Setup: - class DatabaseError(Exception): - pass -.. code:: python - - # Python 3 only - class FileDatabase: - def __init__(self, filename): - try: - self.file = open(filename) - except IOError as exc: - raise DatabaseError('failed to open') from exc -.. code:: python - - # Python 2 and 3: - from future.utils import raise_from - - class FileDatabase: - def __init__(self, filename): - try: - self.file = open(filename) - except IOError as exc: - raise_from(DatabaseError('failed to open'), exc) -.. code:: python - - # Testing the above: - try: - fd = FileDatabase('non_existent_file.txt') - except Exception as e: - assert isinstance(e.__cause__, IOError) # FileNotFoundError on Py3.3+ inherits from IOError -Catching exceptions -~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - try: - ... - except ValueError, e: - ... -.. code:: python - - # Python 2 and 3: - try: - ... - except ValueError as e: - ... -Division -~~~~~~~~ - -Integer division (rounding down): - -.. code:: python - - # Python 2 only: - assert 2 / 3 == 0 -.. code:: python - - # Python 2 and 3: - assert 2 // 3 == 0 -"True division" (float division): - -.. code:: python - - # Python 3 only: - assert 3 / 2 == 1.5 -.. code:: python - - # Python 2 and 3: - from __future__ import division # (at top of module) - - assert 3 / 2 == 1.5 -"Old division" (i.e. compatible with Py2 behaviour): - -.. code:: python - - # Python 2 only: - a = b / c # with any types -.. code:: python - - # Python 2 and 3: - from past.utils import old_div - - a = old_div(b, c) # always same as / on Py2 -Long integers -~~~~~~~~~~~~~ - -Short integers are gone in Python 3 and ``long`` has become ``int`` -(without the trailing ``L`` in the ``repr``). - -.. code:: python - - # Python 2 only - k = 9223372036854775808L - - # Python 2 and 3: - k = 9223372036854775808 -.. code:: python - - # Python 2 only - bigint = 1L - - # Python 2 and 3 - from builtins import int - bigint = int(1) -To test whether a value is an integer (of any kind): - -.. code:: python - - # Python 2 only: - if isinstance(x, (int, long)): - ... - - # Python 3 only: - if isinstance(x, int): - ... - - # Python 2 and 3: option 1 - from builtins import int # subclass of long on Py2 - - if isinstance(x, int): # matches both int and long on Py2 - ... - - # Python 2 and 3: option 2 - from past.builtins import long - - if isinstance(x, (int, long)): - ... -Octal constants -~~~~~~~~~~~~~~~ - -.. code:: python - - 0644 # Python 2 only -.. code:: python - - 0o644 # Python 2 and 3 -Backtick repr -~~~~~~~~~~~~~ - -.. code:: python - - `x` # Python 2 only -.. code:: python - - repr(x) # Python 2 and 3 -Metaclasses -~~~~~~~~~~~ - -.. code:: python - - class BaseForm(object): - pass - - class FormType(type): - pass -.. code:: python - - # Python 2 only: - class Form(BaseForm): - __metaclass__ = FormType - pass -.. code:: python - - # Python 3 only: - class Form(BaseForm, metaclass=FormType): - pass -.. code:: python - - # Python 2 and 3: - from six import with_metaclass - # or - from future.utils import with_metaclass - - class Form(with_metaclass(FormType, BaseForm)): - pass -Strings and bytes ------------------ - -Unicode (text) string literals -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If you are upgrading an existing Python 2 codebase, it may be preferable -to mark up all string literals as unicode explicitly with ``u`` -prefixes: - -.. code:: python - - # Python 2 only - s1 = 'The Zen of Python' - s2 = u'きたないのよりきれいな方がいい\n' - - # Python 2 and 3 - s1 = u'The Zen of Python' - s2 = u'きたないのよりきれいな方がいい\n' -The ``futurize`` and ``python-modernize`` tools do not currently offer -an option to do this automatically. - -If you are writing code for a new project or new codebase, you can use -this idiom to make all string literals in a module unicode strings: - -.. code:: python - - # Python 2 and 3 - from __future__ import unicode_literals # at top of module - - s1 = 'The Zen of Python' - s2 = 'きたないのよりきれいな方がいい\n' -See http://python-future.org/unicode\_literals.html for more discussion -on which style to use. - -Byte-string literals -~~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only - s = 'This must be a byte-string' - - # Python 2 and 3 - s = b'This must be a byte-string' -To loop over a byte-string with possible high-bit characters, obtaining -each character as a byte-string of length 1: - -.. code:: python - - # Python 2 only: - for bytechar in 'byte-string with high-bit chars like \xf9': - ... - - # Python 3 only: - for myint in b'byte-string with high-bit chars like \xf9': - bytechar = bytes([myint]) - - # Python 2 and 3: - from builtins import bytes - for myint in bytes(b'byte-string with high-bit chars like \xf9'): - bytechar = bytes([myint]) -As an alternative, ``chr()`` and ``.encode('latin-1')`` can be used to -convert an int into a 1-char byte string: - -.. code:: python - - # Python 3 only: - for myint in b'byte-string with high-bit chars like \xf9': - char = chr(myint) # returns a unicode string - bytechar = char.encode('latin-1') - - # Python 2 and 3: - from builtins import bytes, chr - for myint in bytes(b'byte-string with high-bit chars like \xf9'): - char = chr(myint) # returns a unicode string - bytechar = char.encode('latin-1') # forces returning a byte str -basestring -~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - a = u'abc' - b = 'def' - assert (isinstance(a, basestring) and isinstance(b, basestring)) - - # Python 2 and 3: alternative 1 - from past.builtins import basestring # pip install future - - a = u'abc' - b = b'def' - assert (isinstance(a, basestring) and isinstance(b, basestring)) -.. code:: python - - # Python 2 and 3: alternative 2: refactor the code to avoid considering - # byte-strings as strings. - - from builtins import str - a = u'abc' - b = b'def' - c = b.decode() - assert isinstance(a, str) and isinstance(c, str) - # ... -unicode -~~~~~~~ - -.. code:: python - - # Python 2 only: - templates = [u"blog/blog_post_detail_%s.html" % unicode(slug)] -.. code:: python - - # Python 2 and 3: alternative 1 - from builtins import str - templates = [u"blog/blog_post_detail_%s.html" % str(slug)] -.. code:: python - - # Python 2 and 3: alternative 2 - from builtins import str as text - templates = [u"blog/blog_post_detail_%s.html" % text(slug)] -StringIO -~~~~~~~~ - -.. code:: python - - # Python 2 only: - from StringIO import StringIO - # or: - from cStringIO import StringIO - - # Python 2 and 3: - from io import BytesIO # for handling byte strings - from io import StringIO # for handling unicode strings -Imports relative to a package ------------------------------ - -Suppose the package is: - -:: - - mypackage/ - __init__.py - submodule1.py - submodule2.py - - -and the code below is in ``submodule1.py``: - -.. code:: python - - # Python 2 only: - import submodule2 -.. code:: python - - # Python 2 and 3: - from . import submodule2 -.. code:: python - - # Python 2 and 3: - # To make Py2 code safer (more like Py3) by preventing - # implicit relative imports, you can also add this to the top: - from __future__ import absolute_import -Dictionaries ------------- - -.. code:: python - - heights = {'Fred': 175, 'Anne': 166, 'Joe': 192} -Iterating through ``dict`` keys/values/items -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Iterable dict keys: - -.. code:: python - - # Python 2 only: - for key in heights.iterkeys(): - ... -.. code:: python - - # Python 2 and 3: - for key in heights: - ... -Iterable dict values: - -.. code:: python - - # Python 2 only: - for value in heights.itervalues(): - ... -.. code:: python - - # Idiomatic Python 3 - for value in heights.values(): # extra memory overhead on Py2 - ... -.. code:: python - - # Python 2 and 3: option 1 - from builtins import dict - - heights = dict(Fred=175, Anne=166, Joe=192) - for key in heights.values(): # efficient on Py2 and Py3 - ... -.. code:: python - - # Python 2 and 3: option 2 - from future.utils import itervalues - # or - from six import itervalues - - for key in itervalues(heights): - ... -Iterable dict items: - -.. code:: python - - # Python 2 only: - for (key, value) in heights.iteritems(): - ... -.. code:: python - - # Python 2 and 3: option 1 - for (key, value) in heights.items(): # inefficient on Py2 - ... -.. code:: python - - # Python 2 and 3: option 2 - from future.utils import viewitems - - for (key, value) in viewitems(heights): # also behaves like a set - ... -.. code:: python - - # Python 2 and 3: option 3 - from future.utils import iteritems - # or - from six import iteritems - - for (key, value) in iteritems(heights): - ... -dict keys/values/items as a list -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -dict keys as a list: - -.. code:: python - - # Python 2 only: - keylist = heights.keys() - assert isinstance(keylist, list) -.. code:: python - - # Python 2 and 3: - keylist = list(heights) - assert isinstance(keylist, list) -dict values as a list: - -.. code:: python - - # Python 2 only: - heights = {'Fred': 175, 'Anne': 166, 'Joe': 192} - valuelist = heights.values() - assert isinstance(valuelist, list) -.. code:: python - - # Python 2 and 3: option 1 - valuelist = list(heights.values()) # inefficient on Py2 -.. code:: python - - # Python 2 and 3: option 2 - from builtins import dict - - heights = dict(Fred=175, Anne=166, Joe=192) - valuelist = list(heights.values()) -.. code:: python - - # Python 2 and 3: option 3 - from future.utils import listvalues - - valuelist = listvalues(heights) -.. code:: python - - # Python 2 and 3: option 4 - from future.utils import itervalues - # or - from six import itervalues - - valuelist = list(itervalues(heights)) -dict items as a list: - -.. code:: python - - # Python 2 and 3: option 1 - itemlist = list(heights.items()) # inefficient on Py2 -.. code:: python - - # Python 2 and 3: option 2 - from future.utils import listitems - - itemlist = listitems(heights) -.. code:: python - - # Python 2 and 3: option 3 - from future.utils import iteritems - # or - from six import iteritems - - itemlist = list(iteritems(heights)) -Custom class behaviour ----------------------- - -Custom iterators -~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only - class Upper(object): - def __init__(self, iterable): - self._iter = iter(iterable) - def next(self): # Py2-style - return self._iter.next().upper() - def __iter__(self): - return self - - itr = Upper('hello') - assert itr.next() == 'H' # Py2-style - assert list(itr) == list('ELLO') -.. code:: python - - # Python 2 and 3: option 1 - from builtins import object - - class Upper(object): - def __init__(self, iterable): - self._iter = iter(iterable) - def __next__(self): # Py3-style iterator interface - return next(self._iter).upper() # builtin next() function calls - def __iter__(self): - return self - - itr = Upper('hello') - assert next(itr) == 'H' # compatible style - assert list(itr) == list('ELLO') -.. code:: python - - # Python 2 and 3: option 2 - from future.utils import implements_iterator - - @implements_iterator - class Upper(object): - def __init__(self, iterable): - self._iter = iter(iterable) - def __next__(self): # Py3-style iterator interface - return next(self._iter).upper() # builtin next() function calls - def __iter__(self): - return self - - itr = Upper('hello') - assert next(itr) == 'H' - assert list(itr) == list('ELLO') -Custom ``__str__`` methods -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - class MyClass(object): - def __unicode__(self): - return 'Unicode string: \u5b54\u5b50' - def __str__(self): - return unicode(self).encode('utf-8') - - a = MyClass() - print(a) # prints encoded string -.. code:: python - - # Python 2 and 3: - from future.utils import python_2_unicode_compatible - - @python_2_unicode_compatible - class MyClass(object): - def __str__(self): - return u'Unicode string: \u5b54\u5b50' - - a = MyClass() - print(a) # prints string encoded as utf-8 on Py2 - -.. parsed-literal:: - - Unicode string: 孔子 - - -Custom ``__nonzero__`` vs ``__bool__`` method: -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - class AllOrNothing(object): - def __init__(self, l): - self.l = l - def __nonzero__(self): - return all(self.l) - - container = AllOrNothing([0, 100, 200]) - assert not bool(container) -.. code:: python - - # Python 2 and 3: - from builtins import object - - class AllOrNothing(object): - def __init__(self, l): - self.l = l - def __bool__(self): - return all(self.l) - - container = AllOrNothing([0, 100, 200]) - assert not bool(container) -Lists versus iterators ----------------------- - -xrange -~~~~~~ - -.. code:: python - - # Python 2 only: - for i in xrange(10**8): - ... -.. code:: python - - # Python 2 and 3: forward-compatible - from builtins import range - for i in range(10**8): - ... -.. code:: python - - # Python 2 and 3: backward-compatible - from past.builtins import xrange - for i in xrange(10**8): - ... -range -~~~~~ - -.. code:: python - - # Python 2 only - mylist = range(5) - assert mylist == [0, 1, 2, 3, 4] -.. code:: python - - # Python 2 and 3: forward-compatible: option 1 - mylist = list(range(5)) # copies memory on Py2 - assert mylist == [0, 1, 2, 3, 4] -.. code:: python - - # Python 2 and 3: forward-compatible: option 2 - from builtins import range - - mylist = list(range(5)) - assert mylist == [0, 1, 2, 3, 4] -.. code:: python - - # Python 2 and 3: option 3 - from future.utils import lrange - - mylist = lrange(5) - assert mylist == [0, 1, 2, 3, 4] -.. code:: python - - # Python 2 and 3: backward compatible - from past.builtins import range - - mylist = range(5) - assert mylist == [0, 1, 2, 3, 4] -map -~~~ - -.. code:: python - - # Python 2 only: - mynewlist = map(f, myoldlist) - assert mynewlist == [f(x) for x in myoldlist] -.. code:: python - - # Python 2 and 3: option 1 - # Idiomatic Py3, but inefficient on Py2 - mynewlist = list(map(f, myoldlist)) - assert mynewlist == [f(x) for x in myoldlist] -.. code:: python - - # Python 2 and 3: option 2 - from builtins import map - - mynewlist = list(map(f, myoldlist)) - assert mynewlist == [f(x) for x in myoldlist] -.. code:: python - - # Python 2 and 3: option 3 - try: - import itertools.imap as map - except ImportError: - pass - - mynewlist = list(map(f, myoldlist)) # inefficient on Py2 - assert mynewlist == [f(x) for x in myoldlist] -.. code:: python - - # Python 2 and 3: option 4 - from future.utils import lmap - - mynewlist = lmap(f, myoldlist) - assert mynewlist == [f(x) for x in myoldlist] -.. code:: python - - # Python 2 and 3: option 5 - from past.builtins import map - - mynewlist = map(f, myoldlist) - assert mynewlist == [f(x) for x in myoldlist] -imap -~~~~ - -.. code:: python - - # Python 2 only: - from itertools import imap - - myiter = imap(func, myoldlist) - assert isinstance(myiter, iter) -.. code:: python - - # Python 3 only: - myiter = map(func, myoldlist) - assert isinstance(myiter, iter) -.. code:: python - - # Python 2 and 3: option 1 - from builtins import map - - myiter = map(func, myoldlist) - assert isinstance(myiter, iter) -.. code:: python - - # Python 2 and 3: option 2 - try: - import itertools.imap as map - except ImportError: - pass - - myiter = map(func, myoldlist) - assert isinstance(myiter, iter) -.. code:: python - - # Python 2 and 3: option 3 - from six.moves import map - - myiter = map(func, myoldlist) - assert isinstance(myiter, iter) - -zip, izip -~~~~~~~~~ - -As above with ``zip`` and ``itertools.izip``. - -filter, ifilter -~~~~~~~~~~~~~~~ - -As above with ``filter`` and ``itertools.ifilter`` too. - -Other builtins --------------- - -File IO with open() -~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only - f = open('myfile.txt') - data = f.read() # as a byte string - text = data.decode('utf-8') - - # Python 2 and 3: alternative 1 - from io import open - f = open('myfile.txt', 'rb') - data = f.read() # as bytes - text = data.decode('utf-8') # unicode, not bytes - - # Python 2 and 3: alternative 2 - from io import open - f = open('myfile.txt', encoding='utf-8') - text = f.read() # unicode, not bytes -reduce() -~~~~~~~~ - -.. code:: python - - # Python 2 only: - assert reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) == 1+2+3+4+5 -.. code:: python - - # Python 2 and 3: - from functools import reduce - - assert reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) == 1+2+3+4+5 -raw\_input() -~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - name = raw_input('What is your name? ') - assert isinstance(name, str) # native str -.. code:: python - - # Python 2 and 3: - from builtins import input - - name = input('What is your name? ') - assert isinstance(name, str) # native str on Py2 and Py3 -input() -~~~~~~~ - -.. code:: python - - # Python 2 only: - input("Type something safe please: ") -.. code:: python - - # Python 2 and 3 - from builtins import input - eval(input("Type something safe please: ")) -Warning: using either of these is **unsafe** with untrusted input. - -file() -~~~~~~ - -.. code:: python - - # Python 2 only: - f = file(pathname) -.. code:: python - - # Python 2 and 3: - f = open(pathname) - - # But preferably, use this: - from io import open - f = open(pathname, 'rb') # if f.read() should return bytes - # or - f = open(pathname, 'rt') # if f.read() should return unicode text -exec -~~~~ - -.. code:: python - - # Python 2 only: - exec 'x = 10' - - # Python 2 and 3: - exec('x = 10') -.. code:: python - - # Python 2 only: - g = globals() - exec 'x = 10' in g - - # Python 2 and 3: - g = globals() - exec('x = 10', g) -.. code:: python - - # Python 2 only: - l = locals() - exec 'x = 10' in g, l - - # Python 2 and 3: - exec('x = 10', g, l) -execfile() -~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - execfile('myfile.py') -.. code:: python - - # Python 2 and 3: alternative 1 - from past.builtins import execfile - - execfile('myfile.py') -.. code:: python - - # Python 2 and 3: alternative 2 - exec(compile(open('myfile.py').read())) - - # This can sometimes cause this: - # SyntaxError: function ... uses import * and bare exec ... - # See https://github.com/PythonCharmers/python-future/issues/37 -unichr() -~~~~~~~~ - -.. code:: python - - # Python 2 only: - assert unichr(8364) == '€' -.. code:: python - - # Python 3 only: - assert chr(8364) == '€' -.. code:: python - - # Python 2 and 3: - from builtins import chr - assert chr(8364) == '€' -intern() -~~~~~~~~ - -.. code:: python - - # Python 2 only: - intern('mystring') -.. code:: python - - # Python 3 only: - from sys import intern - intern('mystring') -.. code:: python - - # Python 2 and 3: alternative 1 - from past.builtins import intern - intern('mystring') -.. code:: python - - # Python 2 and 3: alternative 2 - from six.moves import intern - intern('mystring') -.. code:: python - - # Python 2 and 3: alternative 3 - from future.standard_library import install_aliases - install_aliases() - from sys import intern - intern('mystring') -.. code:: python - - # Python 2 and 3: alternative 2 - try: - from sys import intern - except ImportError: - pass - intern('mystring') -apply() -~~~~~~~ - -.. code:: python - - args = ('a', 'b') - kwargs = {'kwarg1': True} -.. code:: python - - # Python 2 only: - apply(f, args, kwargs) -.. code:: python - - # Python 2 and 3: alternative 1 - f(*args, **kwargs) -.. code:: python - - # Python 2 and 3: alternative 2 - from past.builtins import apply - apply(f, args, kwargs) -chr() -~~~~~ - -.. code:: python - - # Python 2 only: - assert chr(64) == b'@' - assert chr(200) == b'\xc8' -.. code:: python - - # Python 3 only: option 1 - assert chr(64).encode('latin-1') == b'@' - assert chr(0xc8).encode('latin-1') == b'\xc8' -.. code:: python - - # Python 2 and 3: option 1 - from builtins import chr - - assert chr(64).encode('latin-1') == b'@' - assert chr(0xc8).encode('latin-1') == b'\xc8' -.. code:: python - - # Python 3 only: option 2 - assert bytes([64]) == b'@' - assert bytes([0xc8]) == b'\xc8' -.. code:: python - - # Python 2 and 3: option 2 - from builtins import bytes - - assert bytes([64]) == b'@' - assert bytes([0xc8]) == b'\xc8' -cmp() -~~~~~ - -.. code:: python - - # Python 2 only: - assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0 -.. code:: python - - # Python 2 and 3: alternative 1 - from past.builtins import cmp - assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0 -.. code:: python - - # Python 2 and 3: alternative 2 - cmp = lambda(x, y): (x > y) - (x < y) - assert cmp('a', 'b') < 0 and cmp('b', 'a') > 0 and cmp('c', 'c') == 0 -reload() -~~~~~~~~ - -.. code:: python - - # Python 2 only: - reload(mymodule) -.. code:: python - - # Python 2 and 3 - from imp import reload - reload(mymodule) -Standard library ----------------- - -dbm modules -~~~~~~~~~~~ - -.. code:: python - - # Python 2 only - import anydbm - import whichdb - import dbm - import dumbdbm - import gdbm - - # Python 2 and 3: alternative 1 - from future import standard_library - standard_library.install_aliases() - - import dbm - import dbm.ndbm - import dbm.dumb - import dbm.gnu - - # Python 2 and 3: alternative 2 - from future.moves import dbm - from future.moves.dbm import dumb - from future.moves.dbm import ndbm - from future.moves.dbm import gnu - - # Python 2 and 3: alternative 3 - from six.moves import dbm_gnu - # (others not supported) -commands / subprocess modules -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only - from commands import getoutput, getstatusoutput - - # Python 2 and 3 - from future import standard_library - standard_library.install_aliases() - - from subprocess import getoutput, getstatusoutput -StringIO module -~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only - from StringIO import StringIO - from cStringIO import StringIO -.. code:: python - - # Python 2 and 3 - from io import BytesIO - # and refactor StringIO() calls to BytesIO() if passing byte-strings -http module -~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - import httplib - import Cookie - import cookielib - import BaseHTTPServer - import SimpleHTTPServer - import CGIHttpServer - - # Python 2 and 3 (after ``pip install future``): - import http.client - import http.cookies - import http.cookiejar - import http.server -xmlrpc module -~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - import DocXMLRPCServer - import SimpleXMLRPCServer - - # Python 2 and 3 (after ``pip install future``): - import xmlrpc.server -.. code:: python - - # Python 2 only: - import xmlrpclib - - # Python 2 and 3 (after ``pip install future``): - import xmlrpc.client -html escaping and entities -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 and 3: - from cgi import escape - - # Safer (Python 2 and 3, after ``pip install future``): - from html import escape - - # Python 2 only: - from htmlentitydefs import codepoint2name, entitydefs, name2codepoint - - # Python 2 and 3 (after ``pip install future``): - from html.entities import codepoint2name, entitydefs, name2codepoint -html parsing -~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - from HTMLParser import HTMLParser - - # Python 2 and 3 (after ``pip install future``) - from html.parser import HTMLParser - - # Python 2 and 3 (alternative 2): - from future.moves.html.parser import HTMLParser -urllib module -~~~~~~~~~~~~~ - -``urllib`` is the hardest module to use from Python 2/3 compatible code. -You might want to switch to Requests (http://python-requests.org) instead. - -.. code:: python - - # Python 2 only: - from urlparse import urlparse - from urllib import urlencode - from urllib2 import urlopen, Request, HTTPError -.. code:: python - - # Python 3 only: - from urllib.parse import urlparse, urlencode - from urllib.request import urlopen, Request - from urllib.error import HTTPError -.. code:: python - - # Python 2 and 3: easiest option - from future.standard_library import install_aliases - install_aliases() - - from urllib.parse import urlparse, urlencode - from urllib.request import urlopen, Request - from urllib.error import HTTPError -.. code:: python - - # Python 2 and 3: alternative 2 - from future.standard_library import hooks - - with hooks(): - from urllib.parse import urlparse, urlencode - from urllib.request import urlopen, Request - from urllib.error import HTTPError -.. code:: python - - # Python 2 and 3: alternative 3 - from future.moves.urllib.parse import urlparse, urlencode - from future.moves.urllib.request import urlopen, Request - from future.moves.urllib.error import HTTPError - # or - from six.moves.urllib.parse import urlparse, urlencode - from six.moves.urllib.request import urlopen - from six.moves.urllib.error import HTTPError -.. code:: python - - # Python 2 and 3: alternative 4 - try: - from urllib.parse import urlparse, urlencode - from urllib.request import urlopen, Request - from urllib.error import HTTPError - except ImportError: - from urlparse import urlparse - from urllib import urlencode - from urllib2 import urlopen, Request, HTTPError -Tkinter -~~~~~~~ - -.. code:: python - - # Python 2 only: - import Tkinter - import Dialog - import FileDialog - import ScrolledText - import SimpleDialog - import Tix - import Tkconstants - import Tkdnd - import tkColorChooser - import tkCommonDialog - import tkFileDialog - import tkFont - import tkMessageBox - import tkSimpleDialog - import ttk - - # Python 2 and 3 (after ``pip install future``): - import tkinter - import tkinter.dialog - import tkinter.filedialog - import tkinter.scrolledtext - import tkinter.simpledialog - import tkinter.tix - import tkinter.constants - import tkinter.dnd - import tkinter.colorchooser - import tkinter.commondialog - import tkinter.filedialog - import tkinter.font - import tkinter.messagebox - import tkinter.simpledialog - import tkinter.ttk -socketserver -~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - import SocketServer - - # Python 2 and 3 (after ``pip install future``): - import socketserver -copy\_reg, copyreg -~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - import copy_reg - - # Python 2 and 3 (after ``pip install future``): - import copyreg -configparser -~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - from ConfigParser import ConfigParser - - # Python 2 and 3 (after ``pip install configparser``): - from configparser import ConfigParser -queue -~~~~~ - -.. code:: python - - # Python 2 only: - from Queue import Queue, heapq, deque - - # Python 2 and 3 (after ``pip install future``): - from queue import Queue, heapq, deque -repr, reprlib -~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - from repr import aRepr, repr - - # Python 2 and 3 (after ``pip install future``): - from reprlib import aRepr, repr -UserDict, UserList, UserString -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - from UserDict import UserDict - from UserList import UserList - from UserString import UserString - - # Python 3 only: - from collections import UserDict, UserList, UserString - - # Python 2 and 3: alternative 1 - from future.moves.collections import UserDict, UserList, UserString - - # Python 2 and 3: alternative 2 - from six.moves import UserDict, UserList, UserString - - # Python 2 and 3: alternative 3 - from future.standard_library import install_aliases - install_aliases() - from collections import UserDict, UserList, UserString -itertools: filterfalse, zip\_longest -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. code:: python - - # Python 2 only: - from itertools import ifilterfalse, izip_longest - - # Python 3 only: - from itertools import filterfalse, zip_longest - - # Python 2 and 3: alternative 1 - from future.moves.itertools import filterfalse, zip_longest - - # Python 2 and 3: alternative 2 - from six.moves import filterfalse, zip_longest - - # Python 2 and 3: alternative 3 - from future.standard_library import install_aliases - install_aliases() - from itertools import filterfalse, zip_longest |
