Exemple #1
0
 def __new__(
     cls,
     left: 'Origin',
     right: 'Origin',
     condition: typing.Optional['series.Expression'] = None,
     kind: typing.Optional[typing.Union['Join.Kind', str]] = None,
 ):
     kind = cls.Kind(kind) if kind else cls.Kind.INNER if condition is not None else cls.Kind.CROSS
     if condition is not None:
         if kind is cls.Kind.CROSS:
             raise error.Syntax('Illegal use of condition for cross-join')
         condition = series.Cumulative.ensure_notin(series.Predicate.ensure_is(condition))
         if not series.Element.dissect(condition).issubset(series.Element.dissect(*left.columns, *right.columns)):
             raise error.Syntax(f'({condition}) not a subset of source columns ({left.columns}, {right.columns})')
     return super().__new__(cls, left, right, condition, kind)
Exemple #2
0
    def make(
        cls,
        specs: typing.Sequence[
            typing.Union[
                Operable,
                typing.Union['Ordering.Direction', str],
                typing.Tuple[Operable, typing.Union['Ordering.Direction', str]],
            ]
        ],
    ) -> typing.Iterable['Ordering']:
        """Helper to generate orderings from given columns and directions.

        Args:
            specs: One or many columns or actual ordering instances.

        Returns:
            Sequence of ordering terms.
        """
        specs = itertools.zip_longest(specs, specs[1:])
        for column, direction in specs:
            if isinstance(column, Column):
                if isinstance(direction, (Ordering.Direction, str)):
                    yield Ordering.Direction(direction)(column)
                    next(specs)  # pylint: disable=stop-iteration-return
                else:
                    yield Ordering(column)
            elif isinstance(column, colabc.Sequence) and len(column) == 2:
                column, direction = column
                yield Ordering.Direction(direction)(column)
            else:
                raise error.Syntax('Expecting pair of column and direction')
Exemple #3
0
 def __new__(mcs, name: str, bases: typing.Tuple[typing.Type], namespace: typing.Dict[str, typing.Any]):
     existing = {s[k].name: k for s in bases if isinstance(s, Table.Schema) for k in s}
     for key, field in namespace.items():
         if not isinstance(field, struct.Field):
             continue
         if not field.name:
             namespace[key] = field = field.renamed(key)  # to normalize so that hash/eq is consistent
         if field.name in existing and field.name != existing[field.name]:
             raise error.Syntax(f'Colliding field name {field.name} in schema {name}')
         existing[field.name] = key
     return super().__new__(mcs, name, bases, namespace)
Exemple #4
0
        def ensure_subset(*columns: 'series.Column') -> typing.Sequence['series.Column']:
            """Ensure the provided columns is a valid subset of the available source columns.

            Args:
                *columns: List of columns to validate.

            Returns:
                Original list of columns if all valid.
            """
            if not series.Element.dissect(*columns).issubset(superset):
                raise error.Syntax(f'{columns} not a subset of source columns: {superset}')
            return columns
Exemple #5
0
    def ensure_notin(cls, column: 'Column') -> 'Column':
        """Ensure given column is not composed of our type.

        Args:
            column: Column to be verified.

        Returns:
            Original column if not of our type or raising otherwise.
        """
        if cls.dissect(column):
            raise error.Syntax(f'{cls.__name__} instance(s) found in {column}')
        return column
Exemple #6
0
    def ensure(cls, kind: 'Any') -> 'Any':
        """Ensure given kind is of our type.

        Args:
            kind: Kind to be verified.

        Returns:
            Original kind if instance of our type or raising otherwise.
        """
        if not cls.match(kind):
            raise error.Syntax(f'{kind} not an instance of a {cls.__name__}')
        return kind
Exemple #7
0
    def ensure_is(cls, column: 'Column') -> 'Column':
        """Ensure given column is of our type.

        Args:
            column: Column to be verified.

        Returns:
            Original column if instance of our type or raising otherwise.
        """
        column = cast(column)
        if not isinstance(column, cls):
            raise error.Syntax(f'{column} not an instance of a {cls.__name__}')
        return column
Exemple #8
0
    def ensure_is(cls: typing.Type[Operable], column: Operable) -> Operable:
        """Ensure given column is a predicate. Since this mixin class is supposed to be used as a first base class of
        its column implementors, this will mask the Column.ensure_is API. Here we add special implementation depending
        on whether it is used directly on the Predicate class or its bare mixin subclasses or the actual Column
        implementation using this mixin.

        Args:
            column: Column instance to be checked for its compliance.

        Returns:
            Column instance.
        """
        column = Operable.ensure_is(column)
        if cls is Predicate:  # bare Predicate - accept anything of a boolean kind.
            kindmod.Boolean.ensure(column.kind)
        elif not issubclass(cls, Column):  # bare Predicate mixin subclasses
            if not isinstance(column, cls):
                raise error.Syntax(f'{column} not an instance of a {cls.__name__}')
        else:  # defer to the column's .ensure_is implementation
            column = next(b for b in cls.__bases__ if issubclass(b, Column)).ensure_is(column)
        return column
Exemple #9
0
 def __init__(self, *operands: Operable):
     operands = [Operable.ensure_is(o) for o in operands]
     if not all(kindmod.Numeric.match(o.kind) for o in operands):
         raise error.Syntax(f'Invalid arithmetic operands for {self}')
Exemple #10
0
 def __init__(self, *operands: Operable):
     operands = [Operable.ensure_is(o) for o in operands]
     if not (
         all(kindmod.Numeric.match(o.kind) for o in operands) or all(o.kind == operands[0].kind for o in operands)
     ):
         raise error.Syntax(f'Invalid operands for {self} comparison')