Skip to content
Browse files

initial checkin of python files

  • Loading branch information...
1 parent 38ec4c3 commit a60b51e226a60651f21f930639f3e060099d01de @llimllib committed Aug 12, 2009
Showing with 83 additions and 0 deletions.
  1. +47 −0 accepts_block.py
  2. +36 −0 test.py
View
47 accepts_block.py
@@ -0,0 +1,47 @@
+from __future__ import with_statement
+from functools import partial
+import inspect
+
+def accepts_block(f):
+ class _accepts_block(object):
+ def __call__(self, *args, **kwargs):
+ if len(args) == len(inspect.getargspec(f)[0]):
+ return f(*args, **kwargs)
+ self.thefunction = partial(f, *args, **kwargs)
+ return self
+
+ def __enter__(self):
+ # keep track of all that's already defined BEFORE the `with`
+ frame = inspect.currentframe(1)
+ self.mustignore = dict(frame.f_locals)
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ frame = inspect.currentframe(1)
+ # see what's been bound anew in the body of the `with`
+ interesting = dict()
+ for n in frame.f_locals:
+ newf = frame.f_locals[n]
+ if n not in self.mustignore:
+ interesting[n] = newf
+ continue
+ anf = self.mustignore[n]
+ if id(newf) != id(anf):
+ interesting[n] = newf
+ if interesting:
+ if len(interesting) > 2:
+ raise "you are only allowed to define a single function inside this with block"
+ elif len(interesting) == 1:
+ block = list(interesting.itervalues())[0]
+ if not isinstance(block, type(lambda:None)):
+ raise "you must define a function inside this with block"
+ self.thefunction(block)
+ elif len(interesting) == 2:
+ block = None
+ savename = None
+ for n,v in interesting.iteritems():
+ if isinstance(v, type(lambda:None)): block = v
+ else: savename = n
+ if not savename or not isinstance(block, type(lambda:None)):
+ raise "you must define a single function inside this with block"
+ frame.f_locals[savename] = self.thefunction(block)
+ return _accepts_block()
View
36 test.py
@@ -0,0 +1,36 @@
+from __future__ import with_statement
+from accepts_block import accepts_block
+
+@accepts_block
+def bmap(arr, block):
+ return map(block, arr)
+
+with bmap([1,2,3]) as zootrope:
+ def foo(x):
+ return (float(x) + 1) / 2
+print zootrope
+
+#make sure it works if we don't use a with block
+print bmap([1,2,3], lambda x: (float(x)+1)/2)
+
+@accepts_block
+def each(iterable, block):
+ for i in iterable: block(i)
+
+with each(["twelve", "fourteen", "sixteen"]):
+ def _(x):
+ print x
+
+#XXX: this doesn't work, because _ is not redefined. Need a "def".
+with each(["twelve", "fourteen", "sixteen"]):
+ _
+
+each(["twelve", "fourteen", "sixteen"], _)
+
+#let's try and fool len(interesting) == 2
+with bmap([1,2,3]):
+ result = 12
+ y = lambda x:x
+
+#result is [1,2,3], but it should probably still be 12
+print result

0 comments on commit a60b51e

Please sign in to comment.
Something went wrong with that request. Please try again.