def test_cursing_a_reversed_curse(): curse(str, 'one', 1) assert str.one == 1 reverse(str, 'one') curse(str, 'one', 2) assert str.one == 2
def setup(): global hasSetup; if not hasSetup: curse(list, 'where', where); curse(list, 'exists', exists); hasSetup = True;
def test_sequence_dunder(): def derive_func(func, deriv_grad): if deriv_grad == 0: return func e = 0.0000001 def wrapper(x): return (func(x + e) - func(x - e)) / (2 * e) if deriv_grad == 1: return wrapper return wrapper[deriv_grad - 1] curse(FunctionType, "__getitem__", derive_func) # a function an its derivations f = lambda x: x ** 3 - 2 * x ** 2 f_1 = lambda x: 3 * x ** 2 - 4 * x f_2 = lambda x: 6 * x - 4 for x in range(0, 10): x = float(x) / 10. assert almost_equal(f(x), f[0](x)) assert almost_equal(f_1(x), f[1](x)) # our hacky derivation becomes numerically unstable here assert almost_equal(f_2(x), f[2](x), e=.01)
def __enter__(self): if type(self.new_now) != datetime: raise ValueError( 'The freeze_date argument must be a datetime.datetime' ' instance, got %s' % type(self.new_now).__name__) self.mocker = Mocker() # Replace "datetime.datetime.now" classmethod self._previous_datetime_now = datetime.now @classmethod def freezed_now(klass, tz=None): if not tz: return self.new_now.replace(tzinfo=None) elif self.new_now.tzinfo != tz: return tz.normalize(self.new_now.astimezone(tz)) else: return self.new_now curse(datetime, 'now', freezed_now) # Replace "time.time" function new_time = (calendar.timegm(self.new_now.timetuple()) + (self.new_now.timetuple().tm_isdst * 60 * 60) + (self.new_now.microsecond * 0.000001)) time_class = self.mocker.replace('time.time') expect(time_class()).call(lambda: new_time).count(0, None) self.mocker.replay() return self
def decorator(func): @wraps(func) def _wrapper_add_method(*args, **kwargs): return func(*args, **kwargs) curse(cls, func.__name__, _wrapper_add_method) return func
def test_dunder_str(): assert str(1) == "1" def always_one(self): return 'one' curse(int, '__str__', always_one) assert str(1) == "one" reverse(int, '__str__')
def test_dir_filtering(): # Given that I curse the `str` built-in asking the curse to hide it from # the built-in `dir()` function curse(str, "my_stuff", "blah", hide_from_dir=True) # Then I see that my new stuff is installed but without appearing on dir assert str.my_stuff == "blah" assert "my_stuff" not in dir(str)
def test_dunder_new(): assert str(1) == "1" def the_answer(cls, args, kwargs): return 'fourty-two' curse(str, '__new__', the_answer) assert str(1) == "fourty-two" reverse(str, '__new__') assert str(1) == "1"
def test_overriding_class_method(): # Given that I have a cursed object curse(datetime, "now", classmethod(lambda *p: False)) # Then I see that the method was replaced, but we still have the original # method set as `_c_apppend` assert "_c_now" in dir(datetime) assert datetime.now() is False assert datetime(2013, 4, 5).now() is False
def assertSQL(self, sql, **kwargs): def execute(self, sql, args=None): pass mocked_execute = mock.create_autospec(execute, return_value='worked') curse(psycopg2.extensions.cursor, 'execute', mocked_execute) cursor = CommenterCursorFactory(**kwargs) self.assertEqual(cursor.execute(None, 'SELECT 1;'), 'worked') mocked_execute.assert_called_with(None, sql, None)
def test_overriding_class_method(): # Given that I have a cursed object curse(datetime, 'now', classmethod(lambda *p: False)) # Then I see that the method was replaced, but we still have the original # method set as `_c_apppend` assert '_c_now' in dir(datetime) assert datetime.now() is False assert datetime(2013, 4, 5).now() is False
def test_reversing_a_builtin(): # Given that I have a cursed object curse(str, 'stuff', property(lambda s: s * 2)) # When I bless it reverse(str, 'stuff') # Then I see that str won't contain assert 'stuff' not in dir(str)
def setUp(test): functional.FunctionalTestSetup().setUp() newInteraction() def fake_utcnow(self): return datetime.datetime(2015, 7, 30, 8, 0, 0) curse(datetime.datetime, 'utcnow', classmethod(fake_utcnow)) root = functional.getRootFolder() setSite(root) sm = root.getSiteManager() # IIntIds root['intids'] = IntIds() sm.registerUtility(root['intids'], IIntIds) root['intids'].register(root) # catalog root['catalog'] = Catalog() sm.registerUtility(root['catalog'], ICatalog) # PluggableAuthentication pau = PluggableAuthentication(u'') event.notify(ObjectCreatedEvent(pau)) sm[u'auth'] = pau sm.registerUtility(pau, IAuthentication) # Credentials Plugin defaultCreds.install() defaultCreds.activate() # people people = PersonalSpaceManager(title=u'People') event.notify(ObjectCreatedEvent(people)) root['people'] = people sm.registerUtility(root['people'], IPersonalSpaceManager) user = sm.getUtility(IAuthentication).getPrincipal('zope.mgr') people.assignPersonalSpace(user) user = sm.getUtility(IAuthentication).getPrincipal('zope.user') people.assignPersonalSpace(user) # default content content = Content(u'Content1', u'Some Content1') event.notify(ObjectCreatedEvent(content)) IOwnership(content).ownerId = 'zope.user' root['content1'] = content content = Content(u'Content2', u'Some Content2') event.notify(ObjectCreatedEvent(content)) IOwnership(content).ownerId = 'zope.user' root['content2'] = content endInteraction()
def test_reversing_a_builtin(): # Given that I have a cursed object curse(str, "stuff", property(lambda s: s * 2)) # When I bless it reverse(str, "stuff") # Then I see that str won't contain assert "stuff" not in dir(str)
def test_dunder_reverse(): def type_error_str(self): return 'type error' curse(TypeError, '__str__', type_error_str) te = TypeError("testing") assert str(te) == "type error" reverse(TypeError, '__str__') assert str(te) == "testing"
def test_overriding_instance_method(): # Given that I have an instance of a `Dummy` object obj = ffruit.Dummy() # When I curse an instance method curse(ffruit.Dummy, "my_method", lambda *a, **k: "Yo!") # Then I see that my object was cursed properly assert obj.my_method() == "Yo!"
def test_dir_filtering_same_symbol_different_instance(): # Given that I curse both `str` and `int` built-ins curse(str, "attr_y", "stuff", hide_from_dir=True) curse(int, "attr_y", "stuff") # Then I see that the dir() thing also works for instances assert "Hello".attr_y == "stuff" assert "attr_y" not in dir("hello") assert (1).attr_y == "stuff" assert "attr_y" in dir(1)
def test_cursing_a_builtin_class_dunder_with_a_random_callable(): # Given that I have an object that returns *blah* class Twelver(object): def __call__(self, one, two): return 12 # When I try to curse a built-in class's __sub__ with that function curse(str, "__sub__", Twelver()) # Then I see that the class was cursed assert ("hello" - "world") == 12
def test_cursing_a_builtin_class(): # Given that I have a function that returns *blah* def words_of_wisdom(self): return self * "blah " # When I try to curse a built-in class with that function curse(int, "words_of_wisdom", words_of_wisdom) # Then I see that the class was cursed assert (2).words_of_wisdom() == "blah blah " assert 'words_of_wisdom' in dir(int)
def test_cursing_a_builtin_class_with_a_class_method(): # Given that I have a function that returns *blah* def hello(self): return "blah" # When I try to curse a built-in class with that function curse(str, "hello", classmethod(hello)) # Then I see that the class was cursed assert str.hello() == "blah" assert 'hello' in dir(str)
def test_cursing_a_builting_class_with_a_class_method(): # Given that I have a function that returns *blah* def hello(self): return "blah" # When I try to curse a built-in class with that function curse(str, "hello", classmethod(hello)) # Then I see that the class was cursed assert str.hello() == "blah" assert "hello" in dir(str)
def test_cursing_a_builting_class(): # Given that I have a function that returns *blah* def words_of_wisdom(self): return self * "blah " # When I try to curse a built-in class with that function curse(int, "words_of_wisdom", words_of_wisdom) # Then I see that the class was cursed assert (2).words_of_wisdom() == "blah blah " assert "words_of_wisdom" in dir(int)
def variable(Pt): class Point: def softplus(self): return F.softplus(self) def log_softmax(self, *args, dim=1, **kargs): return F.log_softmax(self, dim=dim, *args, **kargs) def conv3d(self, *args, **kargs): return F.conv3d(self, *args, **kargs) def conv2d(self, *args, **kargs): return F.conv2d(self, *args, **kargs) def max_pool2d(self, *args, **kargs): return F.max_pool2d(self, *args, **kargs) def conv1d(self, *args, **kargs): return F.conv1d(self, *args, **kargs) def conv1d(self, *args, **kargs): return F.conv1d(self, *args, **kargs) def cat(self, other, dim=0, **kargs): return torch.cat((self, other), dim=dim, **kargs) @staticmethod def attack(model, radius, original, target): return original @staticmethod def box(original, *args, **kargs): return original @staticmethod def line(original, other, w=None, *args, **kargs): return (original + other) / 2 def diameter(self): return pyval(0) # dtype([[[10000]]]) def lb(self): return self def ub(self): return self def cudify(self, cuda, cuda_async): return self.cuda(async=cuda_async) if cuda else self for nm in getMethodNames(Point): curse(Pt, nm, getattr(Point, nm))
def test_dunder_list_map(): """Overload * (__mul__) operator to apply function to a list""" def map_list(func, list_): if not callable(func): raise NotImplementedError() return map(func, list_) curse(list, "__mul__", map_list) list_ = list(range(10)) times_2 = lambda x: x * 2 assert list(times_2 * list_) == list(range(0, 20, 2))
def test_dir_filtering_same_symbol_different_type(): # Given that I curse both `str` and `int` built-ins but only hide the new # attribute from the one installed on `str` curse(str, "attr_x", "blah", hide_from_dir=True) curse(int, "attr_x", "blah") # Then I see that both attributes were installed, but only one is filtered # by dir assert str.attr_x == "blah" assert "attr_x" not in dir(str) assert int.attr_x == "blah" assert "attr_x" in dir(int)
def mix_method(target, method_name, method, method_type=None): if method_type == 'static': method = staticmethod(method) elif method_type == 'class': method = classmethod(method) if method_name in target.__dict__: reverse_the_curse(target, method_name) if method_type is None and hasattr(method, '__func__'): curse(target, method_name, method.__func__) else: curse(target, method_name, method)
def curse(classes=[list, tuple, set, dict]): """Add functional methods to list, tuple, set, and dict in-place.""" cursed_methods = { "map": _map, "filter": _filter, "reduce": _reduce, "apply": _apply, "zip": _zip, "enumerate": _enumerate, } for klass in classes: for name, fun in cursed_methods.items(): forbiddenfruit.curse(klass, name, fun)
def setUpClass(cls): super(test_Base, cls).setUpClass() def _datetime_to_timestamp(self): epoch = datetime(1970, 1, 1) diff = self - epoch return int(diff.total_seconds()) if six.PY2: print 'Patching datetime.timestamp for PY2' print 'Patching unittest.TestCase.subTest for PY2' curse(datetime, 'timestamp', _datetime_to_timestamp) curse(TestCase, 'subTest', DummyContextManager)
def test_overriding_dict_pop(): "The `curse` function should be able to curse existing symbols" # Given that I have an instance of a python class obj = {"a": 1, "b": 2} # When I curse an instance method curse(dict, "pop", lambda self, key: self[key]) # Then I see that my object was cursed properly assert obj.pop("a") == 1 assert obj.pop("b") == 2 assert "a" in obj assert "b" in obj
def test_overriding_non_c_things(): "The `curse` function should not blow up on non-c python objs" # Given that I have an instance of a python class class Yo(object): pass obj = Yo() # When I curse an instance method curse(Yo, "my_method", lambda *a, **k: "Yo" * 2) # Then I see that my object was cursed properly assert obj.my_method() == "YoYo"
def test_overriding_dict_pop(): "The `curse` function should be able to curse existing symbols" # Given that I have an instance of a python class obj = {'a': 1, 'b': 2} # When I curse an instance method curse(dict, "pop", lambda self, key: self[key]) # Then I see that my object was cursed properly assert obj.pop('a') == 1 assert obj.pop('b') == 2 assert 'a' in obj assert 'b' in obj
def spy_on_file_io(): orig_read = io.BufferedReader.read orig_write = io.TextIOWrapper.write forbiddenfruit.curse(io.BufferedReader, "read", spy_read(io.BufferedReader.read)) forbiddenfruit.curse(io.TextIOWrapper, "write", spy_write(io.TextIOWrapper.write)) yield forbiddenfruit.curse(io.BufferedReader, "read", orig_read) forbiddenfruit.curse(io.TextIOWrapper, "write", orig_write)
def mockey_patch_formatting(): from datetime import date original_strftime = date.strftime patterns = { "%-d": lambda d: str(d.day), } def _date_strftime_patch(self: date, fmt: Text) -> str: for pattern, get_value in patterns.items(): if pattern in fmt: fmt = fmt.replace(pattern, get_value(self)) result = original_strftime(self, fmt) return result curse(date, "strftime", _date_strftime_patch)
def _replace_numpy_method(np_path: str, replacement_function: Callable) -> None: np_path_sub_attributes = np_path.split('.') module = np for np_path_sub_attribute in np_path_sub_attributes[1:-1]: module = getattr(module, np_path_sub_attribute) try: setattr(module, np_path_sub_attributes[-1], replacement_function) except TypeError as error: if len( error.args ) == 1 and 'can\'t set attributes of built-in/extension type' in error.args[ 0]: forbiddenfruit.curse(module, np_path_sub_attributes[-1], replacement_function) else: raise error return
def test_dunder_unary(): """Overload ~ operator to compute a derivative of function""" def derive_func(func): e = 0.001 def wrapper(x): """Poor man's derivation""" x_0 = x - e x_1 = x + e y_delta = func(x_1) - func(x_0) return y_delta / (2 * e) return wrapper curse(FunctionType, "__inv__", derive_func) f = lambda x: x**2 + x # true derivation f_ = lambda x: 2*x + 1 assert almost_equal((~f)(10), f_(10))
def _patch(entry): m_obj = getattr(entry[0], entry[1]) m_str = str(m_obj) method_invocations[m_str] = {'__count__': 0} def m_patched(*args, **kwargs): entry = method_invocations[m_str] stack = traceback.format_stack() last_frame = str(stack[-2]).strip() entry[last_frame] = entry.get(last_frame, 0) + 1 if entry['__count__'] % 1000 == 0: # TODO print(''.join(stack)) pass entry['__count__'] += 1 return m_obj(*args, **kwargs) try: from forbiddenfruit import curse curse(entry[0], entry[1], m_patched) except Exception as e: print('Unable to set attr:', entry[0], entry[1], m_patched, e)
def test_dunder_func_chaining(): """Overload * (mul) operator to to chaining between functions""" def matmul_chaining(self, other): if not isinstance(other, FunctionType): raise NotImplementedError() def wrapper(*args, **kwargs): res = other(*args, **kwargs) if hasattr(res, "__iter__"): return self(*res) return self(res) return wrapper curse(FunctionType, "__mul__", matmul_chaining) f = lambda x, y: x * y g = lambda x: (x, x) squared = f * g for i in range(0, 10, 2): assert squared(i) == i ** 2
def test_dunder_list_revert(): """Test reversion of a curse with dunders""" def map_list(func, list_): if not callable(func): raise NotImplementedError() return map(func, list_) curse(list, "__add__", map_list) list_ = list(range(10)) times_2 = lambda x: x * 2 assert list(times_2 + list_) == list(range(0, 20, 2)) reverse(list, "__add__") try: times_2 + list_ except TypeError: pass else: # should always raise an exception assert False
def test_overriding_list_append(): "The `curse` function should be able to curse existing symbols" # Given that I have an instance of a python class obj = [] # When I curse an instance method fn = lambda self, v: self._c_append(v) or self foo = curse(list, "append", fn) # Then I see that my object was cursed properly assert obj.append(1) == [1] assert obj.append(2) == [1, 2] assert 1 in obj assert 2 in obj
def setup(): curse(list, 'where', where); curse(list, 'exists', exists);
from forbiddenfruit import curse import itertools class enumerable: @staticmethod def map(self, fn): return map(fn, self) @staticmethod def filter(self, fn): return filter(fn, self) @staticmethod def reduce(self, fn, initial=None): return reduce(fn, self, initial) if initial else reduce(fn, self) @staticmethod def take(self, number): return itertools.islice(self, number) @staticmethod def toList(self): return list(self) curse(object, "map", enumerable.map) curse(object, "filter", enumerable.filter) curse(object, "reduce", enumerable.reduce) curse(object, "take", enumerable.take) curse(object, "toList", enumerable.toList)
def inner(*args, **kwargs): all_args = bound_args + args all_kwargs = dict(bound_kwargs.items() + kwargs.items()) return func(*all_args, **all_kwargs) # Fetch the original argspec, remove the curried arguments, and create a # new argspec argspec_orig = inspect.getargspec(func) args = argspec_orig.args[len(bound_args):] for arg_name in bound_kwargs: args.remove(arg_name) argspec_new = inspect.ArgSpec(args = args, varargs = argspec_orig.varargs, keywords = argspec_orig.keywords, defaults = argspec_orig.defaults) # Create a lambda to wrap the inner function with the correct argspec. We # use eval for this because it's the only way I know of to create a # function with an arbitrary argspec. formatted_args = inspect.formatargspec(*argspec_new) params = formatted_args.lstrip('(').rstrip(')') lambda_str = 'lambda %s: inner%s' % (params, formatted_args) eval_func = eval(lambda_str, {'inner' : inner}) return wraps(func)(eval_func) curse(types.FunctionType, 'bind', bind)
""" datetimex.intervals ~~~~~~~~~~~~~~~~~~~ Adds some methods to intervals in order to get dates. So far: * ago * since """ from datetime import datetime, timedelta from forbiddenfruit import curse @property def ago(self): return datetime.now() - self def since(self, date): return date + self curse(timedelta, 'ago', ago) curse(timedelta, 'since', since)
# Substitute for '%pylab inline' from # https://ipython.org/ipython-doc/3/interactive/magics.html#magic-pylab import numpy import matplotlib from matplotlib import pylab, mlab, pyplot np = numpy plt = pyplot from IPython.display import display from IPython.core.pylabtools import figsize, getfigs from pylab import * from numpy import * from forbiddenfruit import curse curse(np.ndarray,'H',property(fget=lambda A: A.T.conj())) # In[2]: from scipy.io import loadmat from scipy.sparse import coo_matrix from scipy.special import iv as besseli def fftc(img): return ifftshift(fftn(fftshift(img))) def ifftc(ksp): return fftshift(ifftn(ifftshift(ksp))) # get data from http://hansenms.github.io/sunrise/sunrise2013/
if target is None: return obj.__getmeta__(attr) else: return obj.__getmeta__(target, attr) except KeyError: return default @Modeless def delmeta(obj,attr,target=None): if target is None: return obj.__delmeta__(attr) else: return obj.__delmeta__(target, attr) # __metadata__ is a global slot, so we have to manage the namespaces curse(object, "__metadata__", {}) def _get(namespace,obj): try: return namespace[id(obj)] except KeyError: namespace[id(obj)] = {} return namespace[id(obj)] @Modeless def _object_getmeta(obj,attr): return _get(object.__metadata__, obj).get(attr) @Modeless def _object_setmeta(obj,attr,val): _get(object.__metadata__, obj)[attr] = val
def __exit__(self, exc_type, exc_value, traceback): self.mocker.restore() self.mocker.verify() curse(datetime, 'now', self._previous_datetime_now)
return int(self) def to_f(self): return float(self) def _sum(self): # avoid keyword `sum` return sum(self) def instance_of(self, t): return isinstance(self, t) curse(int, "instance_of", instance_of) curse(int, "to_s", to_s) curse(int, "to_f", to_f) curse(float, "instance_of", instance_of) curse(float, "to_s", to_s) curse(float, "to_i", to_i) curse(str, "instance_of", instance_of) curse(str, "length", property(length)) curse(str, "to_i", to_i) curse(str, "to_f", to_f) curse(str, "to_s", _return_self) curse(unicode, "instance_of", instance_of) curse(unicode, "length", property(length))
def __enter__(self): if type(self.new_now) != datetime: raise ValueError( 'The freeze_date argument must be a datetime.datetime' ' instance, got %s' % type(self.new_now).__name__) def is_caller_ignored(frames_up): """Inspect the stack for n frames up for a blacklisted caller. Stack inspection is very expensive, so we skip this per default as we hit this on every access to a frozen time. A fine case example of catastrophic access density is a bunch of Plone workflow event handlers firing off a Dexterity ``createdInContainer`` event. """ if self.ignore_modules: caller_frame = inspect.stack()[frames_up][0] module_name = inspect.getmodule(caller_frame).__name__ return module_name in self.ignore_modules return False self.mocker = Mocker() # Replace "datetime.datetime.now" classmethod self._previous_datetime_now = datetime.now # Replace "datetime.datetime.utcnow" classmethod self._previous_datetime_utcnow = datetime.utcnow @classmethod def freezed_now(klass, tz=None): if is_caller_ignored(2): return self._previous_datetime_now(tz) if not tz: return self.new_now.replace(tzinfo=None) # Time was frozen to a naive DT, but a TZ-aware time is being requested # from now(). We assume the same TZ for freezing as requested by now. elif self.new_now.tzinfo is None: return self.new_now.replace(tzinfo=tz) elif self.new_now.tzinfo != tz: return tz.normalize(self.new_now.astimezone(tz)) return self.new_now @classmethod def freezed_utcnow(klass): if is_caller_ignored(2): return self._previous_datetime_utcnow() if self.new_now.tzinfo and self.new_now.tzinfo != pytz.UTC: return pytz.UTC.normalize(self.new_now.astimezone(pytz.UTC)) return self.new_now curse(datetime, 'now', freezed_now) curse(datetime, 'utcnow', freezed_utcnow) # Replace "time.time" function # datetime.timetuple does not contain any timezone information, so this # information will be lost. Moreover time.time should be in the system # timezone, so we need to correct for the offset of timezone used in # the freezing relative to the system timezone. local_tz = pytz.timezone(tzname[0]) if self.new_now.tzinfo is None: new_time = mktime(self.new_now.timetuple()) else: new_time = mktime(self.new_now.tzinfo.normalize(self.new_now + local_tz._utcoffset).utctimetuple()) time_class = self.mocker.replace('time.time') def frozen_time(): if is_caller_ignored(7): if self.new_now.tzinfo is None: return mktime(self._previous_datetime_now().timetuple()) else: return mktime(self._previous_datetime_now().tzinfo.normalize( self.new_now + local_tz._utcoffset).utctimetuple()) return new_time expect(time_class()).call(frozen_time).count(0, None) self.mocker.replay() return self