fuzzy notepad

Tagged: python

[blog] A Rebuttal For Python 3

Zed Shaw, of Learn Python the Hard Way fame, has now written The Case Against Python 3.

Iā€™m not involved with core Python development. The only skin I have in this game is that I like Python 3. Itā€™s a good language. And one of the big factors Iā€™ve seen slowing its adoption is that respected people in the Python community keep grouching about it. Iā€™ve had multiple newcomers tell me they have the impression that Python 3 is some kind of unusable disaster, though they donā€™t know exactly why; itā€™s just something they hear from people who sound like they know what theyā€™re talking about. Then they actually use the language, and itā€™s fine.

Iā€™m sad to see the Python community needlessly sabotage itself, but Zedā€™s contribution is beyond the pale. Itā€™s not just making a big deal about changed details that wonā€™t affect most beginners; itā€™s complete and utter nonsense, on a platform aimed at people who canā€™t yet recognize it as nonsense. I am so mad.

[blog] Python FAQ: How do I port to Python 3?

Part of my Python FAQ, which is doomed to never be finished.

Maybe you have a Python 2 codebase. Maybe youā€™d like to make it work with Python 3. Maybe you really wish someone would write a comically long article on how to make that happen.

I have good news! Youā€™re already reading one.

(And if youā€™re not sure why youā€™d want to use Python 3 in the first place, perhaps youā€™d be interested in the companion article which delves into exactly that question?)

[blog] Python FAQ: Why should I use Python 3?

Part of my Python FAQ, which is doomed to never be finished.

The short answer is: because itā€™s the actively-developed version of the language, and you should use it for the same reason youā€™d use 2.7 instead of 2.6.

If youā€™re here, Iā€™m guessing thatā€™s not enough. You need something to sweeten the deal. Well, friend, I have got a whole mess of sugar cubes just for you.

And once youā€™re convinced, you may enjoy the companion article, how to port to Python 3! It also has some more details on the diffences between Python 2 and 3, whereas this article doesnā€™t focus too much on the features removed in Python 3.

[blog] Converting a Git repo from tabs to spaces

This post is about the thing in the title.

I used to work for Yelp. For historical reasons ā€” probably ā€œthe initial developers preferred itā€ ā€” their mostly-Python codebase had always been indented with tabs. Thatā€™s in stark contrast to the vast majority of the Python ecosystem, which generally uses the standard libraryā€™s style guide recommendation of four spaces. The presence of tabs caused occasional minor headaches and grumbles among the Python developers, who now numbered in the dozens and were generally used to spaces.

At the end of 2013, I bestowed Yelp with a Christmas gift: I converted their entire primary codebase from tabs to four spaces. On the off chance anyone else ever wants to do the same, hereā€™s how I did it. Probably. I mean, itā€™s been two and a half years, but I wrote most of this at the time, so it should be correct.

Please note: I do not care what you think about tabs versus spaces. Thatā€™s for a different post! I no longer work for Yelp, anyway ā€” so as compelling as your argument may be, I can no longer undo what I have done.

[blog] Embedding Lua vs Python

Nova Dasterin asks, with money:

How about usage of Lua for game development? Love2d etc. Also http://lexaloffle.com/pico-8.php which I recently heard about.

clarification: thoughts on Lua as a ā€˜good choiceā€™, also Lua vs Python for that subject (gamedev)

There are a couple ways I can interpret this, so Iā€™ll go with: all of them.

(edit: you may be interested in a subsequent post about the game I actually made for the PICO-8!)

[dev] Did some Spline work, again

Sketch is still buying days of my time, which is super cool of him. Continuing from last month, he asked that I make it possible to disable normal editing and only accept proposals on the wiki.

After some internal debate about how to add a real configuration system, I realized this could just be expressed with permissions, so I wrote some little permissions UI. And actually added them to the proposal code. Which is good.

I wanted to have a nice way to iterate all possible permissions from whatever plugins are currently active, but the way permissions work right now is kind of fucked up anyway, so in the end I just hardcoded a list of existing permissions. Oh, well. Iā€™ll get around to it.

Also I added CSRF protection everywhere. Whoops. Like I said, spline is still lacking in a lot of niceties, such as ā€œbeing ready for production useā€. But itā€™s getting there, one architecture astronauting session at a time.

While I was in there I finally added UI so Glip can attach videos and cutscenes to Floraverse pages without my intervention. It was pretty easy and I donā€™t know why I subjected myself to messing with the db manually for so long.

This isnā€™t very long or exciting; it was my project and I knew what I was doing, and there was a lot of pondering involved, and I donā€™t have anything to complain about.


Which is why Iā€™m using it to start off a dev log, containing shorter posts about things I have done that donā€™t merit some deep dive into obscure technology. I also started keeping a notebook (a real, physical notebook) for jotting down stuff I do every day, and maybe Iā€™ll summarize it once a week or so. Iā€™ll also post about little ā€œreleasesā€ like Mario Maker levels. In fact I might go make backdated posts for all the levels Iā€™ve made so far.

Remember, if youā€™re following via the Atom feed and only want to see the blog, thereā€™s a feed with only blog posts.

Iā€™m not sure what this means for the projects page, which has always been kind of a mess. Itā€™s also annoying that you canā€™t easily filter by project, because theyā€™re just tags, and itā€™s not obvious which tags are projects. Iā€™ll figure this out as I go, I suppose.

[release] Donā€™t use pickle ā€” use Camel

Donā€™t use pickle. Donā€™t use pickle. Donā€™t use pickle.

The problems with Pythonā€™s pickle module are extensively documented (and repeated). Itā€™s unsafe by default: untrusted pickles can execute arbitrary Python code. Its automatic, magical behavior shackles you to the internals of your classes in non-obvious ways. You canā€™t even easily tell which classes are baked forever into your pickles. Once a pickle breaks, figuring out why and where and how to fix it is an utter nightmare.

Donā€™t use pickle.

So we keep saying. But people keep using pickle. Because we donā€™t offer any real alternatives. Oops.

You can fix pickle, of course, by writing a bunch of __setstate__ and __reduce_ex__ methods, and maybe using the copyreg module that you didnā€™t know existed, and oops that didnā€™t work, and itā€™s trial and error figuring out which types you actually need to write this code for, and all you have to do is overlook one type and all your rigor was for nothing.

What about PyYAML? Oops, same problems: itā€™s dangerous by default, it shackles you to your class internals, itā€™s possible to be rigorous but hard to enforce it.

Okay, how about that thing Alex Gaynor told me to do at PyCon, where I write custom load and dump methods on my classes that just spit out JSON? Sure, you can do that. But if you want to serialize a nested object, then you have to manually call dump on it, and it has to not do the JSON dumping itself. Thereā€™s also the slight disadvantage that all the knowledge about what the data means is locked in your application, in code ā€” if all you have to look at is the JSON itself, thereā€™s no metadata besides ā€œversionā€. You canā€™t even tell if your codebase can still load a document without, well, just trying to load it. Weā€™re really talking about rolling ad-hoc data formats here, so I think thatā€™s a shame.

But I have good news: I have solved all of your problems.

[blog] Cython versus CFFI

(This article has been translated into Russian by Everycloudtechā€”thanks!)

I have a hilariously unfinished Python module I work on from time to time named sanpera. Itā€™s an imaging library for Python, with the vain hope that it might replace PIL someday. But this isnā€™t about sanpera.

sanpera happens to be powered by ImageMagick. I distinguish this from being an ā€œImageMagick wrapperā€, as it explicitly has nothing resembling the ImageMagick API, because said API is insane. But this isnā€™t about ImageMagick, either.

Using ImageMagick requires binding Python to C, and thatā€™s what this is about. There are several ways to use C libraries from Python:

  • Writing an extension module means the Python API is defined in C, so the library is used exactly as it was intended: with C code. Unfortunately this requires writing a lot of C, as well as a lot of careful Python refcounting. My C is passable, but Iā€™ve done far more reading it than writing it, so this is not an appealing option.

  • ctypes is a standard-library module that can load shared libraries and call functions from them without the use of a C compiler or any new C code. Convenient, especially if you hate dependencies (in which case why are you binding to C?), but all the ctypes-powered code Iā€™ve read has been tedious and fiddly and ugly.

  • Cython, a spiritual port/evolution/fork/something of the older Pyrex, is a language similar to Python that translates to C and then compiles into an extension module. Cython code can define Python classes and functions, but also call C functions and perform other C operations directly. Code with C semantics is translated fairly directly to C; code with Python semantics is translated to appropriate use of the CPython API; and Cython fills in all the bits to translate between the two.

I went with Cython because it looked interesting, it seemed to reduce the number of translation layers Iā€™d have to care about, and it would even let me write hot loops (this is an imaging library) in C without actually writing any C. Plus, since itā€™s not actually Python code, it can compile to both Python 2 and Python 3 extension modules with very little effort on my part.

Hereā€™s what Cython looks like:

[blog] dictproxyhack, or: ActiveState Code considered harmful

This is a story of how nothing in this story is my fault.

Iā€™ve got a coworker whoā€™s super into Clojure, a Lisp-like that runs on the JVM. In particular heā€™s super into how itā€™s got notions of mutability (and, thus, immutability) all throughout.

More than once heā€™s lamented that Python lacks a frozendictā€”a dictionary type that canā€™t be changed. Dictionaries tend to crop up a lot in Python, and in a very large codebase, itā€™s very easy to end up with this scenario:

  1. Some function somewhere generates a dict thatā€™s only used by one caller. The interface is obvious since the keys and values are created right there in one place. No problem.
  2. Other code comes along, notices this handy function, and starts using its return value. Some of this code may pass the ad-hoc dict up to callers, too.
  3. Some of that other code needs more things added to the dict, but computing the extra data is expensive, so arguments are added to the function that optionally turn on certain keys.
  4. Some code needs even more things added to the dict that are outside the purview of the original function, so they add helper functions that take the ad-hoc dict and add more things to it.
  5. Since this has all now happened multiple times throughout your codebase, someone addresses the problem by writing adapter code that infers the original dict from some other object describing its structure, thus saving everyone from writing all these functions that return dicts.

A lovely spaghetti dinner. Itā€™s now nigh impossible to trace what the dict contains or where half of it came from.

Returning an object in the first place would have avoided much of this, but when youā€™re sitting at step 1, that seems like a lot of effort just to return half a dozen things from a function you wrote to another function you wrote. Swapping out dict() for frozendict() is easy.

My opinion on frozendict had never grown stronger than ā€œI guess that would be coolā€, so I never sat down and wrote the class, and there must be enough subtleties that nobody else at Yelp has either.

Then today, PEP 416 came to my attention. This PEP proposed adding a frozendict type, but was rejected last year as being largely unnecessary. Whatā€™s interesting about it is that the rejection ends with almost a footnote suggesting that perhaps dictproxy ought to be exposed to Python-land, instead. And indeed this was done, and it exists in Python 3.3.

[blog] The controller pattern is awful (and other OO heresy)

Almost a year ago now, Jack Diederich gave a talk entitled ā€œStop Writing Classesā€œ, in which he implores Python programmers to stop creating classes just for the hell of it, and specifically calls out the common pattern of a class with only a constructor/initializer and a single methodā€”which should, of course, just be a function.

A few weeks ago, Armin Ronacher wrote a rebuttal entitled ā€œStart Writing More Classesā€œ, which argues that classes are essential for both writing extensible code and smoothing over crappy interfaces. (Hm. Now that I look at it again, if you read the post backwards, it almost sounds like heā€™s suggesting writing a class to smooth out the crappy interface you get from using too many classesā€¦)

Iā€™m having some trouble here, because I agree with both points of view. There must be a way to resolve this contradiction, a message that resonates with everyone.

I think Iā€™ve found it.

Stop writing stupid classes.

[blog] A new use for StackOverflow

Itā€™s hard to get a feel for a new tool. Is it any good? Does it do anything I canā€™t already do? Whatā€™s the community like? Tough questions to answer without diving in and using it for a significant amount of timeā€”and then you risk not liking the answers you get.

But fear not! I have discovered a new and brilliant way to discern the novel features of a tool, the vibrance of its community, and its range of users all at once. In mere minutes.

Look at its ten highest-voted questions on StackOverflow.

Iā€™m totally serious. Watch.

[blog] Quick doesnā€™t have to mean dirty

From TechCrunch:

Anyway, my sympathy for PHPā€™s deviltry is because I appreciate its ethos. Its just-get-it-done attitude. Or, as Melvin Tercan put it in his recent blog post, ā€œhereā€™s to the PHP Misfits. The pragmatic ones who would pick up anything ā€“ even double-clawed hammers ā€“ to build their own future. Often ridiculed and belittled by the hip guys in class who write cool code in Ruby or Python, but always the ones who just get shit done.ā€

Heā€™s on to something there. The best is the enemy of the good, and shipping some working PHP code is approximately a million times better than designing something mindblowing in Haskell that never actually ships. I fully support Jeff Atwoodā€™s call to replace PHP once and for allā€“but I hope that everyone realizes that eliminating its many, many, multitudinous flaws wonā€™t be enough; theyā€™ll have to somehow duplicate its just-make-it-work ethos, too.

This is a recurring sentiment: developers telling me, well, yeah, Python may be all cool in your ivory tower, man, but like, I just want to write some programs.

To which I say: what the fuck are you people smoking? Whence comes this belief that anything claimed to be a better tool must be some hellacious academic-only monstrosity which actively resists real-world use?

But, hey, Iā€™m sick of talking about PHP. So letā€™s talk about Python. In honor of the 90s, letā€™s make a guestbook.