def test_settings() -> None: meta = meta_from_def(TestObjectWithSettings) assert len(meta.settings) == 6 assert meta.settings[0].name == "string" assert not meta.settings[0].children assert meta.settings[0].type == plugin_from_type(str).type_name() assert meta.settings[1].name == "integer" assert not meta.settings[1].children assert meta.settings[1].type == plugin_from_type(int).type_name() assert meta.settings[2].name == "boolean" assert not meta.settings[2].children assert meta.settings[2].type == plugin_from_type(bool).type_name() assert meta.settings[3].name == "double" assert not meta.settings[3].children assert meta.settings[3].type == plugin_from_type(float).type_name() assert meta.settings[4].name == "enum" assert not meta.settings[4].children assert meta.settings[4].type == plugin_from_type(StrEnum).type_name() assert meta.settings[5].name == "nested_settings" assert len(meta.settings[5].children) == 1 assert meta.settings[5].type == "dataclass" # TODO plugin for this? nested = meta.settings[5].children[0] assert nested.name == "boolean" assert not nested.children assert nested.type == plugin_from_type(bool).type_name()
def test_meta_from_def() -> None: meta = meta_from_def(TestObject) assert meta.type == TestObject.__name__ assert meta.description == "TestObject description." assert not meta.disabled assert not meta.abstract assert not meta.needs_parent_type assert not meta.settings assert meta.object_model is None assert not meta.built_in assert meta.base == GenericWithPose.__name__ assert meta.has_pose assert not meta.settings
async def get_object_data(object_types: ObjectTypeDict, obj_id: str) -> None: glob.logger.debug(f"Processing {obj_id}.") if obj_id in object_types: glob.logger.debug(f"{obj_id} already processed, skipping...") return obj = await storage.get_object_type(obj_id) if obj_id in glob.OBJECT_TYPES and glob.OBJECT_TYPES[obj_id].type_def is not None: stored_type_def = glob.OBJECT_TYPES[obj_id].type_def assert stored_type_def # TODO do not compare sources but 'modified` # the code we get from type_def has Unix line endings, while the code from Project service might have Windows... obj.source = convert_line_endings_to_unix(obj.source) if get_containing_module_sources(stored_type_def) == obj.source: glob.logger.debug(f"No need to update {obj_id}.") return try: bases = otu.base_from_source(obj.source, obj_id) if bases and bases[0] not in object_types.keys() | built_in_types_names(): glob.logger.debug(f"Getting base class {bases[0]} for {obj_id}.") await get_object_data(object_types, bases[0]) for mixin in bases[1:]: mixin_obj = await storage.get_object_type(mixin) await hlp.run_in_executor( hlp.save_and_import_type_def, mixin_obj.source, mixin_obj.id, object, settings.OBJECT_TYPE_PATH, settings.OBJECT_TYPE_MODULE, ) except Arcor2Exception as e: glob.logger.warn(f"Disabling object type {obj.id}: can't get a base. {str(e)}") object_types[obj_id] = ObjectTypeData( ObjectTypeMeta(obj_id, "Object type disabled.", disabled=True, problem="Can't get base.") ) return glob.logger.debug(f"Updating {obj_id}.") try: type_def = await hlp.run_in_executor( hlp.save_and_import_type_def, obj.source, obj.id, Generic, settings.OBJECT_TYPE_PATH, settings.OBJECT_TYPE_MODULE, ) except Arcor2Exception as e: glob.logger.debug(f"{obj.id} is probably not an object type. {str(e)}") return assert issubclass(type_def, Generic) try: meta = meta_from_def(type_def) otu.get_settings_def(type_def) # just to check if settings are ok except Arcor2Exception as e: glob.logger.warning(f"Disabling object type {obj.id}.") glob.logger.debug(e, exc_info=True) object_types[obj_id] = ObjectTypeData( ObjectTypeMeta(obj_id, "Object type disabled.", disabled=True, problem=str(e)) ) return if obj.model: try: model = await storage.get_model(obj.model.id, obj.model.type) except Arcor2Exception: glob.logger.error(f"{obj.model.id}: failed to get collision model of type {obj.model.type}.") meta.disabled = True meta.problem = "Can't get collision model." object_types[obj_id] = ObjectTypeData(meta) return kwargs = {model.type().value.lower(): model} meta.object_model = ObjectModel(model.type(), **kwargs) # type: ignore ast = parse(obj.source) otd = ObjectTypeData(meta, type_def, object_actions(type_def, ast), ast) object_types[obj_id] = otd
async def get_object_data(object_types: ObjectTypeDict, obj_id: str) -> None: logger.debug(f"Processing {obj_id}.") if obj_id in object_types: logger.debug(f"{obj_id} already processed, skipping...") return obj_iddesc = await storage.get_object_type_iddesc(obj_id) if obj_id in glob.OBJECT_TYPES: assert obj_iddesc.modified assert glob.OBJECT_TYPES[ obj_id].meta.modified, f"Object {obj_id} does not have 'modified' in its meta." if obj_iddesc.modified == glob.OBJECT_TYPES[obj_id].meta.modified: logger.debug(f"No need to update {obj_id}.") return obj = await storage.get_object_type(obj_id) try: bases = otu.base_from_source(obj.source, obj_id) if not bases: logger.debug( f"{obj_id} is definitely not an ObjectType (subclass of {object.__name__}), maybe mixin?" ) return if bases[0] not in object_types.keys() | built_in_types_names(): logger.debug(f"Getting base class {bases[0]} for {obj_id}.") await get_object_data(object_types, bases[0]) for mixin in bases[1:]: mixin_obj = await storage.get_object_type(mixin) await hlp.run_in_executor( hlp.save_and_import_type_def, mixin_obj.source, mixin_obj.id, object, settings.OBJECT_TYPE_PATH, settings.OBJECT_TYPE_MODULE, ) except Arcor2Exception as e: logger.error( f"Disabling ObjectType {obj.id}: can't get a base. {str(e)}") object_types[obj_id] = ObjectTypeData( ObjectTypeMeta(obj_id, "ObjectType disabled.", disabled=True, problem="Can't get base.", modified=obj.modified)) return logger.debug(f"Updating {obj_id}.") try: type_def = await hlp.run_in_executor( hlp.save_and_import_type_def, obj.source, obj.id, Generic, settings.OBJECT_TYPE_PATH, settings.OBJECT_TYPE_MODULE, ) except Arcor2Exception as e: logger.debug(f"{obj.id} is probably not an ObjectType. {str(e)}") return assert issubclass(type_def, Generic) try: meta = meta_from_def(type_def) except Arcor2Exception as e: logger.error(f"Disabling ObjectType {obj.id}.") logger.debug(e, exc_info=True) object_types[obj_id] = ObjectTypeData( ObjectTypeMeta(obj_id, "ObjectType disabled.", disabled=True, problem=str(e), modified=obj.modified)) return meta.modified = obj.modified if obj.model: try: model = await storage.get_model(obj.model.id, obj.model.type) except Arcor2Exception as e: logger.error( f"{obj.model.id}: failed to get collision model of type {obj.model.type}. {str(e)}" ) meta.disabled = True meta.problem = "Can't get collision model." object_types[obj_id] = ObjectTypeData(meta) return if isinstance(model, Mesh) and model.data_id not in await storage.files_ids(): logger.error( f"Disabling {meta.type} as its mesh file {model.data_id} does not exist." ) meta.disabled = True meta.problem = "Mesh file does not exist." object_types[obj_id] = ObjectTypeData(meta) return kwargs = {model.type().value.lower(): model} meta.object_model = ObjectModel(model.type(), **kwargs) # type: ignore ast = parse(obj.source) otd = ObjectTypeData(meta, type_def, object_actions(type_def, ast), ast) object_types[obj_id] = otd
async def get_object_data(object_types: ObjectTypeDict, obj_id: str) -> None: glob.logger.debug(f"Processing {obj_id}.") if obj_id in object_types: glob.logger.debug(f"{obj_id} already processed, skipping...") return obj = await storage.get_object_type(obj_id) if obj_id in glob.OBJECT_TYPES and glob.OBJECT_TYPES[ obj_id].type_def is not None: stored_type_def = glob.OBJECT_TYPES[obj_id].type_def assert stored_type_def if hash(get_containing_module_sources(stored_type_def)) == hash( obj.source): glob.logger.debug(f"No need to update {obj_id}.") return try: base = otu.base_from_source(obj.source, obj_id) if base and base not in object_types.keys() | built_in_types_names(): glob.logger.debug(f"Getting base class {base} for {obj_id}.") await get_object_data(object_types, base) except Arcor2Exception: object_types[obj_id] = ObjectTypeData( ObjectTypeMeta(obj_id, "Object type disabled.", disabled=True, problem="Can't get base.")) return glob.logger.debug(f"Updating {obj_id}.") try: type_def = await hlp.run_in_executor( hlp.save_and_import_type_def, obj.source, obj.id, Generic, settings.OBJECT_TYPE_PATH, settings.OBJECT_TYPE_MODULE, ) assert issubclass(type_def, Generic) meta = meta_from_def(type_def) otu.get_settings_def(type_def) # just to check if settings are ok except Arcor2Exception as e: glob.logger.warning(f"Disabling object type {obj.id}.") glob.logger.debug(e, exc_info=True) object_types[obj_id] = ObjectTypeData( ObjectTypeMeta(obj_id, "Object type disabled.", disabled=True, problem=str(e))) return if obj.model: try: model = await storage.get_model(obj.model.id, obj.model.type) except Arcor2Exception: glob.logger.error( f"{obj.model.id}: failed to get collision model of type {obj.model.type}." ) meta.disabled = True meta.problem = "Can't get collision model." object_types[obj_id] = ObjectTypeData(meta) return kwargs = {model.type().value.lower(): model} meta.object_model = ObjectModel(model.type(), **kwargs) # type: ignore ast = parse(obj.source) otd = ObjectTypeData(meta, type_def, object_actions(type_def, ast), ast) object_types[obj_id] = otd