Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
penguinpee opened this issue Jun 26, 2024 · 3 comments
Labels
enhancement maintenance something should be improved or is outdated

Comments

@penguinpee
Copy link

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
__________________________ 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 = <igraph.Graph object at 0x7f00841a4a50>, 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: <method 'get_adjacency' of 'igraph._igraph.GraphBase' objects> 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 = <pyunicorn.climate.tsonis.TsonisClimateNetwork object at 0x7f9692579160>
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: <method 'distances' of 'igraph._igraph.GraphBase' objects> 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
Copy link
Collaborator

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

@fkuehlein fkuehlein added maintenance something should be improved or is outdated enhancement labels Jun 27, 2024
@penguinpee
Copy link
Author

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
Copy link
Collaborator

fkuehlein commented Jun 27, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement maintenance something should be improved or is outdated
Projects
None yet
Development

No branches or pull requests

2 participants