Archive for July, 2010

Upgrading to Python3: minor things which caught me out

I’ve already made one module Python3-compatible. I decided to bite the bullet and make my not-really-released winsys module completely Python3. I’d tried the 2to3.py approach but it left just enough false positives & negatives (sorry, don’t remember the details) that I decided to go by hand, including translating the unit tests from nose format to the updated unittest format.

Although I was reasonably clued-in on the changes from 2 to 3, I was caught out by a few things, which I list here in case they help anyone else:

  • __nonzero__ is now __bool__: I knew this perfectly well, but it took me a while to find out why my tests were failing. 2to3 would have picked this up straightaway.
  • __hash__ isn’t inherited if __eq__ is defined: this one surprised me and took a bit of research. (All right; I actually read the docs for __hash__).
  • bytes vs str: well, obviously you knew this, but it’s bitten me in some slightly unexpected places when interfacing via pywin32. The error message speaks of expecting a buffer object, which threw me slightly.
  • assertTrue doesn’t bool its param: UPDATE - of course this isn’t true at all; I was confusing this and the __bool__/__nonzero__ issue above. Thanks to Marius Gedminas for pointing this out.
  • pywin32 generates tz-aware datetime objects: for a long time, pywin32 rolled its own datetime type (as Python had none). Last year, Mark H canvassed the python-win32 list about committing to the Python datetime type. And now it’s there. But it’s tz-aware. And the core Python type isn’t. Fortunately, pywin32 has for a while shipped with the win32timezone module which solves the issue.

I’m sure there’ll be more which I’ll add here as they come along.

Python 2.7 is out. The end of the road approaches.

Congratulations to Benjamin Peterson and everyone else who’s contributed to the release of Python 2.7. I’m already trying to push myself over to 3.x for everyday use and I’m confident that this psychological milestone will give other library developers the motivation to start looking at the 3.x series for their live code and newer releases.

Irmen de Jong has released a Python3-compatible version of the newly-rewritten Pyro4 (as well as maintaining for 2.x). The developers of pyodbc (a module I use extensively) have a Python3 branch which is due to be merged soon. pywin32 has been 3.x for quite a while now (thanks, Mark & Roger). Once I finish porting my own win32-specific stuff, I’ll be well-placed to see 3.x rolled out here at work.

I don’t really do reddit

Following an interesting-looking link from someone’s blog / tweet / don’t remember led me to the Python section on reddit. Where I was surprised to find a link to my recent print/print() post with some comments. Now, apart from the occasional glance I don’t follow reddit. It looks like an interesting place, but frankly my time is already over-committed and I just know I’ll get drawn into discussing something or helping someone out. So I stay away.

The only drawback to this approach is that people are commenting on a post I made (and which someone else submitted to reddit) without my being aware that the discussing is taking place, and without my being able to engage in that discussion. Which is a shame. But probably for the best :)

Python 3: print or print()

There’s a thread over on the Python list which started a week ago as I write and is still running. The OP titled his post the provocative “I strongly dislike Python 3″ but what it really comes down to is “I strongly dislike print()”. Various people have come in on both sides of this well-worn argument.

Now, I don’t really mind futile discussions, and this clearly is one: Python 3 isn’t going to switch back, no matter how many people weigh in on the print-as-statement side. I’m in that camp myself, and when the matter was first up for discussion I had a to-and-fro with Alex Martelli on the subject which I backed away from fairly quickly. I continue to enjoy and benefit from Python regardless; I contribute to its development very slightly and very rarely; and even were I the most prolific contributor on the planet, I don’t believe that would give me any particular right to dictate design decisions of this sort. You take the rough with the smooth.

I think the side of the discussion which irks me the most is from those who are defending the print-as-function decision. Clearly there are cogent and persuasive reasons why print should be / should have been a function. No-one’s pretending that this was a decision taken randomly and for the sake of change. Or even for the sake of a foolish consistency. But if someone’s working practice involves using print a lot — perhaps in the interpreter rather than in a code editor — then the switch to the function version is clearly a burden. It may be more or less of a burden, but it involves having to do something which you didn’t have to do before. Being told that you should have been using logging or pdb or sys.stdout.write — all of which are valid tools to use in the proper place — doesn’t really make your life any easier.

So while Python 3 is now the default interpreter on my shortcut keys and I’m trying to write new code against 3.2, I still find it a pain to overcome the very long habit of, eg, print ad.find_user ().sAMAccountName. Obviously if Python 1.5.2 had had print () as a function originally, I wouldn’t find is so hard now. ;)

(As an aside I did wonder at first whether the American or some other non-UK keyboards had the brackets in some more convenient spot, but it doesn’t appear so…)

Dojo Attack!

We had a blast at the London Python Dojo last night. Food, drink, and location generously provided as ever by Fry-IT (may all their contracts come in on time and under budget!) and a book for the raffle from O’Reilly (may all their titles remain in demand). While the wining and dining (or was that whining and dinning?) was in progress, Nicholas had set up a whiteboard for what-to-do suggestions. When it came to vote, some ideas were thought good but impractical for one evening, and the winner was the original suggestion: Cells.

Well I had misgivings as to whether we could grasp the codebase and get a workable solution in place within an hour and a bit, but it was great. The idea is — within the rules of the game — to pit your agents against the other teams’, trying for a winning strategy combining eating, attacking, moving, and replicating, each of which need, lose or gain energy according to certain rules. The agents can also message others on the same team to communicate, eg, the location of food or enemies. We had four teams, some with agents based on the sample code, others with from-scratch algorithms.

The clear winners were the “white” agents — Team 2 — who’d based their strategy on one of the supplied examples plus an expansion phase which kicked in only once a certain amount of time had passed and involved replicating like mad. On Team 1, we’d gone for a pacifist approach, with some of our agents as “Buddhas”, staying still and eating, the rest “Hungry Ghosts”, eating, moving and replicating. None of them attacked. FWIW, we got wiped out pretty quickly, although that did depend on how far you started from the voracious white team.

The other teams had differing strategies: explorers and eaters; or tribal warfare — which looked hilarious on-screen, as all the yellows suddenly went into warfare mode, sending each other the location of nearby enemies and flocking towards them.

Next Dojo’s in September, but EuroPython’s later this month and I’m sure there’ll be quite a few us there.