sqlmesh.utils API documentation

Edit on GitHub

# sqlmesh.utils

View Source

      1from __future__ import annotations
      2
      3import importlib
      4import re
      5import sys
      6import traceback
      7import types
      8import typing as t
      9import uuid
     10from contextlib import contextmanager
     11from functools import wraps
     12from pathlib import Path
     13
     14T = t.TypeVar("T")
     15KEY = t.TypeVar("KEY", bound=t.Hashable)
     16VALUE = t.TypeVar("VALUE")
     17DECORATOR_RETURN_TYPE = t.TypeVar("DECORATOR_RETURN_TYPE")
     18
     19
     20def optional_import(name: str) -> t.Optional[types.ModuleType]:
     21    """Optionally import a module.
     22
     23    Args:
     24        name: The name of the module to import.
     25    Returns:
     26        The module if it is installed.
     27    """
     28    try:
     29        module = importlib.import_module(name)
     30    except ImportError:
     31        return None
     32    return module
     33
     34
     35def unique(iterable: t.Iterable[T], by: t.Callable[[T], t.Any] = lambda i: i) -> t.List[T]:
     36    return list({by(i): None for i in iterable})
     37
     38
     39def random_id() -> str:
     40    return uuid.uuid4().hex
     41
     42
     43class UniqueKeyDict(dict, t.Mapping[KEY, VALUE]):
     44    """Dict that raises when a duplicate key is set."""
     45
     46    def __init__(self, name: str, *args: t.Dict[KEY, VALUE], **kwargs: VALUE) -> None:
     47        self.name = name
     48        super().__init__(*args, **kwargs)
     49
     50    def __setitem__(self, k: KEY, v: VALUE) -> None:
     51        if k in self:
     52            raise ValueError(
     53                f"Duplicate key '{k}' found in UniqueKeyDict<{self.name}>. Call dict.update(...) if this is intentional."
     54            )
     55        super().__setitem__(k, v)
     56
     57
     58class AttributeDict(dict, t.Mapping[KEY, VALUE]):
     59    __getattr__ = dict.get
     60
     61
     62class registry_decorator:
     63    """A decorator that registers itself."""
     64
     65    registry_name = ""
     66    _registry: t.Optional[UniqueKeyDict] = None
     67
     68    @classmethod
     69    def registry(cls) -> UniqueKeyDict:
     70        if cls._registry is None:
     71            cls._registry = UniqueKeyDict(cls.registry_name)
     72        return cls._registry
     73
     74    def __init__(self, name: str = "") -> None:
     75        self.name = name
     76
     77    def __call__(
     78        self, func: t.Callable[..., DECORATOR_RETURN_TYPE]
     79    ) -> t.Callable[..., DECORATOR_RETURN_TYPE]:
     80        self.func = func
     81        self.registry()[(self.name or func.__name__)] = self
     82
     83        @wraps(func)
     84        def wrapper(*args: t.Any, **kwargs: t.Any) -> DECORATOR_RETURN_TYPE:
     85            return func(*args, **kwargs)
     86
     87        return wrapper
     88
     89    @classmethod
     90    def get_registry(cls) -> UniqueKeyDict:
     91        """Get a copy of the registry"""
     92        return UniqueKeyDict(cls.registry_name, **(cls._registry or {}))
     93
     94    @classmethod
     95    def set_registry(cls, registry: UniqueKeyDict) -> None:
     96        """Set the registry."""
     97        cls._registry = registry
     98
     99
    100@contextmanager
    101def sys_path(path: Path) -> t.Generator[None, None, None]:
    102    """A context manager to temporarily add a path to 'sys.path'."""
    103    path_str = str(path.absolute())
    104
    105    if path_str in sys.path:
    106        inserted = False
    107    else:
    108        sys.path.insert(0, path_str)
    109        inserted = True
    110
    111    try:
    112        yield
    113    finally:
    114        if inserted:
    115            sys.path.remove(path_str)
    116
    117
    118def format_exception(exception: BaseException) -> t.List[str]:
    119    if sys.version_info < (3, 10):
    120        return traceback.format_exception(
    121            type(exception), exception, exception.__traceback__
    122        )  # type: ignore
    123    else:
    124        return traceback.format_exception(exception)  # type: ignore
    125
    126
    127def word_characters_only(s: str, replacement_char: str = "_") -> str:
    128    """
    129    Replace all non-word characters in string with the replacement character.
    130    Reference SO: https://stackoverflow.com/questions/1276764/stripping-everything-but-alphanumeric-chars-from-a-string-in-python/70310018#70310018
    131
    132    >>> word_characters_only("Hello, world!")
    133    'Hello__world_'
    134    >>> word_characters_only("Hello, world! 123", '')
    135    'Helloworld123'
    136    """
    137    return re.sub(r"\W", replacement_char, s)
    138
    139
    140def double_escape(s: str) -> str:
    141    """
    142    Replace backslashes with another backslash.
    143    """
    144    return s.replace("\\", "\\\\")
    145
    146
    147def nullsafe_join(join_char: str, *args: t.Optional[str]) -> str:
    148    return join_char.join(filter(None, args))

def optional_import(name: str) -> Optional[module]: View Source

    21def optional_import(name: str) -> t.Optional[types.ModuleType]:
    22    """Optionally import a module.
    23
    24    Args:
    25        name: The name of the module to import.
    26    Returns:
    27        The module if it is installed.
    28    """
    29    try:
    30        module = importlib.import_module(name)
    31    except ImportError:
    32        return None
    33    return module

Optionally import a module.

###### Arguments:

- name: The name of the module to import.

###### Returns:

> The module if it is installed.

def unique( iterable: Iterable[~T], by: Callable[[~T], Any] = <function <lambda>>) -> List[~T]: View Source

    36def unique(iterable: t.Iterable[T], by: t.Callable[[T], t.Any] = lambda i: i) -> t.List[T]:
    37    return list({by(i): None for i in iterable})

def random_id() -> str: View Source

    40def random_id() -> str:
    41    return uuid.uuid4().hex

class UniqueKeyDict(builtins.dict, typing.Mapping[~KEY, ~VALUE]): View Source

    44class UniqueKeyDict(dict, t.Mapping[KEY, VALUE]):
    45    """Dict that raises when a duplicate key is set."""
    46
    47    def __init__(self, name: str, *args: t.Dict[KEY, VALUE], **kwargs: VALUE) -> None:
    48        self.name = name
    49        super().__init__(*args, **kwargs)
    50
    51    def __setitem__(self, k: KEY, v: VALUE) -> None:
    52        if k in self:
    53            raise ValueError(
    54                f"Duplicate key '{k}' found in UniqueKeyDict<{self.name}>. Call dict.update(...) if this is intentional."
    55            )
    56        super().__setitem__(k, v)

Dict that raises when a duplicate key is set.

##### Inherited Members

builtins.dict
  get
  setdefault
  pop
  popitem
  keys
  items
  values
  update
  fromkeys
  clear
  copy

class AttributeDict(builtins.dict, typing.Mapping[~KEY, ~VALUE]): View Source

    59class AttributeDict(dict, t.Mapping[KEY, VALUE]):
    60    __getattr__ = dict.get

##### Inherited Members

builtins.dict
  get
  setdefault
  pop
  popitem
  keys
  items
  values
  update
  fromkeys
  clear
  copy

class registry_decorator: View Source

    63class registry_decorator:
    64    """A decorator that registers itself."""
    65
    66    registry_name = ""
    67    _registry: t.Optional[UniqueKeyDict] = None
    68
    69    @classmethod
    70    def registry(cls) -> UniqueKeyDict:
    71        if cls._registry is None:
    72            cls._registry = UniqueKeyDict(cls.registry_name)
    73        return cls._registry
    74
    75    def __init__(self, name: str = "") -> None:
    76        self.name = name
    77
    78    def __call__(
    79        self, func: t.Callable[..., DECORATOR_RETURN_TYPE]
    80    ) -> t.Callable[..., DECORATOR_RETURN_TYPE]:
    81        self.func = func
    82        self.registry()[(self.name or func.__name__)] = self
    83
    84        @wraps(func)
    85        def wrapper(*args: t.Any, **kwargs: t.Any) -> DECORATOR_RETURN_TYPE:
    86            return func(*args, **kwargs)
    87
    88        return wrapper
    89
    90    @classmethod
    91    def get_registry(cls) -> UniqueKeyDict:
    92        """Get a copy of the registry"""
    93        return UniqueKeyDict(cls.registry_name, **(cls._registry or {}))
    94
    95    @classmethod
    96    def set_registry(cls, registry: UniqueKeyDict) -> None:
    97        """Set the registry."""
    98        cls._registry = registry

A decorator that registers itself.

registry_decorator(name: str = '') View Source

    75    def __init__(self, name: str = "") -> None:
    76        self.name = name

@classmethod
def registry(cls) -> sqlmesh.utils.UniqueKeyDict: View Source

    69    @classmethod
    70    def registry(cls) -> UniqueKeyDict:
    71        if cls._registry is None:
    72            cls._registry = UniqueKeyDict(cls.registry_name)
    73        return cls._registry

@classmethod
def get_registry(cls) -> sqlmesh.utils.UniqueKeyDict: View Source

    90    @classmethod
    91    def get_registry(cls) -> UniqueKeyDict:
    92        """Get a copy of the registry"""
    93        return UniqueKeyDict(cls.registry_name, **(cls._registry or {}))

Get a copy of the registry

@classmethod
def set_registry(cls, registry: sqlmesh.utils.UniqueKeyDict) -> None: View Source

    95    @classmethod
    96    def set_registry(cls, registry: UniqueKeyDict) -> None:
    97        """Set the registry."""
    98        cls._registry = registry

Set the registry.

@contextmanager
def sys_path(path: pathlib.Path) -> Generator[NoneType, NoneType, NoneType]: View Source

    101@contextmanager
    102def sys_path(path: Path) -> t.Generator[None, None, None]:
    103    """A context manager to temporarily add a path to 'sys.path'."""
    104    path_str = str(path.absolute())
    105
    106    if path_str in sys.path:
    107        inserted = False
    108    else:
    109        sys.path.insert(0, path_str)
    110        inserted = True
    111
    112    try:
    113        yield
    114    finally:
    115        if inserted:
    116            sys.path.remove(path_str)

A context manager to temporarily add a path to 'sys.path'.

def format_exception(exception: BaseException) -> List[str]: View Source

    119def format_exception(exception: BaseException) -> t.List[str]:
    120    if sys.version_info < (3, 10):
    121        return traceback.format_exception(
    122            type(exception), exception, exception.__traceback__
    123        )  # type: ignore
    124    else:
    125        return traceback.format_exception(exception)  # type: ignore

def word_characters_only(s: str, replacement_char: str = '_') -> str: View Source

    128def word_characters_only(s: str, replacement_char: str = "_") -> str:
    129    """
    130    Replace all non-word characters in string with the replacement character.
    131    Reference SO: https://stackoverflow.com/questions/1276764/stripping-everything-but-alphanumeric-chars-from-a-string-in-python/70310018#70310018
    132
    133    >>> word_characters_only("Hello, world!")
    134    'Hello__world_'
    135    >>> word_characters_only("Hello, world! 123", '')
    136    'Helloworld123'
    137    """
    138    return re.sub(r"\W", replacement_char, s)

Replace all non-word characters in string with the replacement character. Reference SO: https://stackoverflow.com/questions/1276764/stripping-everything-but-alphanumeric-chars-from-a-string-in-python/70310018#70310018

    >>> word_characters_only("Hello, world!")
    'Hello__world_'
    >>> word_characters_only("Hello, world! 123", '')
    'Helloworld123'

def double_escape(s: str) -> str: View Source

    141def double_escape(s: str) -> str:
    142    """
    143    Replace backslashes with another backslash.
    144    """
    145    return s.replace("\\", "\\\\")

Replace backslashes with another backslash.

def nullsafe_join(join_char: str, *args: Optional[str]) -> str: View Source

    148def nullsafe_join(join_char: str, *args: t.Optional[str]) -> str:
    149    return join_char.join(filter(None, args))