Example #1
0
 def check(value):
     value = cast_value(attrib_def.code, value)
     if not attrib_def.is_valid_value(value):
         if attrib_def.fixer:
             value = attrib_def.fixer(value)
             logger.debug(f'Fixed invalid attribute "{key}" in entity'
                          f' {entity()} to "{str(value)}".')
         else:
             raise const.DXFValueError(
                 f'Invalid value {str(value)} for attribute "{key}" in '
                 f'entity {entity()}.')
     return value
Example #2
0
    def __setattr__(self, key: str, value: Any) -> None:
        attrib_def = self.dxfattribs.get(key, None)  # type: DXFAttr
        if attrib_def:
            if attrib_def.xtype == XType.callback:
                attrib_def.set_callback_value(self._entity, value)
            else:
                self.__dict__[key] = cast_value(attrib_def.code, value)
        else:
            raise DXFAttributeError(ERR_INVALID_DXF_ATTRIB.format(key, self.dxftype))

        if key in SETTER_EVENTS:
            handler = getattr(self._entity, SETTER_EVENTS[key], None)
            if handler:
                handler(value)
Example #3
0
    def fast_load_dxfattribs(self,
                             dxf: DXFNamespace,
                             group_code_mapping: Dict[int, Union[str, List]],
                             subclass: Union[int, str, Tags],
                             *,
                             recover=False,
                             log=True) -> Tags:
        """ Load DXF attributes into the DXF namespace and returns the
        unprocessed tags without leading subclass marker(100, AcDb...).
        Bypasses the DXF attribute validity checks.

        Args:
            dxf: entity DXF namespace
            group_code_mapping: group code to DXF attribute name mapping,
                callback attributes have to be marked with a leading "*"
            subclass: subclass by index, by name or as Tags()
            recover: recover graphic attributes
            log: enable/disable logging of unprocessed tags

        """
        if self.r12:
            tags = self.subclasses[0]
        else:
            if isinstance(subclass, int):
                tags = self.subclass_by_index(subclass)
            elif isinstance(subclass, str):
                tags = self.find_subclass(subclass)
            else:
                tags = subclass

        unprocessed_tags = Tags()
        if tags is None or len(tags) == 0:
            return unprocessed_tags

        processed_names = set()
        # Localize attributes:
        get_attrib_name = group_code_mapping.get
        append_unprocessed_tag = unprocessed_tags.append
        unprotected_set_attrib = dxf.unprotected_set
        mark_attrib_as_processed = processed_names.add

        # Ignore (100, "AcDb...") or (0, "ENTITY") tag in case of DXF R12
        start = 1 if tags[0].code in (0, 100) else 0
        for tag in tags[start:]:
            name = get_attrib_name(tag.code)
            if isinstance(name, list):  # process group code duplicates:
                names = name
                # If all existing attrib names are used, treat this tag
                # like an unprocessed tag.
                name = None
                # The attribute names are processed in the order of their
                # definition:
                for name_ in names:
                    if name_ not in processed_names:
                        name = name_
                        mark_attrib_as_processed(name_)
                        break
            if name:
                # Ignore callback attributes and group codes explicit marked
                # as "*IGNORE":
                if name[0] != '*':
                    unprotected_set_attrib(name,
                                           cast_value(tag.code, tag.value))
            else:
                append_unprocessed_tag(tag)

        if self.r12:
            # R12 has always unprocessed tags, because there are all tags in one
            # subclass and one subclass definition never covers all tags e.g.
            # handle is processed in DXFEntity, so it is an unprocessed tag in
            # AcDbEntity.
            return unprocessed_tags

        # Only DXF R13+
        if recover and len(unprocessed_tags):
            unprocessed_tags = recover_graphic_attributes(
                unprocessed_tags, dxf)
        if len(unprocessed_tags) and log:
            # First tag is the subclass specifier (100, "AcDb...")
            name = tags[0].value
            self.log_unprocessed_tags(tags,
                                      subclass=name,
                                      handle=dxf.get('handle'))
        return unprocessed_tags