From b183708bfe43a4d18215f77514bd5368f8120e4a Mon Sep 17 00:00:00 2001 From: Isaac To Date: Thu, 19 Sep 2024 18:01:55 -0700 Subject: [PATCH] Replace use of the root logger with use of module-level logger --- linkml_runtime/dumpers/rdflib_dumper.py | 10 ++- linkml_runtime/index/object_index.py | 4 +- linkml_runtime/loaders/json_loader.py | 5 +- linkml_runtime/loaders/rdflib_loader.py | 29 ++++---- linkml_runtime/utils/csvutils.py | 7 +- linkml_runtime/utils/distroutils.py | 5 +- linkml_runtime/utils/inference_utils.py | 9 ++- linkml_runtime/utils/ruleutils.py | 6 +- linkml_runtime/utils/schemaview.py | 4 +- linkml_runtime/utils/schemaview_cli.py | 15 ++-- .../test_linkml_runtime_issue_68.py | 11 ++- .../test_csv_tsv_loader_dumper.py | 30 ++++---- .../test_loaders_dumpers.py | 9 ++- .../test_rdflib_dumper.py | 9 ++- tests/test_utils/test_schema_as_dict.py | 4 +- tests/test_utils/test_schemaview.py | 74 ++++++++++--------- 16 files changed, 134 insertions(+), 97 deletions(-) diff --git a/linkml_runtime/dumpers/rdflib_dumper.py b/linkml_runtime/dumpers/rdflib_dumper.py index 976a928f..4a3d1864 100644 --- a/linkml_runtime/dumpers/rdflib_dumper.py +++ b/linkml_runtime/dumpers/rdflib_dumper.py @@ -15,6 +15,8 @@ from linkml_runtime.utils.schemaview import SchemaView, ElementName, PermissibleValue, PermissibleValueText from linkml_runtime.utils.yamlutils import YAMLRoot +logger = logging.getLogger(__name__) + class RDFLibDumper(Dumper): """ @@ -44,7 +46,7 @@ def as_rdf_graph( if isinstance(prefix_map, Converter): # TODO replace with `prefix_map = prefix_map.bimap` after making minimum requirement on python 3.8 prefix_map = {record.prefix: record.uri_prefix for record in prefix_map.records} - logging.debug(f'PREFIXMAP={prefix_map}') + logger.debug(f'PREFIXMAP={prefix_map}') if prefix_map: for k, v in prefix_map.items(): if k == "@base": @@ -80,7 +82,7 @@ def inject_triples(self, element: Any, schemaview: SchemaView, graph: Graph, tar """ namespaces = schemaview.namespaces() slot_name_map = schemaview.slot_name_mappings() - logging.debug(f'CONVERT: {element} // {type(element)} // {target_type}') + logger.debug(f'CONVERT: {element} // {type(element)} // {target_type}') if target_type in schemaview.all_enums(): if isinstance(element, PermissibleValueText): e = schemaview.get_enum(target_type) @@ -105,7 +107,7 @@ def inject_triples(self, element: Any, schemaview: SchemaView, graph: Graph, tar namespaces["xsd"] = XSD return Literal(element, datatype=namespaces.uri_for(dt_uri)) else: - logging.warning(f'No datatype specified for : {t.name}, using plain Literal') + logger.warning(f'No datatype specified for : {t.name}, using plain Literal') return Literal(element) element_vars = {k: v for k, v in vars(element).items() if not k.startswith('_')} if len(element_vars) == 0: @@ -134,7 +136,7 @@ def inject_triples(self, element: Any, schemaview: SchemaView, graph: Graph, tar if k in slot_name_map: k = slot_name_map[k].name else: - logging.error(f'Slot {k} not in name map') + logger.error(f'Slot {k} not in name map') slot = schemaview.induced_slot(k, cn) if not slot.identifier: slot_uri = URIRef(schemaview.get_uri(slot, expand=True)) diff --git a/linkml_runtime/index/object_index.py b/linkml_runtime/index/object_index.py index 5178a5aa..56c7cbe3 100644 --- a/linkml_runtime/index/object_index.py +++ b/linkml_runtime/index/object_index.py @@ -16,6 +16,8 @@ from linkml_runtime.utils import eval_utils from linkml_runtime.utils.yamlutils import YAMLRoot +logger = logging.getLogger(__name__) + class ObjectIndex: """ @@ -257,7 +259,7 @@ def _map(self, obj: Any, in_range: str) -> Any: module = inspect.getmodule(self._shadowed) cls_dict = dict(inspect.getmembers(module, inspect.isclass)) if in_range not in cls_dict: - logging.warning(f"Class {in_range} not found in {module}, classes: {cls_dict}") + logger.warning(f"Class {in_range} not found in {module}, classes: {cls_dict}") return obj cls = cls_dict[in_range] return cls(obj) diff --git a/linkml_runtime/loaders/json_loader.py b/linkml_runtime/loaders/json_loader.py index 0d7f58b1..5d4d94cf 100644 --- a/linkml_runtime/loaders/json_loader.py +++ b/linkml_runtime/loaders/json_loader.py @@ -8,6 +8,9 @@ from linkml_runtime.utils.yamlutils import YAMLRoot from pydantic import BaseModel +logger = logging.getLogger(__name__) + + class JSONLoader(Loader): def load_as_dict(self, @@ -31,6 +34,6 @@ def load_any(self, if isinstance(data_as_dict, dict): typ = data_as_dict.pop('@type', None) if typ and typ != target_class.__name__: - logging.warning(f"Warning: input type mismatch. Expected: {target_class.__name__}, Actual: {typ}") + logger.warning(f"Warning: input type mismatch. Expected: {target_class.__name__}, Actual: {typ}") return self._construct_target_class(data_as_dict, target_class) diff --git a/linkml_runtime/loaders/rdflib_loader.py b/linkml_runtime/loaders/rdflib_loader.py index e26d3707..84e98d61 100644 --- a/linkml_runtime/loaders/rdflib_loader.py +++ b/linkml_runtime/loaders/rdflib_loader.py @@ -18,6 +18,9 @@ from linkml_runtime.utils.yamlutils import YAMLRoot from pydantic import BaseModel +logger = logging.getLogger(__name__) + + VALID_SUBJECT = Union[URIRef, BNode] ANYDICT = Dict[str, Any] @@ -60,7 +63,7 @@ def from_rdf_graph( if c2.name in schemaview.class_ancestors(cn): continue else: - logging.error(f'Inconsistent URI to class map: {uri} -> {c2.name}, {c.name}') + logger.error(f'Inconsistent URI to class map: {uri} -> {c2.name}, {c.name}') uri_to_class_map[uri] = c # data prefix map: supplements or overrides existing schema prefix map if isinstance(prefix_map, Converter): @@ -74,7 +77,7 @@ def from_rdf_graph( target_class_uriref: URIRef = target_class.class_class_uri root_dicts: List[ANYDICT] = [] root_subjects: List[VALID_SUBJECT] = list(graph.subjects(RDF.type, target_class_uriref)) - logging.debug(f'ROOTS = {root_subjects}') + logger.debug(f'ROOTS = {root_subjects}') # Step 2: walk RDF graph starting from root subjects, constructing dict tree node_tuples_to_visit: List[Tuple[VALID_SUBJECT, ClassDefinitionName]] ## nodes and their type still to visit node_tuples_to_visit = [(subject, target_class.class_name) for subject in root_subjects] @@ -101,14 +104,14 @@ def from_rdf_graph( type_classes = [uri_to_class_map[str(x)] for x in type_vals] if len(type_classes) > 1: raise ValueError(f'Ambiguous types for {subject} == {type_classes}') - logging.info(f'Replacing {subject_class} with {type_classes}') + logger.info(f'Replacing {subject_class} with {type_classes}') subject_class = type_classes[0].name # process all triples for this node for (_, p, o) in graph.triples((subject, None, None)): processed_triples.add((subject,p,o)) - logging.debug(f' Processing triple {subject} {p} {o}, subject type = {subject_class}') + logger.debug(f' Processing triple {subject} {p} {o}, subject type = {subject_class}') if p == RDF.type: - logging.debug(f'Ignoring RDF.type for {subject} {o}, we automatically infer this from {subject_class}') + logger.debug(f'Ignoring RDF.type for {subject} {o}, we automatically infer this from {subject_class}') elif p not in uri_to_slot: if ignore_unmapped_predicates: unmapped_predicates.add(p) @@ -121,13 +124,13 @@ def from_rdf_graph( slot_name = underscore(slot.name) if isinstance(o, Literal): if EnumDefinition.class_name in range_applicable_elements: - logging.debug(f'Assuming no meaning assigned for value {o} for Enum {slot.range}') + logger.debug(f'Assuming no meaning assigned for value {o} for Enum {slot.range}') elif TypeDefinition.class_name not in range_applicable_elements: raise ValueError(f'Cannot map Literal {o} to a slot {slot.name} whose range {slot.range} is not a type;') v = o.value elif isinstance(o, BNode): if not is_inlined: - logging.error(f'blank nodes should be inlined; {slot_name}={o} in {subject}') + logger.error(f'blank nodes should be inlined; {slot_name}={o} in {subject}') v = Pointer(o) else: if ClassDefinition.class_name in range_applicable_elements: @@ -137,7 +140,7 @@ def from_rdf_graph( else: v = namespaces.curie_for(o) if v is None: - logging.debug(f'No CURIE for {p}={o} in {subject} [{subject_class}]') + logger.debug(f'No CURIE for {p}={o} in {subject} [{subject_class}]') v = str(o) elif EnumDefinition.class_name in range_applicable_elements: range_union_elements = schemaview.slot_range_as_union(slot) @@ -156,7 +159,7 @@ def from_rdf_graph( v = namespaces.curie_for(o) if v is None: v = str(o) - logging.debug(f'Casting {o} to string') + logger.debug(f'Casting {o} to string') else: raise ValueError(f'Expected literal value ({range_applicable_elements}) for {slot_name}={o}') if is_inlined: @@ -175,13 +178,13 @@ def from_rdf_graph( if slot.range in schemaview.all_classes(): node_tuples_to_visit.append((o, ClassDefinitionName(slot.range))) if unmapped_predicates: - logging.info(f'Unmapped predicated: {unmapped_predicates}') + logger.info(f'Unmapped predicated: {unmapped_predicates}') unprocessed_triples = set(graph.triples((None, None, None))) - processed_triples - logging.info(f'Triple processed = {len(processed_triples)}, unprocessed = {len(unprocessed_triples)}') + logger.info(f'Triple processed = {len(processed_triples)}, unprocessed = {len(unprocessed_triples)}') if len(unprocessed_triples) > 0: if not allow_unprocessed_triples: for t in unprocessed_triples: - logging.warning(f' Unprocessed: {t}') + logger.warning(f' Unprocessed: {t}') raise ValueError(f'Unprocessed triples: {len(unprocessed_triples)}') # Step 2: replace inline pointers with object dicts def repl(v): @@ -195,7 +198,7 @@ def repl(v): objs_to_visit: List[ANYDICT] = copy(root_dicts) while len(objs_to_visit) > 0: obj = objs_to_visit.pop() - logging.debug(f'Replacing pointers for {obj}') + logger.debug(f'Replacing pointers for {obj}') for k, v in obj.items(): if v is None: continue diff --git a/linkml_runtime/utils/csvutils.py b/linkml_runtime/utils/csvutils.py index 36fa11eb..f233f2ae 100644 --- a/linkml_runtime/utils/csvutils.py +++ b/linkml_runtime/utils/csvutils.py @@ -5,6 +5,9 @@ SlotDefinition, ClassDefinition, ClassDefinitionName from linkml_runtime.utils.schemaview import SchemaView +logger = logging.getLogger(__name__) + + def get_configmap(schemaview: SchemaView, index_slot: SlotDefinitionName) -> CONFIGMAP: """ Generates a configuration that specifies mapping between a CSV and a JSON structure @@ -28,9 +31,9 @@ def get_configmap(schemaview: SchemaView, index_slot: SlotDefinitionName) -> CON cm[sn] = config return cm else: - logging.warning(f'Index slot range not to class: {slot.range}') + logger.warning(f'Index slot range not to class: {slot.range}') else: - logging.warning(f'Index slot or schema not specified') + logger.warning(f'Index slot or schema not specified') return {} def _get_key_config(schemaview: SchemaView, tgt_cls: ClassDefinitionName, sn: SlotDefinitionName, sep='_'): diff --git a/linkml_runtime/utils/distroutils.py b/linkml_runtime/utils/distroutils.py index 61a34a92..d7986fe4 100644 --- a/linkml_runtime/utils/distroutils.py +++ b/linkml_runtime/utils/distroutils.py @@ -6,6 +6,7 @@ from pathlib import PurePath from typing import List, Type +logger = logging.getLogger(__name__) def get_default_paths(file_type: str) -> List[PurePath]: @@ -41,7 +42,7 @@ def get_default_paths(file_type: str) -> List[PurePath]: paths.append(rel_dir) # YAML files may be in the same directory as the python paths.append(PurePath('.')) - logging.debug(f"Paths to search: {paths}") + logger.debug(f"Paths to search: {paths}") return paths def get_packaged_file_as_str(package: str, file_type: str, rel_paths: List[PurePath]=[], encoding="utf-8") -> str: @@ -65,7 +66,7 @@ def get_packaged_file_as_str(package: str, file_type: str, rel_paths: List[PureP if data: break except FileNotFoundError: - logging.debug(f'candidate {path} not found') + logger.debug(f'candidate {path} not found') if not data: raise FileNotFoundError(f'package: {package} file: {file_type}') return data.decode(encoding) diff --git a/linkml_runtime/utils/inference_utils.py b/linkml_runtime/utils/inference_utils.py index 858f5b1d..ea554529 100644 --- a/linkml_runtime/utils/inference_utils.py +++ b/linkml_runtime/utils/inference_utils.py @@ -11,6 +11,9 @@ from linkml_runtime.utils.walker_utils import traverse_object_tree from linkml_runtime.utils.yamlutils import YAMLRoot +logger = logging.getLogger(__name__) + + RESOLVE_FUNC = Callable[[str, Any], Any] def obj_as_dict_nonrecursive(obj: YAMLRoot, resolve_function: RESOLVE_FUNC = None) -> Dict[str, Any]: @@ -73,7 +76,7 @@ def generate_slot_value(obj: YAMLRoot, slot_name: Union[str, SlotDefinitionName] mapped_slot = schemaview.slot_name_mappings()[slot_name] slot_name = mapped_slot.name slot = schemaview.induced_slot(slot_name, class_name) - logging.debug(f' CONF={config}') + logger.debug(f' CONF={config}') if config.use_string_serialization: if slot.string_serialization: if isinstance(obj, JsonObj): @@ -106,7 +109,7 @@ def infer_slot_value(obj: YAMLRoot, slot_name: Union[str, SlotDefinitionName], s if v is not None and policy == Policy.KEEP: return v new_v = generate_slot_value(obj, slot_name, schemaview, class_name=class_name, config=config) - logging.debug(f'SETTING {slot_name} = {new_v} // current={v}, {policy}') + logger.debug(f'SETTING {slot_name} = {new_v} // current={v}, {policy}') if new_v: # check if new value is different; not str check is necessary as enums may not be converted if v is not None and new_v != v and str(new_v) != str(v): @@ -138,7 +141,7 @@ def infer_all_slot_values(obj: YAMLRoot, schemaview: SchemaView, :return: """ def infer(in_obj: YAMLRoot): - logging.debug(f'INFER={in_obj}') + logger.debug(f'INFER={in_obj}') if isinstance(in_obj, YAMLRoot) and not isinstance(in_obj, EnumDefinitionImpl) and not isinstance(in_obj, PermissibleValue): for k, v in vars(in_obj).items(): #print(f' ISV={k} curr={v} policy={policy} in_obj={type(in_obj)}') diff --git a/linkml_runtime/utils/ruleutils.py b/linkml_runtime/utils/ruleutils.py index 36b379f8..2f1f664d 100644 --- a/linkml_runtime/utils/ruleutils.py +++ b/linkml_runtime/utils/ruleutils.py @@ -6,6 +6,8 @@ from linkml_runtime.linkml_model.meta import SchemaDefinition, ClassDefinition, SlotDefinition, Expression, \ ClassExpression, ClassDefinitionName, ClassRule, AnonymousClassExpression, SlotExpression, SlotDefinitionName +logger = logging.getLogger(__name__) + class AtomicClassExpression: """ @@ -58,12 +60,12 @@ def get_range_as_disjunction(slot: SlotExpression) -> Set[ClassDefinitionName]: if isinstance(slot.range_expression, ClassExpression): conjs.append(get_disjunction(slot.range_expression)) else: - logging.warning(f'Expected range_expression for {slot.name} to be a class expression, not {type(slot.range_expression)}') + logger.warning(f'Expected range_expression for {slot.name} to be a class expression, not {type(slot.range_expression)}') if len(conjs) == 0: if slot.range: conjs.append({slot.range}) else: - logging.warning(f'No range for {slot.name}') + logger.warning(f'No range for {slot.name}') if len(conjs) > 1: raise Exception(f'Cannot determine range disjunction for {slot}, got conjunctions: {conjs}') if len(conjs) == 0: diff --git a/linkml_runtime/utils/schemaview.py b/linkml_runtime/utils/schemaview.py index 0a4ce77b..1bc97f1e 100644 --- a/linkml_runtime/utils/schemaview.py +++ b/linkml_runtime/utils/schemaview.py @@ -224,7 +224,7 @@ def load_import(self, imp: str, from_schema: SchemaDefinition = None): base_dir = os.path.dirname(from_schema.source_file) else: base_dir = None - logging.info(f'Importing {imp} as {sname} from source {from_schema.source_file}; base_dir={base_dir}') + logger.info(f'Importing {imp} as {sname} from source {from_schema.source_file}; base_dir={base_dir}') schema = load_schema_wrap(sname + '.yaml', base_dir=base_dir) return schema @@ -1403,7 +1403,7 @@ def induced_slot(self, slot_name: SLOT_NAME, class_name: CLASS_NAME = None, impo # ) if not is_empty(v2): v = v2 - logging.debug(f'{v} takes precedence over {v2} for {induced_slot.name}.{metaslot_name}') + logger.debug(f'{v} takes precedence over {v2} for {induced_slot.name}.{metaslot_name}') if v is None: if metaslot_name == 'range': v = self.schema.default_range diff --git a/linkml_runtime/utils/schemaview_cli.py b/linkml_runtime/utils/schemaview_cli.py index d9ba47eb..7d4a862e 100644 --- a/linkml_runtime/utils/schemaview_cli.py +++ b/linkml_runtime/utils/schemaview_cli.py @@ -13,6 +13,9 @@ import click import yaml +logger = logging.getLogger(__name__) + + DEFAULT_DISPLAY_COLS = [ 'name', 'is_a', @@ -58,8 +61,8 @@ def list(schema, columns, element_type): """ schema_view = SchemaView(schema) - logging.info(f'id={schema_view.schema.id}') - logging.info(f'name={schema_view.schema.name}') + logger.info(f'id={schema_view.schema.id}') + logger.info(f'name={schema_view.schema.name}') enames = schema_view.all_element() elements = [schema_view.get_element(ename) for ename in enames] if element_type is not None: @@ -79,7 +82,7 @@ def islot(schema, columns, class_names): """ schema_view = SchemaView(schema) for cn in class_names: - logging.info(f'Class: {cn}') + logger.info(f'Class: {cn}') islots = schema_view.class_induced_slots(cn) _show_elements(islots, columns=columns) @@ -97,7 +100,7 @@ def ancs(schema, class_names, is_a, mixins): """ schema_view = SchemaView(schema) for cn in class_names: - logging.info(f'Class: {cn}') + logger.info(f'Class: {cn}') ancs = schema_view.class_ancestors(cn, is_a=is_a, mixins=mixins) for a in ancs: print(f'{cn}\t{a}') @@ -116,7 +119,7 @@ def descs(schema, class_names, is_a, mixins): """ schema_view = SchemaView(schema) for cn in class_names: - logging.info(f'Class: {cn}') + logger.info(f'Class: {cn}') ds = schema_view.class_descendants(cn, is_a=is_a, mixins=mixins) for d in ds: print(f'{cn}\t{d}') @@ -130,7 +133,7 @@ def delete(schema, class_names): """ schema_view = SchemaView(schema) for cn in class_names: - logging.info(f'Class: {cn}') + logger.info(f'Class: {cn}') schema_view.delete_class(cn) print(yaml_dumper.dumps(schema_view.schema)) diff --git a/tests/test_issues/test_linkml_runtime_issue_68.py b/tests/test_issues/test_linkml_runtime_issue_68.py index c58fcb6a..859bbb27 100644 --- a/tests/test_issues/test_linkml_runtime_issue_68.py +++ b/tests/test_issues/test_linkml_runtime_issue_68.py @@ -3,6 +3,9 @@ from unittest import TestCase from linkml_runtime.utils.schemaview import SchemaView +logger = logging.getLogger(__name__) + + schema_str = """ id: https://example.com/test-induced name: test-induced @@ -91,12 +94,12 @@ def test_issue_68(self): # test description for slot2 # this behavior is expected see: https://github.com/linkml/linkml-runtime/issues/68 - logging.info(f"s2_induced.description: {s2_induced.description}") + logger.info(f"s2_induced.description: {s2_induced.description}") assert s2_induced.description == "induced slot2" s2_induced_c2 = view.induced_slot('slot2', 'class2') assert s2_induced_c2.required - logging.info(f"s2_induced_c2.description: {s2_induced_c2.description}") + logger.info(f"s2_induced_c2.description: {s2_induced_c2.description}") assert s2_induced_c2.description == "induced slot2" assert s2_induced.range == 'class1' @@ -109,13 +112,13 @@ def test_issue_68(self): # mixins specified in order of priority s2_induced_c2_1a = view.induced_slot('slot2', 'class2_1a') assert not s2_induced_c2_1a.required - logging.info(f"s2_induced_c2_1a.description: {s2_induced_c2_1a.description}") + logger.info(f"s2_induced_c2_1a.description: {s2_induced_c2_1a.description}") assert s2_induced_c2_1a.description == "mixin slot2" assert s2_induced_c2_1a.range == 'mixin1a' s2_induced_c2_1b = view.induced_slot('slot2', 'class2_1b') assert not s2_induced_c2_1b.required - logging.info(f"s2_induced_c2_1a.description: {s2_induced_c2_1b.description}") + logger.info(f"s2_induced_c2_1a.description: {s2_induced_c2_1b.description}") assert s2_induced_c2_1b.description == "mixin slot2" assert s2_induced_c2_1b.range == 'mixin1b' diff --git a/tests/test_loaders_dumpers/test_csv_tsv_loader_dumper.py b/tests/test_loaders_dumpers/test_csv_tsv_loader_dumper.py index f13de9c6..80dc5a5d 100644 --- a/tests/test_loaders_dumpers/test_csv_tsv_loader_dumper.py +++ b/tests/test_loaders_dumpers/test_csv_tsv_loader_dumper.py @@ -14,6 +14,8 @@ from linkml_runtime.utils.yamlutils import as_json_object from tests.test_loaders_dumpers.models.books_normalized import Author, Review, Shop, Book, GenreEnum, BookSeries +logger = logging.getLogger(__name__) + ROOT = os.path.abspath(os.path.dirname(__file__)) INPUT_DIR = os.path.join(ROOT, 'input') @@ -34,7 +36,7 @@ class CsvAndTsvGenTestCase(unittest.TestCase): def test_object_model(self): book = Book(id='B1', genres=['fantasy'], creator={}) - logging.debug(as_json_obj(book.genres[0])) + logger.debug(as_json_obj(book.genres[0])) assert str(book.genres[0]) == 'fantasy' assert book.genres[0].code.text == 'fantasy' processed = remove_empty_items(book.genres) @@ -57,9 +59,9 @@ def test_csvgen_roundtrip(self): data = yaml_loader.load(DATA, target_class=Shop) csv_dumper.dump(data, to_file=OUTPUT, index_slot='all_book_series', schemaview=schemaview) roundtrip = csv_loader.load(OUTPUT, target_class=Shop, index_slot='all_book_series', schemaview=schemaview) - logging.debug(json_dumper.dumps(roundtrip)) - logging.debug(f'COMPARE 1: {roundtrip}') - logging.debug(f'COMPARE 2: {data}') + logger.debug(json_dumper.dumps(roundtrip)) + logger.debug(f'COMPARE 1: {roundtrip}') + logger.debug(f'COMPARE 2: {data}') assert roundtrip == data def test_csvgen_roundtrip_to_dict(self): @@ -87,24 +89,24 @@ def test_csvgen_unroundtrippable(self): schemaview = SchemaView(SCHEMA) #schema = YAMLGenerator(SCHEMA).schema data = yaml_loader.load(DATA2, target_class=Shop) - logging.debug(data.all_book_series[0]) - logging.debug(data.all_book_series[0].genres[0]) + logger.debug(data.all_book_series[0]) + logger.debug(data.all_book_series[0].genres[0]) assert str(data.all_book_series[0].genres[0]) == 'fantasy' - logging.debug(yaml_dumper.dumps(data)) - logging.debug(json_dumper.dumps(data)) + logger.debug(yaml_dumper.dumps(data)) + logger.debug(json_dumper.dumps(data)) processed = remove_empty_items(data) - logging.debug(f'PROC {processed["all_book_series"]}') + logger.debug(f'PROC {processed["all_book_series"]}') asj = as_json_object(processed, None) - logging.debug(f'ASJ {asj["all_book_series"]}') + logger.debug(f'ASJ {asj["all_book_series"]}') reconstituted_json = json.loads(json_dumper.dumps(data)) s0 = reconstituted_json['all_book_series'][0] - logging.debug(s0) - logging.debug(json_dumper.dumps(data)) - #logging.debug(csv_dumper.dumps(data, index_slot='all_book_series', schema=schema)) + logger.debug(s0) + logger.debug(json_dumper.dumps(data)) + #logger.debug(csv_dumper.dumps(data, index_slot='all_book_series', schema=schema)) csv_dumper.dump(data, to_file=OUTPUT2, index_slot='all_book_series', schemaview=schemaview) #assert False roundtrip = csv_loader.load(OUTPUT2, target_class=Shop, index_slot='all_book_series', schemaview=schemaview) - logging.debug(json_dumper.dumps(roundtrip)) + logger.debug(json_dumper.dumps(roundtrip)) assert roundtrip == data def test_tsvgen_unroundtrippable(self): diff --git a/tests/test_loaders_dumpers/test_loaders_dumpers.py b/tests/test_loaders_dumpers/test_loaders_dumpers.py index 30a6ded6..a48eb77c 100644 --- a/tests/test_loaders_dumpers/test_loaders_dumpers.py +++ b/tests/test_loaders_dumpers/test_loaders_dumpers.py @@ -18,6 +18,9 @@ from tests.test_loaders_dumpers.models.personinfo import Container, Person, Address, Organization, OrganizationType from tests.test_loaders_dumpers.models.node_object import NodeObject, Triple +logger = logging.getLogger(__name__) + + SCHEMA = os.path.join(INPUT_DIR, 'personinfo.yaml') DATA = os.path.join(INPUT_DIR, 'example_personinfo_data.yaml') OUT_TTL = os.path.join(OUTPUT_DIR, 'example_out.ttl') @@ -173,7 +176,7 @@ def test_edge_cases(self): assert x.subject is None assert x.predicate is not None assert x.object is not None - logging.info(f' x={x}') + logger.info(f' x={x}') # ranges that are objects are contracted assert Triple(subject=None, predicate='rdfs:subClassOf', object='owl:Thing') in obj.statements assert Triple(subject=None, predicate='rdfs:subClassOf', object='NCBITaxon:1') in obj.statements @@ -185,7 +188,7 @@ def test_edge_cases(self): cast_literals=False, allow_unprocessed_triples=False, prefix_map=taxon_prefix_map) - logging.error(f'Passed unexpectedly: there are known to be unreachable triples') + logger.error(f'Passed unexpectedly: there are known to be unreachable triples') # removing complex range, object has a range of string view.schema.slots['object'].exactly_one_of = [] view.set_modified() @@ -200,7 +203,7 @@ def test_edge_cases(self): cast_literals=False, allow_unprocessed_triples=True, prefix_map=taxon_prefix_map) - logging.error(f'Passed unexpectedly: rdf:object is known to have a mix of literals and nodes') + logger.error(f'Passed unexpectedly: rdf:object is known to have a mix of literals and nodes') if __name__ == '__main__': diff --git a/tests/test_loaders_dumpers/test_rdflib_dumper.py b/tests/test_loaders_dumpers/test_rdflib_dumper.py index 487ccb3a..846b9a4b 100644 --- a/tests/test_loaders_dumpers/test_rdflib_dumper.py +++ b/tests/test_loaders_dumpers/test_rdflib_dumper.py @@ -20,6 +20,9 @@ from tests.test_loaders_dumpers.models.phenopackets import PhenotypicFeature, OntologyClass, Phenopacket, MetaData, \ Resource +logger = logging.getLogger(__name__) + + SCHEMA = os.path.join(INPUT_DIR, 'personinfo.yaml') DATA = os.path.join(INPUT_DIR, 'example_personinfo_data.yaml') DATA_TTL = os.path.join(INPUT_DIR, 'example_personinfo_data.ttl') @@ -318,7 +321,7 @@ def test_edge_cases(self): assert x.subject is None assert x.predicate is not None assert x.object is not None - logging.info(f' x={x}') + logger.info(f' x={x}') # ranges that are objects are contracted assert Triple(subject=None, predicate='rdfs:subClassOf', object='owl:Thing') in obj.statements assert Triple(subject=None, predicate='rdfs:subClassOf', object='NCBITaxon:1') in obj.statements @@ -330,7 +333,7 @@ def test_edge_cases(self): cast_literals=False, allow_unprocessed_triples=False, prefix_map=taxon_prefix_map) - logging.error(f'Passed unexpectedly: there are known to be unreachable triples') + logger.error(f'Passed unexpectedly: there are known to be unreachable triples') # removing complex range, object has a range of string view.schema.slots['object'].exactly_one_of = [] view.set_modified() @@ -345,7 +348,7 @@ def test_edge_cases(self): cast_literals=False, allow_unprocessed_triples=True, prefix_map=taxon_prefix_map) - logging.error(f'Passed unexpectedly: rdf:object is known to have a mix of literals and nodes') + logger.error(f'Passed unexpectedly: rdf:object is known to have a mix of literals and nodes') def test_phenopackets(self): view = SchemaView(str(Path(INPUT_DIR) / "phenopackets"/ "phenopackets.yaml")) diff --git a/tests/test_utils/test_schema_as_dict.py b/tests/test_utils/test_schema_as_dict.py index 569e84f0..f9f2c53b 100644 --- a/tests/test_utils/test_schema_as_dict.py +++ b/tests/test_utils/test_schema_as_dict.py @@ -11,6 +11,8 @@ from tests.test_utils import INPUT_DIR, OUTPUT_DIR +logger = logging.getLogger(__name__) + SCHEMA_NO_IMPORTS = os.path.join(INPUT_DIR, 'kitchen_sink_noimports.yaml') SCHEMA_WITH_IMPORTS = os.path.join(INPUT_DIR, 'kitchen_sink.yaml') CLEAN_SCHEMA = os.path.join(OUTPUT_DIR, 'kitchen_sink.clean.yaml') @@ -27,7 +29,7 @@ def test_as_dict(self): view = SchemaView(SCHEMA_NO_IMPORTS) all_slots = view.all_slots() self.assertIn('name', all_slots) - logging.debug(view.schema.id) + logger.debug(view.schema.id) ystr = schema_as_yaml_dump(view.schema) with open(CLEAN_SCHEMA, 'w') as stream: stream.write(ystr) diff --git a/tests/test_utils/test_schemaview.py b/tests/test_utils/test_schemaview.py index 687c6631..8056ba9e 100644 --- a/tests/test_utils/test_schemaview.py +++ b/tests/test_utils/test_schemaview.py @@ -17,6 +17,8 @@ from linkml_runtime.utils.schemaops import roll_up, roll_down from tests.test_utils import INPUT_DIR +logger = logging.getLogger(__name__) + SCHEMA_NO_IMPORTS = Path(INPUT_DIR) / 'kitchen_sink_noimports.yaml' SCHEMA_WITH_IMPORTS = Path(INPUT_DIR) / 'kitchen_sink.yaml' SCHEMA_WITH_STRUCTURED_PATTERNS = Path(INPUT_DIR) / "pattern-example.yaml" @@ -97,17 +99,17 @@ def test_schemaview_enums(self): def test_schemaview(self): # no import schema view = SchemaView(SCHEMA_NO_IMPORTS) - logging.debug(view.imports_closure()) + logger.debug(view.imports_closure()) self.assertEqual(len(view.imports_closure()), 1) all_cls = view.all_classes() - logging.debug(f'n_cls = {len(all_cls)}') + logger.debug(f'n_cls = {len(all_cls)}') self.assertEqual(list(view.annotation_dict(IS_CURRENT).values()), ['bar']) - logging.debug(view.annotation_dict(EMPLOYED_AT)) + logger.debug(view.annotation_dict(EMPLOYED_AT)) e = view.get_element(EMPLOYED_AT) - logging.debug(e.annotations) + logger.debug(e.annotations) e = view.get_element('has employment history') - logging.debug(e.annotations) + logger.debug(e.annotations) elements = view.get_elements_applicable_by_identifier("ORCID:1234") self.assertIn("Person", elements) @@ -118,11 +120,11 @@ def test_schemaview(self): elements = view.get_elements_applicable_by_identifier("TEST:1234") self.assertNotIn("anatomical entity", elements) self.assertEqual(list(view.annotation_dict(SlotDefinitionName(IS_CURRENT)).values()), ['bar']) - logging.debug(view.annotation_dict(SlotDefinitionName(EMPLOYED_AT))) + logger.debug(view.annotation_dict(SlotDefinitionName(EMPLOYED_AT))) element = view.get_element(SlotDefinitionName(EMPLOYED_AT)) - logging.debug(element.annotations) + logger.debug(element.annotations) element = view.get_element(SlotDefinitionName('has employment history')) - logging.debug(element.annotations) + logger.debug(element.annotations) self.assertTrue(view.is_mixin('WithLocation')) self.assertFalse(view.is_mixin('BirthEvent')) @@ -146,10 +148,10 @@ def test_schemaview(self): view.slot_is_true_for_metadata_property('aliases', 'aliases') for tn, t in view.all_types().items(): - logging.info(f'TN = {tn}') + logger.info(f'TN = {tn}') self.assertEqual('https://w3id.org/linkml/tests/kitchen_sink', t.from_schema) for sn, s in view.all_slots().items(): - logging.info(f'SN = {sn} RANGE={s.range}') + logger.info(f'SN = {sn} RANGE={s.range}') self.assertEqual('https://w3id.org/linkml/tests/kitchen_sink', s.from_schema) # range should always be populated: See https://github.com/linkml/linkml/issues/733 rng = view.induced_slot(sn).range @@ -158,23 +160,23 @@ def test_schemaview(self): for cn in all_cls.keys(): c = view.get_class(cn) self.assertEqual('https://w3id.org/linkml/tests/kitchen_sink', c.from_schema) - logging.debug(f'{cn} PARENTS = {view.class_parents(cn)}') - logging.debug(f'{cn} ANCS = {view.class_ancestors(cn)}') - logging.debug(f'{cn} CHILDREN = {view.class_children(cn)}') - logging.debug(f'{cn} DESCS = {view.class_descendants(cn)}') - logging.debug(f'{cn} SCHEMA = {view.in_schema(cn)}') - logging.debug(f' SLOTS = {view.class_slots(cn)}') + logger.debug(f'{cn} PARENTS = {view.class_parents(cn)}') + logger.debug(f'{cn} ANCS = {view.class_ancestors(cn)}') + logger.debug(f'{cn} CHILDREN = {view.class_children(cn)}') + logger.debug(f'{cn} DESCS = {view.class_descendants(cn)}') + logger.debug(f'{cn} SCHEMA = {view.in_schema(cn)}') + logger.debug(f' SLOTS = {view.class_slots(cn)}') for sn in view.class_slots(cn): slot = view.get_slot(sn) self.assertEqual('https://w3id.org/linkml/tests/kitchen_sink', slot.from_schema) - logging.debug(f' SLOT {sn} R: {slot.range} U: {view.get_uri(sn)} ANCS: {view.slot_ancestors(sn)}') + logger.debug(f' SLOT {sn} R: {slot.range} U: {view.get_uri(sn)} ANCS: {view.slot_ancestors(sn)}') induced_slot = view.induced_slot(sn, cn) - logging.debug(f' INDUCED {sn}={induced_slot}') + logger.debug(f' INDUCED {sn}={induced_slot}') # range should always be populated: See https://github.com/linkml/linkml/issues/733 self.assertIsNotNone(induced_slot.range) - logging.debug(f'ALL = {view.all_elements().keys()}') + logger.debug(f'ALL = {view.all_elements().keys()}') # -- TEST ANCESTOR/DESCENDANTS FUNCTIONS -- @@ -202,7 +204,7 @@ def test_schemaview(self): self.assertEqual(view.get_class(AGENT).class_uri, 'prov:Agent') self.assertEqual(view.get_uri(AGENT), 'prov:Agent') - logging.debug(view.get_class(COMPANY).class_uri) + logger.debug(view.get_class(COMPANY).class_uri) self.assertEqual(view.get_uri(COMPANY), 'ks:Company') @@ -226,7 +228,7 @@ def test_schemaview(self): self.assertEqual(view.induced_slot('name', c).owner, c, 'owner does not match') for c in ['Event', 'EmploymentEvent', 'MedicalEvent']: s = view.induced_slot('started at time', c) - logging.debug(f's={s.range} // c = {c}') + logger.debug(f's={s.range} // c = {c}') self.assertEqual(s.range, 'date') self.assertEqual(s.slot_uri, 'prov:startedAtTime') self.assertEqual(s.owner, c, 'owner does not match') @@ -250,13 +252,13 @@ def test_schemaview(self): a = view.get_class(ACTIVITY) self.assertCountEqual(a.exact_mappings, ['prov:Activity']) - logging.debug(view.get_mappings(ACTIVITY, expand=True)) + logger.debug(view.get_mappings(ACTIVITY, expand=True)) self.assertCountEqual(view.get_mappings(ACTIVITY)['exact'], ['prov:Activity']) self.assertCountEqual(view.get_mappings(ACTIVITY, expand=True)['exact'], ['http://www.w3.org/ns/prov#Activity']) u = view.usage_index() for k, v in u.items(): - logging.debug(f' {k} = {v}') + logger.debug(f' {k} = {v}') self.assertIn(SchemaUsage(used_by='FamilialRelationship', slot=RELATED_TO, metaslot='range', used='Person', inferred=False), u['Person']) self.assertListEqual( @@ -298,18 +300,18 @@ def test_schemaview(self): # test methods also work for attributes leaves = view.class_leaves() - logging.debug(f'LEAVES={leaves}') + logger.debug(f'LEAVES={leaves}') self.assertIn('MedicalEvent', leaves) roots = view.class_roots() - logging.debug(f'ROOTS={roots}') + logger.debug(f'ROOTS={roots}') self.assertIn('Dataset', roots) ds_slots = view.class_slots('Dataset') - logging.debug(ds_slots) + logger.debug(ds_slots) self.assertEqual(len(ds_slots), 3) self.assertCountEqual(['persons', 'companies', 'activities'], ds_slots) for sn in ds_slots: s = view.induced_slot(sn, 'Dataset') - logging.debug(s) + logger.debug(s) def test_all_classes_ordered_lexical(self): view = SchemaView(SCHEMA_NO_IMPORTS) @@ -376,9 +378,9 @@ def test_rollup_rolldown(self): element_name = 'Event' roll_up(view, element_name) for slot in view.class_induced_slots(element_name): - logging.debug(slot) + logger.debug(slot) induced_slot_names = [s.name for s in view.class_induced_slots(element_name)] - logging.debug(induced_slot_names) + logger.debug(induced_slot_names) self.assertCountEqual(['started at time', 'ended at time', IS_CURRENT, 'in location', EMPLOYED_AT, 'married to'], induced_slot_names) # check to make sure rolled-up classes are deleted @@ -387,9 +389,9 @@ def test_rollup_rolldown(self): for element_name in view.all_classes(): c = view.get_class(element_name) - logging.debug(f'{element_name}') - logging.debug(f' {element_name} SLOTS(i) = {view.class_slots(element_name)}') - logging.debug(f' {element_name} SLOTS(d) = {view.class_slots(element_name, direct=True)}') + logger.debug(f'{element_name}') + logger.debug(f' {element_name} SLOTS(i) = {view.class_slots(element_name)}') + logger.debug(f' {element_name} SLOTS(d) = {view.class_slots(element_name, direct=True)}') self.assertCountEqual(view.class_slots(element_name), view.class_slots(element_name, direct=True)) self.assertNotIn('Thing', view.all_classes()) self.assertNotIn('Person', view.all_classes()) @@ -444,10 +446,10 @@ def test_imports(self): """ view = SchemaView(SCHEMA_WITH_IMPORTS) self.assertIsNotNone(view.schema.source_file) - logging.debug(view.imports_closure()) + logger.debug(view.imports_closure()) self.assertCountEqual(['kitchen_sink', 'core', 'linkml:types'], view.imports_closure()) for t in view.all_types().keys(): - logging.debug(f'T={t} in={view.in_schema(t)}') + logger.debug(f'T={t} in={view.in_schema(t)}') self.assertEqual(view.in_schema(ClassDefinitionName('Person')), 'kitchen_sink') self.assertEqual(view.in_schema(SlotDefinitionName('id')), 'core') self.assertEqual(view.in_schema(SlotDefinitionName('name')), 'core') @@ -508,11 +510,11 @@ def test_imports(self): self.assertEqual(view.get_class('agent').class_uri, 'prov:Agent') self.assertEqual(view.get_uri(AGENT), 'prov:Agent') - logging.debug(view.get_class('Company').class_uri) + logger.debug(view.get_class('Company').class_uri) self.assertEqual(view.get_uri(COMPANY), 'ks:Company') self.assertEqual(view.get_uri(COMPANY, expand=True), 'https://w3id.org/linkml/tests/kitchen_sink/Company') - logging.debug(view.get_uri('TestClass')) + logger.debug(view.get_uri('TestClass')) self.assertEqual(view.get_uri('TestClass'), 'core:TestClass') self.assertEqual(view.get_uri('TestClass', expand=True), 'https://w3id.org/linkml/tests/core/TestClass')