![]() | Ned Batchelder : Blog | Code | Text | Site Blog » Home |
Global Django requestsSaturday 28 August 2010 As my Django sites get larger and larger, there inevitably comes a point where I want access to the current request from deep inside some function that doesn't have the request object. The latest reason was that I wanted a model class helper to have access to the session so it could access some debug flags. The first option for making this work was to pass the request object through two or three layers of code that otherwise didn't need a request. This meant changing the signature and callers of the two or three functions, which felt messy. The prospect of it made me unhappy. The second option was to create a way for any code invoked as part of a request to get access to the request, even if it weren't passed to it explicitly. I think of this as a global request object. Of course, there isn't really a single global request object, since there can be many threads, each of which is handling a separate request. We need a way to associate the request with a thread, and then to get the request for our thread. This middleware does the job nicely: from django.utils.thread_support import currentThread I didn't write this code, I got it from here and here, not sure who wrote it first. I'm also not sure why Django provides its own currentThread function when the Python standard module threading provides thread locals to acheive the same effect. There's another way to get a global request object, but you probably won't like it: def get_request(): This function looks at the stack frames of all of its callers, looking for one with a first argument named "request". If found, it returns the value. The problem with this function is that it can be fooled, and will return the "request" it finds regardless of its type. In its defense: GlobalRequestMiddleware requires more machinery, and adds a tiny tax to every request. If your need for the global request object is rare, the frame-based get_request() may be better for you. Also, it's a (nasty) technique that can be adapted to other situations.
tagged:
django» 6 reactions Coverage.py v3.4 beta 1Saturday 21 August 2010 Coverage.py v3.4 beta 1 is available now. 3.4 brings improved source code specification. The --omit and --include switches have changed in an incompatible way, taking file patterns rather than prefixes, and a new --source switch specifies directories or modules to measure. Details are in the new page about specifying source files in the coverage.py docs. These changes should help people focus coverage.py on the code they really want to measure. In addition, a few bug fixes have helped in this area: Jinja templates and doctest bodies are no longer measured, since they produced errors during reporting anyway. One other notable change: coverage.py used to report the number of statements, and the number of executed statements. Now instead of executed statements, it reports missed statements. This is a better indicator of how well your code is covered, because it's clear what the goal is: zero missed statements. Give this version a try. There have been lots of changes. Also, I hate to admit it: but this version has broken my own coverage measurement of coverage.py itself, and I haven't figured out why yet...
tagged:
my code,
coverage» 4 reactions EntrepreneurshipTuesday 17 August 2010 After posting Alain De Botton's quote about meaningful work, I read his book The Joys and Sorrows of Work. It was an interesting read, but ultimately a bit empty. He described a number of unusual working environments, but managed not to get a single worker's words or thoughts onto the page. Mostly what he describes are the factual landscape, his own reactions to what he sees, and way too much about his own difficulties traveling. But he is a thoughtful observer, and a good writer. After watching inventors pitch futilely to investors, he summed up the dynamics of venture capital thus:
A bit cynical, but spot on. I added an admin trapdoor login to a project the other day. This is the technique where a superuser can log in to a site as any other user. My preferred way to do this is to use the standard login form in a clever way: enter the desired user's name as the username, and both your superuser name and superuser password into the password field. But this project was modern enough that I could use a Django authentication backend to get the job done: from django.contrib.auth import login, authenticate Very nice.
tagged:
django» 10 reactions Better error messagesWednesday 28 July 2010 A simple piece of advice: If you are throwing an exception (or logging an error) about a value being incorrect in some way, include the value itself. It will make it so much easier for the poor sap who has to figure out why the exception is happening. I found myself in this situation, this code throwing an exception: if not isinstance(key, str): There are a few things wrong with this message, the first being that the multi-line string concatenation is missing a space, so the message actually has the word "notunicode" in it. Why are we so sure the wrong value is Unicode in the first place? And of course, it should include the actual value: if not isinstance(key, str): If you want to be paranoid, you can limit the amount of repr text that will appear in the message: if not isinstance(key, str): If you are really paranoid, you're worried that getting the repr of your unknown object could itself throw an exception: def safe_repr(o): or even: def safe_repr(o): Good error handling is always a pain, but it's worth it when things start hitting the fan and you have to figure out what's going on.
tagged:
python,
exceptions» 4 reactions Armin's post about Whitespace sensitivity in Ruby piqued my interest. It points out that in Ruby, foo[42] is different than foo [42] and that foo/bar is the same as foo / bar but different than foo /bar. So I wanted to learn more about Ruby, and looked at a bunch of tutorials, finally ending up at Mitch Fincher's Ruby Tutorial with Code Samples, which had the right breezy pace with no, "a variable is like a box for your numbers" stuff in it. But I had originally gotten to Mitch's page from a Google search for ruby puts gets. If you try it, you'll see that when you get to Mitch's page, a small box appears near the top, saying, Welcome. You seem to have come here from a search engine. Your search words (ruby puts gets) are highlighted on this page for your reading pleasure. I thought "nice," then I thought, "that looks familiar," then I realized it was almost exactly the box that appears at the top of my pages when you visit from a search engine (try it: batchelder white house adventure). In fact, it used the same colors. I looked at his page, and it used near-verbatim copies of my three Javascript files, though a few years ago I consolidated them into one. I was amused, and wondered where else the code is being used. But the search engines are smart enough not to index comments in Javascript files, or names of Javascript files referenced in HTML pages, unless there's some tricky syntax I don't know about. PS: about whitespace sensitivity: I've decided that phrase means a programming language needs tokens consisting of only whitespace in order to be parsed properly. Python and Ruby are whitespace-sensitive, and C is not, for example.
tagged:
google,
ruby» 3 reactions My wife's book Making Peace with Autism is now available in Korean: 자폐아 가정의 좌충우돌 성장 이야기. The publishing business is a strange place. The first we knew the book was being translated into Korean was when a box of the books was delivered to our doorstep. Apparently there was also an entry in the latest sales statement from the publisher, but those things are completely indecipherable, so we didn't notice. The Korean culture also seems to value cute more than we Americans do: the book is full of cartoony decorations. I guess that chipper salaryman on the cover is me!
tagged:
autism,
books,
susan» 3 reactions I'm a recent convert to virtualenv, it's a great way to maintain a number of different Python installations so that you can install packages for one project without it polluting the environment for all your projects. I also work on Windows, which can be a pain. In particular, many interesting Python packages involve compiling extensions, which is not always easy, and especially not easy on Windows. So I'm glad when package authors provide pre-built binaries for Windows. These are typically delivered as .exe Windows installers. Here's the problem: these installers know to look in the registry to find the Python installation. There are many things developers dislike about Windows, and the registry is often at the top of the list. One of the bad things about it is that it encourages a mindset of their being one of everything. Starting with the concept of "one registry", it seeps into the whole culture of Windows, invading even to Python, which cannot abide more than one installation of a major release. So when running a Windows package installer, it will find the Python 2.6 installation in the registry, and that's the only option you've got for where the code is going to go. Your nice isolated virtualenvs are completely out of the picture. I asked on Stack Overflow if there's a way to install Windows package installers into virtualenvs, and didn't get the answers I wanted. So I decided the best approach was to change the registry, install my package, then change the registry back. I adapted a classic script to register Python installations, to create what I've called the_python.py: # script to register Python 2.0 or later for use with win32all Use your desired Python to run this script, and it will be entered into the registry as the Python. When you run your Windows package installer, it will go into your virtualenv. Don't forget to run it again at the end to put things back the way they were.
tagged:
python,
windows» 6 reactions Zach AnnerFriday 16 July 2010 Zach Anner is a funny guy, who happens to have cerebral palsy, as Zach puts it, "the sexiest of the palsies". He submitted a video to Oprah's Search for the next TV star: He ended up with 2.5 million votes: I really like Zach's humor because it doesn't avoid his disability, and it isn't just about his disability. It's about funny Zach and the funny world, and Zach's cerebral palsy is part of it, but just a part. He strikes just the right balance, and he's got a great attitude. Watch him train for the 2011 Austin marathon: He has more stuff with Lark the Beard. I hope he goes far.
tagged:
funny» 1 reaction Recent tweetsMonday 5 July 2010 ¶ RT @catherinedevlin: I am so moving to France. Castle under construction w/ 100% historical technology. http://tinyurl.com/3acrbve (Jul 02) ¶ Awesome and sweet.. RT @sgalineau: http://www.youtube.com/watch?v=-CVYOCMpJRY #classic #starwars (via @bcongdon) (Jun 28) ¶ Not often you get bitingly mean graphic design humor: RT @jackschofield: Missing cat poster story http://www.27bslash6.com/missy.html [Cat lovers beware] (Jun 25) ¶ Tons of recreational math stuff! Sadly, no RSS: http://www.mathpuzzle.com/ (Jun 20) ¶ The Omnificent English Dictionary In Limerick Form: http://www.oedilf.com. Really. (Jun 20) ¶ iPad + autism = win! http://www.blogher.com/ipad-nearmiracle-my-son-autism (Jun 18) ¶ About time we took a hard look at couch architecture: http://blog.buildllc.com/2010/04/couch-cushion-architecture-a-critical-analysis/ lol. (Jun 09) ¶ Pretty, in a geometry/typography kind of way: http://www.flickr.com/photos/quasimondo/4644498892/in/photostream/ See the paintings in the stream too. (Jun 05) ¶ RT @sgalineau: Once in a while Smashing Mag surprises: Arabic, East Asian and Indic calligraphy & writing systems http://www.smashingmagazine.com/2010/05/18/the-beauty-of-typography-writing-systems-and-calligraphy-of-the-world/ #i18n (May 29)
tagged:
quick links» 1 reaction In the last year, people have been experimenting with 3D variations of the Mandelbrot fractal. The first to get a lot of attention was the Mandelbulb, but I didn't like it, it just looks blobby to me, with no apparent self-similarity. Then in February, a new formula appeared, called Mandelbox. It's a clever two-step formula using folding, first with squares, then with circles. The combination provides a very rich generative source. Being a 3D structure, you can fly through it: There's an amazing variety of textures and structures here, reminiscent of many other fractals. Some of the vistas seem like science-fiction sets, but generated by a formula rather than drawn by hand. Fascinating. Mandelbox is a rich world to explore, and it's really new, so we can expect to see lots more innovation and exploration. Missing wordsSaturday 26 June 2010 It is said that English has about a quarter million words. So it surprises me when I can't find a word I want. For example, we have a bunch of words that mean, "tastes good": delicious, scrumptious, delectable, appetizing, yummy, toothsome, and mouthwatering. So why is there no word that means just, "tastes bad"? We have disgusting, unpleasant, gross, and disagreeable, but none of those apply only to eating. Even the literal distasteful or unsavory are almost quaint when applied to food. And if scary means "fills me with fear", as do terrifying, frightening, horrifying, and hair-raising, where is the word that means "fills me with anxiety"? Unnerving or nerve-racking seem to be the closest I can find, but even those seem closer to fear than to anxiety. Time for some new words?
tagged:
language» 18 reactions Older: Sun 20: Sat 19: Wed 16: Sun 13: Sun 6: Sun 6: Sun 23: Sat 22: | |