.gitignore (original) (raw)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})
import util |
---|
from collections import namedtuple |
Foo = namedtuple('Foo', 'x y') |
@util.member(Foo) |
def frob(self): |
return self.x + self.y |
util.cleanup() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})
#!/usr/bin/env python3 |
---|
import foo |
assert not hasattr(foo, 'frob') |
assert foo.Foo(1, 2).frob() == 3 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})
#!/usr/bin/env python3 |
---|
import traceback |
import util |
class Foo: |
def oops(self): |
raise ValueError |
class Bar: |
pass |
@util.member(Bar) |
def oops(self): |
raise ValueError |
util.cleanup() |
def tb_has_qualname(cls): |
try: |
cls().oops() |
except ValueError as e: |
fun_name = traceback.extract_tb(e.__traceback__)[-1][2] |
unqual = fun_name == 'oops' |
assert unqual or fun_name.endswith('.oops') |
return not unqual |
assert False, 'unreachable' |
def test(): |
foo_q = tb_has_qualname(Foo) |
print('Foo qualname?', foo_q) |
bar_q = tb_has_qualname(Bar) |
print('Bar qualname?', bar_q) |
assert foo_q == bar_q |
if __name__ == '__main__': |
test() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.Learn more about bidirectional Unicode characters
[ Show hidden characters]({{ revealButtonHref }})
import sys |
---|
# It is not possible to delete something from the calling globals before |
# it exists. Remember, the decorator (necessarily) operates on the |
# function *before* its own result is assigned to the namespace. |
DELETEME = object() |
def member(cls): |
def decorator(fun): |
name = fun.__name__ |
fun.__qualname__ = '%s.%s' % (cls.__qualname__, name) |
setattr(cls, name, fun) |
return DELETEME |
return decorator |
def filtered_dir(obj): |
return [x for x in dir(obj) if x != '__%s__' % x.strip('_')] |
def print_info(name, obj): |
print('%s: ' % name, obj) |
print('type(%s): ' % name, type(obj)) |
print('filtered_dir(%s):' % name, filtered_dir(obj)) |
if hasattr(obj, '__dict__'): |
print('vars(%s): ' % name, vars(obj)) |
print() |
def cleanup(exclude={'DELETEME'}): |
# Basically the same logic as collections.namedtuple uses |
# to set the returned class's __module__ |
try: |
mod_globals = sys._getframe(1).f_globals |
except (AttributeError, ValueError): |
print('Unable to get caller\'s globals for cleanup') |
return |
keys_to_delete = {k for k, v in mod_globals.items() if v is DELETEME} |
for k in keys_to_delete - exclude: |
del mod_globals[k] |