From f530e4691421bae3c3c95475c90073b3edf38e57 Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 12:59:30 -0400 Subject: [PATCH 01/13] try 311 and warning handling --- .github/workflows/testing.yml | 3 +- ci/311.yaml | 29 ++++ spaghetti/network.py | 19 ++- spaghetti/tests/test_api_network.py | 23 --- spaghetti/tests/test_dev_network.py | 29 ---- ...etwork_test_classes.py => test_network.py} | 148 ++++++++++-------- 6 files changed, 128 insertions(+), 123 deletions(-) create mode 100644 ci/311.yaml delete mode 100644 spaghetti/tests/test_api_network.py delete mode 100644 spaghetti/tests/test_dev_network.py rename spaghetti/tests/{network_test_classes.py => test_network.py} (86%) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 58afa95d..3ea34a98 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -27,7 +27,7 @@ testing: needs: linting env: - RUN_TEST: pytest -v -n auto spaghetti --cov spaghetti --doctest-modules --cov-config .coveragerc --cov-report xml --color yes --cov-append --cov-report term-missing --timeout 60 + RUN_TEST: pytest spaghetti -v -r a -n auto --cov spaghetti --doctest-modules --cov-config .coveragerc --cov-report xml --color yes --cov-append --cov-report term-missing --timeout 60 name: ${{ matrix.os }}, ${{ matrix.environment-file }} runs-on: ${{ matrix.os }} timeout-minutes: 30 @@ -41,6 +41,7 @@ - ci/310-BASE.yaml - ci/310-DEV.yaml - ci/310-DEV_shapely_dev.yaml + - ci/311.yaml include: - environment-file: ci/310.yaml os: macos-latest diff --git a/ci/311.yaml b/ci/311.yaml new file mode 100644 index 00000000..6283255b --- /dev/null +++ b/ci/311.yaml @@ -0,0 +1,29 @@ +name: test +channels: + - conda-forge +dependencies: + - python=3.11 + # required + - esda + - libpysal + - numpy + - pandas>=1.0 + - pip + - rtree + - scipy>=1.0 + - watermark + # testing/formatting + - black + - codecov + - pytest + - pytest-cov + - pytest-timeout + - pytest-xdist + # optional + - geopandas>=0.7.0 + # for docs build action (this env only) + - nbsphinx + - numpydoc + - sphinx + - sphinxcontrib-bibtex + - sphinx_bootstrap_theme diff --git a/spaghetti/network.py b/spaghetti/network.py index 8a002331..911831dc 100644 --- a/spaghetti/network.py +++ b/spaghetti/network.py @@ -1010,19 +1010,29 @@ def distancebandweights(self, threshold, n_processes=1, gen_tree=False): >>> import spaghetti >>> from libpysal import examples + >>> import warnings >>> streets_file = examples.get_path("streets.shp") >>> ntw = spaghetti.Network(in_data=streets_file) Create a contiguity-based ``W`` object based on network distance, ``500`` US feet in this case. - >>> w = ntw.distancebandweights(threshold=500) + >>> with warnings.catch_warnings(): + ... warnings.filterwarnings( + ... "ignore", "The weights matrix is not fully connected", UserWarning + ... ) + ... w = ntw.distancebandweights(threshold=500) Show the number of units in the ``W`` object. >>> w.n 230 + There are 7 components in the ``W`` object. + + >>> w.n_components + 7 + There are ``8`` units with ``3`` neighbors in the ``W`` object. >>> w.histogram[-1] @@ -2757,8 +2767,13 @@ def extract_component(net, component_id, weightings=None): >>> from libpysal import examples >>> import spaghetti + >>> import warnings >>> snow_net = examples.get_path("Soho_Network.shp") - >>> ntw = spaghetti.Network(in_data=snow_net, extractgraph=False) + >>> with warnings.catch_warnings(): + ... warnings.filterwarnings( + ... "ignore", "The weights matrix is not fully connected", UserWarning + ... ) + ... ntw = spaghetti.Network(in_data=snow_net, extractgraph=False) The network is not fully connected. diff --git a/spaghetti/tests/test_api_network.py b/spaghetti/tests/test_api_network.py deleted file mode 100644 index 3fbcaee5..00000000 --- a/spaghetti/tests/test_api_network.py +++ /dev/null @@ -1,23 +0,0 @@ -""" Testing for the spaghetti api import structure. -""" - -# api import structure -import spaghetti - -from .network_test_classes import ( - TestNetwork, - TestNetworkAnalysis, - TestNetworkPointPattern, -) - -# run tests on spaghetti.network.Network -TestNetwork.spaghetti = spaghetti -TestNetwork() - -# run tests on spaghetti.network.PointPattern -TestNetworkPointPattern.spaghetti = spaghetti -TestNetworkPointPattern() - -# run tests on spaghetti.analysis -TestNetworkAnalysis.spaghetti = spaghetti -TestNetworkAnalysis() diff --git a/spaghetti/tests/test_dev_network.py b/spaghetti/tests/test_dev_network.py deleted file mode 100644 index 5f09a1d0..00000000 --- a/spaghetti/tests/test_dev_network.py +++ /dev/null @@ -1,29 +0,0 @@ -""" Testing for the spaghetti development import structure. -""" - -# dev import structure -from .. import network as spaghetti -from .. import util -from .network_test_classes import ( - TestNetwork, - TestNetworkAnalysis, - TestNetworkPointPattern, - TestNetworkUtils, -) - -# run tests on spaghetti.network.Network -TestNetwork.spaghetti = spaghetti -TestNetwork() - -# run tests on spaghetti.network.PointPattern -TestNetworkPointPattern.spaghetti = spaghetti -TestNetworkPointPattern() - -# run tests on spaghetti.analysis -TestNetworkAnalysis.spaghetti = spaghetti -TestNetworkAnalysis() - -# run tests on spaghetti.util -TestNetworkUtils.spaghetti = spaghetti -TestNetworkUtils.util = util -TestNetworkUtils() diff --git a/spaghetti/tests/network_test_classes.py b/spaghetti/tests/test_network.py similarity index 86% rename from spaghetti/tests/network_test_classes.py rename to spaghetti/tests/test_network.py index 17185046..c70a64e3 100644 --- a/spaghetti/tests/network_test_classes.py +++ b/spaghetti/tests/test_network.py @@ -1,10 +1,16 @@ +""" Testing for the spaghetti api import structure. +""" + import copy +import warnings import numpy import pytest from libpysal import cg, examples, io from libpysal.common import ATOL, RTOL +import spaghetti + try: import geopandas @@ -12,6 +18,7 @@ except ImportError: GEOPANDAS_EXTINCT = True + # empirical data --------------------------------------------------------------- # network shapefile STREETS = examples.get_path("streets.shp") @@ -85,7 +92,7 @@ class TestNetwork: def setup_method(self): # empirical network instantiated from shapefile - self.ntw_shp = self.spaghetti.Network(in_data=STREETS, weightings=True) + self.ntw_shp = spaghetti.Network(in_data=STREETS, weightings=True) self.n_known_shp_arcs, self.n_known_shp_vertices = 303, 230 # native pysal geometries @@ -94,15 +101,19 @@ def setup_method(self): for arc in self.ntw_shp.arcs ] - # lattice and ring + extension - bounds, h, v = (0, 0, 2, 2), 1, 1 - self.lattice = self.spaghetti.regular_lattice(bounds, h, nv=v) - self.lines = self.lattice + RING + EXTENSION - self.ntw_from_lattice_ring = self.spaghetti.Network(in_data=self.lines) - self.ntw_from_lattice_ring.snapobservations([P0505, P052], "points") + with warnings.catch_warnings(): + warnings.filterwarnings( + "ignore", "The weights matrix is not fully connected", UserWarning + ) + # lattice and ring + extension + bounds, h, v = (0, 0, 2, 2), 1, 1 + self.lattice = spaghetti.regular_lattice(bounds, h, nv=v) + self.lines = self.lattice + RING + EXTENSION + self.ntw_from_lattice_ring = spaghetti.Network(in_data=self.lines) + self.ntw_from_lattice_ring.snapobservations([P0505, P052], "points") # Pythagorean Triple - self.triangle = self.spaghetti.Network(in_data=GOOD_TRIANGLE) + self.triangle = spaghetti.Network(in_data=GOOD_TRIANGLE) def test_network_data_read(self): # shp test against known @@ -122,7 +133,7 @@ def test_network_from_libpysal_chains(self): # network instantiated from libpysal.cg.Chain objects for dtype in (list, tuple, numpy.array): ntw_data = dtype(self.chains_from_shp) - self.ntw_from_chains = self.spaghetti.Network(in_data=ntw_data) + self.ntw_from_chains = spaghetti.Network(in_data=ntw_data) observed_components = self.ntw_from_chains.network_n_components observed_length = sum(self.ntw_from_chains.arc_lengths.values()) assert observed_components == known_components @@ -130,37 +141,37 @@ def test_network_from_libpysal_chains(self): def test_network_from_single_libpysal_chain(self): # network instantiated from a single libpysal.cg.Chain - self.ntw_chain_out = self.spaghetti.Network(in_data=P11P22_CHAIN) + self.ntw_chain_out = spaghetti.Network(in_data=P11P22_CHAIN) known_edges = self.ntw_chain_out.edges fname = "test_network.pkl" # test save and load network self.ntw_chain_out.savenetwork(fname) - self.ntw_chain_in = self.spaghetti.Network.loadnetwork(fname) + self.ntw_chain_in = spaghetti.Network.loadnetwork(fname) observed_arcs = self.ntw_chain_in.arcs assert observed_arcs == known_edges def test_network_from_vertical_libpysal_chains(self): vert_up = cg.Chain([P0505, P052]) - self.ntw_up_chain = self.spaghetti.Network(in_data=vert_up) + self.ntw_up_chain = spaghetti.Network(in_data=vert_up) assert len(self.ntw_up_chain.arcs) == len(vert_up.segments) vert_down = cg.Chain([P052, P0505]) - self.ntw_down_chain = self.spaghetti.Network(in_data=vert_down) + self.ntw_down_chain = spaghetti.Network(in_data=vert_down) assert len(self.ntw_down_chain.arcs) == len(vert_down.segments) def test_network_failures(self): # try instantiating network with single point with pytest.raises(TypeError): - self.spaghetti.Network(in_data=P11) + spaghetti.Network(in_data=P11) # try instantiating network with list of single point with pytest.raises(TypeError): - self.spaghetti.Network(in_data=[P11]) + spaghetti.Network(in_data=[P11]) @pytest.mark.skipif(GEOPANDAS_EXTINCT, reason="Missing Geopandas") def test_network_from_geopandas(self): # network instantiated from geodataframe gdf = geopandas.read_file(STREETS) - self.ntw_gdf = self.spaghetti.Network(in_data=gdf, w_components=True) + self.ntw_gdf = spaghetti.Network(in_data=gdf, w_components=True) # gdf test against known assert len(self.ntw_gdf.arcs) == self.n_known_shp_arcs @@ -185,7 +196,7 @@ def test_round_sig(self): def test_vertex_atol(self): known_components = 1 - ntw_triangle = self.spaghetti.Network(in_data=BAD_TRIANGLE, vertex_atol=2) + ntw_triangle = spaghetti.Network(in_data=BAD_TRIANGLE, vertex_atol=2) observed_components = ntw_triangle.network_n_components assert observed_components == known_components @@ -207,6 +218,7 @@ def test_components(self): observed_graph_edge = self.ntw_shp.graph_component2edge[0][-1] assert observed_graph_edge == known_graph_edge + @pytest.mark.filterwarnings("ignore:The weights matrix is not fully connected") def test_connected_components(self): ntw = copy.deepcopy(self.ntw_from_lattice_ring) @@ -255,6 +267,7 @@ def test_connected_components(self): known_lengths = {0: 6.0, 1: 1.914213562373095} assert observed_lengths == known_lengths + @pytest.mark.filterwarnings("ignore:The weights matrix is not fully connected") def test_distance_band_weights(self): w = self.ntw_shp.distancebandweights(threshold=500) assert w.n == 230 @@ -277,18 +290,21 @@ def test_split_arcs_dist_1000(self): n1000 = self.ntw_shp.split_arcs(1000.0) assert len(n1000.arcs) == 303 + @pytest.mark.filterwarnings("ignore:The weights matrix is not fully connected") def test_split_arcs_dist_ntw_from_lattice_ring_2(self): n_2 = self.ntw_from_lattice_ring.split_arcs(0.2) known_neighbors = [(1, 17), (1, 25), (1, 26), (18, 19)] observed_neighbors = n_2.w_network.neighbors[1, 18] assert observed_neighbors == known_neighbors + @pytest.mark.filterwarnings("ignore:The weights matrix is not fully connected") def test_split_arcs_dist_ntw_from_lattice_ring_3(self): n_3 = self.ntw_from_lattice_ring.split_arcs(0.3) known_neighbors = [(1, 16), (1, 22), (1, 23), (17, 18)] observed_neighbors = n_3.w_network.neighbors[1, 17] assert observed_neighbors == known_neighbors + @pytest.mark.filterwarnings("ignore:The weights matrix is not fully connected") def test_split_arcs_dist_ntw_from_lattice_ring_5(self): n_5 = self.ntw_from_lattice_ring.split_arcs(0.5) known_neighbors = [(1, 14), (1, 16), (1, 17), (2, 15)] @@ -330,8 +346,8 @@ def test_shortest_paths(self): # asymmetric point pattern bounds, h, v = (0, 0, 3, 3), 2, 2 - lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) - ntw = self.spaghetti.Network(in_data=lattice) + lattice = spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) + ntw = spaghetti.Network(in_data=lattice) POINTS1 = [P0505, P2525] POINTS2 = [P0525, P2505, cg.Point((0.75, 0.6))] @@ -355,8 +371,8 @@ def test_shortest_paths(self): # test error with pytest.raises(AttributeError): - lattice = self.spaghetti.regular_lattice((0, 0, 4, 4), 4) - ntw = self.spaghetti.Network(in_data=lattice) + lattice = spaghetti.regular_lattice((0, 0, 4, 4), 4) + ntw = spaghetti.Network(in_data=lattice) ntw.shortest_paths([], synth_obs) @pytest.mark.filterwarnings("ignore:There is a least one point pattern") @@ -366,9 +382,7 @@ def test_extract_component(self): # test longest component with pytest.warns(UserWarning, match="There is a least one point pattern"): - longest = self.spaghetti.extract_component( - ntw, ntw.network_longest_component - ) + longest = spaghetti.extract_component(ntw, ntw.network_longest_component) # observed values observed_napts = longest.non_articulation_points # known values @@ -376,7 +390,7 @@ def test_extract_component(self): assert observed_napts == known_napts # test largest component - largest = self.spaghetti.extract_component(ntw, ntw.network_largest_component) + largest = spaghetti.extract_component(ntw, ntw.network_largest_component) # observed values observed_arcs, observed_edges = largest.arcs, largest.edges @@ -400,7 +414,7 @@ def test_extract_component(self): def test_spanning_tree(self): # minimum known_len = 7.0 - mst = self.spaghetti.spanning_tree( + mst = spaghetti.spanning_tree( self.triangle, method="sort", maximum=False, silence_warnings=True ) observed_len = sum(mst.arc_lengths.values()) @@ -408,7 +422,7 @@ def test_spanning_tree(self): # maximum known_len = 9.0 - mst = self.spaghetti.spanning_tree( + mst = spaghetti.spanning_tree( self.triangle, method="sort", maximum=True, silence_warnings=True ) observed_len = sum(mst.arc_lengths.values()) @@ -416,12 +430,12 @@ def test_spanning_tree(self): # method error with pytest.raises(ValueError): - self.spaghetti.spanning_tree(self.triangle, method="tors") + spaghetti.spanning_tree(self.triangle, method="tors") @pytest.mark.skipif(GEOPANDAS_EXTINCT, reason="Missing Geopandas") def test_element_as_gdf(self): # extract both vertices and arcs - vertices, arcs = self.spaghetti.element_as_gdf( + vertices, arcs = spaghetti.element_as_gdf( self.ntw_shp, vertices=True, arcs=True ) # test arcs @@ -438,34 +452,34 @@ def test_element_as_gdf(self): assert observed_arc_wkt == known_arc_wkt # extract only arcs - arcs = self.spaghetti.element_as_gdf(self.ntw_shp, arcs=True) + arcs = spaghetti.element_as_gdf(self.ntw_shp, arcs=True) observed_arc = arcs.loc[(arcs["id"] == (0, 1)), "geometry"].squeeze() observed_arc_wkt = observed_arc.wkt assert observed_arc_wkt == known_arc_wkt # extract symmetric routes known_length, bounds, h, v = 2.6, (0, 0, 3, 3), 2, 2 - lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) - ntw = self.spaghetti.Network(in_data=lattice) + lattice = spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) + ntw = spaghetti.Network(in_data=lattice) SYNTH_OBS = [cg.Point([0.2, 1.3]), cg.Point([0.2, 1.7]), cg.Point([2.8, 1.5])] ntw.snapobservations(SYNTH_OBS, synth_obs) _, tree = ntw.allneighbordistances(synth_obs, gen_tree=True) paths = ntw.shortest_paths(tree, synth_obs) - paths_gdf = self.spaghetti.element_as_gdf(ntw, routes=paths) + paths_gdf = spaghetti.element_as_gdf(ntw, routes=paths) observed_length = paths_gdf.loc[0, "geometry"].length assert observed_length == known_length # extract asymmetric routes known_origins, bounds, h, v = 2, (0, 0, 3, 3), 2, 2 - lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) - ntw = self.spaghetti.Network(in_data=lattice) + lattice = spaghetti.regular_lattice(bounds, h, nv=v, exterior=False) + ntw = spaghetti.Network(in_data=lattice) POINTS1 = [P0505, P2525] POINTS2 = [P0525, P2505] ntw.snapobservations(POINTS1, points1) ntw.snapobservations(POINTS2, points2) _, tree = ntw.allneighbordistances(points1, points2, gen_tree=True) paths = ntw.shortest_paths(tree, points1, pp_dest=points2) - paths_gdf = self.spaghetti.element_as_gdf(ntw, routes=paths) + paths_gdf = spaghetti.element_as_gdf(ntw, routes=paths) observed_origins = paths_gdf["O"].nunique() assert observed_origins == known_origins @@ -473,14 +487,14 @@ def test_regular_lattice(self): # 4x4 regular lattice with the exterior known = [P00, P10] bounds = (0, 0, 3, 3) - lattice = self.spaghetti.regular_lattice(bounds, 2, nv=2, exterior=True) + lattice = spaghetti.regular_lattice(bounds, 2, nv=2, exterior=True) observed = lattice[0].vertices assert observed == known # 5x5 regular lattice without the exterior known = [P33, P34] bounds = (0, 0, 4, 4) - lattice = self.spaghetti.regular_lattice(bounds, 3, exterior=False) + lattice = spaghetti.regular_lattice(bounds, 3, exterior=False) observed = lattice[-1].vertices assert observed == known @@ -490,24 +504,24 @@ def test_regular_lattice(self): (724286.1381211297, 875929.0396895551), ] shp = io.open(STREETS) - lattice = self.spaghetti.regular_lattice(shp.bbox, 5, nv=7, exterior=True) + lattice = spaghetti.regular_lattice(shp.bbox, 5, nv=7, exterior=True) observed_vertices = lattice[0].vertices for observed, known in zip(observed_vertices, known_vertices): assert (observed[0], observed[1]) == known # test for Type Error with pytest.raises(TypeError): - self.spaghetti.regular_lattice(bounds, [[4]]) + spaghetti.regular_lattice(bounds, [[4]]) # test for Runtime Error with pytest.raises(RuntimeError): - self.spaghetti.regular_lattice((0, 0, 1), 1) + spaghetti.regular_lattice((0, 0, 1), 1) # ------------------------------------------------------------------------------- class TestNetworkPointPattern: def setup_method(self): - self.ntw = self.spaghetti.Network(in_data=STREETS) + self.ntw = spaghetti.Network(in_data=STREETS) self.obs = [schools, crimes] self.OBS = [SCHOOLS, CRIMES] self.idxs = ["pp1", "pp2"] @@ -535,7 +549,7 @@ def test_pp_from_libpysal_points(self): def test_pp_from_single_libpysal_point(self): # network instantiated from a single libpysal.cg.Chain known_dist = 1.4142135623730951 - self.ntw_from_chain = self.spaghetti.Network(in_data=P11P22_CHAIN) + self.ntw_from_chain = spaghetti.Network(in_data=P11P22_CHAIN) self.ntw_from_chain.snapobservations(P00, synth_obs) snap_dist = self.ntw_from_chain.pointpatterns[synth_obs].dist_snapped[0] assert snap_dist == pytest.approx(known_dist, 0.0000000001) @@ -543,7 +557,7 @@ def test_pp_from_single_libpysal_point(self): # network instantiated from a single vertical (up) libpysal.cg.Chain chain = cg.Chain([P11, P12]) known_dist = 1.0 - self.ntw_from_chain = self.spaghetti.Network(in_data=chain) + self.ntw_from_chain = spaghetti.Network(in_data=chain) self.ntw_from_chain.snapobservations(cg.Point((0, 1.5)), synth_obs) snap_dist = self.ntw_from_chain.pointpatterns[synth_obs].dist_snapped[0] assert snap_dist == known_dist @@ -551,14 +565,14 @@ def test_pp_from_single_libpysal_point(self): # network instantiated from a single vertical (down) libpysal.cg.Chain chain = cg.Chain([cg.Point((5, 5)), cg.Point((5, 4))]) known_dist = 1.5 - self.ntw_from_chain = self.spaghetti.Network(in_data=chain) + self.ntw_from_chain = spaghetti.Network(in_data=chain) self.ntw_from_chain.snapobservations(cg.Point((6.5, 4.5)), synth_obs) snap_dist = self.ntw_from_chain.pointpatterns[synth_obs].dist_snapped[0] assert snap_dist == known_dist def test_pp_failures(self): # network instantiated from a single libpysal.cg.Chain - self.ntw_from_chain = self.spaghetti.Network(in_data=P11P22_CHAIN) + self.ntw_from_chain = spaghetti.Network(in_data=P11P22_CHAIN) # try snapping chain with pytest.raises(TypeError): self.ntw_from_chain.snapobservations(P11P22_CHAIN, "chain") @@ -711,10 +725,8 @@ def test_nearest_neighbor_distances(self): @pytest.mark.skipif(GEOPANDAS_EXTINCT, reason="Missing Geopandas") def test_element_as_gdf(self): - obs = self.spaghetti.element_as_gdf(self.ntw, pp_name=schools) - snap_obs = self.spaghetti.element_as_gdf( - self.ntw, pp_name=schools, snapped=True - ) + obs = spaghetti.element_as_gdf(self.ntw, pp_name=schools) + snap_obs = spaghetti.element_as_gdf(self.ntw, pp_name=schools, snapped=True) known_dist = 205.65961300587043 observed_point = obs.loc[(obs["id"] == 0), "geometry"].squeeze() @@ -723,7 +735,7 @@ def test_element_as_gdf(self): assert observed_dist == pytest.approx(known_dist, 0.00000001) with pytest.raises(KeyError): - self.spaghetti.element_as_gdf(self.ntw, pp_name="i_should_not_exist") + spaghetti.element_as_gdf(self.ntw, pp_name="i_should_not_exist") # ------------------------------------------------------------------------------- @@ -731,8 +743,8 @@ class TestNetworkAnalysis: def setup_method(self): # synthetic test data bounds, h, v = (0, 0, 3, 3), 2, 2 - lattice = self.spaghetti.regular_lattice(bounds, h, nv=v, exterior=True) - self.ntw = self.spaghetti.Network(in_data=lattice) + lattice = spaghetti.regular_lattice(bounds, h, nv=v, exterior=True) + self.ntw = spaghetti.Network(in_data=lattice) chains = [ cg.Chain( [ @@ -753,7 +765,7 @@ def setup_method(self): self.test_steps = 10 # empirical test_data - self.ntw_shp = self.spaghetti.Network(in_data=STREETS) + self.ntw_shp = spaghetti.Network(in_data=STREETS) self.ntw_shp.snapobservations(CRIMES, crimes, attribute=True) def test_global_auto_k_uniform(self): @@ -810,19 +822,19 @@ def test_moran_graph(self): # ------------------------------------------------------------------------------- class TestNetworkUtils: def setup_method(self): - self.ntw = self.spaghetti.Network(in_data=STREETS) + self.ntw = spaghetti.Network(in_data=STREETS) self.P00, self.P01 = P00, P01 self.P10, self.P11 = P10, P11 def test_compute_length(self): point1, point2 = (0, 0), (1, 1) known_length = 1.4142135623730951 - observed_length = self.util.compute_length(point1, point2) + observed_length = spaghetti.util.compute_length(point1, point2) assert observed_length == pytest.approx(known_length, 0.0001) def test_get_neighbor_distances(self): known_neighs = {1: 102.62353453439829, 2: 660.000001049743} - observed_neighs = self.util.get_neighbor_distances( + observed_neighs = spaghetti.util.get_neighbor_distances( self.ntw, 0, self.ntw.arc_lengths ) for k in known_neighs.keys(): @@ -830,23 +842,23 @@ def test_get_neighbor_distances(self): def test_generate_tree(self): known_path = [23, 22, 20, 19, 170, 2, 0] - distance, pred = self.util.dijkstra(self.ntw, 0) - tree = self.util.generatetree(pred) + distance, pred = spaghetti.util.dijkstra(self.ntw, 0) + tree = spaghetti.util.generatetree(pred) assert tree[3] == known_path def test_dijkstra(self): - distance, pred = self.util.dijkstra(self.ntw, 0) + distance, pred = spaghetti.util.dijkstra(self.ntw, 0) assert distance[196] == pytest.approx(5505.668247, 0.0001) assert pred[196] == 133 def test_dijkstra_mp(self): - distance, pred = self.util.dijkstra_mp((self.ntw, 0)) + distance, pred = spaghetti.util.dijkstra_mp((self.ntw, 0)) assert distance[196] == pytest.approx(5505.668247, 0.0001) assert pred[196] == 133 def test_chain_constr(self): known_len = 1.4142135623730951 - chain = self.util.chain_constr({0: (0.0, 0.0), 1: (1.0, 1.0)}, [(0, 1)])[0] + chain = spaghetti.util.chain_constr({0: (0.0, 0.0), 1: (1.0, 1.0)}, [(0, 1)])[0] assert chain.len == pytest.approx(known_len, 0.00000000001) def test_build_chains(self): @@ -855,8 +867,8 @@ def test_build_chains(self): h_known = [self.P01, self.P11] space_h = space_v = [0.0, 1.0, 2.0] exterior, bounds = False, (0, 0, 2, 2) - _vl = self.util.build_chains(space_h, space_v, exterior, bounds, h=False) - _hl = self.util.build_chains(space_h, space_v, exterior, bounds, h=True) + _vl = spaghetti.util.build_chains(space_h, space_v, exterior, bounds, h=False) + _hl = spaghetti.util.build_chains(space_h, space_v, exterior, bounds, h=True) v_observed = _vl[0].vertices h_observed = _hl[0].vertices assert v_observed == v_known @@ -866,8 +878,8 @@ def test_build_chains(self): v_known = [self.P00, self.P01] h_known = [self.P00, self.P10] exterior, bounds = True, (0, 0, 2, 2) - _vl = self.util.build_chains(space_h, space_v, exterior, bounds, h=False) - _hl = self.util.build_chains(space_h, space_v, exterior, bounds, h=True) + _vl = spaghetti.util.build_chains(space_h, space_v, exterior, bounds, h=False) + _hl = spaghetti.util.build_chains(space_h, space_v, exterior, bounds, h=True) v_observed = _vl[0].vertices h_observed = _hl[0].vertices assert v_observed == v_known @@ -877,14 +889,14 @@ def test_build_chains(self): # see https://github.com/pysal/spaghetti/issues/666 def test_squared_distance_point_link(self): point, link = (1, 1), ((0, 0), (2, 0)) - sqrd_nearp = self.util.squared_distance_point_link(point, link) + sqrd_nearp = spaghetti.util.squared_distance_point_link(point, link) assert sqrd_nearp[0] == 1.0 assert sqrd_nearp[1].all() == numpy.array([1.0, 0.0]).all() def test_snap_points_to_links(self): points = {0: P11} links = [cg.shapes.Chain([P00, cg.shapes.Point((2, 0))])] - snapped = self.util.snap_points_to_links(points, links) + snapped = spaghetti.util.snap_points_to_links(points, links) known_coords = [xy._Point__loc for xy in snapped[0][0]] assert known_coords == [(0.0, 0.0), (2.0, 0.0)] assert snapped[0][1].all() == numpy.array([1.0, 0.0]).all() From 0e3d5c05c579ffe501082de2625ac613da8a661d Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 13:07:49 -0400 Subject: [PATCH 02/13] attempt DEV 3.11 testing --- .github/workflows/testing.yml | 12 ++++++------ ci/{310-BASE.yaml => 311-BASE.yaml} | 2 +- ci/{310-DEV.yaml => 311-DEV.yaml} | 2 +- ...DEV_shapely_dev.yaml => 311-DEV_shapely_dev.yaml} | 2 +- setup.py | 1 + 5 files changed, 10 insertions(+), 9 deletions(-) rename ci/{310-BASE.yaml => 311-BASE.yaml} (94%) rename ci/{310-DEV.yaml => 311-DEV.yaml} (94%) rename ci/{310-DEV_shapely_dev.yaml => 311-DEV_shapely_dev.yaml} (95%) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 3ea34a98..ea5cd9f7 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -38,14 +38,14 @@ - ci/38.yaml - ci/39.yaml - ci/310.yaml - - ci/310-BASE.yaml - - ci/310-DEV.yaml - - ci/310-DEV_shapely_dev.yaml - ci/311.yaml + - ci/311-BASE.yaml + - ci/311-DEV.yaml + - ci/311-DEV_shapely_dev.yaml include: - - environment-file: ci/310.yaml + - environment-file: ci/311.yaml os: macos-latest - - environment-file: ci/310.yaml + - environment-file: ci/311.yaml os: windows-latest steps: @@ -59,7 +59,7 @@ micromamba-version: 'latest' channel-priority: 'flexible' - - name: install bleeding edge libpysal & esda (Ubuntu / Python 3.10) + - name: install bleeding edge libpysal & esda (Ubuntu / Python 3.11) shell: bash -l {0} run: | pip install git+https://github.com/pysal/libpysal.git@master diff --git a/ci/310-BASE.yaml b/ci/311-BASE.yaml similarity index 94% rename from ci/310-BASE.yaml rename to ci/311-BASE.yaml index 12d6c4df..0017a3da 100644 --- a/ci/310-BASE.yaml +++ b/ci/311-BASE.yaml @@ -2,7 +2,7 @@ name: test channels: - conda-forge dependencies: - - python=3.10 + - python=3.11 # required - esda - libpysal diff --git a/ci/310-DEV.yaml b/ci/311-DEV.yaml similarity index 94% rename from ci/310-DEV.yaml rename to ci/311-DEV.yaml index 46b7e6ed..0768e40c 100644 --- a/ci/310-DEV.yaml +++ b/ci/311-DEV.yaml @@ -2,7 +2,7 @@ name: test channels: - conda-forge dependencies: - - python=3.10 + - python=3.11 # required - numpy - pandas>=1.0 diff --git a/ci/310-DEV_shapely_dev.yaml b/ci/311-DEV_shapely_dev.yaml similarity index 95% rename from ci/310-DEV_shapely_dev.yaml rename to ci/311-DEV_shapely_dev.yaml index 71117805..423fc9e5 100644 --- a/ci/310-DEV_shapely_dev.yaml +++ b/ci/311-DEV_shapely_dev.yaml @@ -3,7 +3,7 @@ channels: - conda-forge - conda-forge/label/shapely_dev dependencies: - - python=3.10 + - python=3.11 # required - numpy - pandas>=1.0 diff --git a/setup.py b/setup.py index 8eeecff7..84c6e9b7 100644 --- a/setup.py +++ b/setup.py @@ -78,6 +78,7 @@ def setup_package(): "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", ], license="3-Clause BSD", packages=[package], From 6fd50eb4834fd4c197f75192c2230dcae90067ff Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 13:13:39 -0400 Subject: [PATCH 03/13] drop shapely DEV 3.11 testing --- .github/workflows/testing.yml | 5 ++++- ci/{311-DEV_shapely_dev.yaml => 310-DEV_shapely_dev.yaml} | 0 2 files changed, 4 insertions(+), 1 deletion(-) rename ci/{311-DEV_shapely_dev.yaml => 310-DEV_shapely_dev.yaml} (100%) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index ea5cd9f7..ec452a32 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -38,16 +38,19 @@ - ci/38.yaml - ci/39.yaml - ci/310.yaml + - ci/310-DEV_shapely_dev.yaml - ci/311.yaml - ci/311-BASE.yaml - ci/311-DEV.yaml - - ci/311-DEV_shapely_dev.yaml + include: - environment-file: ci/311.yaml os: macos-latest - environment-file: ci/311.yaml os: windows-latest + fail-fast: false + steps: - name: checkout repo uses: actions/checkout@v3 diff --git a/ci/311-DEV_shapely_dev.yaml b/ci/310-DEV_shapely_dev.yaml similarity index 100% rename from ci/311-DEV_shapely_dev.yaml rename to ci/310-DEV_shapely_dev.yaml From cfe3103b858bb3e35e334f9a0605060a42d0d07f Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 13:15:33 -0400 Subject: [PATCH 04/13] forgot to change Py vers in .yml --- ci/310-DEV_shapely_dev.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/310-DEV_shapely_dev.yaml b/ci/310-DEV_shapely_dev.yaml index 423fc9e5..71117805 100644 --- a/ci/310-DEV_shapely_dev.yaml +++ b/ci/310-DEV_shapely_dev.yaml @@ -3,7 +3,7 @@ channels: - conda-forge - conda-forge/label/shapely_dev dependencies: - - python=3.11 + - python=3.10 # required - numpy - pandas>=1.0 From 0168d2dba8bd98191e57c4d742d63bda1056651f Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 14:18:02 -0400 Subject: [PATCH 05/13] more robust error testing --- spaghetti/network.py | 10 ++--- spaghetti/tests/test_network.py | 75 +++++++++++++++++++++++---------- 2 files changed, 57 insertions(+), 28 deletions(-) diff --git a/spaghetti/network.py b/spaghetti/network.py index 911831dc..6c224c33 100644 --- a/spaghetti/network.py +++ b/spaghetti/network.py @@ -2339,15 +2339,15 @@ def int_coord(c): return int(c) if (type(c) == float and c.is_integer()) else c # catch invalid split types - split_by = split_by.lower() + _split_by = split_by.lower() valid_split_types = ["distance", "count"] - if split_by not in valid_split_types: + if _split_by not in valid_split_types: msg = f"'{split_by}' is not a valid value for 'split_by'. " msg += f"Valid arguments include: {valid_split_types}." raise ValueError(msg) # catch invalid count params - if split_by == "count": + if _split_by == "count": if split_param <= 1: msg = "Splitting arcs by 1 or less is not possible. " msg += f"Currently 'split_param' is set to {split_param}." @@ -2386,7 +2386,7 @@ def int_coord(c): length = split_network.arc_lengths[arc] # set initial segmentation interval - if split_by == "distance": + if _split_by == "distance": interval = split_param else: interval = length / float(split_param) @@ -3024,7 +3024,7 @@ def spanning_tree(net, method="sort", maximum=False, silence_warnings=True): if method.lower() == "sort": spanning_tree = mst_weighted_sort(net, maximum, net_kws) else: - msg = "'%s' not a valid method for minimum spanning tree creation" + msg = "'%s' not a valid method for minimum spanning tree creation." raise ValueError(msg % method) # instantiate the spanning tree as a network object diff --git a/spaghetti/tests/test_network.py b/spaghetti/tests/test_network.py index c70a64e3..0a16cd2b 100644 --- a/spaghetti/tests/test_network.py +++ b/spaghetti/tests/test_network.py @@ -160,11 +160,12 @@ def test_network_from_vertical_libpysal_chains(self): assert len(self.ntw_down_chain.arcs) == len(vert_down.segments) def test_network_failures(self): + msg = "'libpysal.cg.shapes.Point' not supported for network instantiation." # try instantiating network with single point - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): spaghetti.Network(in_data=P11) # try instantiating network with list of single point - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): spaghetti.Network(in_data=[P11]) @pytest.mark.skipif(GEOPANDAS_EXTINCT, reason="Missing Geopandas") @@ -316,20 +317,37 @@ def test_split_arcs_count_2(self): assert len(n200.arcs) == 606 def test_split_arcs_count_1(self): - with pytest.raises(ValueError): - self.ntw_shp.split_arcs(1, split_by="count") + split_param = 1 + msg = ( + f"Splitting arcs by 1 or less is not possible. " + f"Currently 'split_param' is set to {split_param}." + ) + with pytest.raises(ValueError, match=msg): + self.ntw_shp.split_arcs(split_param, split_by="count") def test_split_arcs_count_half(self): - with pytest.raises(ValueError): - self.ntw_shp.split_arcs(0.5, split_by="count") + split_param = 0.5 + msg = ( + f"Splitting arcs by 1 or less is not possible. " + f"Currently 'split_param' is set to {split_param}." + ) + with pytest.raises(ValueError, match=msg): + self.ntw_shp.split_arcs(split_param, split_by="count") def test_split_arcs_count_1_and_half(self): - with pytest.raises(TypeError): - self.ntw_shp.split_arcs(1.99, split_by="count") + split_param = 1.5 + msg = ( + "Network arcs must split by an integer. " + f"Currently 'split_param' is set to {split_param}." + ) + with pytest.raises(TypeError, match=msg): + self.ntw_shp.split_arcs(split_param, split_by="count") def test_split_arcs_misspell(self): - with pytest.raises(ValueError): - self.ntw_shp.split_arcs(3, split_by="MasterP") + split_by = "MasterP" + msg = f"'{split_by}' is not a valid value for 'split_by'. " + with pytest.raises(ValueError, match=msg): + self.ntw_shp.split_arcs(3, split_by=split_by) def test_enum_links_vertex(self): coincident = self.ntw_shp.enum_links_vertex(24) @@ -370,7 +388,9 @@ def test_shortest_paths(self): assert observed_vertices2 == known_vertices2 # test error - with pytest.raises(AttributeError): + with pytest.raises( + AttributeError, match="The 'network_trees' attribute has not been created." + ): lattice = spaghetti.regular_lattice((0, 0, 4, 4), 4) ntw = spaghetti.Network(in_data=lattice) ntw.shortest_paths([], synth_obs) @@ -429,8 +449,10 @@ def test_spanning_tree(self): assert observed_len == known_len # method error - with pytest.raises(ValueError): - spaghetti.spanning_tree(self.triangle, method="tors") + method = "tors" + msg = f"'{method}' not a valid method for minimum spanning tree creation." + with pytest.raises(ValueError, match=msg): + spaghetti.spanning_tree(self.triangle, method=method) @pytest.mark.skipif(GEOPANDAS_EXTINCT, reason="Missing Geopandas") def test_element_as_gdf(self): @@ -510,11 +532,11 @@ def test_regular_lattice(self): assert (observed[0], observed[1]) == known # test for Type Error - with pytest.raises(TypeError): + with pytest.raises(TypeError, match="The 'nh' and 'nv' parameters"): spaghetti.regular_lattice(bounds, [[4]]) # test for Runtime Error - with pytest.raises(RuntimeError): + with pytest.raises(RuntimeError, match="The 'bounds' parameter is 3 elements"): spaghetti.regular_lattice((0, 0, 1), 1) @@ -573,11 +595,14 @@ def test_pp_from_single_libpysal_point(self): def test_pp_failures(self): # network instantiated from a single libpysal.cg.Chain self.ntw_from_chain = spaghetti.Network(in_data=P11P22_CHAIN) + msg = ( + "'libpysal.cg.shapes.Chain' not supported for point pattern instantiation." + ) # try snapping chain - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): self.ntw_from_chain.snapobservations(P11P22_CHAIN, "chain") # try snapping list of chain - with pytest.raises(TypeError): + with pytest.raises(TypeError, match=msg): self.ntw_from_chain.snapobservations([P11P22_CHAIN], "chain") @pytest.mark.skipif(GEOPANDAS_EXTINCT, reason="Missing Geopandas") @@ -615,8 +640,10 @@ def test_simulate_uniform_observations(self): assert self.known_pp1_npoints == sim.npoints def test_simulate_unsupported_distribution_observations(self): - with pytest.raises(RuntimeError): - self.ntw.simulate_observations(1, distribution="mrofinu") + distribution = "mrofinu" + msg = f"{distribution} distribution not currently supported." + with pytest.raises(RuntimeError, match=msg): + self.ntw.simulate_observations(1, distribution=distribution) def test_all_neighbor_distances(self): matrix1, tree = self.ntw.allneighbordistances(schools, gen_tree=True) @@ -692,7 +719,7 @@ def test_all_neighbor_distances_multiproccessing(self): def test_nearest_neighbor_distances(self): # general test - with pytest.raises(KeyError): + with pytest.raises(KeyError, match="Available point patterns are"): self.ntw.nearestneighbordistances("i_should_not_exist") nnd1 = self.ntw.nearestneighbordistances(schools) nnd2 = self.ntw.nearestneighbordistances(schools, destpattern=schools) @@ -734,7 +761,7 @@ def test_element_as_gdf(self): observed_dist = observed_point.distance(snap_point) assert observed_dist == pytest.approx(known_dist, 0.00000001) - with pytest.raises(KeyError): + with pytest.raises(KeyError, match="Available point patterns are"): spaghetti.element_as_gdf(self.ntw, pp_name="i_should_not_exist") @@ -794,12 +821,14 @@ def test_global_auto_k_uniform(self): numpy.testing.assert_allclose(obtained.lowerenvelope, known_lowerenvelope) def test_global_auto_k_unsupported_distribution(self): - with pytest.raises(RuntimeError): + distribution = "mrofinu" + msg = f"{distribution} distribution not currently supported." + with pytest.raises(RuntimeError, match=msg): self.ntw.GlobalAutoK( self.ntw.pointpatterns[self.mids], permutations=self.test_permutations, nsteps=self.test_steps, - distribution="mrofinu", + distribution=distribution, ) def test_moran_network(self): From 6a09ef41dcc6dd2787df52437dd6b160444919da Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 14:19:05 -0400 Subject: [PATCH 06/13] add 3.11 ref & binder env. --- .github/workflows/build_docs.yml | 2 +- README.md | 2 +- ci/310.yaml | 6 ------ docs/installation.rst | 3 ++- environment.yml | 2 +- 5 files changed, 5 insertions(+), 10 deletions(-) diff --git a/.github/workflows/build_docs.yml b/.github/workflows/build_docs.yml index 4e35b022..74728916 100644 --- a/.github/workflows/build_docs.yml +++ b/.github/workflows/build_docs.yml @@ -19,7 +19,7 @@ strategy: matrix: os: ['ubuntu-latest'] - environment-file: [ci/310.yaml] + environment-file: [ci/311.yaml] experimental: [false] defaults: run: diff --git a/README.md b/README.md index 7d66eda1..4e6040e1 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ The following are a selection of some examples that can be launched individually ## Installation -Python [3.8](https://docs.python.org/3.8/), [3.9](https://docs.python.org/3.9/), and [3.10](https://docs.python.org/3.10/) are tested for support by `spaghetti`. Please make sure that you are operating in a Python >= 3.8 environment. +Python [3.8](https://docs.python.org/3.8/), [3.9](https://docs.python.org/3.9/), [3.10](https://docs.python.org/3.10/), and [3.11](https://docs.python.org/3.11/) are tested for support by `spaghetti`. Please make sure that you are operating in a Python >= 3.8 environment. **Installing with `conda` via [`conda-forge`](https://github.com/conda-forge/spaghetti-feedstock) (highly recommended)** diff --git a/ci/310.yaml b/ci/310.yaml index 11aa6f88..2ca2b84e 100644 --- a/ci/310.yaml +++ b/ci/310.yaml @@ -21,9 +21,3 @@ dependencies: - pytest-xdist # optional - geopandas>=0.7.0 - # for docs build action (this env only) - - nbsphinx - - numpydoc - - sphinx - - sphinxcontrib-bibtex - - sphinx_bootstrap_theme diff --git a/docs/installation.rst b/docs/installation.rst index 9931d289..8bb035f4 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -1,6 +1,6 @@ .. Installation -Python 3.8_, 3.9_, and 3.10_ are tested for support by `spaghetti`. Please make sure that you are operating in a Python >= 3.8 environment. +Python 3.8_, 3.9_, 3.10_, and 3.11_ are tested for support by `spaghetti`. Please make sure that you are operating in a Python >= 3.8 environment. Installation @@ -51,6 +51,7 @@ You can also fork_ the `pysal/spaghetti`_ repo and create a local clone of your .. _3.8: https://docs.python.org/3.8/ .. _3.9: https://docs.python.org/3.9/ .. _3.10: https://docs.python.org/3.10/ +.. _3.11: https://docs.python.org/3.11/ .. _spaghetti-feedstock: https://github.com/conda-forge/spaghetti-feedstock .. _a nice example: https://geopandas.readthedocs.io/en/latest/getting_started/install.html#creating-a-new-environment .. _conda: https://docs.conda.io/en/latest/ diff --git a/environment.yml b/environment.yml index 54038bef..c917a77e 100644 --- a/environment.yml +++ b/environment.yml @@ -2,7 +2,7 @@ name: notebooks-environment channels: - conda-forge dependencies: - - python=3.10 + - python=3.11 - esda - geopandas>=0.9.0 - libspatialindex From c4b487bee8bc4d88ea083368b7707a3ee3277b71 Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 14:34:18 -0400 Subject: [PATCH 07/13] try micromamba version checking --- .github/workflows/testing.yml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index ec452a32..de6667ac 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -69,6 +69,17 @@ pip install git+https://github.com/pysal/esda.git@master if: matrix.os == 'ubuntu-latest' && contains(matrix.environment-file, 'DEV') + - name: environment info + shell: bash -l {0} + run: | + micromamba info + micromamba list + + - name: spatial versions (where geopandas is installed) + shell: bash -l {0} + run: 'python -c "import geopandas; geopandas.show_versions();"' + if: contains(matrix.environment-file, 'BASE') + - name: run tests - bash shell: bash -l {0} run: ${{ env.RUN_TEST }} From 4375321c7ab39ca83dda7b1205f37abd69096a0e Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 14:42:11 -0400 Subject: [PATCH 08/13] proper BASE logic --- .github/workflows/testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index de6667ac..7fa61c26 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -78,7 +78,7 @@ - name: spatial versions (where geopandas is installed) shell: bash -l {0} run: 'python -c "import geopandas; geopandas.show_versions();"' - if: contains(matrix.environment-file, 'BASE') + if: !contains(matrix.environment-file, 'BASE') - name: run tests - bash shell: bash -l {0} From 640998f9b26f4eb45235c1d3d64067847ab9f406 Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 14:45:18 -0400 Subject: [PATCH 09/13] proper BASE logic [2] --- .github/workflows/testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 7fa61c26..06bf850c 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -78,7 +78,7 @@ - name: spatial versions (where geopandas is installed) shell: bash -l {0} run: 'python -c "import geopandas; geopandas.show_versions();"' - if: !contains(matrix.environment-file, 'BASE') + if: not contains(matrix.environment-file, 'BASE') - name: run tests - bash shell: bash -l {0} From da05906f053562789c2ec68dd4f58c6fa957adff Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 14:51:45 -0400 Subject: [PATCH 10/13] proper BASE logic [3] --- .github/workflows/testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 06bf850c..af32a367 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -78,7 +78,7 @@ - name: spatial versions (where geopandas is installed) shell: bash -l {0} run: 'python -c "import geopandas; geopandas.show_versions();"' - if: not contains(matrix.environment-file, 'BASE') + if: not(contains(matrix.environment-file, 'BASE')) - name: run tests - bash shell: bash -l {0} From 46a3f1a58ba81395ec43625272da5716815b2cb6 Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 14:55:56 -0400 Subject: [PATCH 11/13] proper BASE logic [4] --- .github/workflows/testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index af32a367..357646e7 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -78,7 +78,7 @@ - name: spatial versions (where geopandas is installed) shell: bash -l {0} run: 'python -c "import geopandas; geopandas.show_versions();"' - if: not(contains(matrix.environment-file, 'BASE')) + if: notIn('BASE', matrix.environment-file) - name: run tests - bash shell: bash -l {0} From 8178e4fc217d9816f4e748f14a74fab4e6b0e7e3 Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 15:18:02 -0400 Subject: [PATCH 12/13] update env file names to accomodate logic --- .github/workflows/testing.yml | 16 +++++++--------- ci/{310.yaml => 310-BASE.yaml} | 0 ci/{311.yaml => 311-BARE.yaml} | 8 -------- ci/311-BASE.yaml | 8 ++++++++ ci/{38.yaml => 38-BASE.yaml} | 0 ci/{39.yaml => 39-BASE.yaml} | 0 6 files changed, 15 insertions(+), 17 deletions(-) rename ci/{310.yaml => 310-BASE.yaml} (100%) rename ci/{311.yaml => 311-BARE.yaml} (63%) rename ci/{38.yaml => 38-BASE.yaml} (100%) rename ci/{39.yaml => 39-BASE.yaml} (100%) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 357646e7..380f2193 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -35,20 +35,18 @@ matrix: os: [ubuntu-latest] environment-file: - - ci/38.yaml - - ci/39.yaml - - ci/310.yaml + - ci/38-BASE.yaml + - ci/39-BASE.yaml + - ci/310-BASE.yaml - ci/310-DEV_shapely_dev.yaml - - ci/311.yaml + - ci/311-BARE.yaml - ci/311-BASE.yaml - ci/311-DEV.yaml - include: - - environment-file: ci/311.yaml + - environment-file: ci/311-BASE.yaml os: macos-latest - - environment-file: ci/311.yaml + - environment-file: ci/311-BASE.yaml os: windows-latest - fail-fast: false steps: @@ -78,7 +76,7 @@ - name: spatial versions (where geopandas is installed) shell: bash -l {0} run: 'python -c "import geopandas; geopandas.show_versions();"' - if: notIn('BASE', matrix.environment-file) + if: contains(matrix.environment-file, 'DEV') || contains(matrix.environment-file, 'BASE') - name: run tests - bash shell: bash -l {0} diff --git a/ci/310.yaml b/ci/310-BASE.yaml similarity index 100% rename from ci/310.yaml rename to ci/310-BASE.yaml diff --git a/ci/311.yaml b/ci/311-BARE.yaml similarity index 63% rename from ci/311.yaml rename to ci/311-BARE.yaml index 6283255b..0017a3da 100644 --- a/ci/311.yaml +++ b/ci/311-BARE.yaml @@ -19,11 +19,3 @@ dependencies: - pytest-cov - pytest-timeout - pytest-xdist - # optional - - geopandas>=0.7.0 - # for docs build action (this env only) - - nbsphinx - - numpydoc - - sphinx - - sphinxcontrib-bibtex - - sphinx_bootstrap_theme diff --git a/ci/311-BASE.yaml b/ci/311-BASE.yaml index 0017a3da..6283255b 100644 --- a/ci/311-BASE.yaml +++ b/ci/311-BASE.yaml @@ -19,3 +19,11 @@ dependencies: - pytest-cov - pytest-timeout - pytest-xdist + # optional + - geopandas>=0.7.0 + # for docs build action (this env only) + - nbsphinx + - numpydoc + - sphinx + - sphinxcontrib-bibtex + - sphinx_bootstrap_theme diff --git a/ci/38.yaml b/ci/38-BASE.yaml similarity index 100% rename from ci/38.yaml rename to ci/38-BASE.yaml diff --git a/ci/39.yaml b/ci/39-BASE.yaml similarity index 100% rename from ci/39.yaml rename to ci/39-BASE.yaml From 48069206069597127e09ab27ab1c78150e00214b Mon Sep 17 00:00:00 2001 From: James Gaboardi Date: Tue, 1 Nov 2022 15:23:14 -0400 Subject: [PATCH 13/13] update step name --- .github/workflows/testing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 380f2193..47a14b90 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -73,7 +73,7 @@ micromamba info micromamba list - - name: spatial versions (where geopandas is installed) + - name: spatial versions (if geopandas is installed) shell: bash -l {0} run: 'python -c "import geopandas; geopandas.show_versions();"' if: contains(matrix.environment-file, 'DEV') || contains(matrix.environment-file, 'BASE')