facedancer.magic module

Functionally for automatic instantiations / tracking via decorators.

class facedancer.magic.AutoInstantiable[source]

Bases: object

Base class for methods that can be decorated with use_automatically.

abstract get_identifier() int[source]

Returns a unique integer identifier for this object.

This is usually the index or address of the relevant USB object.

matches_identifier(other: int) bool[source]
class facedancer.magic.AutoInstantiator(target_type)[source]

Bases: object

Simple wrapper class annotated on objects that can be instantiated automatically.

Used for the @use_automatically decorator; which removes a lot of the Facedancer boilerplate at the cost of being somewhat cryptic.

creates_instance_of(expected_type)[source]
class facedancer.magic.DescribableMeta(name, bases, ns)[source]

Bases: ABCMeta

Metaclass for USBDescribable subclasses.

static __new__(cls, name, bases, ns)[source]

Construct a new dataclass from the given class which inherits all type annotations from its base classes.

facedancer.magic.adjust_defaults(cls, **kwargs)[source]

Adjusts the defaults of an existing dataclass.

facedancer.magic.instantiate_subordinates(obj, expected_type)[source]

Automatically instantiates any inner classes with a matching type.

This is used by objects that represent USB hardware behaviors (e.g. USBDevice, USBConfiguration, USBInterface, USBEndpoint) in order to automatically create objects of any inner class decorated with @use_automatically.

facedancer.magic.use_automatically(cls)[source]

Class decorator used to annotate Facedancer inner classes. Implies @dataclass.

This decorator can be placed on inner classes that describe “subordinate” objects on USB devices. For example, a USBDevice can have several subordinate USBConfigurations; which select the various configurations for that class.

When placed on a subordinate class, this allows the parent class to automatically instantiate the relevant given class during its creation; automatically populating the subordinate properties of the relevant device.

For example, assume we have a Facedancer class representing a custom USB device:

class ExampleDevice(USBDevice):
    product_string : str = "My Example Device"

    @use_automatically
    class DefaultConfiguration(USBConfiguration):
        number : int = 1

In this case, when an ExampleDevice is instantiated, the USBDevice code knows how to instantiate DefaultConfiguration, and will do so automatically.

Note that this decorator should _only_ be used for subordinate types; and expects that the decorated class has no explicitly-declared __init__ method. The __post_init__ mechanism of python dataclasses can be overridden to perform any needed initialization.

facedancer.magic.use_inner_classes_automatically(cls)[source]

Decorator that acts as if all inner classes were defined with use_automatically.