Module arti.fingerprints
None
None
View Source
from __future__ import annotations
__path__ = __import__("pkgutil").extend_path(__path__, __name__)
import operator
from collections.abc import Callable
from functools import reduce
from typing import Optional, Union
import farmhash
from arti.internal.models import Model
from arti.internal.utils import int64, uint64
def _gen_fingerprint_binop(
    op: Callable[[int, int], int]
) -> Callable[[Fingerprint, Union[int, Fingerprint]], Fingerprint]:
    def _fingerprint_binop(self: Fingerprint, other: Union[int, Fingerprint]) -> Fingerprint:
        if isinstance(other, int):
            other = Fingerprint.from_int(other)
        if isinstance(other, Fingerprint):
            if self.key is None or other.key is None:
                return Fingerprint.empty()
            return Fingerprint(key=op(self.key, other.key))
        return NotImplemented
    return _fingerprint_binop
class Fingerprint(Model):
    """Fingerprint represents a unique identity as an int64 value.
    Using an int(64) has a number of convenient properties:
    - can be combined independent of order with XOR
    - can be stored relatively cheaply
    - empty 0 values drop out when combined (5 ^ 0 = 5)
    - is relatively cross-platform (across databases, languages, etc)
    There are two "special" Fingerprints w/ factory functions that, when combined with other
    Fingerprints:
    - `empty()`: returns `empty()`
    - `identity()`: return the other Fingerprint
    """
    key: Optional[int64]
    def combine(self, *others: Fingerprint) -> Fingerprint:
        return reduce(operator.xor, others, self)
    @classmethod
    def empty(cls) -> Fingerprint:
        """Return a Fingerprint that, when combined, will return Fingerprint.empty()"""
        return cls(key=None)
    @classmethod
    def from_int(cls, x: int, /) -> Fingerprint:
        return cls.from_int64(int64(x))
    @classmethod
    def from_int64(cls, x: int64, /) -> Fingerprint:
        return cls(key=x)
    @classmethod
    def from_string(cls, x: str, /) -> Fingerprint:
        """Fingerprint an arbitrary string.
        Fingerprints using Farmhash Fingerprint64, converted to int64 via two's complement.
        """
        return cls.from_uint64(uint64(farmhash.fingerprint64(x)))
    @classmethod
    def from_uint64(cls, x: uint64, /) -> Fingerprint:
        return cls.from_int64(int64(x))
    @classmethod
    def identity(cls) -> Fingerprint:
        """Return a Fingerprint that, when combined, will return the other Fingerprint."""
        return cls(key=int64(0))
    @property
    def is_empty(self) -> bool:
        return self.key is None
    @property
    def is_identity(self) -> bool:
        return self.key == 0
    __and__ = _gen_fingerprint_binop(operator.__and__)
    __lshift__ = _gen_fingerprint_binop(operator.__lshift__)
    __or__ = _gen_fingerprint_binop(operator.__or__)
    __rshift__ = _gen_fingerprint_binop(operator.__rshift__)
    __xor__ = _gen_fingerprint_binop(operator.__xor__)
    def __eq__(self, other: object) -> bool:
        if isinstance(other, int):
            other = Fingerprint.from_int(other)
        if isinstance(other, Fingerprint):
            return self.key == other.key
        return NotImplemented
Classes
Fingerprint
class Fingerprint(
    __pydantic_self__,
    **data: Any
)
View Source
class Fingerprint(Model):
    """Fingerprint represents a unique identity as an int64 value.
    Using an int(64) has a number of convenient properties:
    - can be combined independent of order with XOR
    - can be stored relatively cheaply
    - empty 0 values drop out when combined (5 ^ 0 = 5)
    - is relatively cross-platform (across databases, languages, etc)
    There are two "special" Fingerprints w/ factory functions that, when combined with other
    Fingerprints:
    - `empty()`: returns `empty()`
    - `identity()`: return the other Fingerprint
    """
    key: Optional[int64]
    def combine(self, *others: Fingerprint) -> Fingerprint:
        return reduce(operator.xor, others, self)
    @classmethod
    def empty(cls) -> Fingerprint:
        """Return a Fingerprint that, when combined, will return Fingerprint.empty()"""
        return cls(key=None)
    @classmethod
    def from_int(cls, x: int, /) -> Fingerprint:
        return cls.from_int64(int64(x))
    @classmethod
    def from_int64(cls, x: int64, /) -> Fingerprint:
        return cls(key=x)
    @classmethod
    def from_string(cls, x: str, /) -> Fingerprint:
        """Fingerprint an arbitrary string.
        Fingerprints using Farmhash Fingerprint64, converted to int64 via two's complement.
        """
        return cls.from_uint64(uint64(farmhash.fingerprint64(x)))
    @classmethod
    def from_uint64(cls, x: uint64, /) -> Fingerprint:
        return cls.from_int64(int64(x))
    @classmethod
    def identity(cls) -> Fingerprint:
        """Return a Fingerprint that, when combined, will return the other Fingerprint."""
        return cls(key=int64(0))
    @property
    def is_empty(self) -> bool:
        return self.key is None
    @property
    def is_identity(self) -> bool:
        return self.key == 0
    __and__ = _gen_fingerprint_binop(operator.__and__)
    __lshift__ = _gen_fingerprint_binop(operator.__lshift__)
    __or__ = _gen_fingerprint_binop(operator.__or__)
    __rshift__ = _gen_fingerprint_binop(operator.__rshift__)
    __xor__ = _gen_fingerprint_binop(operator.__xor__)
    def __eq__(self, other: object) -> bool:
        if isinstance(other, int):
            other = Fingerprint.from_int(other)
        if isinstance(other, Fingerprint):
            return self.key == other.key
        return NotImplemented
Ancestors (in MRO)
- arti.internal.models.Model
- pydantic.main.BaseModel
- pydantic.utils.Representation
Class variables
Config
Static methods
construct
def construct(
    _fields_set: Optional[ForwardRef('SetStr')] = None,
    **values: Any
) -> 'Model'
Creates a new model setting dict and fields_set from trusted or pre-validated data.
Default values are respected, but no other validation is performed.
Behaves as if Config.extra = 'allow' was set since it adds all passed values
empty
def empty(
) -> 'Fingerprint'
Return a Fingerprint that, when combined, will return Fingerprint.empty()
View Source
    @classmethod
    def empty(cls) -> Fingerprint:
        """Return a Fingerprint that, when combined, will return Fingerprint.empty()"""
        return cls(key=None)
from_int
def from_int(
    x: 'int',
    /
) -> 'Fingerprint'
View Source
    @classmethod
    def from_int(cls, x: int, /) -> Fingerprint:
        return cls.from_int64(int64(x))
from_int64
def from_int64(
    x: 'int64',
    /
) -> 'Fingerprint'
View Source
    @classmethod
    def from_int64(cls, x: int64, /) -> Fingerprint:
        return cls(key=x)
from_orm
def from_orm(
    obj: Any
) -> 'Model'
from_string
def from_string(
    x: 'str',
    /
) -> 'Fingerprint'
Fingerprint an arbitrary string.
Fingerprints using Farmhash Fingerprint64, converted to int64 via two's complement.
View Source
    @classmethod
    def from_string(cls, x: str, /) -> Fingerprint:
        """Fingerprint an arbitrary string.
        Fingerprints using Farmhash Fingerprint64, converted to int64 via two's complement.
        """
        return cls.from_uint64(uint64(farmhash.fingerprint64(x)))
from_uint64
def from_uint64(
    x: 'uint64',
    /
) -> 'Fingerprint'
View Source
    @classmethod
    def from_uint64(cls, x: uint64, /) -> Fingerprint:
        return cls.from_int64(int64(x))
identity
def identity(
) -> 'Fingerprint'
Return a Fingerprint that, when combined, will return the other Fingerprint.
View Source
    @classmethod
    def identity(cls) -> Fingerprint:
        """Return a Fingerprint that, when combined, will return the other Fingerprint."""
        return cls(key=int64(0))
parse_file
def parse_file(
    path: Union[str, pathlib.Path],
    *,
    content_type: 'unicode' = None,
    encoding: 'unicode' = 'utf8',
    proto: pydantic.parse.Protocol = None,
    allow_pickle: bool = False
) -> 'Model'
parse_obj
def parse_obj(
    obj: Any
) -> 'Model'
parse_raw
def parse_raw(
    b: Union[str, bytes],
    *,
    content_type: 'unicode' = None,
    encoding: 'unicode' = 'utf8',
    proto: pydantic.parse.Protocol = None,
    allow_pickle: bool = False
) -> 'Model'
schema
def schema(
    by_alias: bool = True,
    ref_template: 'unicode' = '#/definitions/{model}'
) -> 'DictStrAny'
schema_json
def schema_json(
    *,
    by_alias: bool = True,
    ref_template: 'unicode' = '#/definitions/{model}',
    **dumps_kwargs: Any
) -> 'unicode'
update_forward_refs
def update_forward_refs(
    **localns: Any
) -> None
Try to update ForwardRefs on fields based on this Model, globalns and localns.
validate
def validate(
    value: Any
) -> 'Model'
Instance variables
fingerprint
is_empty
is_identity
Methods
combine
def combine(
    self,
    *others: 'Fingerprint'
) -> 'Fingerprint'
View Source
    def combine(self, *others: Fingerprint) -> Fingerprint:
        return reduce(operator.xor, others, self)
copy
def copy(
    self,
    *,
    deep: 'bool' = False,
    validate: 'bool' = True,
    **kwargs: 'Any'
) -> 'Self'
Duplicate a model, optionally choose which fields to include, exclude and change.
Parameters:
| Name | Type | Description | Default | 
|---|---|---|---|
| include | None | fields to include in new model | None | 
| exclude | None | fields to exclude from new model, as with values this takes precedence over include | None | 
| update | None | values to change/add in the new model. Note: the data is not validated before creating | |
| the new model: you should trust this data | None | ||
| deep | None | set to Trueto make a deep copy of the model | None | 
Returns:
| Type | Description | 
|---|---|
| None | new model instance | 
View Source
    def copy(self, *, deep: bool = False, validate: bool = True, **kwargs: Any) -> Self:
        copy = super().copy(deep=deep, **kwargs)
        if validate:
            # NOTE: We set exclude_unset=False so that all existing defaulted fields are reused (as
            # is normal `.copy` behavior).
            #
            # To reduce `repr` noise, we'll reset .__fields_set__ to those of the pre-validation copy
            # (which includes those originally set + updated).
            fields_set = copy.__fields_set__
            copy = copy.validate(
                dict(copy._iter(to_dict=False, by_alias=False, exclude_unset=False))
            )
            # Use object.__setattr__ to bypass frozen model assignment errors
            object.__setattr__(copy, "__fields_set__", set(fields_set))
            # Copy over the private attributes, which are missing after validation (since we're only
            # passing the fields).
            for name in self.__private_attributes__:
                if (value := getattr(self, name, Undefined)) is not Undefined:
                    if deep:
                        value = deepcopy(value)
                    object.__setattr__(copy, name, value)
        return copy
dict
def dict(
    self,
    *,
    include: Union[ForwardRef('AbstractSetIntStr'), ForwardRef('MappingIntStrAny'), NoneType] = None,
    exclude: Union[ForwardRef('AbstractSetIntStr'), ForwardRef('MappingIntStrAny'), NoneType] = None,
    by_alias: bool = False,
    skip_defaults: Optional[bool] = None,
    exclude_unset: bool = False,
    exclude_defaults: bool = False,
    exclude_none: bool = False
) -> 'DictStrAny'
Generate a dictionary representation of the model, optionally specifying which fields to include or exclude.
json
def json(
    self,
    *,
    include: Union[ForwardRef('AbstractSetIntStr'), ForwardRef('MappingIntStrAny'), NoneType] = None,
    exclude: Union[ForwardRef('AbstractSetIntStr'), ForwardRef('MappingIntStrAny'), NoneType] = None,
    by_alias: bool = False,
    skip_defaults: Optional[bool] = None,
    exclude_unset: bool = False,
    exclude_defaults: bool = False,
    exclude_none: bool = False,
    encoder: Optional[Callable[[Any], Any]] = None,
    models_as_dict: bool = True,
    **dumps_kwargs: Any
) -> 'unicode'
Generate a JSON representation of the model, include and exclude arguments as per dict().
encoder is an optional function to supply as default to json.dumps(), other arguments as per json.dumps().