From 8b4ef6d08c44d33367472c4789886591ff66e706 Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Wed, 16 Aug 2023 22:57:40 -0500 Subject: [PATCH 1/3] Allow cugraph-nx to run networkx tests for nx versions 3.0, 3.1, and 3.2 Note that NetworkX version 3.2 is currently under development. --- python/cugraph-nx/cugraph_nx/interface.py | 107 ++++++++++++++++++++-- python/cugraph-nx/pyproject.toml | 1 + python/cugraph-nx/run_nx_tests.sh | 8 +- 3 files changed, 106 insertions(+), 10 deletions(-) diff --git a/python/cugraph-nx/cugraph_nx/interface.py b/python/cugraph-nx/cugraph_nx/interface.py index fe492c43ca2..1b4ff04980d 100644 --- a/python/cugraph-nx/cugraph_nx/interface.py +++ b/python/cugraph-nx/cugraph_nx/interface.py @@ -51,17 +51,108 @@ def key(testpath): return (testname, frozenset({classname, filename})) return (testname, frozenset({filename})) - string_attribute = "unable to handle string attributes" + no_weights = "weighted implementation not currently supported" + no_multigraph = "multigraphs not currently supported" - skip = { - key("test_pajek.py:TestPajek.test_ignored_attribute"): string_attribute, - key( - "test_agraph.py:TestAGraph.test_no_warnings_raised" - ): "pytest.warn(None) deprecated", - } + xfail = {} + + from packaging.version import parse + + if parse("3.0a0") <= parse(nx.__version__) < parse("3.2dev0"): + xfail.update( + { + key( + "test_agraph.py:TestAGraph.test_no_warnings_raised" + ): "pytest.warn(None) deprecated", + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_K5" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_P3_normalized" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_P3" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_krackhardt_kite_graph" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality." + "test_krackhardt_kite_graph_normalized" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality." + "test_florentine_families_graph" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_les_miserables_graph" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_ladder_graph" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_G" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_G2" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_G3" + ): no_multigraph, + key( + "test_betweenness_centrality.py:" + "TestWeightedBetweennessCentrality.test_G4" + ): no_multigraph, + key( + "test_betweenness_centrality.py:" + "TestWeightedEdgeBetweennessCentrality.test_K5" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedEdgeBetweennessCentrality.test_C4" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedEdgeBetweennessCentrality.test_P4" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedEdgeBetweennessCentrality.test_balanced_tree" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedEdgeBetweennessCentrality.test_weighted_graph" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedEdgeBetweennessCentrality." + "test_normalized_weighted_graph" + ): no_weights, + key( + "test_betweenness_centrality.py:" + "TestWeightedEdgeBetweennessCentrality.test_weighted_multigraph" + ): no_multigraph, + key( + "test_betweenness_centrality.py:" + "TestWeightedEdgeBetweennessCentrality." + "test_normalized_weighted_multigraph" + ): no_multigraph, + } + ) for item in items: kset = set(item.keywords) - for (test_name, keywords), reason in skip.items(): + for (test_name, keywords), reason in xfail.items(): if item.name == test_name and keywords.issubset(kset): item.add_marker(pytest.mark.xfail(reason=reason)) diff --git a/python/cugraph-nx/pyproject.toml b/python/cugraph-nx/pyproject.toml index 8b0ae11fbe0..df1e7a7a9ab 100644 --- a/python/cugraph-nx/pyproject.toml +++ b/python/cugraph-nx/pyproject.toml @@ -40,6 +40,7 @@ test = [ "pytest", "pytest-benchmark", "pytest-mpl", + "packaging >=21", ] [project.urls] diff --git a/python/cugraph-nx/run_nx_tests.sh b/python/cugraph-nx/run_nx_tests.sh index 5d3b616304d..8736d77010f 100755 --- a/python/cugraph-nx/run_nx_tests.sh +++ b/python/cugraph-nx/run_nx_tests.sh @@ -12,5 +12,9 @@ # # Coverage of `cugraph_nx.algorithms` is reported and is a good sanity check that algorithms run. -# NETWORKX_GRAPH_CONVERT=cugraph NETWORKX_BACKEND_TEST_EXHAUSTIVE=True pytest --pyargs networkx "$@" -NETWORKX_TEST_BACKEND=cugraph NETWORKX_TEST_FALLBACK_TO_NX=True pytest --pyargs networkx --cov=cugraph_nx/algorithms --cov-report term-missing --no-cov-on-fail "$@" +NETWORKX_GRAPH_CONVERT=cugraph NETWORKX_BACKEND_TEST_EXHAUSTIVE=True \ +NETWORKX_TEST_BACKEND=cugraph NETWORKX_TEST_FALLBACK_TO_NX=True \ + pytest --pyargs networkx \ + --cov=cugraph_nx/algorithms \ + --cov-report term-missing --no-cov-on-fail \ + "$@" From 28faf521ff2c6e76fd49399167b63fab83ce51b6 Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Thu, 17 Aug 2023 00:10:51 -0500 Subject: [PATCH 2/3] clearer --- python/cugraph-nx/cugraph_nx/interface.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/cugraph-nx/cugraph_nx/interface.py b/python/cugraph-nx/cugraph_nx/interface.py index 1b4ff04980d..d39f7df8d6b 100644 --- a/python/cugraph-nx/cugraph_nx/interface.py +++ b/python/cugraph-nx/cugraph_nx/interface.py @@ -22,6 +22,7 @@ class BackendInterface: @staticmethod def convert_from_nx(graph, *args, edge_attrs=None, weight=None, **kwargs): if weight is not None: + # MAINT: networkx 3.0, 3.1 # For networkx 3.0 and 3.1 compatibility if edge_attrs is not None: raise TypeError( @@ -58,7 +59,9 @@ def key(testpath): from packaging.version import parse - if parse("3.0a0") <= parse(nx.__version__) < parse("3.2dev0"): + nxver = parse(nx.__version__) + if nxver.major == 3 and nxver.minor in {0, 1}: + # MAINT: networkx 3.0, 3.1 xfail.update( { key( From a04883a2e1829f710354a2502beb227938282fda Mon Sep 17 00:00:00 2001 From: Erik Welch Date: Mon, 21 Aug 2023 14:49:34 -0500 Subject: [PATCH 3/3] Add docstring to `on_start_tests` --- python/cugraph-nx/cugraph_nx/interface.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/python/cugraph-nx/cugraph_nx/interface.py b/python/cugraph-nx/cugraph_nx/interface.py index d39f7df8d6b..ccd8d418d30 100644 --- a/python/cugraph-nx/cugraph_nx/interface.py +++ b/python/cugraph-nx/cugraph_nx/interface.py @@ -39,6 +39,13 @@ def convert_to_nx(obj, *, name: str | None = None): @staticmethod def on_start_tests(items): + """Modify pytest items after tests have been collected. + + This is called during ``pytest_collection_modifyitems`` phase of pytest. + We use this to set `xfail` on tests we expect to fail. See: + + https://docs.pytest.org/en/stable/reference/reference.html#std-hook-pytest_collection_modifyitems + """ try: import pytest except ModuleNotFoundError: