pik-copan / pyunicorn

Unified Complex Network and Recurrence Analysis Toolbox
http://pik-potsdam.de/~donges/pyunicorn/
Other
200 stars 87 forks source link

Python 3.13: igraph tests fail with SystemError (method returned NULL without setting an exception) #227

Open penguinpee opened 5 months ago

penguinpee commented 5 months ago

Building pyunicorn (from master) with Python 3.13 (3.13.0b2) and igraph 0.11.5 the igraph tests fail.

Example of failing igraph test ```python __________________________ test_number_internal_links __________________________ [gw7] linux -- Python 3.13.0 /usr/bin/python3 def test_number_internal_links(): net = InteractingNetworks.SmallTestNetwork() > res = net.number_internal_links([0, 3, 5]) tests/test_core/test_interacting_networks.py:139: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib64/python3.13/site-packages/pyunicorn/core/interacting_networks.py:655: in number_internal_links n_links = self.internal_adjacency(node_list).sum() ../BUILDROOT/usr/lib64/python3.13/site-packages/pyunicorn/core/interacting_networks.py:402: in internal_adjacency return np.array(subgraph.get_adjacency(type=2).data).astype(np.int8) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = , type = 2, attribute = None default = 0, eids = False def _get_adjacency( self, type=GET_ADJACENCY_BOTH, attribute=None, default=0, eids=False ): """Returns the adjacency matrix of a graph. @param type: either C{GET_ADJACENCY_LOWER} (uses the lower triangle of the matrix) or C{GET_ADJACENCY_UPPER} (uses the upper triangle) or C{GET_ADJACENCY_BOTH} (uses both parts). Ignored for directed graphs. @param attribute: if C{None}, returns the ordinary adjacency matrix. When the name of a valid edge attribute is given here, the matrix returned will contain the default value at the places where there is no edge or the value of the given attribute where there is an edge. Multiple edges are not supported, the value written in the matrix in this case will be unpredictable. This parameter is ignored if I{eids} is C{True} @param default: the default value written to the cells in the case of adjacency matrices with attributes. @param eids: specifies whether the edge IDs should be returned in the adjacency matrix. Since zero is a valid edge ID, the cells in the matrix that correspond to unconnected vertex pairs will contain -1 instead of 0 if I{eids} is C{True}. If I{eids} is C{False}, the number of edges will be returned in the matrix for each vertex pair. @return: the adjacency matrix as a L{Matrix}. """ if ( type != GET_ADJACENCY_LOWER and type != GET_ADJACENCY_UPPER and type != GET_ADJACENCY_BOTH ): # Maybe it was called with the first argument as the attribute name type, attribute = attribute, type if type is None: type = GET_ADJACENCY_BOTH if eids: result = Matrix(GraphBase.get_adjacency(self, type, eids)) result -= 1 return result if attribute is None: > return Matrix(GraphBase.get_adjacency(self, type)) E SystemError: returned NULL without setting an exception /usr/lib64/python3.13/site-packages/igraph/adjacency.py:62: SystemError _____________________ test_correlation_weighted_closeness ______________________ [gw2] linux -- Python 3.13.0 /usr/bin/python3 def test_correlation_weighted_closeness(): res = TsonisClimateNetwork.SmallTestNetwork().\ > correlation_weighted_closeness() tests/test_climate/test_tsonis.py:98: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ../BUILDROOT/usr/lib64/python3.13/site-packages/pyunicorn/climate/tsonis.py:300: in correlation_weighted_closeness return self.closeness('correlation') ../BUILDROOT/usr/lib64/python3.13/site-packages/pyunicorn/core/network.py:3396: in closeness path_lengths = self.path_lengths(link_attribute) ../BUILDROOT/usr/lib64/python3.13/site-packages/pyunicorn/core/cache.py:118: in uncached return f(self, *args, **kwargs) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ self = link_attribute = 'correlation' @Cached.method(name="path lengths") def path_lengths(self, link_attribute=None): """ For each pair of nodes i,j, return the (weighted) shortest path length from i to j (also called the distance from i to j). This is the shortest length of a path from i to j along links, or infinity if there is no such path. The length of links can be specified by an optional link attribute. **Example:** >>> print(Network.SmallTestNetwork().path_lengths()) Calculating all shortest path lengths... [[ 0. 2. 2. 1. 1. 1.] [ 2. 0. 1. 1. 1. 3.] [ 2. 1. 0. 2. 1. 3.] [ 1. 1. 2. 0. 2. 2.] [ 1. 1. 1. 2. 0. 2.] [ 1. 3. 3. 2. 2. 0.]] :arg str link_attribute: Optional name of the link attribute to be used as the links' length. If None, links have length 1. (Default: None) :rtype: square array [[float]] """ if link_attribute == "topological": print("WARNING: link_attribute='topological' is deprecated.\n" + "Use link_attribute=None instead.") link_attribute = None if link_attribute is None: if self.silence_level <= 1: print("Calculating all shortest path lengths...") # fixed negative numbers to infinity! pl = np.array(self.graph.distances(), dtype=float) pl[pl < 0] = np.inf return pl else: if self.silence_level <= 1: print("Calculating weighted shortest path lengths...") return np.array( > self.graph.distances(weights=link_attribute, mode=1)) E SystemError: returned NULL without setting an exception ../BUILDROOT/usr/lib64/python3.13/site-packages/pyunicorn/core/network.py:2887: SystemError ```

List of all failed tests (all with SystemError):

FAILED tests/test_core/test_interacting_networks.py::test_number_internal_links
FAILED tests/test_climate/test_tsonis.py::test_correlation_weighted_closeness
FAILED tests/test_core/test_interacting_networks.py::test_internal_link_density
FAILED tests/test_core/test_interacting_networks.py::test_internal_degree - S...
FAILED tests/test_core/test_geo_network.py::test_ErdosRenyi - SystemError: <m...
FAILED tests/test_climate/test_climate_network.py::test_correlation_distance_weighted_closeness
FAILED tests/test_core/test_geo_network.py::test_average_distance_weighted_path_length
FAILED tests/test_core/test_interacting_networks.py::test_internal_indegree
FAILED tests/test_core/test_interacting_networks.py::test_internal_outdegree
FAILED tests/test_core/test_geo_network.py::test_ConfigurationModel - SystemE...
FAILED tests/test_core/test_network.py::test_BarabasiAlbert_igraph - SystemEr...
FAILED tests/test_core/test_geo_network.py::test_distance_weighted_closeness
FAILED tests/test_climate/test_tsonis.py::test_local_correlation_weighted_vulnerability
FAILED tests/test_climate/test_climate_network.py::test_local_correlation_distance_weighted_vulnerability
FAILED tests/test_core/test_geo_network.py::test_local_distance_weighted_vulnerability
FAILED tests/test_core/test_interacting_networks.py::test_internal_adjacency
FAILED tests/test_core/test_network.py::test_nsi_newman_betweenness - SystemE...
FAILED tests/test_climate/test_coupled_climate_network.py::test_internal_link_density
FAILED tests/test_core/test_network.py::test_ConfigurationModel - SystemError...
FAILED tests/test_core/test_network.py::test_WattsStrogatz - SystemError: <me...
FAILED tests/test_core/test_spatial_network.py::test_average_distance_weighted_path_length
FAILED tests/test_climate/test_tsonis.py::test_correlation_weighted_average_path_length
FAILED tests/test_core/test_spatial_network.py::test_distance_weighted_closeness
FAILED tests/test_core/test_spatial_network.py::test_local_distance_weighted_vulnerability
FAILED tests/test_core/test_network.py::test_permutations - SystemError: <met...
FAILED tests/test_core/test_network.py::test_nsi - SystemError: <method 'get_...
FAILED tests/test_core/test_network.py::test_ErdosRenyi - SystemError: <metho...
FAILED tests/test_core/test_network.py::test_arenas_betweenness - SystemError...
FAILED tests/test_core/test_network.py::test_nsi_arenas_betweenness - SystemE...
FAILED tests/test_core/test_network.py::test_newman_betweenness - SystemError...

With Python 3.12 those tests succeed.

fkuehlein commented 5 months ago

Hi @penguinpee,

thank you for the report!

Python 3.13 builds are not yet included in Pyunicorn's CI. Will definitely look into this in the future. Currently, Python 3.8/3.9/3.10/3.11/3.12 are actively maintained.

If you need to run Python 3.13 and can find a fix, feel free to send a PR! :)

Cheers, f

penguinpee commented 5 months ago

Thanks. One could argue that Python 3.13 is more actively maintained than the current stable releases as it is prepared for release in three month time. It will be the version Fedora 41 ships with, also planned for October.

fkuehlein commented 5 months ago

Sure! Establishing Python 3.13 support is definitely on the TODO.

Edit: What I meant to say was that currently Pyunicorn is actively maintained to run on Python 3.8/3.9/3.10/3.11/3.12. As we have not been able to establish Python 3.13 support yet, please resort to previous versions if possible.