[Baypiggies] Discussion for newbies/beginner night talks

Shannon -jj Behrens jjinux at gmail.com
Wed Feb 14 00:33:53 CET 2007


Python experts know about this, but Python newbies might not:

#) Monkey patching!

At runtime, anything is hackable.  Sometimes you have to rely on a
third party library that does the wrong thing.  Now, you should start
by submitting a bug or a patch.  In the meantime, you still need to
fix it to solve your own needs.  Modifying third party packages sucks.
 It's not fun to maintain custom versions of a bunch of third party
packages.  Both packaging and upgrading suddenly becomes yucky.
Instead of actually editing the code, sometimes you can get by with
monkey patching, that is, fixing it at runtime.  That way, you don't
have to modify the other code.  This is best used sparingly,
carefully, and lightly.  You also have to remember to undo your monkey
patches once the problem gets resolved ;)

Ok, let's say I have a naughty third-party library that thinks it
lives in DOS land.  However, it only does bad things when I'm not
looking.  I haven't been able to find the culprit.  I need to spot it
red handed, preferably with a stack trace!  I know it's using the
os.path.join function.  Hence, I use an undercover decoy version of
os.path.join to nab him in the act!

>>> import os
>>>
>>> # Here's an example of naughty code that thinks it lives in DOS:
>>> os.path.join(r"\usr", "local")
'\\usr/local'
>>>
>>> # Let's replace os.path.join with my own "special" version.  Notice how
>>> # I'm using *args so that any number of arguments will get carried through
>>> # seamlessly.  Correctly using *args and *kargs is an important part of
>>> # wrapping other functions.
>>>
>>> def my_join(*args):
...     """Figure out who thinks he's living in DOS land."""
...     for arg in args:
...         if arg.find("\\") != -1:
...             raise ValueError("This ain't DOS bub!")
...     return os.path.old_join(*args)
...
>>> # Swap in my new version.
>>> os.path.old_join = os.path.join
>>> os.path.join = my_join
>>>
>>> # Well behaved code is safe:
>>> os.path.join("/usr", "local")
'/usr/local'
>>> # Naughty code isn't!
>>> os.path.join(r"\usr", "local")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "<stdin>", line 5, in my_join
ValueError: This ain't DOS bub!

Happy Hacking!
-jj


More information about the Baypiggies mailing list