Ejemplo n.º 1
0
def is_property_flat_field(obj: Union[list, Entity], property_name: str) -> bool:
    """Returns true if the attribute corresponding to |property_name| on the
     given object is a flat field (not a List, attr class, or ForwardRef)."""

    if not isinstance(obj, Entity) and not isinstance(obj, list):
        raise TypeError(f'Unexpected type [{type(obj)}]')

    attribute = attr.fields_dict(obj.__class__).get(property_name)

    if not attribute:
        raise ValueError(f'Unexpected None attribute for property_name [{property_name}] on obj [{obj}]')

    return not is_list(attribute) and not is_forward_ref(attribute)
Ejemplo n.º 2
0
 def schema_type_for_attribute(attribute: Any) -> str:
     # Race and ethnicity fields are the only ones that support list form. These
     # are converted to comma-separated lists stored as strings in BigQuery.
     if is_enum(attribute) or is_list(attribute) or is_str(attribute):
         return bigquery.enums.SqlTypeNames.STRING.value
     if is_int(attribute):
         return bigquery.enums.SqlTypeNames.INTEGER.value
     if is_float(attribute):
         return bigquery.enums.SqlTypeNames.FLOAT.value
     if is_date(attribute):
         return bigquery.enums.SqlTypeNames.DATE.value
     if is_bool(attribute):
         return bigquery.enums.SqlTypeNames.BOOLEAN.value
     raise ValueError(f"Unhandled attribute type for attribute: {attribute}")
Ejemplo n.º 3
0
def is_property_list(obj: Union[list, Entity], property_name: str) -> bool:
    """Returns true if the attribute corresponding to |property_name| on the
    given object is a List type."""

    if not isinstance(obj, Entity) and not isinstance(obj, list):
        raise TypeError(f"Unexpected type [{type(obj)}]")

    attribute = attr.fields_dict(obj.__class__).get(property_name)

    if not attribute:
        raise ValueError(
            f"Unexpected None attribute for property_name [{property_name}] on obj [{obj}]"
        )

    return is_list(attribute)
Ejemplo n.º 4
0
    def build_from_dictionary(cls, build_dict: Dict[str, Any]) -> \
            Optional['BuildableAttr']:
        """Builds a BuildableAttr with values from the given build_dict.

        Given build_dict must contain all required fields, and cannot contain
        any fields with attribute types of List or ForwardRef. Any date values
        must be in the format 'YYYY-MM-DD' if they are present.
        """
        if not attr.has(cls):
            raise Exception("Parent class must be an attr class")

        if not build_dict:
            raise ValueError("build_dict cannot be empty")

        cls_builder = cls.builder()

        for field, attribute in attr.fields_dict(cls).items():
            if field in build_dict:
                if is_list(attribute):
                    raise ValueError("build_dict should be a dictionary of "
                                     "flat values. Should not contain any "
                                     f"lists: {build_dict}.")
                if is_forward_ref(attribute):
                    # TODO(1886): Implement detection of non-ForwardRefs
                    # ForwardRef fields are expected to be references to other
                    # BuildableAttrs
                    raise ValueError("build_dict should be a dictionary of "
                                     "flat values. Should not contain any "
                                     f"ForwardRef fields: {build_dict}")

                if is_enum(attribute):
                    value = cls.extract_enum_value(build_dict, field,
                                                   attribute)
                elif is_date(attribute):
                    value = cls.extract_date_value(build_dict, field)
                else:
                    value = build_dict.get(field)

                setattr(cls_builder, field, value)

        return cls_builder.build()
Ejemplo n.º 5
0
    def convert_field_value(field: attr.Attribute,
                            field_value: Union[str, EnumParser]) -> Any:
        if field_value is None:
            return None

        if is_forward_ref(field) or is_list(field):
            return field_value

        if isinstance(field_value, str):
            if not field_value or not field_value.strip():
                return None

        if field.name in converter_overrides:
            converter = converter_overrides[field.name]
            if not isinstance(field_value, converter.field_type):
                raise ValueError(
                    f"Found converter for field [{field.name}] in the converter_overrides, but expected "
                    f"field type [{converter.field_type}] does not match actual field type "
                    f"[{type(field_value)}]")
            return converter.convert(field_value)

        if isinstance(field_value, EnumParser):
            if is_enum(field):
                return field_value.parse()
            raise ValueError(
                f"Found field value [{field_value}] for field that is not an enum [{field}]."
            )

        if isinstance(field_value, str):
            if is_str(field):
                return normalize(field_value)
            if is_date(field):
                return parse_date(field_value)
            if is_int(field):
                return parse_int(field_value)
            if field.type in {bool, Union[bool, None]}:
                return parse_bool(field_value)

        raise ValueError(f"Unsupported field {field.name}")