diff options
author | Bartek Sokorski <b.sokorski@gmail.com> | 2023-01-19 01:08:51 +0100 |
---|---|---|
committer | Phil Jones <philip.graham.jones@googlemail.com> | 2023-01-22 11:31:40 +0000 |
commit | f9d51929f71295d0b0f3acfce2e47656bd0472e1 (patch) | |
tree | b53cc0975649a104ea1e5b6836fa08e016774530 | |
parent | adb22e4b04658a654d6b8dac695b41a6c634ac1c (diff) | |
download | blinker-f9d51929f71295d0b0f3acfce2e47656bd0472e1.tar.gz |
Move to src/ layout
-rw-r--r-- | blinker/__init__.py | 22 | ||||
-rw-r--r-- | src/blinker/__init__.py | 20 | ||||
-rw-r--r-- | src/blinker/_saferef.py (renamed from blinker/_saferef.py) | 40 | ||||
-rw-r--r-- | src/blinker/_utilities.py (renamed from blinker/_utilities.py) | 82 | ||||
-rw-r--r-- | src/blinker/base.py (renamed from blinker/base.py) | 83 |
5 files changed, 92 insertions, 155 deletions
diff --git a/blinker/__init__.py b/blinker/__init__.py deleted file mode 100644 index bed55ca..0000000 --- a/blinker/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -from blinker.base import ( - ANY, - NamedSignal, - Namespace, - Signal, - WeakNamespace, - receiver_connected, - signal, -) - -__all__ = [ - 'ANY', - 'NamedSignal', - 'Namespace', - 'Signal', - 'WeakNamespace', - 'receiver_connected', - 'signal', - ] - - -__version__ = '1.5' diff --git a/src/blinker/__init__.py b/src/blinker/__init__.py new file mode 100644 index 0000000..5ec9d0b --- /dev/null +++ b/src/blinker/__init__.py @@ -0,0 +1,20 @@ +from blinker.base import ANY +from blinker.base import NamedSignal +from blinker.base import Namespace +from blinker.base import receiver_connected +from blinker.base import Signal +from blinker.base import signal +from blinker.base import WeakNamespace + +__all__ = [ + "ANY", + "NamedSignal", + "Namespace", + "Signal", + "WeakNamespace", + "receiver_connected", + "signal", +] + + +__version__ = "1.5" diff --git a/blinker/_saferef.py b/src/blinker/_saferef.py index 081173d..8848dea 100644 --- a/blinker/_saferef.py +++ b/src/blinker/_saferef.py @@ -33,26 +33,14 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # """Refactored 'safe reference from dispatcher.py""" - import operator import sys import traceback import weakref -try: - callable -except NameError: - def callable(object): - return hasattr(object, '__call__') - - -if sys.version_info < (3,): - get_self = operator.attrgetter('im_self') - get_func = operator.attrgetter('im_func') -else: - get_self = operator.attrgetter('__self__') - get_func = operator.attrgetter('__func__') +get_self = operator.attrgetter("__self__") +get_func = operator.attrgetter("__func__") def safe_ref(target, on_delete=None): @@ -78,14 +66,15 @@ def safe_ref(target, on_delete=None): if im_self is not None: # Turn a bound method into a BoundMethodWeakref instance. # Keep track of these instances for lookup by disconnect(). - assert hasattr(target, 'im_func') or hasattr(target, '__func__'), ( - "safe_ref target %r has im_self, but no im_func, " - "don't know how to create reference" % target) + assert hasattr(target, "im_func") or hasattr(target, "__func__"), ( + f"safe_ref target {target!r} has im_self, but no im_func, " + "don't know how to create reference" + ) reference = BoundMethodWeakref(target=target, on_delete=on_delete) return reference -class BoundMethodWeakref(object): +class BoundMethodWeakref: """'Safe' and reusable weak references to instance methods. BoundMethodWeakref objects provide a mechanism for referencing a @@ -125,7 +114,7 @@ class BoundMethodWeakref(object): """Create new instance or return current instance. Basically this method of construction allows us to - short-circuit creation of references to already- referenced + short-circuit creation of references to already-referenced instance methods. The key corresponding to the target is calculated, and if there is already an existing reference, that is returned, with its deletion_methods attribute updated. @@ -138,7 +127,7 @@ class BoundMethodWeakref(object): current.deletion_methods.append(on_delete) return current else: - base = super(BoundMethodWeakref, cls).__new__(cls) + base = super().__new__(cls) cls._all_instances[key] = base base.__init__(target, on_delete, *arguments, **named) return base @@ -159,6 +148,7 @@ class BoundMethodWeakref(object): single argument, which will be passed a pointer to this object. """ + def remove(weak, self=self): """Set self.isDead to True when method or instance is destroyed.""" methods = self.deletion_methods[:] @@ -176,8 +166,11 @@ class BoundMethodWeakref(object): traceback.print_exc() except AttributeError: e = sys.exc_info()[1] - print ('Exception during saferef %s ' - 'cleanup function %s: %s' % (self, function, e)) + print( + f"Exception during saferef {self} " + f"cleanup function {function}: {e}" + ) + self.deletion_methods = [on_delete] self.key = self.calculate_key(target) im_self = get_self(target) @@ -194,6 +187,7 @@ class BoundMethodWeakref(object): object and the target function respectively. """ return (id(get_self(target)), id(get_func(target))) + calculate_key = classmethod(calculate_key) def __str__(self): @@ -202,7 +196,7 @@ class BoundMethodWeakref(object): self.__class__.__name__, self.self_name, self.func_name, - ) + ) __repr__ = __str__ diff --git a/blinker/_utilities.py b/src/blinker/_utilities.py index 133c57a..d64d8e8 100644 --- a/blinker/_utilities.py +++ b/src/blinker/_utilities.py @@ -3,62 +3,7 @@ from weakref import ref from blinker._saferef import BoundMethodWeakref -try: - callable -except NameError: - def callable(object): - return hasattr(object, '__call__') - - -try: - from collections import defaultdict -except: - class defaultdict(dict): - - def __init__(self, default_factory=None, *a, **kw): - if (default_factory is not None and - not hasattr(default_factory, '__call__')): - raise TypeError('first argument must be callable') - dict.__init__(self, *a, **kw) - self.default_factory = default_factory - - def __getitem__(self, key): - try: - return dict.__getitem__(self, key) - except KeyError: - return self.__missing__(key) - - def __missing__(self, key): - if self.default_factory is None: - raise KeyError(key) - self[key] = value = self.default_factory() - return value - - def __reduce__(self): - if self.default_factory is None: - args = () - else: - args = self.default_factory, - return type(self), args, None, None, self.items() - - def copy(self): - return self.__copy__() - - def __copy__(self): - return type(self)(self.default_factory, self) - - def __deepcopy__(self, memo): - import copy - return type(self)(self.default_factory, - copy.deepcopy(self.items())) - - def __repr__(self): - return 'defaultdict({}, {})'.format(self.default_factory, - dict.__repr__(self)) - - -class _symbol(object): - +class _symbol: def __init__(self, name): """Construct a new named symbol.""" self.__name__ = self.name = name @@ -68,10 +13,12 @@ class _symbol(object): def __repr__(self): return self.name -_symbol.__name__ = 'symbol' -class symbol(object): +_symbol.__name__ = "symbol" + + +class symbol: """A constant symbol. >>> symbol('foo') is symbol('foo') @@ -85,6 +32,7 @@ class symbol(object): Repeated calls of symbol('name') will all return the same instance. """ + symbols = {} def __new__(cls, name): @@ -94,18 +42,12 @@ class symbol(object): return cls.symbols.setdefault(name, _symbol(name)) -try: - text = (str, unicode) -except NameError: - text = str - - def hashable_identity(obj): - if hasattr(obj, '__func__'): + if hasattr(obj, "__func__"): return (id(obj.__func__), id(obj.__self__)) - elif hasattr(obj, 'im_func'): + elif hasattr(obj, "im_func"): return (id(obj.im_func), id(obj.im_self)) - elif isinstance(obj, text): + elif isinstance(obj, str): return obj else: return id(obj) @@ -131,14 +73,14 @@ def reference(object, callback=None, **annotations): def callable_reference(object, callback=None): """Return an annotated weak ref, supporting bound instance methods.""" - if hasattr(object, 'im_self') and object.im_self is not None: + if hasattr(object, "im_self") and object.im_self is not None: return BoundMethodWeakref(target=object, on_delete=callback) - elif hasattr(object, '__self__') and object.__self__ is not None: + elif hasattr(object, "__self__") and object.__self__ is not None: return BoundMethodWeakref(target=object, on_delete=callback) return annotatable_weakref(object, callback) -class lazy_property(object): +class lazy_property: """A @property that is only evaluated once.""" def __init__(self, deferred): diff --git a/blinker/base.py b/src/blinker/base.py index 8a3e4f9..467e0ac 100644 --- a/blinker/base.py +++ b/src/blinker/base.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8; fill-column: 76 -*- """Signals and events. A small implementation of signals, inspired by a snippet of Django signal @@ -8,26 +7,24 @@ each manages its own receivers and message emission. The :func:`signal` function provides singleton behavior for named signals. """ +from collections import defaultdict from contextlib import contextmanager from warnings import warn from weakref import WeakValueDictionary -from blinker._utilities import ( - WeakTypes, - defaultdict, - hashable_identity, - lazy_property, - reference, - symbol, - ) +from src.blinker._utilities import hashable_identity +from src.blinker._utilities import lazy_property +from src.blinker._utilities import reference +from src.blinker._utilities import symbol +from src.blinker._utilities import WeakTypes -ANY = symbol('ANY') +ANY = symbol("ANY") ANY.__doc__ = 'Token for "any sender".' ANY_ID = 0 -class Signal(object): +class Signal: """A notification emitter.""" #: An :obj:`ANY` convenience synonym, allows ``Signal.ANY`` @@ -136,22 +133,19 @@ class Signal(object): del sender_ref # broadcast this connection. if receivers raise, disconnect. - if ('receiver_connected' in self.__dict__ and - self.receiver_connected.receivers): + if "receiver_connected" in self.__dict__ and self.receiver_connected.receivers: try: - self.receiver_connected.send(self, - receiver=receiver, - sender=sender, - weak=weak) + self.receiver_connected.send( + self, receiver=receiver, sender=sender, weak=weak + ) except: self.disconnect(receiver, sender) raise if receiver_connected.receivers and self is not receiver_connected: try: - receiver_connected.send(self, - receiver_arg=receiver, - sender_arg=sender, - weak_arg=weak) + receiver_connected.send( + self, receiver_arg=receiver, sender_arg=sender, weak_arg=weak + ) except: self.disconnect(receiver, sender) raise @@ -178,9 +172,11 @@ class Signal(object): .. versionadded:: 1.1 """ + def decorator(fn): self.connect(fn, sender, weak) return fn + return decorator @contextmanager @@ -226,9 +222,10 @@ class Signal(object): deprecated in 1.2 and will be removed in a subsequent version. """ - warn("temporarily_connected_to is deprecated; " - "use connected_to instead.", - DeprecationWarning) + warn( + "temporarily_connected_to is deprecated; " "use connected_to instead.", + DeprecationWarning, + ) return self.connected_to(receiver, sender) def send(self, *sender, **kwargs): @@ -246,8 +243,10 @@ class Signal(object): # Ensure correct signature even on no-op sends, disable with -O # for lowest possible cost. if __debug__ and sender and len(sender) > 1: - raise TypeError('send() accepts only one positional ' - 'argument, %s given' % len(sender)) + raise TypeError( + "send() accepts only one positional " + "argument, %s given" % len(sender) + ) return [] # Using '*sender' rather than 'sender=None' allows 'sender' to be @@ -256,12 +255,15 @@ class Signal(object): if len(sender) == 0: sender = None elif len(sender) > 1: - raise TypeError('send() accepts only one positional argument, ' - '%s given' % len(sender)) + raise TypeError( + "send() accepts only one positional argument, " "%s given" % len(sender) + ) else: sender = sender[0] - return [(receiver, receiver(sender, **kwargs)) - for receiver in self.receivers_for(sender)] + return [ + (receiver, receiver(sender, **kwargs)) + for receiver in self.receivers_for(sender) + ] def has_receivers_for(self, sender): """True if there is probably a receiver for *sender*. @@ -285,8 +287,7 @@ class Signal(object): if self.receivers: sender_id = hashable_identity(sender) if sender_id in self._by_sender: - ids = (self._by_sender[ANY_ID] | - self._by_sender[sender_id]) + ids = self._by_sender[ANY_ID] | self._by_sender[sender_id] else: ids = self._by_sender[ANY_ID].copy() for receiver_id in ids: @@ -317,11 +318,11 @@ class Signal(object): receiver_id = hashable_identity(receiver) self._disconnect(receiver_id, sender_id) - if ('receiver_disconnected' in self.__dict__ and - self.receiver_disconnected.receivers): - self.receiver_disconnected.send(self, - receiver=receiver, - sender=sender) + if ( + "receiver_disconnected" in self.__dict__ + and self.receiver_disconnected.receivers + ): + self.receiver_disconnected.send(self, receiver=receiver, sender=sender) def _disconnect(self, receiver_id, sender_id): if sender_id == ANY_ID: @@ -379,7 +380,8 @@ class Signal(object): self._by_receiver.clear() -receiver_connected = Signal("""\ +receiver_connected = Signal( + """\ Sent by a :class:`Signal` after a receiver connects. :argument: the Signal that was connected to @@ -394,7 +396,8 @@ As of 1.2, individual signals have their own private :attr:`~Signal.receiver_disconnected` signals with a slightly simplified call signature. This global signal is planned to be removed in 1.6. -""") +""" +) class NamedSignal(Signal): @@ -408,7 +411,7 @@ class NamedSignal(Signal): def __repr__(self): base = Signal.__repr__(self) - return "{}; {!r}>".format(base[:-1], self.name) + return f"{base[:-1]}; {self.name!r}>" class Namespace(dict): |