Beispiel #1
0
    def __post_init__(self):

        if not isinstance(self.validation, ValidationModes):
            self.validation = ValidationModes.from_string(self.validation)

        self.env_keys = ensure_iterable(self.env_keys,
                                        coercion=tuple,
                                        force_coerce=True)
        self.command_line_args = ensure_iterable(self.command_line_args,
                                                 coercion=tuple,
                                                 force_coerce=True)

        for cli_arg in DEFAULT_CMD_LINE_ARGS:
            if cli_arg not in self.command_line_args:
                self.command_line_args = self.command_line_args + (cli_arg, )
Beispiel #2
0
    def _initialization_kwargs(self, **overrides):
        """
        If an empty list is passed in for the styles, or None, we assume the
        user wants to remove the styles.  Otherwise, styles are applied on
        top of the currenet styles.  We also allow styles to be explicitly
        specified as True or False.
        """
        data = copy.deepcopy(self.__dict__)
        for key, val in overrides.items():

            if Style.supported(key):
                if val is True:
                    data['styles'].add_style(key, strict=False)
                elif val is False:
                    data['styles'].remove_style(key, strict=False)
                else:
                    raise ValueError(
                        f'{key} must be speceified as True or False')

            # Have to Set Union of Styles
            elif key == 'styles':
                if val is None or val == []:
                    data['styles'] = Style()
                else:
                    styles = ensure_iterable(val)
                    for style in styles:
                        data['styles'].add_style(style, strict=False)

            # Treat style the same way
            elif key == 'style':
                if val is None or val == []:
                    data['styles'] = Style()
                else:
                    styles = ensure_iterable(val)
                    for style in styles:
                        data['styles'].add_style(style, strict=False)

            else:
                if key not in data:
                    raise FormatError(f'Invalid format attribute {key}.')
                data[key] = val
        return data
Beispiel #3
0
    def __post_init__(self, style, depth):

        FormatDataClass.__post_init__(self)

        if self.color and not isinstance(self.color, Color):
            self.color = Color(self.color, depth=depth)

        if self.highlight and not isinstance(self.highlight, Color):
            self.highlight = Highlight(self.highlight, depth=depth)

        if style and not self.styles:
            if isinstance(style, Style):
                self.styles = Style
            else:
                self.styles = ensure_iterable(style,
                                              coercion=tuple,
                                              force_coerce=True)

        if not isinstance(self.styles, Style):
            self.styles = self.styles or []
            self.styles = ensure_iterable(self.styles,
                                          coercion=tuple,
                                          force_coerce=True)
            self.styles = Style(*self.styles)
Beispiel #4
0
    def _validate_element_key(self, k):
        """
        [x] TODO:
        --------
        Differentiate between expected types of fields vs. values in the
        FieldConfigurationError instantiations.
        """
        tp = self._keys.get('type') or self._keys.get('types')
        if tp:
            types = ensure_iterable(tp, coercion=tuple, force_coerce=True)
            if not isinstance(k, types):
                raise FieldConfigurationError.ExpectedType(k, *types)

        allowed = self._keys.get('allowed')
        if allowed:
            if k not in allowed:
                raise FieldConfigurationError.DisallowedKey(key=k)
Beispiel #5
0
    def get_ansi_codes(cls, value, depth=None):
        if isinstance(value, cls):
            return value._ansi_codes

        # This block can hit a circular import when initializing a color from
        # settings if the color depth is not directly passed in.
        elif isinstance(value, str):
            return cls.get_ansi_codes_for_color_string(value, depth=depth)

        elif isinstance(value, (tuple, list)):
            if any([not isinstance(v, int) for v in value]):
                raise InvalidColor(value)
            return value

        elif isinstance(value, int):
            return ensure_iterable(value, coercion=list, force_coerce=True)

        else:
            raise InvalidColor(value)
Beispiel #6
0
    def get_ansi_codes_for_color_string(cls, color, depth=None):
        """
        Returns the ANSI related codes for a given color string.  The color
        string can be specified as HEX value, a simple color string like `blue`
        or `green`, or more complicated color strings supported by Pllumbum.

        [x] TODO:
        --------
        Add support for other forms of specification, like RGBA.
        """
        try:
            cl = cls.plumbum_operator(color)
        except plumbum.colorlib.styles.ColorNotFound:
            raise InvalidColor(color)
        else:
            # This block can hit a circular import when initializing a color from
            # settings if the color depth is not directly passed in.
            if not depth:
                from termx.config import settings
                depth = settings.COLOR_DEPTH

            codes = cls.get_ansi_codes_for_color_depth(cl, depth)
            return ensure_iterable(codes, coercion=list, force_coerce=True)
Beispiel #7
0
def get_record_attribute(record, params):
    """
    Given an "attribute" set as `params` and a record, finds the value for
    each attr in the set, returning the first non-null value on the record.

    The parameter `params` can be an iterable or a single string, and can
    reference nested or top level dictionary/object attributes separated
    by '.'.

    >>> record = {'child': {'grandchild': {'age': 10}}, 'name': 'Jack'}
    >>> get_record_attribute(record, ['child.grandchild.name', 'child.name'])
    >>> 'Jack'
    """
    # TODO: Need to catch more singletons here.
    params = ensure_iterable(params)
    params = ["%s" % param for param in params]

    # Here, each param can be something like "context.index", or "index"
    # Higher priority is given to less deeply nested versions.
    for param in params:
        value = get_obj_attribute(record, param)
        if value is not None:
            return value
    return None
Beispiel #8
0
 def __init__(self, *args):
     self._styles = self._set_styles(
         ensure_iterable(args, coercion=tuple, force_coerce=True))