예제 #1
0
    def parse(cls, filepath: str, filecontent: bytes, parser: Parser) -> "AddressMap":
        """Parses a source for addressable Serializable objects.

        No matter the parser used, the parsed and mapped addressable objects are all 'thin'; ie: any
        objects they point to in other namespaces or even in the same namespace but from a separate
        source are left as unresolved pointers.

        :param filepath: The path to the byte source containing serialized objects.
        :param filecontent: The content of byte source containing serialized objects to be parsed.
        :param parser: The parser cls to use.
        """
        try:
            objects = parser.parse(filepath, filecontent)
        except Exception as e:
            raise MappingError(f"Failed to parse {filepath}:\n{e!r}")
        objects_by_name: Dict[str, ThinAddressableObject] = {}
        for obj in objects:
            if not Serializable.is_serializable(obj):
                raise UnaddressableObjectError("Parsed a non-serializable object: {!r}".format(obj))
            attributes = obj._asdict()

            name = attributes.get("name")
            if not name:
                raise UnaddressableObjectError("Parsed a non-addressable object: {!r}".format(obj))

            if name in objects_by_name:
                raise DuplicateNameError(
                    "An object already exists at {!r} with name {!r}: {!r}.  Cannot "
                    "map {!r}".format(filepath, name, objects_by_name[name], obj)
                )
            objects_by_name[name] = obj
        return cls(filepath, dict(sorted(objects_by_name.items())))
예제 #2
0
 def __call__(self, *args, **kwargs):
     # Target names default to the name of the directory their BUILD file is in
     # (as long as it's not the root directory).
     if "name" not in kwargs:
         dirname = os.path.basename(self._parse_context.rel_path)
         if not dirname:
             raise UnaddressableObjectError(
                 "Targets in root-level BUILD files must be named explicitly."
             )
         kwargs["name"] = dirname
     kwargs.setdefault("type_alias", self._type_alias)
     target_adaptor = TargetAdaptor(**kwargs)
     self._parse_context._storage.add(target_adaptor)
     return target_adaptor
예제 #3
0
파일: parser.py 프로젝트: wiwa/pants
 def __call__(self, *args, **kwargs):
     # Target names default to the name of the directory their BUILD file is in
     # (as long as it's not the root directory).
     if "name" not in kwargs and issubclass(self._object_type, TargetAdaptor):
         dirname = os.path.basename(self._parse_context.rel_path)
         if dirname:
             kwargs["name"] = dirname
         else:
             raise UnaddressableObjectError(
                 "Targets in root-level BUILD files must be named explicitly."
             )
     name = kwargs.get("name")
     if name and self._serializable:
         kwargs.setdefault("type_alias", self._type_alias)
         obj = self._object_type(**kwargs)
         self._parse_context._storage.add(obj)
         return obj
     else:
         return self._object_type(*args, **kwargs)