def _convert_identifier_to_mathobject(term) -> '( A )': """Return an :class:`~.Atom` with the rdflib identifier ``term`` converted into the atom's value. :param term: Must be an `rdflib.URIRef`, `rdflib.BNode` or an `rdflib.Literal`. :return: An :class:`~.Atom` with a value derived from ``term``: - `URIRef` and `BNode` instances are inserted into the atom as their type. - `Literal` instances are inserted as the intuitive native Python type (using `Literal.toPython` -- see the documentation for `Literal`). """ if isinstance(term, _rdflib.URIRef) or isinstance(term, _rdflib.BNode): return _mo.Atom(term) elif isinstance(term, _rdflib.Literal): return _mo.Atom(term.toPython()) else: raise TypeError("'term' must be 'URIRef', 'BNode' or 'Literal'")
def _process_nodes(nodes): for node in nodes: if node.nodeType == node.ELEMENT_NODE: # attributes and children are sets of Couplets. attributes = set(_process_attributes(node)) children = set(_process_nodes( node.childNodes)) # May include text (text_left). children = children.union(attributes) if len(children) == 1 and _contains_text_node(children): # We have a single child that is a text node. Remove one layer of couplets. yield _mo.Couplet( left=_util.get_left_cached(node.tagName), right=_misc.get_single_iter_elem(children).right, direct_load=True) else: yield _mo.Couplet(left=_util.get_left_cached(node.tagName), right=_mo.Set(children, direct_load=True), direct_load=True) elif node.nodeType == node.TEXT_NODE: text_node_text = node.data.strip() if len(text_node_text) > 0: yield _mo.Couplet(left=text_left, right=_mo.Atom( _get_atom_value(text_node_text), direct_load=True), direct_load=True) else: assert False # Node type not supported.
def object_hook_f(obj): """``obj`` is a representation of a straightforward translation of JSON into Python. For a known special construct (must be a ``dict``), convert it into its correct object representation and return it. Otherwise return ``obj`` as-is. (May be used as ``object_hook`` function for the various JSON decoder APIs.) """ if len(obj) == 2 and '__cls__' in obj and '__val__' in obj: if obj['__cls__'] == 'builtin.bytes': return bytes(elem for elem in obj['__val__']) if obj['__cls__'] == 'builtin.complex': return complex(obj['__val__']) if obj['__cls__'] == 'builtin.frozenset': return frozenset(decode(elem) for elem in obj['__val__']) if obj['__cls__'] == 'builtin.list': return list(decode(elem) for elem in obj['__val__']) if obj['__cls__'] == 'builtin.range': return range(decode(obj['__val__'][0]), decode(obj['__val__'][1]), decode(obj['__val__'][2])) if obj['__cls__'] == 'builtin.tuple': return tuple(decode(elem) for elem in obj['__val__']) if obj['__cls__'] == 'Atom': return _mo.Atom(decode(obj['__val__']), direct_load=True) if obj['__cls__'] == 'Couplet': return _mo.Couplet(left=decode(obj['__val__'][0]), right=decode(obj['__val__'][1]), direct_load=True) if obj['__cls__'] == 'Set': return _mo.Set((decode(elem) for elem in obj['__val__']), direct_load=True) if obj['__cls__'] == 'Multiset': return _mo.Multiset( {decode(val): mult for val, mult in obj['__val__']}, direct_load=True) return obj
def _process_nodes(nodes): if isinstance(nodes, list): for list_data in nodes: yield _mo.Set(*list(_process_nodes(list_data))) else: for key, value in nodes.items(): if isinstance(value, list): for list_data in value: child = _process_nodes(list_data) yield _mo.Couplet(_mo.Atom(key), _mo.Set(child), direct_load=True) elif isinstance(value, dict): children = _process_nodes(value) yield _mo.Couplet(_mo.Atom(key), _mo.Set(children), direct_load=True) elif isinstance(value, (str, int)): yield _mo.Couplet(_mo.Atom(key), _mo.Atom(value), direct_load=True) else: assert False # Node type not supported.
def _to_listgen_check_args(mclan: 'P(P(M x M) x N)', offset: '( A )', limit: '( A )', _checked: bool = True) -> (): """Check the arguments of `multiclan_to_listgen` and `order_slice_to_listgen`. Return a tuple with the clean values of ``offset`` and ``limit`` or `Undef()` if there was a problem. """ if _checked: if not is_member(mclan): return _undef.make_or_raise_undef2(mclan) if isinstance(offset, _mo.Atom) and isinstance(offset.value, int): pass elif isinstance(offset, int): offset = _mo.Atom(limit) elif offset is _undef.Undef(): return _undef.make_or_raise_undef(2) else: return _undef.make_or_raise_undef() if isinstance(limit, _mo.Atom) \ and (isinstance(limit.value, int) or limit.value == float('inf')): pass elif isinstance(limit, int) or limit == float('inf'): limit = _mo.Atom(limit) elif limit is _undef.Undef(): return _undef.make_or_raise_undef(2) else: return _undef.make_or_raise_undef() else: if mclan is _undef.Undef() or offset is _undef.Undef( ) or limit is _undef.Undef(): return _undef.make_or_raise_undef(2) assert is_member(mclan) assert offset.is_atom and isinstance(offset.value, int) assert limit.is_atom and (isinstance(limit.value, int) or limit.value == float('inf')) return offset, limit
def _import_csv(csv_file): for _ in range(0, skip_rows): next(csv_file) reader = _csv.DictReader(csv_file, fieldnames=columns) _index = 0 for row in reader: filtered_row = {key: val for key, val in _filter_row(row)} if import_csv.regular and len(row) != len(filtered_row): import_csv.regular = False for key, val in types.items(): if key in filtered_row: filtered_row[key] = val(filtered_row[key]) if index_column is not None: filtered_row[index_column] = _index _index += 1 yield _mo.Set( (_mo.Couplet(left=_util.get_left_cached(left), right=_mo.Atom(right), direct_load=True) for left, right in filtered_row.items()), direct_load=True)\ .cache_relation(_mo.CacheStatus.IS).cache_functional(_mo.CacheStatus.IS)
def _process_attributes(node): for (name, value) in node.attributes.items(): yield _mo.Couplet(left=_util.get_left_cached(name), right=_mo.Atom(_get_atom_value(value), True), direct_load=True)
def import_xml(xml_file_or_filepath, convert_numerics: bool = False) -> 'P( A x M )': """Import the file ``xml_file_or_filepath`` as XML file and return nested relations. :param xml_file_or_filepath: A file path or a file object of the file to be imported. :param convert_numerics: If ``True``, numeric values (integers, floating-point numbers) are imported as number types. If ``False`` (default), everything is imported as string. :return: A nested :term:`relation` starting with a :term:`relation` that contains a single :term:`couplet` that represents the single XML root element. """ def _get_atom_value_convert(atom_value: str): try: return int(atom_value) except ValueError: try: return float(atom_value) except ValueError: return atom_value def _get_atom_value_direct(atom_value: str) -> str: return atom_value _get_atom_value = _get_atom_value_convert if convert_numerics else _get_atom_value_direct def _process_attributes(node): for (name, value) in node.attributes.items(): yield _mo.Couplet(left=_util.get_left_cached(name), right=_mo.Atom(_get_atom_value(value), True), direct_load=True) text_left = _mo.Atom('$') def _contains_text_node(set_: set) -> bool: # Return True if set_ (a set of Couplets) contains a couplet with the left component # text_left. for couplet in set_: if couplet.left == text_left: return True return False _util.get_left_cached.left_cache = {} def _process_nodes(nodes): for node in nodes: if node.nodeType == node.ELEMENT_NODE: # attributes and children are sets of Couplets. attributes = set(_process_attributes(node)) children = set(_process_nodes( node.childNodes)) # May include text (text_left). children = children.union(attributes) if len(children) == 1 and _contains_text_node(children): # We have a single child that is a text node. Remove one layer of couplets. yield _mo.Couplet( left=_util.get_left_cached(node.tagName), right=_misc.get_single_iter_elem(children).right, direct_load=True) else: yield _mo.Couplet(left=_util.get_left_cached(node.tagName), right=_mo.Set(children, direct_load=True), direct_load=True) elif node.nodeType == node.TEXT_NODE: text_node_text = node.data.strip() if len(text_node_text) > 0: yield _mo.Couplet(left=text_left, right=_mo.Atom( _get_atom_value(text_node_text), direct_load=True), direct_load=True) else: assert False # Node type not supported. def _import_xml(xml_file): import xml.dom.minidom tree = xml.dom.minidom.parse(xml_file) return _mo.Set(_process_nodes(tree.childNodes), direct_load=True) if hasattr(xml_file_or_filepath, "readlines"): # support StringIO return _import_xml(xml_file_or_filepath) else: with open(xml_file_or_filepath, encoding='utf-8') as file: return _import_xml(file)
def get_left_cached(tag): cache = getattr(get_left_cached, 'left_cache', {}) if tag not in cache: cache[tag] = _mo.Atom(tag, True) return cache[tag]