Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions pyshacl/constraints/core/shape_based_constraints.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"""
https://www.w3.org/TR/shacl/#core-components-shape
"""
from dataclasses import dataclass
from textwrap import indent
from typing import Dict, List
from warnings import warn
Expand Down Expand Up @@ -77,14 +76,13 @@ def evaluate(
):
"""
Entrypoint for constraint evaluation.
:type executor: dataclass
:type executor: SHACLExecutor
:type target_graph: rdflib.Graph
:type focus_value_nodes: dict
:type _evaluation_path: list
"""
reports: List[Dict] = []
non_conformant = False
shape = self.shape

# Shortcut, when there are no value nodes, don't check for recursion, don't validate and exit early
value_node_count = 0
Expand Down Expand Up @@ -178,7 +176,6 @@ def evaluate(
"""
reports: List[Dict] = []
non_conformant = False
shape = self.shape

# Shortcut, when there are no value nodes, don't check for recursion, don't validate and exit early
value_node_count = 0
Expand Down Expand Up @@ -344,7 +341,6 @@ def evaluate(
"""
reports: List[Dict] = []
non_conformant = False
shape = self.shape

# Shortcut, when there are no value nodes, don't check for recursion, don't validate and exit early
value_node_count = 0
Expand Down
37 changes: 32 additions & 5 deletions pyshacl/rdfutil/clone.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
# -*- coding: utf-8 -*-
#
from typing import Optional, Union
from typing import Optional, Union, overload

import rdflib
from rdflib.collection import Collection
from rdflib.graph import DATASET_DEFAULT_GRAPH_ID
from rdflib.namespace import NamespaceManager

from .consts import OWL, RDF_first
from .consts import OWL, RDF_first, RDFNode
from .pytypes import ConjunctiveLike, GraphLike

OWLsameAs = OWL.sameAs
Expand Down Expand Up @@ -237,6 +237,28 @@ def mix_graphs(base_graph: GraphLike, extra_graph: GraphLike, target_graph: Opti
return g


@overload
def clone_list(
graph: rdflib.Graph,
lnode: rdflib.BNode,
target_graph: rdflib.Graph,
keepid: bool = ...,
recursion: int = ...,
deep_clone: bool = ...,
) -> rdflib.BNode: ...


@overload
def clone_list(
graph: rdflib.Graph,
lnode: rdflib.URIRef,
target_graph: rdflib.Graph,
keepid: bool = ...,
recursion: int = ...,
deep_clone: bool = ...,
) -> rdflib.URIRef: ...


def clone_list(graph, lnode, target_graph, keepid=False, recursion=0, deep_clone=False):
# If deep_clone, copy all the contents (subjects, predicates) of a named member item
if isinstance(lnode, rdflib.BNode):
Expand All @@ -254,7 +276,9 @@ def clone_list(graph, lnode, target_graph, keepid=False, recursion=0, deep_clone
return cloned_node


def clone_blank_node(graph, bnode, target_graph, keepid=False, recursion=0):
def clone_blank_node(
graph: rdflib.Graph, bnode: rdflib.BNode, target_graph: rdflib.Graph, keepid: bool = False, recursion: int = 0
) -> rdflib.BNode:
if not isinstance(graph, rdflib.Graph):
raise RuntimeError("clone_blank_node must take an rdflib.Graph as first parameter")
if not isinstance(bnode, rdflib.BNode):
Expand Down Expand Up @@ -287,16 +311,19 @@ def clone_blank_node(graph, bnode, target_graph, keepid=False, recursion=0):
return cloned_bnode


def clone_literal(graph, node, target_graph):
def clone_literal(graph: rdflib.Graph, node: rdflib.Literal, target_graph: rdflib.Graph) -> rdflib.Literal:
lex_val_string = str(node)
lang = node.language
datatype = node.datatype
new_literal = rdflib.Literal(lex_val_string, lang, datatype)
return new_literal


def clone_node(graph, node, target_graph, recursion=0, deep_clone=False):
def clone_node(
graph: rdflib.Graph, node: RDFNode, target_graph: rdflib.Graph, recursion: int = 0, deep_clone: bool = False
) -> RDFNode:
# If deepclone, when the type is URIRef, it clones _all_ node content (properties, objects)
new_node: RDFNode
if isinstance(node, rdflib.Literal):
new_node = clone_literal(graph, node, target_graph)
elif isinstance(node, rdflib.BNode):
Expand Down
6 changes: 3 additions & 3 deletions pyshacl/rdfutil/load.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from io import BufferedIOBase, BytesIO, TextIOBase, UnsupportedOperation
from logging import WARNING, Logger, getLogger
from pathlib import Path
from typing import IO, List, Optional, Union, cast
from typing import IO, BinaryIO, List, Optional, Union, cast
from urllib import request
from urllib.error import HTTPError

Expand Down Expand Up @@ -113,7 +113,7 @@ def get_rdf_from_web(url: Union[rdflib.URIRef, str]):


def load_from_source(
source: Union[GraphLike, BufferedIOBase, TextIOBase, str, bytes],
source: Union[GraphLike, BufferedIOBase, TextIOBase, BinaryIO, str, bytes],
g: Optional[GraphLike] = None,
rdf_format: Optional[str] = None,
multigraph: bool = False,
Expand All @@ -139,7 +139,7 @@ def load_from_source(
:return:
"""
source_is_graph = False
open_source: Optional[BufferedIOBase] = None
open_source: Optional[Union[BufferedIOBase, BinaryIO]] = None
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the purpose of BinaryIO in here?
I added the cast in the previous release specifically to avoid the use of BinaryIO in load.py.

Copy link
Contributor Author

@ajnelson-nist ajnelson-nist Apr 30, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added BinaryIO per a suggestion from make type-check. There was still a type influence from an open(..., 'rb') call. With your note on using cast to avoid BinaryIO, I've pushed another patch to revert the BinaryIO addition.

source_was_open: bool = False
source_as_file: Optional[BufferedIOBase] = None
source_as_filename: Optional[str] = None
Expand Down