示例#1
0
 def __new__(clsarg, *args, **kwargs):
     cls = super(_Signals, clsarg).__new__(clsarg, *args, **kwargs)
     for signal in cls._signals:
         (on, sig) = _handler_factory(signal)
         setattr(cls, on.__name__, types.UnboundMethodType(on, None, cls))
         setattr(cls, sig.__name__, types.UnboundMethodType(sig, None, cls))
     return cls
示例#2
0
    def setup_logging(self):
        # we replace the formatTime() method of the log observer that
        # twistd set up for us, with a method that uses our preferred
        # timestamp format.
        for o in twlog.theLogPublisher.observers:
            # o might be a FileLogObserver's .emit method
            if type(o) is type(self.setup_logging):  # bound method
                ob = o.im_self
                if isinstance(ob, twlog.FileLogObserver):
                    newmeth = types.UnboundMethodType(formatTimeTahoeStyle, ob,
                                                      ob.__class__)
                    ob.formatTime = newmeth
        # TODO: twisted >2.5.0 offers maxRotatedFiles=50

        lgfurl_file = os.path.join(self.basedir, "private",
                                   "logport.furl").encode(
                                       get_filesystem_encoding())
        if os.path.exists(lgfurl_file):
            os.remove(lgfurl_file)
        self.log_tub.setOption("logport-furlfile", lgfurl_file)
        lgfurl = self.config.get_config("node", "log_gatherer.furl", "")
        if lgfurl:
            # this is in addition to the contents of log-gatherer-furlfile
            self.log_tub.setOption("log-gatherer-furl", lgfurl)
        self.log_tub.setOption("log-gatherer-furlfile",
                               os.path.join(self.basedir, "log_gatherer.furl"))

        incident_dir = os.path.join(self.basedir, "logs", "incidents")
        foolscap.logging.log.setLogDir(
            incident_dir.encode(get_filesystem_encoding()))
        twlog.msg("Foolscap logging initialized")
        twlog.msg("Note to developers: twistd.log does not receive very much.")
        twlog.msg(
            "Use 'flogtool tail -c NODEDIR/private/logport.furl' instead")
        twlog.msg("and read docs/logging.rst")
示例#3
0
    def setup_logging(self):
        # we replace the formatTime() method of the log observer that
        # twistd set up for us, with a method that uses our preferred
        # timestamp format.
        for o in twlog.theLogPublisher.observers:
            # o might be a FileLogObserver's .emit method
            if type(o) is type(self.setup_logging): # bound method
                ob = o.im_self
                if isinstance(ob, twlog.FileLogObserver):
                    newmeth = types.UnboundMethodType(formatTimeTahoeStyle, ob, ob.__class__)
                    ob.formatTime = newmeth
        # TODO: twisted >2.5.0 offers maxRotatedFiles=50

        lgfurl_file = os.path.join(self.basedir, "private", "logport.furl").encode(get_filesystem_encoding())
        self.tub.setOption("logport-furlfile", lgfurl_file)
        lgfurl = self.get_config("node", "log_gatherer.furl", "")
        if lgfurl:
            # this is in addition to the contents of log-gatherer-furlfile
            self.tub.setOption("log-gatherer-furl", lgfurl)
        self.tub.setOption("log-gatherer-furlfile",
                           os.path.join(self.basedir, "log_gatherer.furl"))
        self.tub.setOption("bridge-twisted-logs", True)
        incident_dir = os.path.join(self.basedir, "logs", "incidents")
        # this doesn't quite work yet: unit tests fail
        foolscap.logging.log.setLogDir(incident_dir.encode(get_filesystem_encoding()))
示例#4
0
def poisonSpam():
    old = Spam.update

    def newUpdate(self):
        old(self)
        print('poison whole class')

    Spam.update = types.UnboundMethodType(newUpdate, None, Spam)
示例#5
0
def test_methodtype():
    import types

    class A:
        def foo(self):
            return "ok"

    assert types.UnboundMethodType(A.foo, A())() == "ok"
    assert types.MethodType(A.foo, A())() == "ok"
示例#6
0
    def __init__(cls, name, bases, dict):
        type.__init__(cls, name, bases, dict)

        def change_method(self, *args, **kwargs):
            raise NotImplementedError, name + ' instances cannot be changed.'

        if cls.register:
            ContainerRegistry.append((cls, cls.containing_classes))

            for meth in cls.change_methods:
                setattr(cls, meth, types.UnboundMethodType(change_method, None, cls))
        cls.register=False
示例#7
0
 def setfunc(self, hookfunc):
     name = self.ref.__name__
     if self.type == 1:
         setattr(self.ctx, name, hookfunc)
         return hookfunc
     if self.type == 2:
         if self.is_static:
             newfunc = staticmethod(hookfunc)
         else:
             newfunc = hookfunc
         setattr(self.ctx, name, newfunc)
         return newfunc
     if self.type == 3:
         newmethod = types.UnboundMethodType(hookfunc, None, self.ctx)
         setattr(self.ctx, name, newmethod)
         return newmethod
     obj = self.ctx()
     newmethod = weakmethod(hookfunc, self.ctx)
     setattr(obj, name, newmethod)
     return newmethod
示例#8
0
def make_cffi(cls):
    """Decorator to add CFFI versions of each test method."""

    try:
        import zstd_cffi
    except ImportError:
        return cls

    # If CFFI version is available, dynamically construct test methods
    # that use it.

    for attr in dir(cls):
        fn = getattr(cls, attr)
        if not inspect.ismethod(fn) and not inspect.isfunction(fn):
            continue

        if not fn.__name__.startswith('test_'):
            continue

        name = '%s_cffi' % fn.__name__

        # Replace the "zstd" symbol with the CFFI module instance. Then copy
        # the function object and install it in a new attribute.
        if isinstance(fn, types.FunctionType):
            globs = dict(fn.__globals__)
            globs['zstd'] = zstd_cffi
            new_fn = types.FunctionType(fn.__code__, globs, name,
                                        fn.__defaults__, fn.__closure__)
            new_method = new_fn
        else:
            globs = dict(fn.__func__.func_globals)
            globs['zstd'] = zstd_cffi
            new_fn = types.FunctionType(fn.__func__.func_code, globs, name,
                                        fn.__func__.func_defaults,
                                        fn.__func__.func_closure)
            new_method = types.UnboundMethodType(new_fn, fn.im_self,
                                                 fn.im_class)

        setattr(cls, name, new_method)

    return cls
示例#9
0
    def __new__(cls, name, bases, dct):
        cls_obj = type.__new__(cls, name, bases, dct)
        if cls_obj.label is not None:
            for kls in cls_obj._addable_from:
                if cls_obj._is_setter:
                    function_name = 'set_%s' % cls_obj.label
                else:
                    function_name = 'add_%s' % cls_obj.label
                if not getattr(kls, function_name, None):

                    def add_thing(self, *args, **kwargs):
                        if isinstance(self, Pyrehol):
                            kwargs['root'] = self
                        else:
                            kwargs['root'] = self.root
                        if cls_obj._is_setter and getattr(
                                self, 'did_set_%s' % cls_obj.label, False):
                            raise ValueError(
                                'Cannot set %s on the same block more than once'
                                % cls_obj.label)
                        o = cls_obj(*args, **kwargs)
                        setattr(self, 'set_%s' % cls_obj.label, True)
                        self.contents.append(o)
                        return o

                    add_thing.__name__ = function_name
                    add_thing.__doc__ = '%s %s on this %s. Returns the %s.\n\n' % (
                        'Set the' if cls_obj._is_setter else 'Add a new',
                        cls_obj.label,
                        kls.__name__,
                        name.replace('_', '', 1),
                    )
                    if cls_obj.__init__.__doc__:
                        add_thing.__doc__ += cls_obj.__init__.__doc__
                    setattr(kls, function_name,
                            types.UnboundMethodType(add_thing, None, kls))
        return cls_obj
示例#10
0
def Mock(bases=(), *initargs, **kw):
    """
    Simple factory for dummy classes that can be used as replacement for the
    real implementation in tests.

    Base classes for the mock can be specified using the first parameter, which
    must be either a tuple of class objects or a single class object. If the
    bases parameter is omitted, the base class of the mock will be object.

    So to create a mock that is derived from the builtin dict type, you can do:

    >>> mock = Mock(dict)
    >>> mock['foo'] = 'bar'
    >>> mock['foo']
    'bar'

    Attributes of the class are provided by any additional keyword parameters.

    >>> mock = Mock(foo='bar')
    >>> mock.foo
    'bar'

    Objects produces by this function have the special feature of not requiring
    the 'self' parameter on methods, because you should keep data at the scope
    of the test function. So you can just do:

    >>> mock = Mock(add=lambda x,y: x+y)
    >>> mock.add(1, 1)
    2

    To access attributes from the mock object from inside a lambda function,
    just access the mock itself:

    >>> mock = Mock(dict, do=lambda x: 'going to the %s' % mock[x])
    >>> mock['foo'] = 'bar'
    >>> mock.do('foo')
    'going to the bar'

    Because assignments or other types of statements don't work in lambda
    functions, assigning to a local variable from a mock function requires some
    extra work:

    >>> myvar = [None]
    >>> mock = Mock(set=lambda x: myvar.__setitem__(0, x))
    >>> mock.set(1)
    >>> myvar[0]
    1
    """
    if not isinstance(bases, tuple):
        bases = (bases, )

    # if base classes have abstractmethod and abstractproperty,
    # create dummy methods for abstracts
    attrs = {}

    def dummyfn(self, *args, **kwargs):
        raise NotImplementedError

    for base in bases:
        if getattr(base, '__metaclass__', None) is not abc.ABCMeta:
            continue
        fn = types.UnboundMethodType(dummyfn, None, base)
        for name, attr in inspect.getmembers(base):
            if name in attrs:
                continue
            if isinstance(attr, abc.abstractproperty) or \
                    isinstance(attr, types.UnboundMethodType) and \
                    getattr(attr, '__isabstractmethod__', False) is True:
                attrs[name] = fn

    cls = type('Mock', bases, attrs)
    mock = cls(*initargs)
    for k, v in kw.items():
        setattr(mock, k, v)
    return mock
示例#11
0
 def _bind(cls, fn):
     return types.UnboundMethodType(fn, None, cls)
示例#12
0
def make_cffi(cls):
    """Decorator to add CFFI versions of each test method."""

    # The module containing this class definition should
    # `import zstandard as zstd`. Otherwise things may blow up.
    mod = inspect.getmodule(cls)
    if not hasattr(mod, 'zstd'):
        raise Exception('test module does not contain "zstd" symbol')

    if not hasattr(mod.zstd, 'backend'):
        raise Exception('zstd symbol does not have "backend" attribute; did '
                        'you `import zstandard as zstd`?')

    # If `import zstandard` already chose the cffi backend, there is nothing
    # for us to do: we only add the cffi variation if the default backend
    # is the C extension.
    if mod.zstd.backend == 'cffi':
        return cls

    old_env = dict(os.environ)
    os.environ['PYTHON_ZSTANDARD_IMPORT_POLICY'] = 'cffi'
    try:
        try:
            mod_info = imp.find_module('zstandard')
            mod = imp.load_module('zstandard_cffi', *mod_info)
        except ImportError:
            return cls
    finally:
        os.environ.clear()
        os.environ.update(old_env)

    if mod.backend != 'cffi':
        raise Exception('got the zstandard %s backend instead of cffi' % mod.backend)

    # If CFFI version is available, dynamically construct test methods
    # that use it.

    for attr in dir(cls):
        fn = getattr(cls, attr)
        if not inspect.ismethod(fn) and not inspect.isfunction(fn):
            continue

        if not fn.__name__.startswith('test_'):
            continue

        name = '%s_cffi' % fn.__name__

        # Replace the "zstd" symbol with the CFFI module instance. Then copy
        # the function object and install it in a new attribute.
        if isinstance(fn, types.FunctionType):
            globs = dict(fn.__globals__)
            globs['zstd'] = mod
            new_fn = types.FunctionType(fn.__code__, globs, name,
                                        fn.__defaults__, fn.__closure__)
            new_method = new_fn
        else:
            globs = dict(fn.__func__.func_globals)
            globs['zstd'] = mod
            new_fn = types.FunctionType(fn.__func__.func_code, globs, name,
                                        fn.__func__.func_defaults,
                                        fn.__func__.func_closure)
            new_method = types.UnboundMethodType(new_fn, fn.im_self,
                                                 fn.im_class)

        setattr(cls, name, new_method)

    return cls
示例#13
0
def patch_model(model_to_patch, class_to_patch_with):
    """
        Adapted from https://gist.github.com/1402045

        Monkey patch a django model with additional or
        replacement fields and methods.

            - All fields and methods that didn't exist previously are added.

            - Existing methods with the same names are renamed with
              <methodname>__overridden, so there are still accessible,
              then the new ones are added.

            - Existing fields with the same name are deleted and replaced with
              the new fields.

        The class used to patch the model MUST be an old-style class (so
        this may not work with Python 3).

        Example (in your models.py):

            from django.contrib.auth.models import User
            from django_quicky.models import patch_model

            class UserOverride: # we don't need to inherit from anything
                email = models.EmailField(_('e-mail address'), unique=True)
                new_field = models.CharField(_('new field'), max_length=10)

                def save(self, *args, **kwargs):

                    # Call original save() method
                    self.save__overridden(*args, **kwargs)

                    # More custom save

            patch_model(User, UserOverride)

    """
    from django.db.models.fields import Field

    # The _meta attribute is where the definition of the fields is stored in
    # django model classes.
    patched_meta = getattr(model_to_patch, '_meta')
    field_lists = (patched_meta.local_fields, patched_meta.local_many_to_many)

    for name, obj in class_to_patch_with.__dict__.iteritems():

        # If the attribute is a field, delete any field with the same name.
        if isinstance(obj, Field):

            for field_list in field_lists:

                match = ((i, f) for i, f in enumerate(field_list)
                         if f.name == name)
                try:
                    i, field = match.next()
                    # The creation_counter is used by django to know in
                    # which order the database columns are declared. We
                    # get it to ensure that when we override a field it
                    # will be declared in the same position as before.
                    obj.creation_counter = field.creation_counter
                    field_list.pop(i)
                finally:
                    break

        # Add "__overridden" to method names if they already exist.
        elif isinstance(
                obj,
            (types.FunctionType, property, staticmethod, classmethod)):

            # rename the potential old method
            attr = getattr(model_to_patch, name, None)
            if attr:
                setattr(model_to_patch, name + '__overridden', attr)

            # bind the new method to the object
            if isinstance(obj, types.FunctionType):
                obj = types.UnboundMethodType(obj, None, model_to_patch)

        # Add the new field/method name and object to the model.
        model_to_patch.add_to_class(name, obj)
示例#14
0
            raise

    return StrictExceptionIOLoop

def patch_http_client():
    """Patch a simple_httpclient instance to raise exceptions generated in callbacks.

    See https://github.com/facebook/tornado/pull/652
    """
    @contextlib.contextmanager
    def better_cleanup(self):
        try:
            yield
        except Exception, e:
            if self.final_callback:
                self._run_callback(HTTPResponse(self.request, 599, error=e,
                                   request_time=time.time() - self.start_time,
                                ))

                if hasattr(self, "stream"):
                    self.stream.close()
            else:
                # If our callback has already been called, we are probably
                # catching an exception that is not caused by us but rather
                # some child of our callback. Rather than drop it on the floor,
                # pass it along.
                raise

    _HTTPConnection.cleanup = types.UnboundMethodType(better_cleanup, None, _HTTPConnection)

示例#15
0
def patch_model(model_to_patch, class_to_patch_with):
    """ 
    Adapted from http://www.ravelsoft.com/blog/2010/patchmodel-hacky-solution-extending-authuser-class
    
    Monkey patch a django model with additional or replacement fields and methods.
    
        All fields and methods that didn't exist previously are added. 
        Existing methods with the same name are replaced with 
        <methodname>__overridden. Existing fields with the same name
        are deleted and replaced with the new field.
        
        The class used to patch the model must be an old-style class.
        
        Example:
        
        from django.contrib.auth.models import User
        from compatriot.utils import patch_model
        
        class UserOverride:
            email = models.EmailField(_('e-mail address'), unique=True)
            new_field = models.CharField(_('new field'), max_length=10)

            def save(self, *args, **kwargs):
                # Custom save
                
                # Call original save() method
                self.save__overridden(*args, **kwargs)
                
                # More custom save
                
        patch_model(User, UserOverride)

    @param model_to_patch: Class to patch
    @param class_to_patch_with: Class with definitions of new fields and methods.
    """

    # The _meta attribute is where the definition of the fields is stored in
    # django model classes.
    patched_meta = getattr(model_to_patch, '_meta')

    for name, obj in class_to_patch_with.__dict__.items():

        # If the attribute is a field, delete it if it already exists.
        if isinstance(obj, Field):
            index = -1
            for field_table in (patched_meta.local_fields,
                                patched_meta.local_many_to_many):
                for i in xrange(0, len(field_table)):
                    field = field_table[i]
                    if field.name == name:
                        index = i

                        # The creation_counter is used by django to know in
                        # which order the database columns are declared. We
                        # get it to ensure that when we override a field it
                        # will be declared in the same position as before.
                        creation_counter = field_table[i].creation_counter
                        break

                if index != -1:
                    field_table.pop(index)
                    obj.creation_counter = creation_counter
                    break

        # Add "__overridden" to method names if they already exist.
        elif isinstance(obj, types.FunctionType) or isinstance(obj, property):
            if getattr(model_to_patch, name, None):
                setattr(model_to_patch, name + '__overridden',
                        getattr(model_to_patch, name))

            if isinstance(obj, types.FunctionType):
                obj = types.UnboundMethodType(obj, None, model_to_patch)

        # Add the new field/method name and object to the model.
        model_to_patch.add_to_class(name, obj)