<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: python3</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/tags/python3.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2018-09-25T23:02:57+00:00</updated><author><name>Simon Willison</name></author><entry><title>How we rolled out one of the largest Python 3 migrations ever</title><link href="https://simonwillison.net/2018/Sep/25/dropbox/#atom-tag" rel="alternate"/><published>2018-09-25T23:02:57+00:00</published><updated>2018-09-25T23:02:57+00:00</updated><id>https://simonwillison.net/2018/Sep/25/dropbox/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://blogs.dropbox.com/tech/2018/09/how-we-rolled-out-one-of-the-largest-python-3-migrations-ever/"&gt;How we rolled out one of the largest Python 3 migrations ever&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“If you’re using Dropbox today, the application is powered by a Dropbox-customized variant of Python 3.5”


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/dropbox"&gt;dropbox&lt;/a&gt;&lt;/p&gt;



</summary><category term="python"/><category term="python3"/><category term="dropbox"/></entry><entry><title>Wagtail 2.0</title><link href="https://simonwillison.net/2018/Mar/1/wagtail/#atom-tag" rel="alternate"/><published>2018-03-01T16:06:12+00:00</published><updated>2018-03-01T16:06:12+00:00</updated><id>https://simonwillison.net/2018/Mar/1/wagtail/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://wagtail.io/blog/wagtail-2/"&gt;Wagtail 2.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
The leading Django content management system just released it’s 2.0 version—now Django 2.0 and Python 3 only, and with a new rich text editor based on Draft.js. I really like Wagtail—it’s full-feature,d mature, well-documented and philosophically aligned with how I think a CMS should work. I also like this line about the new Python 3 requirement: “Call us reckless neophiles, but we think that, nine years in, Python 3 is looking pretty solid.”


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/cms"&gt;cms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/wagtail"&gt;wagtail&lt;/a&gt;&lt;/p&gt;



</summary><category term="cms"/><category term="django"/><category term="python3"/><category term="wagtail"/></entry><entry><title>Moving a large and old codebase to Python3</title><link href="https://simonwillison.net/2018/Feb/20/moving-a-large-and-old-codebase-to-python3/#atom-tag" rel="alternate"/><published>2018-02-20T14:39:26+00:00</published><updated>2018-02-20T14:39:26+00:00</updated><id>https://simonwillison.net/2018/Feb/20/moving-a-large-and-old-codebase-to-python3/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://medium.com/@boxed/moving-a-large-and-old-codebase-to-python3-33a5a13f8c99"&gt;Moving a large and old codebase to Python3&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Really interesting case study full of good ideas. The codebase in this case was 240,000 lines of Python and Django written over the course of 15 years. The team used Python-Modernize to aid their transition to a six-compatible codebase first.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://www.reddit.com/r/programming/comments/7yuc30/moving_a_large_and_old_codebase_to_python3/"&gt;r/programming&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="python"/><category term="python3"/></entry><entry><title>Python &amp; Async Simplified</title><link href="https://simonwillison.net/2018/Feb/20/async-simplified/#atom-tag" rel="alternate"/><published>2018-02-20T00:30:03+00:00</published><updated>2018-02-20T00:30:03+00:00</updated><id>https://simonwillison.net/2018/Feb/20/async-simplified/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.aeracode.org/2018/02/19/python-async-simplified/"&gt;Python &amp;amp; Async Simplified&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew Godwin: “Python’s async framework is actually relatively simple when you treat it at face value, but a lot of tutorials and documentation discuss it in minute implementation detail, so I wanted to make a higher-level overview that deliberately ignores some of the small facts and focuses on the practicalities of writing projects that mix both kinds of code.” ‪This is really useful: clearly explains the two separate worlds of Python (sync and async functions) and describes Andrew’s clever sync_to_async and async_to_sync decorators as well.‬


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="async"/><category term="python"/><category term="python3"/></entry><entry><title>asgiref: AsyncToSync and SyncToAsync</title><link href="https://simonwillison.net/2018/Feb/2/asgiref-asynctosync-and-synctoasync/#atom-tag" rel="alternate"/><published>2018-02-02T19:06:48+00:00</published><updated>2018-02-02T19:06:48+00:00</updated><id>https://simonwillison.net/2018/Feb/2/asgiref-asynctosync-and-synctoasync/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://github.com/django/asgiref/blob/538ce5ee92962307db1082552839df7d0037176a/asgiref/sync.py"&gt;asgiref: AsyncToSync and SyncToAsync&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew’s classes in asgiref that can turn a synchronous callable into an awaitable (that runs in a thread pool) or an awaitable callable into a synchronous callable, using Python 3 futures and asyncio.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://www.aeracode.org/2018/02/02/channels-20/"&gt;Andrew Godwin&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="async"/><category term="python3"/></entry><entry><title>Channels 2.0</title><link href="https://simonwillison.net/2018/Feb/2/channels-2/#atom-tag" rel="alternate"/><published>2018-02-02T18:19:54+00:00</published><updated>2018-02-02T18:19:54+00:00</updated><id>https://simonwillison.net/2018/Feb/2/channels-2/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.aeracode.org/2018/02/02/channels-20/"&gt;Channels 2.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Andrew just shipped Channels 2.0—a major rewrite and redesign of the Channels project he started back in 2014. Channels brings async to Django, providing a logical, standardized way of supporting things like WebSockets and asynchronous execution on top of a Django application. Previously it required you to run a separate Twisted server and redis/RabbitMQ queue, but thanks to Python 3 async everything can now be deployed as a single process. And the new ASGI spec means its turtles all the way down! Everything from URL routing to view functions to middleware can be composed together using the same ASGI interface.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/andrew-godwin"&gt;andrew-godwin&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/async"&gt;async&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/django"&gt;django&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/websockets"&gt;websockets&lt;/a&gt;&lt;/p&gt;



</summary><category term="andrew-godwin"/><category term="async"/><category term="django"/><category term="python"/><category term="python3"/><category term="websockets"/></entry><entry><title>Let your code type-hint itself: introducing open source MonkeyType</title><link href="https://simonwillison.net/2017/Dec/15/monkeytype/#atom-tag" rel="alternate"/><published>2017-12-15T02:22:30+00:00</published><updated>2017-12-15T02:22:30+00:00</updated><id>https://simonwillison.net/2017/Dec/15/monkeytype/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="https://engineering.instagram.com/let-your-code-type-hint-itself-introducing-open-source-monkeytype-a855c7284881"&gt;Let your code type-hint itself: introducing open source MonkeyType&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Instagram have open sourced their tool for automatically adding type annotations to your Python 3 code via runtime tracing. By default it logs the types it sees to a SQLite database, which means you can browse them with Datasette!


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/static-typing"&gt;static-typing&lt;/a&gt;&lt;/p&gt;



</summary><category term="python"/><category term="python3"/><category term="static-typing"/></entry><entry><title>Python 3 Readiness</title><link href="https://simonwillison.net/2017/Dec/2/python-3-readiness/#atom-tag" rel="alternate"/><published>2017-12-02T23:13:20+00:00</published><updated>2017-12-02T23:13:20+00:00</updated><id>https://simonwillison.net/2017/Dec/2/python-3-readiness/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://py3readiness.org/"&gt;Python 3 Readiness&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
345 of the 360 most popular Python packages are now compatible with Python 3. I’d love to see a version of this graph over time.

    &lt;p&gt;&lt;small&gt;&lt;/small&gt;Via &lt;a href="https://news.ycombinator.com/item?id=15832924"&gt;My post on Hacker News&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="python"/><category term="python3"/></entry><entry><title>Porting my blog to Python 3</title><link href="https://simonwillison.net/2017/Oct/21/python3/#atom-tag" rel="alternate"/><published>2017-10-21T22:22:40+00:00</published><updated>2017-10-21T22:22:40+00:00</updated><id>https://simonwillison.net/2017/Oct/21/python3/#atom-tag</id><summary type="html">
    &lt;p&gt;This blog is now running on Python 3! Admittedly this is nearly nine years after &lt;a href="https://www.python.org/download/releases/3.0/"&gt;the first release of Python 3.0&lt;/a&gt;, but it’s the first Python 3 project I’ve deployed myself so I’m pretty excited about it.&lt;/p&gt;
&lt;p&gt;Library authors like to use &lt;a href="https://pypi.python.org/pypi/six"&gt;six&lt;/a&gt; to allow them to write code that supports both Python 2 and Python 3 at the same time… but my blog isn’t a library, so I used the &lt;a href="https://docs.python.org/3/library/2to3.html"&gt;2to3 conversion tool&lt;/a&gt; that ships with Python instead.&lt;/p&gt;
&lt;p&gt;And… it worked pretty well! I ran the following command from my project’s root directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;2to3 -w -n blog/ config/ redirects/ feedstats/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;-w&lt;/code&gt; option causes the files to be over-written in place. Since everything is already in git, there was no reason to have 2to3 show my a diff without applying it. Likewise, the &lt;code&gt;-n&lt;/code&gt; option tells 2to3 not to bother saving backups of the files it modifies.&lt;/p&gt;
&lt;p&gt;Here’s &lt;a href="https://github.com/simonw/simonwillisonblog/commit/615efeba55c0c32a8147bda49e207a7a52ddb674"&gt;the initial commit&lt;/a&gt; containing mostly the 2to3 changes.&lt;/p&gt;
&lt;p&gt;Next step: run the tests! My test suite may be very thin, but it does at least check that the app can run its migrations, start up and serve a few basic pages without errors. One of my migrations was failing due to rogue bytestrings but that was &lt;a href="https://github.com/simonw/simonwillisonblog/commit/f00224e7375098bb500b56b35c6f40dbc4955abc#diff-15a9a47c9ee1f93f3a07a4dbe0cf4214"&gt;an easy fix&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;At this point I started to lean heavily on my &lt;a href="https://simonwillison.net/2017/Oct/17/free-continuous-deployment/"&gt;continuous integration setup built on Travis CI&lt;/a&gt;. All of my Python 3 work took place &lt;a href="https://github.com/simonw/simonwillisonblog/tree/python3"&gt;in a branch&lt;/a&gt;, and all it took was a &lt;a href="https://github.com/simonw/simonwillisonblog/commit/f00224e7375098bb500b56b35c6f40dbc4955abc#diff-354f30a63fb0907d4ad57269548329e3"&gt;one line change to my .travis.yml&lt;/a&gt; for Travis to start running the tests for that branch using Python 3.&lt;/p&gt;
&lt;p&gt;With the basic tests working, I made my first deploy to my Heroku staging instance - after first &lt;a href="https://github.com/simonw/simonwillisonblog/commit/54b31e98e35031afbbf8c18f3c2446a0af8b5c65"&gt;modifying my Heroku runtime.txt&lt;/a&gt; to tell it to use Python 3.6.2. My staging environment allowed me to sanity check that everything would work OK when deployed to Heroku.&lt;/p&gt;
&lt;p&gt;At this point I got a bit lazy. The responsible thing to do would have been extensive manual testing plus systematic unit test coverage of core functionality. My blog is hardly a critical piece of infrastructure though, so I went with the faster option: put it all live and &lt;a href="https://simonwillison.net/2017/Oct/17/free-continuous-deployment/#Step_4_Monitor_errors_with_Sentry_75"&gt;use Sentry to see if anything breaks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is where Heroku’s ability to deploy a specific branch came in handy: one click to deploy my python3 branch, keep an eye on Sentry (via push notifications from &lt;a href="https://simonwillison.net/2017/Oct/17/free-continuous-deployment/#Step_5_Hook_it_all_together_with_Slack_97"&gt;my private slack channel&lt;/a&gt;) and then one click to deploy my master branch again for an instant rollback in case of errors. Which I had to do instantly, because it turned out I had stored some data in Django’s cache using Python 2 pickle and was trying to read it back out again using Python 3.&lt;/p&gt;
&lt;p&gt;I fixed that by &lt;a href="https://github.com/simonw/simonwillisonblog/commit/41f7a112721ec5772ad189c4293da081291a604a"&gt;bumping my cache VERSION setting&lt;/a&gt; and deployed again. This deploy lasted a few minute longer before Sentry started to fill up with encoding errors and I rolled it back again.&lt;/p&gt;
&lt;p&gt;The single biggest difference between Python 2 and Python 3 is &lt;a href="https://docs.python.org/3.0/whatsnew/3.0.html#text-vs-data-instead-of-unicode-vs-8-bit"&gt;how strings are handled&lt;/a&gt;. Python 3 strings are unicode sequences. Learning to live in a world where strings are all unicode and byte strings are the rare, deliberate exceptions takes some getting used to.&lt;/p&gt;
&lt;p&gt;The key challenge for my blog actually came from &lt;a href="https://github.com/simonw/simonwillisonblog/blob/45d7acd56af475119d2738e736d9b4cb19a9e8eb/blog/templatetags/entry_tags.py"&gt;my custom markup handling template tags&lt;/a&gt;. 15 years ago &lt;a href="https://simonwillison.net/2002/Jun/16/myFirstXhtmlMindBomb/"&gt;I made the decision&lt;/a&gt; to &lt;a href="https://simonwillison.net/2003/Jan/6/xhtmlIsJustFine/"&gt;store all of my blog entries&lt;/a&gt; as valid XHTML fragments. This meant I could use XML processors - back then in PHP, today &lt;a href="https://docs.python.org/3/library/xml.etree.elementtree.html"&gt;Python’s ElementTree&lt;/a&gt; - to perform various transformations on my content.&lt;/p&gt;
&lt;p&gt;ElementTree in Python 2 can only consume bytestrings. In Python 3 it expects unicode strings. Cleaning this up took a while, eventually inspiring me to &lt;a href="https://github.com/simonw/simonwillisonblog/commit/7295cddd1a6ab2c7bc6fcf3da410ab6ea0954791"&gt;refactor my custom template tags completely&lt;/a&gt;. In the process I realized that my blog templates were mostly written back before Django’s template language implemented autoescape (&lt;a href="https://simonwillison.net/2008/Jul/22/alpha/"&gt;in Django 1.0&lt;/a&gt;), so my code was littered with unnecessary &lt;code&gt;|escape&lt;/code&gt; and &lt;code&gt;|safe&lt;/code&gt; filters. Those are all gone now.&lt;/p&gt;
&lt;p&gt;Sentry lets you mark an exception as “resolved” when you think you’ve fixed it - if it occurs again after that it will be re-reported to your Slack channel and added back to the Sentry list of unresolved issues. Once Sentry was clear (especially given Googlebot had crawled my older pages) I could be pretty confident there were no more critical 500-causing errors.&lt;/p&gt;
&lt;p&gt;That left logic errors, of which only one has cropped up so far: the “zero years ago” bug. Entries on my homepage include a relative date representation, e.g. “three days ago”. Python 3 &lt;a href="https://www.python.org/dev/peps/pep-0238/"&gt;changed how the divison operator works on integers&lt;/a&gt; - &lt;code&gt;3 / 2 == 1.5&lt;/code&gt; where in Python 2 it gets truncated to &lt;code&gt;1&lt;/code&gt;. As a result, every entry on my homepage showed “zero years ago”. Thankfully this was &lt;a href="https://github.com/simonw/simonwillisonblog/commit/d6e6eeb93ac02aa33c59b151f2a20e26d41f18b1"&gt;a one-line fix&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;All in all this process was much less painful than I expected. It took me longer to write this blog entry than it did to actually make the conversion (thanks to 2to3 doing most of the tedious work), and the combination of Travis CI, Sentry and Heroku allowed me to ship aggressively with the knowledge that I could promptly identify and resolve any issues that came up.&lt;/p&gt;
&lt;p&gt;Next upgrade: &lt;a href="https://www.djangoproject.com/weblog/2017/oct/16/django-20-beta-1-released/"&gt;Django 2.0&lt;/a&gt;!&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/continuous-integration"&gt;continuous-integration&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/heroku"&gt;heroku&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/travis"&gt;travis&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sentry"&gt;sentry&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="continuous-integration"/><category term="python"/><category term="python3"/><category term="heroku"/><category term="travis"/><category term="sentry"/></entry><entry><title>Python 2.7 Release</title><link href="https://simonwillison.net/2010/Jul/4/python/#atom-tag" rel="alternate"/><published>2010-07-04T23:21:00+00:00</published><updated>2010-07-04T23:21:00+00:00</updated><id>https://simonwillison.net/2010/Jul/4/python/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.python.org/download/releases/2.7/"&gt;Python 2.7 Release&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Includes three of my favourite features from Python 3: odicts, set literals and set and dictionary comprehensions.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/dictionaries"&gt;dictionaries&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/odict"&gt;odict&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sets"&gt;sets&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/recovered"&gt;recovered&lt;/a&gt;&lt;/p&gt;



</summary><category term="dictionaries"/><category term="odict"/><category term="python"/><category term="python3"/><category term="sets"/><category term="recovered"/></entry><entry><title>Reexamining Python 3 Text I/O</title><link href="https://simonwillison.net/2010/Jan/28/python3/#atom-tag" rel="alternate"/><published>2010-01-28T13:28:07+00:00</published><updated>2010-01-28T13:28:07+00:00</updated><id>https://simonwillison.net/2010/Jan/28/python3/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.dabeaz.com/blog/2010/01/reexamining-python-3-text-io.html"&gt;Reexamining Python 3 Text I/O&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Python 3.1’s IO performance is a huge improvement over 3.0, but still considerably slower than 2.6. It turns out it’s all to do with Python 3’s unicode support: When you read a file in to a string, you’re asking Python to decode the bytes in to UTF-8 (the new default encoding) at the same time. If you open the file in binary mode Python 3 will read raw bytes in to a bytestring instead, avoiding the conversion overhead and performing only 4% slower than the equivalent code in Python 2.6.4.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/david-beazley"&gt;david-beazley&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/io"&gt;io&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/performance"&gt;performance&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/text"&gt;text&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/unicode"&gt;unicode&lt;/a&gt;&lt;/p&gt;



</summary><category term="david-beazley"/><category term="io"/><category term="performance"/><category term="python"/><category term="python3"/><category term="text"/><category term="unicode"/></entry><entry><title>Current State of Unladen Swallow (Towards a Faster Python)</title><link href="https://simonwillison.net/2010/Jan/7/voidspace/#atom-tag" rel="alternate"/><published>2010-01-07T12:41:48+00:00</published><updated>2010-01-07T12:41:48+00:00</updated><id>https://simonwillison.net/2010/Jan/7/voidspace/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.voidspace.org.uk/python/weblog/arch_d7_2010_01_02.shtml#e1146"&gt;Current State of Unladen Swallow (Towards a Faster Python)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
The Unladen Swallow team are now planning to merge their work back in to the mainline Python 3 branch, adding a powerful incentive for Python developers to port their old Python 2 code (since the official Python 2.x line is extremely unlikely to have Unladen Swallow merged in to it).


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/unladenswallow"&gt;unladenswallow&lt;/a&gt;&lt;/p&gt;



</summary><category term="python"/><category term="python3"/><category term="unladenswallow"/></entry><entry><title>What's New In Python 3.1</title><link href="https://simonwillison.net/2009/Jun/28/python31/#atom-tag" rel="alternate"/><published>2009-06-28T15:02:09+00:00</published><updated>2009-06-28T15:02:09+00:00</updated><id>https://simonwillison.net/2009/Jun/28/python31/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://docs.python.org/3.1/whatsnew/3.1.html"&gt;What&amp;#x27;s New In Python 3.1&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Lots of stuff, but the best bits are an ordered dictionary type (congrats, Armin), a Counter class for counting unique items in an iterable (I do this on an almost daily basis) and a bunch of performance improvements including a rewrite of the Python 3.0 IO system in C.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/armin-ronacher"&gt;armin-ronacher&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/performance"&gt;performance&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python31"&gt;python31&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/releases"&gt;releases&lt;/a&gt;&lt;/p&gt;



</summary><category term="armin-ronacher"/><category term="performance"/><category term="python"/><category term="python3"/><category term="python31"/><category term="releases"/></entry><entry><title>Dive into Python 3</title><link href="https://simonwillison.net/2009/Jan/26/hooray/#atom-tag" rel="alternate"/><published>2009-01-26T18:10:13+00:00</published><updated>2009-01-26T18:10:13+00:00</updated><id>https://simonwillison.net/2009/Jan/26/hooray/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://diveintopython3.org/"&gt;Dive into Python 3&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Mark Pilgrim’s seminal work taught me Python nearly eight years ago. Now he’s updating it to cover Python 3. It’s just a table of contents at the moment, but the chapter on “Packaging Python libraries” has me very excited.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/diveintopython"&gt;diveintopython&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/mark-pilgrim"&gt;mark-pilgrim&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/packaging"&gt;packaging&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="diveintopython"/><category term="mark-pilgrim"/><category term="packaging"/><category term="python"/><category term="python3"/></entry><entry><title>Quoting Christopher Lenz</title><link href="https://simonwillison.net/2008/Dec/6/cmlenz/#atom-tag" rel="alternate"/><published>2008-12-06T10:00:54+00:00</published><updated>2008-12-06T10:00:54+00:00</updated><id>https://simonwillison.net/2008/Dec/6/cmlenz/#atom-tag</id><summary type="html">
    &lt;blockquote cite="http://www.cmlenz.net/archives/2008/12/py3k"&gt;&lt;p&gt;I don't think that Python 3.0 is a bad thing. But that it's displayed so prominently on the Python web site, without any kind of warning that it's not going to work with 99% of the Python code out there, scares the hell out of me. People are going to download and install 3.0 by default, and nothing's going to work. They're going to complain, and many are going to simply walk away.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p class="cite"&gt;&amp;mdash; &lt;a href="http://www.cmlenz.net/archives/2008/12/py3k"&gt;Christopher Lenz&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/christopher-lenz"&gt;christopher-lenz&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="christopher-lenz"/><category term="python"/><category term="python3"/></entry><entry><title>What's New In Python 3.0</title><link href="https://simonwillison.net/2008/Dec/4/whatsnew/#atom-tag" rel="alternate"/><published>2008-12-04T12:40:57+00:00</published><updated>2008-12-04T12:40:57+00:00</updated><id>https://simonwillison.net/2008/Dec/4/whatsnew/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://docs.python.org/dev/3.0/whatsnew/3.0.html"&gt;What&amp;#x27;s New In Python 3.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Lots.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/guido-van-rossum"&gt;guido-van-rossum&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="guido-van-rossum"/><category term="python"/><category term="python3"/></entry><entry><title>Python 3.0</title><link href="https://simonwillison.net/2008/Dec/4/python/#atom-tag" rel="alternate"/><published>2008-12-04T12:38:41+00:00</published><updated>2008-12-04T12:38:41+00:00</updated><id>https://simonwillison.net/2008/Dec/4/python/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://www.python.org/download/releases/3.0/"&gt;Python 3.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
“We are pleased to announce the release of Python 3.0 (final), a new production-ready release, on December 3rd, 2008.”


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/releases"&gt;releases&lt;/a&gt;&lt;/p&gt;



</summary><category term="python"/><category term="python3"/><category term="releases"/></entry><entry><title>String types in Python 3</title><link href="https://simonwillison.net/2007/Oct/9/strings/#atom-tag" rel="alternate"/><published>2007-10-09T02:08:13+00:00</published><updated>2007-10-09T02:08:13+00:00</updated><id>https://simonwillison.net/2007/Oct/9/strings/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://pyside.blogspot.com/2007/10/string-types-in-python-3.html"&gt;String types in Python 3&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
bytes are now immutable (just like the bytestrings they are replacing) and a new mutable buffer type has been introduced.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/buffers"&gt;buffers&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/bytes"&gt;bytes&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/bytestrings"&gt;bytestrings&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/strings"&gt;strings&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/unicode"&gt;unicode&lt;/a&gt;&lt;/p&gt;



</summary><category term="buffers"/><category term="bytes"/><category term="bytestrings"/><category term="python"/><category term="python3"/><category term="strings"/><category term="unicode"/></entry><entry><title>Sam Ruby: 2to3</title><link href="https://simonwillison.net/2007/Sep/3/sam/#atom-tag" rel="alternate"/><published>2007-09-03T01:38:34+00:00</published><updated>2007-09-03T01:38:34+00:00</updated><id>https://simonwillison.net/2007/Sep/3/sam/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://intertwingly.net/blog/2007/09/01/2to3"&gt;Sam Ruby: 2to3&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Sam’s report on an attempt to port the Universal Feed Parser to Python 3.0. The 2to3 tool does most of the work, but it seems the unicode changes can be pretty tricky.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/2to3"&gt;2to3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/feedparser"&gt;feedparser&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/sam-ruby"&gt;sam-ruby&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/unicode"&gt;unicode&lt;/a&gt;&lt;/p&gt;



</summary><category term="2to3"/><category term="feedparser"/><category term="python"/><category term="python3"/><category term="sam-ruby"/><category term="unicode"/></entry><entry><title>What's New in Python 3.0</title><link href="https://simonwillison.net/2007/Sep/1/new/#atom-tag" rel="alternate"/><published>2007-09-01T01:41:34+00:00</published><updated>2007-09-01T01:41:34+00:00</updated><id>https://simonwillison.net/2007/Sep/1/new/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://docs.python.org/dev/3.0/whatsnew/3.0.html"&gt;What&amp;#x27;s New in Python 3.0&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
They’re definitely taking advantage of the break in backwards compatibility—lots of niggling inconsistencies are finally being cleaned up.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="python"/><category term="python3"/></entry><entry><title>Python 3.0a1 released</title><link href="https://simonwillison.net/2007/Aug/31/python/#atom-tag" rel="alternate"/><published>2007-08-31T20:36:39+00:00</published><updated>2007-08-31T20:36:39+00:00</updated><id>https://simonwillison.net/2007/Aug/31/python/#atom-tag</id><summary type="html">
    
&lt;p&gt;&lt;strong&gt;&lt;a href="http://python.org/download/releases/3.0/"&gt;Python 3.0a1 released&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
Wow, that was a pretty fast turnaround. Betas are planned for 2008, with a final release scheduled for August.


    &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python3"&gt;python3&lt;/a&gt;&lt;/p&gt;



</summary><category term="python"/><category term="python3"/></entry></feed>