"Fossies" - the Fresh Open Source Software Archive

Member "Django-1.11.25/docs/topics/python3.txt" (1 Oct 2019, 14176 Bytes) of package /linux/www/Django-1.11.25.tar.gz:


As a special service "Fossies" has tried to format the requested text file into HTML format (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 ===================
    2 Porting to Python 3
    3 ===================
    4 
    5 Django 1.5 is the first version of Django to support Python 3. The same code
    6 runs both on Python 2 (≥ 2.6.5) and Python 3 (≥ 3.2), thanks to the six_
    7 compatibility layer.
    8 
    9 .. _six: https://pythonhosted.org/six/
   10 
   11 This document is primarily targeted at authors of pluggable applications
   12 who want to support both Python 2 and 3. It also describes guidelines that
   13 apply to Django's code.
   14 
   15 Philosophy
   16 ==========
   17 
   18 This document assumes that you are familiar with the changes between Python 2
   19 and Python 3. If you aren't, read :ref:`Python's official porting guide
   20 <pyporting-howto>` first. Refreshing your knowledge of unicode handling on
   21 Python 2 and 3 will help; the `Pragmatic Unicode`_ presentation is a good
   22 resource.
   23 
   24 Django uses the *Python 2/3 Compatible Source* strategy. Of course, you're
   25 free to chose another strategy for your own code, especially if you don't need
   26 to stay compatible with Python 2. But authors of pluggable applications are
   27 encouraged to use the same porting strategy as Django itself.
   28 
   29 Writing compatible code is much easier if you target Python ≥ 2.6. Django 1.5
   30 introduces compatibility tools such as :mod:`django.utils.six`, which is a
   31 customized version of the :mod:`six module <six>`. For convenience,
   32 forwards-compatible aliases were introduced in Django 1.4.2. If your
   33 application takes advantage of these tools, it will require Django ≥ 1.4.2.
   34 
   35 Obviously, writing compatible source code adds some overhead, and that can
   36 cause frustration. Django's developers have found that attempting to write
   37 Python 3 code that's compatible with Python 2 is much more rewarding than the
   38 opposite. Not only does that make your code more future-proof, but Python 3's
   39 advantages (like the saner string handling) start shining quickly. Dealing
   40 with Python 2 becomes a backwards compatibility requirement, and we as
   41 developers are used to dealing with such constraints.
   42 
   43 Porting tools provided by Django are inspired by this philosophy, and it's
   44 reflected throughout this guide.
   45 
   46 .. _Pragmatic Unicode: http://nedbatchelder.com/text/unipain.html
   47 
   48 Porting tips
   49 ============
   50 
   51 Unicode literals
   52 ----------------
   53 
   54 This step consists in:
   55 
   56 - Adding ``from __future__ import unicode_literals`` at the top of your Python
   57   modules -- it's best to put it in each and every module, otherwise you'll
   58   keep checking the top of your files to see which mode is in effect;
   59 - Removing the ``u`` prefix before unicode strings;
   60 - Adding a ``b`` prefix before bytestrings.
   61 
   62 Performing these changes systematically guarantees backwards compatibility.
   63 
   64 However, Django applications generally don't need bytestrings, since Django
   65 only exposes unicode interfaces to the programmer. Python 3 discourages using
   66 bytestrings, except for binary data or byte-oriented interfaces. Python 2
   67 makes bytestrings and unicode strings effectively interchangeable, as long as
   68 they only contain ASCII data. Take advantage of this to use unicode strings
   69 wherever possible and avoid the ``b`` prefixes.
   70 
   71 .. note::
   72 
   73     Python 2's ``u`` prefix is a syntax error in Python 3.2 but it will be
   74     allowed again in Python 3.3 thanks to :pep:`414`. Thus, this
   75     transformation is optional if you target Python ≥ 3.3. It's still
   76     recommended, per the "write Python 3 code" philosophy.
   77 
   78 String handling
   79 ---------------
   80 
   81 Python 2's `unicode`_ type was renamed :class:`str` in Python 3,
   82 ``str()`` was renamed :class:`bytes`, and `basestring`_ disappeared.
   83 six_ provides :ref:`tools <string-handling-with-six>` to deal with these
   84 changes.
   85 
   86 Django also contains several string related classes and functions in the
   87 :mod:`django.utils.encoding` and :mod:`django.utils.safestring` modules. Their
   88 names used the words ``str``, which doesn't mean the same thing in Python 2
   89 and Python 3, and ``unicode``, which doesn't exist in Python 3. In order to
   90 avoid ambiguity and confusion these concepts were renamed ``bytes`` and
   91 ``text``.
   92 
   93 Here are the name changes in :mod:`django.utils.encoding`:
   94 
   95 ==================  ==================
   96 Old name            New name
   97 ==================  ==================
   98 ``smart_str``       ``smart_bytes``
   99 ``smart_unicode``   ``smart_text``
  100 ``force_unicode``   ``force_text``
  101 ==================  ==================
  102 
  103 For backwards compatibility, the old names still work on Python 2. Under
  104 Python 3, ``smart_str`` is an alias for ``smart_text``.
  105 
  106 For forwards compatibility, the new names work as of Django 1.4.2.
  107 
  108 .. note::
  109 
  110     :mod:`django.utils.encoding` was deeply refactored in Django 1.5 to
  111     provide a more consistent API. Check its documentation for more
  112     information.
  113 
  114 :mod:`django.utils.safestring` is mostly used via the
  115 :func:`~django.utils.safestring.mark_safe` and
  116 :func:`~django.utils.safestring.mark_for_escaping` functions, which didn't
  117 change. In case you're using the internals, here are the name changes:
  118 
  119 ==================  ==================
  120 Old name            New name
  121 ==================  ==================
  122 ``EscapeString``    ``EscapeBytes``
  123 ``EscapeUnicode``   ``EscapeText``
  124 ``SafeString``      ``SafeBytes``
  125 ``SafeUnicode``     ``SafeText``
  126 ==================  ==================
  127 
  128 For backwards compatibility, the old names still work on Python 2. Under
  129 Python 3, ``EscapeString`` and ``SafeString`` are aliases for ``EscapeText``
  130 and ``SafeText`` respectively.
  131 
  132 For forwards compatibility, the new names work as of Django 1.4.2.
  133 
  134 ``__str__()`` and ``__unicode__()`` methods
  135 -------------------------------------------
  136 
  137 In Python 2, the object model specifies :meth:`~object.__str__` and
  138 ` __unicode__()`_ methods. If these methods exist, they must return
  139 ``str`` (bytes) and ``unicode`` (text) respectively.
  140 
  141 The ``print`` statement and the :class:`str` built-in call
  142 :meth:`~object.__str__` to determine the human-readable representation of an
  143 object. The ``unicode`` built-in calls ` __unicode__()`_ if it
  144 exists, and otherwise falls back to :meth:`~object.__str__` and decodes the
  145 result with the system encoding. Conversely, the
  146 :class:`~django.db.models.Model` base class automatically derives
  147 :meth:`~object.__str__` from ` __unicode__()`_ by encoding to UTF-8.
  148 
  149 In Python 3, there's simply :meth:`~object.__str__`, which must return ``str``
  150 (text).
  151 
  152 (It is also possible to define :meth:`~object.__bytes__`, but Django applications
  153 have little use for that method, because they hardly ever deal with ``bytes``.)
  154 
  155 Django provides a simple way to define :meth:`~object.__str__` and
  156 ` __unicode__()`_ methods that work on Python 2 and 3: you must
  157 define a :meth:`~object.__str__` method returning text and to apply the
  158 :func:`~django.utils.encoding.python_2_unicode_compatible` decorator.
  159 
  160 On Python 3, the decorator is a no-op. On Python 2, it defines appropriate
  161 ` __unicode__()`_ and :meth:`~object.__str__` methods (replacing the
  162 original :meth:`~object.__str__` method in the process). Here's an example::
  163 
  164     from __future__ import unicode_literals
  165     from django.utils.encoding import python_2_unicode_compatible
  166 
  167     @python_2_unicode_compatible
  168     class MyClass(object):
  169         def __str__(self):
  170             return "Instance of my class"
  171 
  172 This technique is the best match for Django's porting philosophy.
  173 
  174 For forwards compatibility, this decorator is available as of Django 1.4.2.
  175 
  176 Finally, note that :meth:`~object.__repr__` must return a ``str`` on all
  177 versions of Python.
  178 
  179 :class:`dict` and :class:`dict`-like classes
  180 --------------------------------------------
  181 
  182 :meth:`dict.keys`, :meth:`dict.items` and :meth:`dict.values` return lists in
  183 Python 2 and iterators in Python 3. :class:`~django.http.QueryDict` and the
  184 :class:`dict`-like classes defined in ``django.utils.datastructures``
  185 behave likewise in Python 3.
  186 
  187 six_ provides compatibility functions to work around this change:
  188 :func:`~six.iterkeys`, :func:`~six.iteritems`, and :func:`~six.itervalues`.
  189 It also contains an undocumented ``iterlists`` function that works well for
  190 ``django.utils.datastructures.MultiValueDict`` and its subclasses.
  191 
  192 :class:`~django.http.HttpRequest` and :class:`~django.http.HttpResponse` objects
  193 --------------------------------------------------------------------------------
  194 
  195 According to :pep:`3333`:
  196 
  197 - headers are always ``str`` objects,
  198 - input and output streams are always ``bytes`` objects.
  199 
  200 Specifically, :attr:`HttpResponse.content <django.http.HttpResponse.content>`
  201 contains ``bytes``, which may become an issue if you compare it with a
  202 ``str`` in your tests. The preferred solution is to rely on
  203 :meth:`~django.test.SimpleTestCase.assertContains` and
  204 :meth:`~django.test.SimpleTestCase.assertNotContains`. These methods accept a
  205 response and a unicode string as arguments.
  206 
  207 Coding guidelines
  208 =================
  209 
  210 The following guidelines are enforced in Django's source code. They're also
  211 recommended for third-party applications that follow the same porting strategy.
  212 
  213 Syntax requirements
  214 -------------------
  215 
  216 Unicode
  217 ~~~~~~~
  218 
  219 In Python 3, all strings are considered Unicode by default. The ``unicode``
  220 type from Python 2 is called ``str`` in Python 3, and ``str`` becomes
  221 ``bytes``.
  222 
  223 You mustn't use the ``u`` prefix before a unicode string literal because it's
  224 a syntax error in Python 3.2. You must prefix byte strings with ``b``.
  225 
  226 In order to enable the same behavior in Python 2, every module must import
  227 ``unicode_literals`` from ``__future__``::
  228 
  229     from __future__ import unicode_literals
  230 
  231     my_string = "This is an unicode literal"
  232     my_bytestring = b"This is a bytestring"
  233 
  234 If you need a byte string literal under Python 2 and a unicode string literal
  235 under Python 3, use the :class:`str` builtin::
  236 
  237     str('my string')
  238 
  239 In Python 3, there aren't any automatic conversions between ``str`` and
  240 ``bytes``, and the :mod:`codecs` module became more strict. :meth:`str.encode`
  241 always returns ``bytes``, and ``bytes.decode`` always returns ``str``. As a
  242 consequence, the following pattern is sometimes necessary::
  243 
  244     value = value.encode('ascii', 'ignore').decode('ascii')
  245 
  246 Be cautious if you have to `index bytestrings`_.
  247 
  248 .. _index bytestrings: https://docs.python.org/3/howto/pyporting.html#text-versus-binary-data
  249 
  250 Exceptions
  251 ~~~~~~~~~~
  252 
  253 When you capture exceptions, use the ``as`` keyword::
  254 
  255     try:
  256         ...
  257     except MyException as exc:
  258         ...
  259 
  260 This older syntax was removed in Python 3::
  261 
  262     try:
  263         ...
  264     except MyException, exc:    # Don't do that!
  265         ...
  266 
  267 The syntax to reraise an exception with a different traceback also changed.
  268 Use :func:`six.reraise`.
  269 
  270 Magic methods
  271 -------------
  272 
  273 Use the patterns below to handle magic methods renamed in Python 3.
  274 
  275 Iterators
  276 ~~~~~~~~~
  277 
  278 ::
  279 
  280     class MyIterator(six.Iterator):
  281         def __iter__(self):
  282             return self             # implement some logic here
  283 
  284         def __next__(self):
  285             raise StopIteration     # implement some logic here
  286 
  287 Boolean evaluation
  288 ~~~~~~~~~~~~~~~~~~
  289 
  290 ::
  291 
  292     class MyBoolean(object):
  293 
  294         def __bool__(self):
  295             return True             # implement some logic here
  296 
  297         def __nonzero__(self):      # Python 2 compatibility
  298             return type(self).__bool__(self)
  299 
  300 Division
  301 ~~~~~~~~
  302 
  303 ::
  304 
  305     class MyDivisible(object):
  306 
  307         def __truediv__(self, other):
  308             return self / other     # implement some logic here
  309 
  310         def __div__(self, other):   # Python 2 compatibility
  311             return type(self).__truediv__(self, other)
  312 
  313         def __itruediv__(self, other):
  314             return self // other    # implement some logic here
  315 
  316         def __idiv__(self, other):  # Python 2 compatibility
  317             return type(self).__itruediv__(self, other)
  318 
  319 Special methods are looked up on the class and not on the instance to reflect
  320 the behavior of the Python interpreter.
  321 
  322 .. module: django.utils.six
  323 
  324 Writing compatible code with six
  325 --------------------------------
  326 
  327 six_ is the canonical compatibility library for supporting Python 2 and 3 in
  328 a single codebase. Read its documentation!
  329 
  330 A :mod:`customized version of six <django.utils.six>` is bundled with Django
  331 as of version 1.4.2. You can import it as ``django.utils.six``.
  332 
  333 Here are the most common changes required to write compatible code.
  334 
  335 .. _string-handling-with-six:
  336 
  337 String handling
  338 ~~~~~~~~~~~~~~~
  339 
  340 The ``basestring`` and ``unicode`` types were removed in Python 3, and the
  341 meaning of ``str`` changed. To test these types, use the following idioms::
  342 
  343     isinstance(myvalue, six.string_types)       # replacement for basestring
  344     isinstance(myvalue, six.text_type)          # replacement for unicode
  345     isinstance(myvalue, bytes)                  # replacement for str
  346 
  347 Python ≥ 2.6 provides ``bytes`` as an alias for ``str``, so you don't need
  348 :data:`six.binary_type`.
  349 
  350 ``long``
  351 ~~~~~~~~
  352 
  353 The ``long`` type no longer exists in Python 3. ``1L`` is a syntax error. Use
  354 :data:`six.integer_types` check if a value is an integer or a long::
  355 
  356     isinstance(myvalue, six.integer_types)      # replacement for (int, long)
  357 
  358 ``xrange``
  359 ~~~~~~~~~~
  360 
  361 If you use ``xrange`` on Python 2, import ``six.moves.range`` and use that
  362 instead. You can also import ``six.moves.xrange`` (it's equivalent to
  363 ``six.moves.range``) but the first technique allows you to simply drop the
  364 import when dropping support for Python 2.
  365 
  366 Moved modules
  367 ~~~~~~~~~~~~~
  368 
  369 Some modules were renamed in Python 3. The ``django.utils.six.moves``
  370 module (based on the :mod:`six.moves module <six.moves>`) provides a
  371 compatible location to import them.
  372 
  373 ``PY2``
  374 ~~~~~~~
  375 
  376 If you need different code in Python 2 and Python 3, check :data:`six.PY2`::
  377 
  378     if six.PY2:
  379         # compatibility code for Python 2
  380 
  381 This is a last resort solution when :mod:`six` doesn't provide an appropriate
  382 function.
  383 
  384 .. module:: django.utils.six
  385 
  386 Django customized version of ``six``
  387 ------------------------------------
  388 
  389 The version of six bundled with Django (``django.utils.six``) includes a few
  390 customizations for internal use only.
  391 
  392 .. _unicode: https://docs.python.org/2/library/functions.html#unicode
  393 .. _ __unicode__(): https://docs.python.org/2/reference/datamodel.html#object.__unicode__
  394 .. _basestring: https://docs.python.org/2/library/functions.html#basestring