# Path: fimfarchive/signals.py
# class Signal(blinker.Signal):
#     """
#     Blinker signal with positional arguments.
#     """
# 
#     def __init__(self, *spec):
#         """
#         Constructor.
# 
#         Args:
#             spec: Names of the signal arguments.
#         """
#         if 'sender' in spec:
#             raise ValueError("Reserved argument name: 'sender'")
# 
#         self.spec = ('sender', *spec)
#         super().__init__(doc=repr(self))
# 
#     def __call__(self, *args, **kwargs):
#         """
#         Raises an error regarding unbound signals.
#         """
#         raise ValueError(
#             "Unbound signal. Forgot {}'s initializer?"
#             .format(type(SignalSender).__name__)
#         )
# 
#     def __repr__(self):
#         return "<signal ({})>".format(', '.join(self.spec))
# 
#     def send(self, *args, **kwargs):
#         """
#         Emits this signal on behalf of its sender.
# 
#         Args:
#             sender: Object sending the signal.
#             *args: Values to pass to the receiver.
# 
#         Returns:
#             A list of 2-tuples. Each tuple contains the
#             signal's receiver and its returned values.
#         """
# 
#         if len(self.spec) < len(args):
#             raise ValueError(
#                 "Expected at most {} arguments, got {}."
#                 .format(len(self.spec), len(args))
#             )
# 
#         data = {self.spec[i]: v for i, v in enumerate(args)}
#         duplicates = set(data.keys()).intersection(kwargs.keys())
# 
#         if duplicates:
#             raise ValueError(
#                 "Got duplicate values for: '{}'"
#                 .format("', '".join(duplicates))
#             )
# 
#         data.update(kwargs)
#         sender = data.pop('sender', None)
# 
#         return super().send(sender, **data)
# 
# class SignalBinder:
#     """
#     Bound transparent proxy for signals.
#     """
# 
#     def __init__(self, signal, sender):
#         """
#         Constructor.
# 
#         Args:
#             signal: Object to bind for.
#             sender: Object to bind to.
#         """
#         self.signal = signal
#         self.sender = sender
# 
#     def __call__(self, *args, **kwargs):
#         return self.send(self.sender, *args, **kwargs)
# 
#     def __getattr__(self, attr):
#         return getattr(self.signal, attr)
# 
#     def __repr__(self):
#         return "<bound {} of {}>".format(self.signal, self.sender)
# 
# class SignalSender:
#     """
#     Automatically binds unbound signals on init.
#     """
# 
#     def __init__(self):
#         """
#         Constructor.
#         """
#         for key, source in find_sources(self):
#             if not isinstance(source, SignalBinder):
#                 binding = SignalBinder(source, self)
#                 setattr(self, key, binding)
# 
# class SignalReceiver:
#     """
#     Automatically connects signals on enter.
#     """
# 
#     def __init__(self, sender):
#         """
#         Constructor.
# 
#         Args:
#             sender: Object to connect to.
#         """
#         self.sender = sender
# 
#     def __enter__(self):
#         for key, source, target in find_matches(self.sender, self):
#             source.connect(target, sender=self.sender)
# 
#         return self
# 
#     def __exit__(self, *args):
#         for key, source, target in find_matches(self.sender, self):
#             source.disconnect(target, sender=self.sender)


from collections import OrderedDict
from unittest.mock import patch, Mock
from fimfarchive.signals import (
    Signal, SignalBinder, SignalSender, SignalReceiver
)
import blinker
import pytest
        ('c', 3),
    )

    return OrderedDict(data)


@pytest.fixture
def signal(params):
    """
    Returns an unbound signal instance.
    """
    return Signal(*params.keys())


@pytest.fixture
def sender(signal):
    """
    Returns a signal sender instance.
    """
    class Sender(SignalSender):
        on_signal = signal

    return Sender()


@pytest.fixture
def receiver(sender):
    """
    Returns a connected signal receiver intance.
    """

# Path: fimfarchive/signals.py
# class Signal(blinker.Signal):
#     """
#     Blinker signal with positional arguments.
#     """
# 
#     def __init__(self, *spec):
#         """
#         Constructor.
# 
#         Args:
#             spec: Names of the signal arguments.
#         """
#         if 'sender' in spec:
#             raise ValueError("Reserved argument name: 'sender'")
# 
#         self.spec = ('sender', *spec)
#         super().__init__(doc=repr(self))
# 
#     def __call__(self, *args, **kwargs):
#         """
#         Raises an error regarding unbound signals.
#         """
#         raise ValueError(
#             "Unbound signal. Forgot {}'s initializer?"
#             .format(type(SignalSender).__name__)
#         )
# 
#     def __repr__(self):
#         return "<signal ({})>".format(', '.join(self.spec))
# 
#     def send(self, *args, **kwargs):
#         """
#         Emits this signal on behalf of its sender.
# 
#         Args:
#             sender: Object sending the signal.
#             *args: Values to pass to the receiver.
# 
#         Returns:
#             A list of 2-tuples. Each tuple contains the
#             signal's receiver and its returned values.
#         """
# 
#         if len(self.spec) < len(args):
#             raise ValueError(
#                 "Expected at most {} arguments, got {}."
#                 .format(len(self.spec), len(args))
#             )
# 
#         data = {self.spec[i]: v for i, v in enumerate(args)}
#         duplicates = set(data.keys()).intersection(kwargs.keys())
# 
#         if duplicates:
#             raise ValueError(
#                 "Got duplicate values for: '{}'"
#                 .format("', '".join(duplicates))
#             )
# 
#         data.update(kwargs)
#         sender = data.pop('sender', None)
# 
#         return super().send(sender, **data)
# 
# class SignalBinder:
#     """
#     Bound transparent proxy for signals.
#     """
# 
#     def __init__(self, signal, sender):
#         """
#         Constructor.
# 
#         Args:
#             signal: Object to bind for.
#             sender: Object to bind to.
#         """
#         self.signal = signal
#         self.sender = sender
# 
#     def __call__(self, *args, **kwargs):
#         return self.send(self.sender, *args, **kwargs)
# 
#     def __getattr__(self, attr):
#         return getattr(self.signal, attr)
# 
#     def __repr__(self):
#         return "<bound {} of {}>".format(self.signal, self.sender)
# 
# class SignalSender:
#     """
#     Automatically binds unbound signals on init.
#     """
# 
#     def __init__(self):
#         """
#         Constructor.
#         """
#         for key, source in find_sources(self):
#             if not isinstance(source, SignalBinder):
#                 binding = SignalBinder(source, self)
#                 setattr(self, key, binding)
# 
# class SignalReceiver:
#     """
#     Automatically connects signals on enter.
#     """
# 
#     def __init__(self, sender):
#         """
#         Constructor.
# 
#         Args:
#             sender: Object to connect to.
#         """
#         self.sender = sender
# 
#     def __enter__(self):
#         for key, source, target in find_matches(self.sender, self):
#             source.connect(target, sender=self.sender)
# 
#         return self
# 
#     def __exit__(self, *args):
#         for key, source, target in find_matches(self.sender, self):
#             source.disconnect(target, sender=self.sender)


# Path: tests/test_signals.py
from collections import OrderedDict
from unittest.mock import patch, Mock
from fimfarchive.signals import (
    Signal, SignalBinder, SignalSender, SignalReceiver
)
import blinker
import pytest

        ('c', 3),
    )

    return OrderedDict(data)


@pytest.fixture
def signal(params):
    """
    Returns an unbound signal instance.
    """
    return Signal(*params.keys())


@pytest.fixture
def sender(signal):
    """
    Returns a signal sender instance.
    """
    class Sender(SignalSender):
        on_signal = signal

    return Sender()


@pytest.fixture
def receiver(sender):
    """
    Returns a connected signal receiver intance.
    """

    class Receiver(SignalReceiver):