From a5d5239a2d03c2949b852c2ff32a12adf4234ce1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 05:22:44 +0000 Subject: [PATCH 1/9] build(deps-dev): bump mypy from 1.13.0 to 1.14.1 Bumps [mypy](https://github.com/python/mypy) from 1.13.0 to 1.14.1. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.13.0...v1.14.1) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- poetry.lock | 76 +++++++++++++++++++++++++++++------------------------ 1 file changed, 41 insertions(+), 35 deletions(-) diff --git a/poetry.lock b/poetry.lock index dcd59070d..a526f3f22 100644 --- a/poetry.lock +++ b/poetry.lock @@ -750,49 +750,55 @@ files = [ [[package]] name = "mypy" -version = "1.13.0" +version = "1.14.1" description = "Optional static typing for Python" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"}, - {file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"}, - {file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"}, - {file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"}, - {file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"}, - {file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"}, - {file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"}, - {file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"}, - {file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"}, - {file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"}, - {file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"}, - {file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"}, - {file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"}, - {file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"}, - {file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"}, - {file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"}, - {file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"}, - {file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"}, - {file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"}, - {file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"}, - {file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"}, - {file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"}, - {file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"}, - {file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"}, - {file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"}, - {file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"}, - {file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"}, + {file = "mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb"}, + {file = "mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0"}, + {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d"}, + {file = "mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b"}, + {file = "mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427"}, + {file = "mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f"}, + {file = "mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c"}, + {file = "mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1"}, + {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8"}, + {file = "mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f"}, + {file = "mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1"}, + {file = "mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae"}, + {file = "mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14"}, + {file = "mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9"}, + {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11"}, + {file = "mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e"}, + {file = "mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89"}, + {file = "mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b"}, + {file = "mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255"}, + {file = "mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34"}, + {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a"}, + {file = "mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9"}, + {file = "mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd"}, + {file = "mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107"}, + {file = "mypy-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7084fb8f1128c76cd9cf68fe5971b37072598e7c31b2f9f95586b65c741a9d31"}, + {file = "mypy-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f845a00b4f420f693f870eaee5f3e2692fa84cc8514496114649cfa8fd5e2c6"}, + {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:44bf464499f0e3a2d14d58b54674dee25c031703b2ffc35064bd0df2e0fac319"}, + {file = "mypy-1.14.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c99f27732c0b7dc847adb21c9d47ce57eb48fa33a17bc6d7d5c5e9f9e7ae5bac"}, + {file = "mypy-1.14.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:bce23c7377b43602baa0bd22ea3265c49b9ff0b76eb315d6c34721af4cdf1d9b"}, + {file = "mypy-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:8edc07eeade7ebc771ff9cf6b211b9a7d93687ff892150cb5692e4f4272b0837"}, + {file = "mypy-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3888a1816d69f7ab92092f785a462944b3ca16d7c470d564165fe703b0970c35"}, + {file = "mypy-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46c756a444117c43ee984bd055db99e498bc613a70bbbc120272bd13ca579fbc"}, + {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:27fc248022907e72abfd8e22ab1f10e903915ff69961174784a3900a8cba9ad9"}, + {file = "mypy-1.14.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:499d6a72fb7e5de92218db961f1a66d5f11783f9ae549d214617edab5d4dbdbb"}, + {file = "mypy-1.14.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:57961db9795eb566dc1d1b4e9139ebc4c6b0cb6e7254ecde69d1552bf7613f60"}, + {file = "mypy-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:07ba89fdcc9451f2ebb02853deb6aaaa3d2239a236669a63ab3801bbf923ef5c"}, + {file = "mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1"}, + {file = "mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6"}, ] [package.dependencies] -mypy-extensions = ">=1.0.0" +mypy_extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" +typing_extensions = ">=4.6.0" [package.extras] dmypy = ["psutil (>=4.0)"] From 43bc141a2db91fd1c42ddf7b68142d6d9eaee3b0 Mon Sep 17 00:00:00 2001 From: Nicholas Car Date: Fri, 10 Jan 2025 11:01:14 +1000 Subject: [PATCH 2/9] fix slice typing --- rdflib/graph.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/rdflib/graph.py b/rdflib/graph.py index b43bafba2..e1979597b 100644 --- a/rdflib/graph.py +++ b/rdflib/graph.py @@ -661,10 +661,11 @@ def triples( def __getitem__(self, item): """ - A graph can be "sliced" as a shortcut for the triples method - The python slice syntax is (ab)used for specifying triples. - A generator over matches is returned, - the returned tuples include only the parts not given + A graph can be "sliced" as a shortcut for the triples method. + The Python slice syntax is (ab)used for specifying triples. + + A generator over matches is returned, the returned tuples include only the + parts not given. >>> import rdflib >>> g = rdflib.Graph() @@ -703,6 +704,10 @@ def __getitem__(self, item): if isinstance(item, slice): s, p, o = item.start, item.stop, item.step + s: _SubjectType + p: _PredicateType + o: _ObjectType + if s is None and p is None and o is None: return self.triples((s, p, o)) elif s is None and p is None: From bdbcf7e23de9cc83c9265211d8d97e3a072c0e9e Mon Sep 17 00:00:00 2001 From: Nicholas Car Date: Fri, 10 Jan 2025 11:37:36 +1000 Subject: [PATCH 3/9] fix slice typing #2 --- rdflib/graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rdflib/graph.py b/rdflib/graph.py index e1979597b..b474a15c2 100644 --- a/rdflib/graph.py +++ b/rdflib/graph.py @@ -703,10 +703,10 @@ def __getitem__(self, item): """ if isinstance(item, slice): - s, p, o = item.start, item.stop, item.step s: _SubjectType p: _PredicateType o: _ObjectType + s, p, o = item.start, item.stop, item.step if s is None and p is None and o is None: return self.triples((s, p, o)) From b6017c8669d0a7c579ce5753bee3b4c4c05cb8d5 Mon Sep 17 00:00:00 2001 From: Nicholas Car Date: Fri, 10 Jan 2025 13:07:34 +1000 Subject: [PATCH 4/9] Graph().__getitem_ returns via yield from generators --- rdflib/graph.py | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/rdflib/graph.py b/rdflib/graph.py index b474a15c2..d9a842cc0 100644 --- a/rdflib/graph.py +++ b/rdflib/graph.py @@ -702,34 +702,32 @@ def __getitem__(self, item): """ - if isinstance(item, slice): - s: _SubjectType - p: _PredicateType - o: _ObjectType + if isinstance(item, IdentifiedNode): + yield from self.predicate_objects(item) + elif isinstance(item, slice): s, p, o = item.start, item.stop, item.step - + # type narrowing since we cannot use typing within a slice() + assert isinstance(s, IdentifiedNode) or isinstance(s, Variable) or s is None + assert isinstance(p, IdentifiedNode) or isinstance(p, Variable) or p is None + assert isinstance(o, Node) or isinstance(o, Variable) or o is None + if s is None and p is None and o is None: - return self.triples((s, p, o)) + yield from self.triples((s, p, o)) elif s is None and p is None: - return self.subject_predicates(o) + yield from self.subject_predicates(o) # type: ignore[arg-type] elif s is None and o is None: - return self.subject_objects(p) + yield from self.subject_objects(p) elif p is None and o is None: - return self.predicate_objects(s) + yield from self.predicate_objects(s) elif s is None: - return self.subjects(p, o) + yield from self.subjects(p, o) # type: ignore[arg-type] elif p is None: - return self.predicates(s, o) + yield from self.predicates(s, o) # type: ignore[arg-type] elif o is None: - return self.objects(s, p) + yield from self.objects(s, p) else: # all given - return (s, p, o) in self - - elif isinstance(item, (Path, Node)): - # type error: Argument 1 to "predicate_objects" of "Graph" has incompatible type "Union[Path, Node]"; expected "Optional[Node]" - return self.predicate_objects(item) # type: ignore[arg-type] - + yield s, p, o else: raise TypeError( "You can only index a graph by a single rdflib term or path, or a slice of rdflib terms." From 49fb501bfd396030ac090afe5b847b7ebfff0dc8 Mon Sep 17 00:00:00 2001 From: Nicholas Car Date: Fri, 10 Jan 2025 13:10:07 +1000 Subject: [PATCH 5/9] tests for ypdated Graph().__getitems --- test/test_graph/test_graph_items.py | 45 ++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/test/test_graph/test_graph_items.py b/test/test_graph/test_graph_items.py index 4984792a9..b2f48912c 100644 --- a/test/test_graph/test_graph_items.py +++ b/test/test_graph/test_graph_items.py @@ -1,4 +1,5 @@ -from rdflib import RDF, Graph, Namespace +from rdflib import Graph, Namespace, Literal, URIRef +from rdflib.namespace import RDF, RDFS EX = Namespace("http://example.org/") @@ -62,3 +63,45 @@ def test_recursive_list_detection(): pass else: assert False, "Expected detection of recursive rdf:rest reference" + + +def test_graph_slice_eg(): + g = Graph() + g.add((URIRef("urn:bob"), RDFS.label, Literal("Bob"))) + assert sorted(list(g[URIRef("urn:bob")])) == sorted( + [(URIRef("http://www.w3.org/2000/01/rdf-schema#label"), Literal("Bob"))] + ) + + assert sorted(list(g[: RDFS.label])) == sorted( + [(URIRef("urn:bob"), Literal("Bob"))] + ) + + assert sorted(list(g[:: Literal("Bob")])) == sorted( + [(URIRef("urn:bob"), URIRef("http://www.w3.org/2000/01/rdf-schema#label"))] + ) + + +def test_graph_slice_all(): + g = Graph() + g.parse( + data=""" + PREFIX ex: + + ex:a ex:b ex:c . + ex:a ex:d ex:e . + ex:f ex:b ex:c . + ex:g ex:b ex:h . + """ + ) + + assert len(list(g[EX.a])) == 2 + + assert len(list(g[EX.f])) == 1 + + assert len(list(g[: EX.b])) == 3 + + assert len(list(g[:: EX.c])) == 2 + + assert len(list(g[EX.a : EX.b : EX.c])) == 1 + + assert sorted(list(g[EX.a])) == sorted(list(g.predicate_objects(EX.a))) From 6379c3a04a96037dd82b3a644a5af8afceeda043 Mon Sep 17 00:00:00 2001 From: Nicholas Car Date: Fri, 10 Jan 2025 13:23:45 +1000 Subject: [PATCH 6/9] allow Path as type of 'p' in Graph slice --- rdflib/graph.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rdflib/graph.py b/rdflib/graph.py index d9a842cc0..fc54f51ba 100644 --- a/rdflib/graph.py +++ b/rdflib/graph.py @@ -708,7 +708,7 @@ def __getitem__(self, item): s, p, o = item.start, item.stop, item.step # type narrowing since we cannot use typing within a slice() assert isinstance(s, IdentifiedNode) or isinstance(s, Variable) or s is None - assert isinstance(p, IdentifiedNode) or isinstance(p, Variable) or p is None + assert isinstance(p, IdentifiedNode) or isinstance(p, Path) or isinstance(p, Variable) or p is None assert isinstance(o, Node) or isinstance(o, Variable) or o is None if s is None and p is None and o is None: From 1b0b397221d3cd781dedab5227db0c0ac90d3f17 Mon Sep 17 00:00:00 2001 From: Nicholas Car Date: Fri, 10 Jan 2025 16:22:24 +1000 Subject: [PATCH 7/9] modernise old test; add two new tests --- test/test_graph/test_slice.py | 71 ++++++++++++++++++++++++++++------- 1 file changed, 58 insertions(+), 13 deletions(-) diff --git a/test/test_graph/test_slice.py b/test/test_graph/test_slice.py index 7e503f8ed..eb572d7ef 100644 --- a/test/test_graph/test_slice.py +++ b/test/test_graph/test_slice.py @@ -1,18 +1,21 @@ -from rdflib import Graph +from rdflib import Graph, Literal, Namespace, URIRef +from rdflib.namespace import RDFS from test.data import BOB, CHEESE, HATES, LIKES, MICHEL, PIZZA, TAREK +EX = Namespace("http://example.org/") + class TestGraphSlice: def test_slice(self): """ - We pervert the slice object, - and use start, stop, step as subject, predicate, object + We pervert the slice object, and use start, stop, step as subject, predicate, + object - all operations return generators over full triples + All operations return generators over full triples """ - def sl(x, y): - return len(list(x)) == y + def sl(x): + return len(list(x)) def soe(x, y): return set([a[2] for a in x]) == set(y) # equals objects @@ -30,25 +33,67 @@ def soe(x, y): # single index slices by subject, i.e. return triples((x,None,None)) # tell me everything about "TAREK" - sl(g[TAREK], 2) + assert sl(g[TAREK]) == 2 # single slice slices by s,p,o, with : used to split # tell me everything about "TAREK" (same as above) - sl(g[TAREK::], 2) + assert sl(g[TAREK::]) == 2 # give me every "LIKES" relationship - sl(g[:LIKES:], 5) + assert sl(g[:LIKES:]) == 5 # give me every relationship to PIZZA - sl(g[::PIZZA], 3) + assert sl(g[::PIZZA]) == 3 # give me everyone who LIKES PIZZA - sl(g[:LIKES:PIZZA], 2) + assert sl(g[:LIKES:PIZZA]) == 2 # does TAREK like PIZZA? - assert g[TAREK:LIKES:PIZZA] is True + assert sorted(next(g[TAREK:LIKES:PIZZA])) == sorted((URIRef('urn:example:tarek'), URIRef('urn:example:likes'), URIRef('urn:example:pizza'))) # More intesting is using paths # everything hated or liked - sl(g[: HATES | LIKES], 7) + assert sl(g[: HATES | LIKES]) == 7 + + +def test_graph_slice_eg(): + g = Graph() + g.add((URIRef("urn:bob"), RDFS.label, Literal("Bob"))) + assert sorted(list(g[URIRef("urn:bob")])) == sorted( + [(URIRef("http://www.w3.org/2000/01/rdf-schema#label"), Literal("Bob"))] + ) + + assert sorted(list(g[: RDFS.label])) == sorted( + [(URIRef("urn:bob"), Literal("Bob"))] + ) + + assert sorted(list(g[:: Literal("Bob")])) == sorted( + [(URIRef("urn:bob"), URIRef("http://www.w3.org/2000/01/rdf-schema#label"))] + ) + + +def test_graph_slice_all(): + g = Graph() + g.parse( + data=""" + PREFIX ex: + + ex:a ex:b ex:c . + ex:a ex:d ex:e . + ex:f ex:b ex:c . + ex:g ex:b ex:h . + """ + ) + + assert len(list(g[EX.a])) == 2 + + assert len(list(g[EX.f])) == 1 + + assert len(list(g[: EX.b])) == 3 + + assert len(list(g[:: EX.c])) == 2 + + assert len(list(g[EX.a : EX.b : EX.c])) == 1 + + assert sorted(list(g[EX.a])) == sorted(list(g.predicate_objects(EX.a))) From 6646415d234776e8da43c9811062951f895f4db5 Mon Sep 17 00:00:00 2001 From: Nicholas Car Date: Fri, 10 Jan 2025 16:23:12 +1000 Subject: [PATCH 8/9] moving slice tests to test_slice.py --- test/test_graph/test_graph_items.py | 42 ----------------------------- 1 file changed, 42 deletions(-) diff --git a/test/test_graph/test_graph_items.py b/test/test_graph/test_graph_items.py index b2f48912c..cf776be6b 100644 --- a/test/test_graph/test_graph_items.py +++ b/test/test_graph/test_graph_items.py @@ -63,45 +63,3 @@ def test_recursive_list_detection(): pass else: assert False, "Expected detection of recursive rdf:rest reference" - - -def test_graph_slice_eg(): - g = Graph() - g.add((URIRef("urn:bob"), RDFS.label, Literal("Bob"))) - assert sorted(list(g[URIRef("urn:bob")])) == sorted( - [(URIRef("http://www.w3.org/2000/01/rdf-schema#label"), Literal("Bob"))] - ) - - assert sorted(list(g[: RDFS.label])) == sorted( - [(URIRef("urn:bob"), Literal("Bob"))] - ) - - assert sorted(list(g[:: Literal("Bob")])) == sorted( - [(URIRef("urn:bob"), URIRef("http://www.w3.org/2000/01/rdf-schema#label"))] - ) - - -def test_graph_slice_all(): - g = Graph() - g.parse( - data=""" - PREFIX ex: - - ex:a ex:b ex:c . - ex:a ex:d ex:e . - ex:f ex:b ex:c . - ex:g ex:b ex:h . - """ - ) - - assert len(list(g[EX.a])) == 2 - - assert len(list(g[EX.f])) == 1 - - assert len(list(g[: EX.b])) == 3 - - assert len(list(g[:: EX.c])) == 2 - - assert len(list(g[EX.a : EX.b : EX.c])) == 1 - - assert sorted(list(g[EX.a])) == sorted(list(g.predicate_objects(EX.a))) From d734d575f900e7b13c9d66fd38a42f9a5cc261c5 Mon Sep 17 00:00:00 2001 From: Nicholas Car Date: Fri, 10 Jan 2025 16:32:04 +1000 Subject: [PATCH 9/9] blacked & ruff --fix --- rdflib/graph.py | 7 ++++++- test/test_graph/test_graph_items.py | 4 ++-- test/test_graph/test_slice.py | 8 +++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/rdflib/graph.py b/rdflib/graph.py index fc54f51ba..9ba3dd396 100644 --- a/rdflib/graph.py +++ b/rdflib/graph.py @@ -708,7 +708,12 @@ def __getitem__(self, item): s, p, o = item.start, item.stop, item.step # type narrowing since we cannot use typing within a slice() assert isinstance(s, IdentifiedNode) or isinstance(s, Variable) or s is None - assert isinstance(p, IdentifiedNode) or isinstance(p, Path) or isinstance(p, Variable) or p is None + assert ( + isinstance(p, IdentifiedNode) + or isinstance(p, Path) + or isinstance(p, Variable) + or p is None + ) assert isinstance(o, Node) or isinstance(o, Variable) or o is None if s is None and p is None and o is None: diff --git a/test/test_graph/test_graph_items.py b/test/test_graph/test_graph_items.py index cf776be6b..36ac47032 100644 --- a/test/test_graph/test_graph_items.py +++ b/test/test_graph/test_graph_items.py @@ -1,5 +1,5 @@ -from rdflib import Graph, Namespace, Literal, URIRef -from rdflib.namespace import RDF, RDFS +from rdflib import Graph, Namespace +from rdflib.namespace import RDF EX = Namespace("http://example.org/") diff --git a/test/test_graph/test_slice.py b/test/test_graph/test_slice.py index eb572d7ef..ac7015779 100644 --- a/test/test_graph/test_slice.py +++ b/test/test_graph/test_slice.py @@ -49,7 +49,13 @@ def soe(x, y): assert sl(g[:LIKES:PIZZA]) == 2 # does TAREK like PIZZA? - assert sorted(next(g[TAREK:LIKES:PIZZA])) == sorted((URIRef('urn:example:tarek'), URIRef('urn:example:likes'), URIRef('urn:example:pizza'))) + assert sorted(next(g[TAREK:LIKES:PIZZA])) == sorted( + ( + URIRef("urn:example:tarek"), + URIRef("urn:example:likes"), + URIRef("urn:example:pizza"), + ) + ) # More intesting is using paths