Skip to main content


Showing posts from April, 2005

how well do you know python, part 6

class foo(list): def __eq__(self, other): raise 'foo.__eq__ called' >>> help(list.__eq__) Help on wrapper_descriptor: __eq__(...) x.__eq__(y) <==> x==y >>> [].__eq__(foo()) True >>> [] == foo() Traceback (most recent call last): File " ", line 1, in ? File " ", line 3, in __eq__ foo.__eq__ called Help says those two statements should be equivalent. Why aren't they?

Any questions?

Closing on a real beta for Spyce 2.0, is there anything you'd like to see better illustrated? I have time to do another demo in the next couple days provided the scope is reasonable.

Extending Spyce with spyceModule

One of the ways to extend Spyce is with a "Spyce module." This is a historical term, and a little unfortunate because some people have assumed when I talk about "modules" I automatically mean the Spyce variety rather than the vanilla python variety. A Spyce module is simply a class that extends spyceModule.spyceModule. That's it. Spyce modules may be used in a .spy page with [[.import name="modulename"]] which instructs the compiler to create code that instantiates an instance of the given spyceModule at the beginning of each request for this page. It also automatically invokes the instance's finish method when the request finishes. What can you do with Spyce modules? A common reason to write a Spyce module -- perhaps the most common -- is is to provide some sort of resource pooling. Here's the spydurus module which does exactly that: CONNECTIONS = 3 # max connections to put in the pool import Queue from spyceModule im

how well do you know python, part 5

I was reminded of this one while working on the Spyce/Durus demo to make it a better example of using Durus in a real application. What is wrong with the following code? import time, threading finished = False def foo(): import sys sys.stderr.write('testing') global finished finished = True threading.Thread(target=foo).start() while not finished: time.sleep(1) import A print 'finished' Update: fixed so there was only one problem.

Spyce 2.0 prerelease

There won't be an official beta this week after all; Rimon wants to review the code and docs over the weekend before we take that step. However, as an un official beta, Spyce 2.0 is available from subversion: svn co The featureset is solid at this point. If you start playing around now, you won't get burned by changes of that sort. You may well find bugs, of course, which I'll fix as soon as I can. The docs are up here , including a pretty good introduction as to Why Spyce 2.0 Rocks, if I say so myself. (That is, I say the intro is pretty good. But also that Spyce2 rocks, for that matter.) The to-do demo and an enhanced version of the chatbox demo are both included. Update : forgot a link to the changelog .

Not your father's spyce

You've taken spyce off my "disgusting template engines" list. This is how I'd want to see apps structured, exactly.     -- Tim Lesher As a followup to my Durus notes , I've put up a new Spyce + Durus demo showing off the features of Spyce 2.0. This time I allowed myself more than two files, and split the action logic into a separate module. (To-do lists seem to be the new standard for demoing your web toolkit, and I dare not be less than trendy.) I tried to comment the code (linked from the demo pages) so it speaks for itself. If you have questions after looking at that and the language constructs page, please feel free to ask in the comments here. I'd like the docs to be in good shape for the 2.0 release. Update: I've modified the demo to include spydurus, a Durus connection-pooling module for Spyce, and to use ClientStorage instead of FileStorage. The demo was popular enough that single-threading it got to be annoying. (Updated links to

Introduction to Durus

The README that comes with Durus is missing a couple pieces of information that are critical if you actually want to write a program that uses Durus, and the only other documentation appears to be the 2005 Durus pycon presentation , which gives an admirable description of the technical underpinnings but doesn't fill in the blanks of how to use it, either. Specifically, as far as code samples go, the README gives you this: Example using FileStorage to open a Connection to a file: from durus.file_storage import FileStorage from durus.connection import Connection connection = Connection(FileStorage("test.durus")) And this: # Assume mymodule defines A as a subclass of Persistent. from mymodule import A x = A() root = connection.get_root() # connection set as shown above. root["sample"] = x # root is dict-like connection.commit() # Now x is stored. That's all you get. Okay, in this situation it's

Spyce tag compilation example

I had the question, What do you mean by "compiling" tag libraries? I mean, that Spyce compiles that chatbox.spy into in a more-or-less 1.3-legal python module . (The classcode/handlers/exports features aren't in 1.3, but you get the idea.) The compiled result looks like this (output courtesy of the Spyce -c option): class boxlet(spyceTagPlus): name='boxlet' buffer=False exports=1 classcode=((7,4),(10,83),"def addLine(self):\n # (use get() in case server restarted)\n request._api.getServerGlobals().get('chatlines', []).append(request['newline'])",'test-chatbox.spy') handlers=[('e73068ffe2d1ead1793b6790ec48f92a04fd18641','self.addLine')] def syntax(self): self.syntaxSingleOnly() def begin(self,width='300',lines='5'): pool=self._api._startModule('pool',None,None) taglib=self._api.getModules()['taglib'] taglib.load('form','

Spyce active tags, version 2

(Updated with a little more explanation as to what's going on.) The Spyce Active Tag compiler is coming along nicely. Spyce has had active tags since 1.3.0 (current active release is 1.3.13; it's very, very stable by now), but writing a tag library shares a lot of the problems that JSP 1.x tag libraries had; it takes a lot of code to get something done. Now, I've updated the Spyce compiler to be able to compile tag libaries, and tied it in to the active handler feature as a bonus. Meaning, tags can wrapping their control logic together with the view so all the user has to write is a single tag, like "<chat:boxlet />" below. (You could put the controller logic into another module and write handler="foo.addLine" instead of self, but I'm keeping it simple here.) Here's a simple example that defines and uses a chatbox component. Chat state is stored in the server globals area for simplicity. This code is running (for the next few d

Open-source WYSIWYG editors: not quite there yet?

I'm looking for a free HTML editor suitable for end-users that are less comfortable entering html in a textarea. The most advanced open-source projects that fit this description seem to be xinha , a fork of the discontinued HTMLArea, and FCKEditor . Both suffer from problems with corrupting the browser history; bug reports are here and here (and here too ). I note though that blogger's proprietary editor doesn't have this problem. Breaking my back button is a serious usability problem. I note that both of these projects have huge amounts of features, far more than Blogger does. This would actually be a drawback to me if I were to deploy one, since I'd have to figure how to turn all the bloat off. Perhaps a project that focused less on features and more on usability could succeed better here. (Please, if there's one out there that I missed, point me to it.)

On referential integrity

At my place of employment we have a table that looks like this: CREATE TABLE permissions ( id character(40) NOT NULL, userid character(40) REFERENCES USERS(id), objectid character(40) NOT NULL, permission character varying(15) NOT NULL ); Note that objectid isn't a foreign key to anything. (Before I joined there was no foreign key declared for userid, either.) That is because in this schema, everything gets a unique char(40) ID, and for flexibility the designer wanted to use the same permissions storage for all tables in the database. (The fix for this, BTW, would involve creating an "objects" table that simply held all the IDs in the system and have that referenced by both the objects tables and any table like this one that wants to be able to reference "any object." I haven't done that yet, but I'll be moving that up on my priority list now.) About a month ago, after suitable testing, I ran an upgrade script against our live d

how well do you know python, part 4

import os def foo(s): f = lambda a: a + "; print '%s'" % os.getcwd() exec(f(s)) foo("print 'asdf'") What error does this give? Why? This one is pretty tough. I'll put a simpler illustration that gives the same error in the comments as a hint. (Updated to fix inadvertent SyntaxError in the exec'd string, pointed out by Ian Bicking. Python bails with the error I intended before reaching that point, though.)

plpython intro

My current employer keeps a lot of application metadata as xml in the database, and I needed to make a simple update to some of that. Writing a client program to do this would be immense overkill, as well as not playing nicely with my database auto-upgrade script. The update could be easily handled with a regular expression substitution, but although postgresql has a decent regular expression implementation built-in, it has no function to do replacement with them . [Update: regex_replace was added in version 8.1, six months after this post.) An underused feature of PostgreSQL is its ability to define functions in just about any language you like. Java, Perl, Python, TCL, among others, as well as PL/PGSQL. Most developers, unfortunately, are a bit leery of defining custom functions in the database. Whether this is because of the learning curve (which turns out to be quite shallow), or because they are too used to inferior databases that don't allow such things, I couldn

how well do you know python, part 3

Here's one to file in the "cryptic documentation" category. >>> import inspect >>> help(inspect.getargspec) Help on function getargspec in module inspect: getargspec(func) Get the names and default values of a function's arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments. What conditions would you guess might cause getargspec's args list to contain nested lists?

Spyce + Tiles = ?

Tonight I added Tiles-like functionality to the Spyce trunk. Now, this doesn't mean I cloned Tiles in Spyce. I took the usual Spyce approach of adding functionality found in the JSP world without adding all the complexity. (Actually, in this case it's actually more influenced by the OpenACS master and slave tags, but how many people would that mean anything to? :) Specifically I added a way to create consistent site layout templates in the reverse-include style familiar to users of all modern web frameworks. (No, ASP.NET isn't modern by this definition. But ASP.NET 2.0 will be. They call it "Master pages," and googling for that is an excellent way to find a lot of people talking about how this is the best thing since sliced bread. This entry is long enough without me reiterating the reasons why this is a Good Thing.) Instead of including header and footer in your content page, your content page declares that it belongs to a parent page, which defines

Solving a laptop performance problem

My main vice these days is Warcraft 3. (Not WoW -- I don't have nearly enough time for that. ) It's been frustrating, though, since it could get extremely choppy. Maybe 5 fps choppy. Dropping all the settings to lowest didn't help, which really puzzled me since although a GeForce fx Go5200 isn't the most powerful 3d card around by a long shot, a 2.8 GHz p4 should have been able to render this stuff in software . I didn't do anything about this at first but I got good enough at the game that I started losing games because of the choppiness. So a couple nights ago I went on a killing spree with Task Manager to see if it was a background task causing the problem. I didn't see any likely candidates, and sure enough, it didn't help. I did notice my Insprion 5160 runs rather hot, though, and I wondered if it could be underclocking the CPU and/or GPU to cool off. This program verified this theory: my cpu clock oscillated every few seconds between 2.8 and 1.8

how well do you know python, part 2

An easy one today: import os, threading def foo(s): print s for dir in os.listdir(os.getcwd()): threading.Thread(target=lambda: foo(dir)).start() What bug may cause this to print something other than the contents of the current directory?

corrupting postgresql

Carnage Blender ran out of space on its root partition Saturday. This is also the partition that has the postgresql data on it (WAL on a separate disk). Bad news: data from a few tables just disappeared in total violation of referential constraints. (Perhaps MVCC marked the old row as invalid for an UPDATE, but couldn't create the new row. Just guessing.) This post seems to indicate that this was fixed for 8.0, although it may have gotten into one of the later 7.x releases (CB is still running the ancient-by-postgresql-standards 7.4.2 release, just over a year old) as well. Changelogs don't mention it specifically though. I've rearranged disk usage so this won't happen again, but looking at the list of bugfixes through 7.4.7 I guess I should schedule some downtime to upgrade. Now that 8.0 has its first point release I should probably just bite the bullet and dump/reload to that. Unfortunately, Carnage Blender runs two multi-gig databases now, each with sever

jobs via RSS -- logical use of RSS, really. Example: . Maybe if I were younger or something I would have thought of that too. My grandchildren will mock me for still using email. On the other hand, I did create an rss feed for the python job board several months ago. I guess it didn't occur to me that anyone would want to know about non-python jobs. :)

C# partial classes

A couple days ago I was talking with a former co-instructor at Northface University about the new (in the sense of "been in the language spec for years but since Visual Studio 2003 didn't support it everyone's waiting for Studio 2005 before using it") C# feature called partial classes or partial types . If you're into dynamic languages, maybe you're like me and you think of mixins when you hear the phrase "partial classes." Wouldn't be the first time Microsoft gave old technology a new name and called it innovation, right? Unfortunately for C# developers, partial classes have nothing to do with refactoring common behavior into a single reusable code fragment. All it is is a way to break a class up into multiple files for the benefit of code generation tools like Studio 2005's GUI designer. This is something that could easily be done with annotations/decorators/attributes (Java/Python/C# terms for pretty-close-to-the-same-thing). In fa

Laszlo pycon slides

Unfortunately, not everyone who presented at pycon got notes to the archive . One of the ones I was particularly hoping to see was Oliver Steele 's talk on OpenLaszlo , partly because I love Jython (contributed 8 or so patches about a year ago, some of which have recently been applied now that Samuele isn't the only one with CVS access) but mostly because Laszlo is pretty damn cool. "Ajax" has all the press recently but I think the Laszlo approach has a lot more going for it, especially if IE 7 stays in the dark ages. Fortunately, Oliver just recently put up a a pdf of his openlazlo slides . Unfortunately there's a lot of blank slides, and rather more diagrams than code. (I think they were limited to 30 minutes, though. Ouch!) What I got out of it was, Porting the ActionScript assembler from Jython to Java roughly doubled the LOC for 10x the speed (seems like they use/used Jython 2.0 though, ancient even by Jython standards?) Jython's ease of