예제 #1
0
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'")
예제 #2
0
 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.
예제 #3
0
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
예제 #4
0
 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.
예제 #5
0
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
예제 #6
0
    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)
예제 #7
0
 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)
예제 #8
0
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)
예제 #9
0
파일: _util.py 프로젝트: tomyc/algebraixlib
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]