{ "info": { "author": "Nando Florestan", "author_email": "nandoflorestan@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Intended Audience :: Developers", "License :: Public Domain", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5" ], "description": "Let's write Python 3 right now!\n===============================\n\nWhen the best Python 2/Python 3 compatibility modules -- especially the famous\n`*six* library invented by Benjamin Peterson `_\n-- were created, they were written from the point of view of a Python 2\nprogrammer starting to grok Python 3.\n\nBut it is 2016. Python 3.5 is here. 3.5!!!\n\nIf you use *six*, your code is compatible, but stuck in Python 2 idioms.\n\n**nine** turns **six** upside down. You write your code using Python 3 idioms\n-- as much as possible --, and it is the Python 2 \"version\" that is patched.\nNeedless to say, this approach is more future-proof.\n\nWhen thou writeth Python, thou shalt write Python 3 and,\njust for a little longer, ensure that the thing worketh on Python 2.7.\n\nHonestly you should not spend one thought on Python 2.6 anymore, it is\n`no longer supported `_\nsince its final release (2.6.9) in October 2013. Nobody uses 3.0 or 3.1 either.\n\nPython 2.7 will finally meet its demise in the year 2020. So, starting now,\nthine codebase shall look more like 3 than 2.\n\n*nine* facilitates this point of view. You can write code\nthat is as 3ish as possible while still supporting 2.6.\nVery comfortable for new projects.\n\nFor instance, you don't type ``unicode`` anymore, you type ``str``, and *nine*\nmakes ``str`` point to ``unicode`` on Python 2 (if you use our boilerplate).\nAlso, ``map``, ``zip`` and ``filter`` have Python 3 behaviour, on Python 2,\nmeaning they return iterators, not lists.\n\nThe author(s) of *nine* donate this module to the public domain.\n\nTo understand most of the intricacies involved in achieving 2&3 compatibility\nin a single codebase, I recommend reading this:\nhttp://lucumr.pocoo.org/2013/5/21/porting-to-python-3-redux/\n\n\nUsing nine\n==========\n\nIn each of your modules, start by declaring a text encoding and\nimporting Python 3 behaviours from __future__.\nThen import variables from *nine*, as per this boilerplate::\n\n # -*- coding: utf-8 -*-\n from __future__ import (absolute_import, division, print_function,\n unicode_literals)\n from nine import (IS_PYTHON2, str, basestring, native_str, chr, long,\n integer_types, class_types, range, range_list, reraise,\n iterkeys, itervalues, iteritems, map, zip, filter, input,\n implements_iterator, implements_to_string, implements_repr, nine,\n nimport)\n\nI know that is ugly. What did you expect? *nine* is 3 squared.\nOK, in many cases you can get away with less::\n\n # -*- coding: utf-8 -*-\n\n from __future__ import (absolute_import, division, print_function,\n unicode_literals)\n from nine import IS_PYTHON2, nimport, nine, range, str, basestring\n\nBut in the second case you need to remember to import the missing stuff when\nyou use it, and it is not realistic to expect that you will remember, is it?\n\n\nUnicode\n=======\n\nBecause of the ``unicode_literals`` import, **all string literals in the module\nbecome unicode objects**. No need to add a \"u\" prefix to each string literal.\nThis is the saner approach since in Python 3 strings are unicode objects\nby default, and you can then indicate ``b\"this is a byte string literal\"``.\nThe literals that actually need to be byte strings are very rare.\nBut you wouldn't believe how many developers are irrationally afraid\nof taking this simple step...\n\nIf you don't know much about Unicode, just read\n`The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) `_\n\n\nImporting moved stuff\n=====================\n\nMany standard library modules were renamed in Python 3, but nine can\nhelp. The ``nimport`` function gets the new Python 3 name, but knows to\nimport the old name if running in Python 2.\nFor instance, instead of writing this to import pickle::\n\n # Bad:\n try:\n import cPickle as pickle # Python 2.x\n except ImportError:\n import pickle # Python 3 automatically uses the C version.\n\n...you can write this::\n\n # Good:\n pickle = nimport('pickle')\n\nFor variables that have been moved: In the argument, please separate the module\nfrom the variable with a colon::\n\n name2codepoint = nimport('html.entities:name2codepoint')\n\nWant StringIO? I recommend you build lists instead. But if you really need it::\n\n # Good:\n if IS_PYTHON2:\n from cStringIO import StringIO as BytesIO, StringIO\n NativeStringIO = BytesIO\n else:\n from io import BytesIO, StringIO\n NativeStringIO = StringIO\n\nOur coverage of Python version differences probably isn't exhaustive,\nbut contributions are welcome.\n\nWhen in doubt,\n`use the source `_!\n\nSee the\n`project page at GitHub `_!\nWe also have\n`continuous integration at Travis-CI `_.\n\n\nThe *nine* class decorator\n==========================\n\nWe provide a class decorator for Python 2 and 3 compatibility of magic methods.\nMagic methods are those that start and end with two underlines.\n\nYou define the magic methods with their Python 3 names and,\non Python 2, they get their corresponding names. You may write:\n\n* ``__next__()``. Use the ``next(iterator)`` function to iterate.\n* ``__str__()``: must return a unicode string. In Python 2, we implement\n ``__unicode__()`` and ``__bytes__()`` for you, based on your ``__str__()``.\n* ``__repr__()``: must return a unicode string.\n* ``__bytes__()``: must return a bytes object.\n\nExample::\n\n @nine\n class MyClass(object):\n\n def __str__(self):\n return \"MyClass\" # a unicode string\n\n\nPorting steps\n=============\n\nWhen you are starting to apply *nine* on Python 2 code to achieve Python 3\ncompatibility, you can start by following this list of tasks. It isn't\nexhaustive, just a good start. You can upgrade one ``.py`` module at a time:\n\n* Add our header as mentioned above.\n* Replace ocurrences of the print statement with the print function\n (this roughly means, add parentheses).\n* Replace ``str()``, usually with nine's ``native_str()`` or with ``bytes()``.\n* Replace ``unicode()`` with ``str()`` and ``from nine import str``\n* Replace ``__unicode__()`` methods with ``__str__()`` methods;\n apply the ``@nine`` decorator on the class.\n* Also apply the ``@nine`` decorator on classes that define ``__repr__()``.\n* Search for ``range`` and replace with nine's ``range`` or ``range_list``\n* Some dict methods return different things in Python 3. Only if you need\n exactly the same behavior in both versions, replace:\n\n * ``d.keys()`` or ``d.iterkeys()`` with nine's ``iterkeys(d)``;\n * ``d.values()`` or ``d.itervalues()`` with nine's ``itervalues(d)``; and\n * ``d.items()`` or ``d.iteritems()`` with nine's ``iteritems(d)``.\n\n* Notice that ``map()``, ``zip()`` and ``filter()``, in nine's versions,\n always return iterators independently of Python version.\n\nIf you had been using *six* or another compatibility library before:\n\n* Replace ``string_types`` with nine's ``basestring``\n\nThen run your tests in all the Python versions you wish to support.\n\nIf I forgot to mention anything, could you\n`make a pull request `_, for the\nbenefit of other developers?", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/nandoflorestan/nine", "keywords": "python 2,python 3,python2,python3,migration,compatibility,nine,six,2to3,3to2,future", "license": "Public domain", "maintainer": null, "maintainer_email": null, "name": "nine", "package_url": "https://pypi.org/project/nine/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/nine/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/nandoflorestan/nine" }, "release_url": "https://pypi.org/project/nine/1.0.0/", "requires_dist": null, "requires_python": null, "summary": "Python 2 / 3 compatibility, like six, but favouring Python 3", "version": "1.0.0" }, "last_serial": 2127904, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "b55a58eb1fa7eb459fb604e99b77a6dd", "sha256": "6bac9f4778eaae376a39c97a68c8fbd3e1f77dba5c8d87c1f97f05d66295b38b" }, "downloads": -1, "filename": "nine-0.1.0.tar.gz", "has_sig": false, "md5_digest": "b55a58eb1fa7eb459fb604e99b77a6dd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3706, "upload_time": "2013-06-26T19:04:07", "url": "https://files.pythonhosted.org/packages/9d/0b/0e8cf560ead14fc760641b06792c0264bbecf5f63b419aa8c407c6d6e50b/nine-0.1.0.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "9ffc5d6ff9f991ab293998d1184fa6ab", "sha256": "e760045abd28dfb6c60514304b87a8a36eb7fe21e9a0530f087860829cdd2d05" }, "downloads": -1, "filename": "nine-0.2.0.tar.gz", "has_sig": false, "md5_digest": "9ffc5d6ff9f991ab293998d1184fa6ab", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5801, "upload_time": "2013-06-27T18:23:29", "url": "https://files.pythonhosted.org/packages/28/1b/40b0003769e60f2e1d5c4baf20ad20b3284da4d37f21f49138139a597abf/nine-0.2.0.tar.gz" } ], "0.3.0": [ { "comment_text": "", "digests": { "md5": "8d7c10a09729ca28aeadb18578ea8a1f", "sha256": "be4868388a03759234677cc2fa1ebd67264b805c2a0e35bfdd78e256c564e625" }, "downloads": -1, "filename": "nine-0.3.0.tar.gz", "has_sig": false, "md5_digest": "8d7c10a09729ca28aeadb18578ea8a1f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6045, "upload_time": "2013-06-28T22:59:42", "url": "https://files.pythonhosted.org/packages/12/dd/7997f06683f84d5d303b74be7982dbe44bbc5835ac3bc40140d566273d38/nine-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "6d853e27cc9bde0683995f97be671d5a", "sha256": "293c70be0900e0f165315729542abd7d3607faecdbf5e87ee5551290b468a5ab" }, "downloads": -1, "filename": "nine-0.3.1.tar.gz", "has_sig": false, "md5_digest": "6d853e27cc9bde0683995f97be671d5a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6055, "upload_time": "2013-07-05T16:36:07", "url": "https://files.pythonhosted.org/packages/c0/d3/6045a30182f5d679a19bf7d070c5bfd72913b64bd7e79258ae2bf0417dfb/nine-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "2469b69cf3b0db9ba3958ca95d5b8699", "sha256": "c535263a867e5fb344ebc49df6adabfbf1b4dde348fe324f4a9092ed0f07722e" }, "downloads": -1, "filename": "nine-0.3.2.tar.gz", "has_sig": false, "md5_digest": "2469b69cf3b0db9ba3958ca95d5b8699", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6757, "upload_time": "2013-07-13T00:27:36", "url": "https://files.pythonhosted.org/packages/02/a8/faa5cb8661025a9afca63fd9e476d477097cdd41b2d0b4023f8cba2b4e0c/nine-0.3.2.tar.gz" } ], "0.3.3": [ { "comment_text": "", "digests": { "md5": "867cc934f382fc5ce75f39be686fbfb8", "sha256": "afc288966b0c5e56b71021f6d690f506c36467572fada1b62c8f457e1c6f3434" }, "downloads": -1, "filename": "nine-0.3.3.tar.gz", "has_sig": false, "md5_digest": "867cc934f382fc5ce75f39be686fbfb8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7048, "upload_time": "2013-08-01T00:15:27", "url": "https://files.pythonhosted.org/packages/c8/cb/b37b6f4e8d955413b01613462e091ed4f02fc501393b46dee64d6b2de5f9/nine-0.3.3.tar.gz" } ], "0.3.4": [ { "comment_text": "", "digests": { "md5": "b3415655bba05e8a1a9caa3f8d9f9343", "sha256": "fe1723ca5d3db5cb28a861dca9da1a4a0ce3614057fb07279ddb4905415d3aff" }, "downloads": -1, "filename": "nine-0.3.4.tar.gz", "has_sig": false, "md5_digest": "b3415655bba05e8a1a9caa3f8d9f9343", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7191, "upload_time": "2014-10-12T16:35:15", "url": "https://files.pythonhosted.org/packages/f7/c0/096761e48c2d698661698057e42b40aa1e5feb35dbb60769c8d94e008844/nine-0.3.4.tar.gz" } ], "1.0.0": [ { "comment_text": "", "digests": { "md5": "11a450dbf98c466c96b3d869f59f2442", "sha256": "b87adc05ab148efa45869b63ce5c54d2a0be607c0a96449ea96e20d51a99150f" }, "downloads": -1, "filename": "nine-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "11a450dbf98c466c96b3d869f59f2442", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 12739, "upload_time": "2016-05-22T18:28:23", "url": "https://files.pythonhosted.org/packages/81/d7/e109e43a7e98a8c9ab26ab54aa766072a990fbfa571af07375470cec4819/nine-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "357ec643f17a3eb2a95cb1d5ba19a71e", "sha256": "3064fbeb512e756a415606a1399f49c22de867d5ac7e2b6c91c35e757d3af42d" }, "downloads": -1, "filename": "nine-1.0.0.tar.gz", "has_sig": false, "md5_digest": "357ec643f17a3eb2a95cb1d5ba19a71e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8795, "upload_time": "2016-05-22T18:28:17", "url": "https://files.pythonhosted.org/packages/31/0b/b86e3453dd85bf48eda37f842c91bc6f5ce2d5ffc451b6a88039340ed262/nine-1.0.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "11a450dbf98c466c96b3d869f59f2442", "sha256": "b87adc05ab148efa45869b63ce5c54d2a0be607c0a96449ea96e20d51a99150f" }, "downloads": -1, "filename": "nine-1.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "11a450dbf98c466c96b3d869f59f2442", "packagetype": "bdist_wheel", "python_version": "3.5", "requires_python": null, "size": 12739, "upload_time": "2016-05-22T18:28:23", "url": "https://files.pythonhosted.org/packages/81/d7/e109e43a7e98a8c9ab26ab54aa766072a990fbfa571af07375470cec4819/nine-1.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "357ec643f17a3eb2a95cb1d5ba19a71e", "sha256": "3064fbeb512e756a415606a1399f49c22de867d5ac7e2b6c91c35e757d3af42d" }, "downloads": -1, "filename": "nine-1.0.0.tar.gz", "has_sig": false, "md5_digest": "357ec643f17a3eb2a95cb1d5ba19a71e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8795, "upload_time": "2016-05-22T18:28:17", "url": "https://files.pythonhosted.org/packages/31/0b/b86e3453dd85bf48eda37f842c91bc6f5ce2d5ffc451b6a88039340ed262/nine-1.0.0.tar.gz" } ] }