Skip to content

Instantly share code, notes, and snippets.

@ianb
Created April 30, 2010 05:14
Show Gist options
  • Save ianb/384784 to your computer and use it in GitHub Desktop.
Save ianb/384784 to your computer and use it in GitHub Desktop.
## Descriptors
## Anything with __get__ and optionally __set__:
class classinstancemethod(object):
def __init__(self, func):
self.func = func
def __get__(self, obj, type=None):
def repl(*args, **kw):
return self.func(obj, type, *args, **kw)
return repl
## Then to use it:
class MyValidator(object):
date_format = '%Y-%m-%d'
def __init__(self, date_format=None):
if date_format is not None:
self.date_format = date_format
@classinstancemethod
def check_input(self, cls, input):
if self is None:
self = cls()
return time.strptime(input, self.date_format)
MyValidator('%m-%d-%Y').check_input('5-1-2010')
MyValidator.check_input('2010-05-01')
## A simple mock object:
class Mock(object):
def __init__(self, name, returns=None):
self.name = name
self.returns = returns
def __getattr__(self, attr):
obj = Mock(self.name + '.' + attr)
setattr(self, attr, obj)
return obj
def __call__(self, *args, **kw):
args = [repr(a) for a in args]
args.extend(['%s=%r' % (n, v) for n, v in sorted(kw.items())])
print 'Calling %s(%s)' % (self.name, ', '.join(args))
return self.returns
## Use in a doctest:
>>> import smtplib
>>> smtplib.SMTP = Mock('SMTP')
>>> smtplib.SMTP.returns = Mock('smtplib_connection')
>>> conn = smtplib.SMTP()
Calling SMTP()
>>> conn.sendmail('dest@example.com', 'me@example.com', 'An email...')
Calling smtplib_connection.sendmail('dest@example.com', 'me@example.com', 'An email...')
## lxml stuff:
def webob.dec import wsgify
@wsgify.middleware
def link_rewriter(app, req, dest_href):
if dest_href.endswith('/'):
dest_href = dest_href[:-1]
dest_path = req.path_info
dest_href = dest_href + dest_path
req_href = req.application_url
def link_repl_func(link):
link = urlparse.urljoin(dest_href, link)
if not link.startswith(dest_href):
# Not a local link
return link
new_url = req_href + '/' + link[len(dest_href):]
return new_url
resp = req.get_response(self.app)
resp.decode_content()
if (resp.status_int == 200
and resp.content_type == 'text/html'):
doc = html.fromstring(resp.body, base_url=dest_href)
doc.rewrite_links(link_repl_func)
resp.body = html.tostring(doc)
if resp.location:
resp.location = link_repl_func(resp.location)
return resp(environ, start_response)
from lxml import html
from random import shuffle
@wsgify.middleware
def jumble_words(app, req):
resp = req.get_response(app)
doc = html.fromstring(resp.body)
words = doc.text_content().split()
shuffle(words)
for el in doc.body.iterdescendants():
el.text = random_words(el.text, words)
el.tail = random_words(el.tail, words)
resp.body = html.tostring(doc)
return resp
def random_words(text, words):
if not text:
return text
return ' '.join(words.pop() for i in range(len(text.split())))
from paste.proxy import Proxy
from paste.httpserver import serve
def make_proxy(proxy_url):
app = Proxy(proxy_url)
app = link_rewriter(app, dest_href=proxy_url)
serve(app)
## generic functions:
class multimethod(object):
def __init__(self, default):
self.default = default.__doc__
self.typemap = {}
def __call__(self, *args):
types = tuple(arg.__class__ for arg in args)
function = self.typemap.get(types, self.default)
return function(*args)
def register(self, *types):
def decorator(func):
self.typemap[types] = func
return self
return decorator
@multimethod
def html(obj):
return cgi.escape(unicode(obj))
from tempita import HTMLTemplate
@html.register(dict)
def html(obj):
return HTMLTemplate("""\
<table>
{{for key, value in sorted(obj.items())}}
<tr><td>{{html(key)}}</td>
<td>{{html(value)}}</td></tr>
{{endfor}}
</table>
""").substitute(obj=obj, html=html)
## monkey patching
import inspect
def set(on_obj):
def decorator(func):
args = inspect.getargspec(func)[0]
set = func
if args and args[0] == 'self':
if not isinstance(on_obj, type):
set = func.__get__(on_obj)
elif args and args[0] in ('cls', 'klass'):
if isinstance(on_obj, type):
set = classmethod(func)
else:
set = func.__get__(type(on_obj))
setattr(on_obj, func.__name__, set)
return func
return decorator
@set(smtplib)
def new_function():
print 'hi'
assert smtplib.new_function == new_function
@set(smtplib.SMTP)
def send_hi(self, person):
self.sendmail(person, 'me@example.com', 'Hi!')
def exec_maybe_eval(code, globs, locs, name='<web>'):
c_single = compile(code, name, 'single', 0, 1)
c_exec = compile(code, name, 'exec', 0, 1)
if c_single.co_code == c_exec.co_code:
# this is a statement
exec c_exec in globs, locs
return None
else:
c_eval = compile(code, name, 'eval', 0, 1)
value = eval(c_eval, globs, locs)
return value
def html_repl():
globs = locs = {}
while 1:
expr = raw_input('>>> ')
value = exec_maybe_eval(expr, globs, locs)
print html(value)
@gpiancastelli
Copy link

Small error on line 97: s/def/from.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment