Skip to content

Commit 3a052c6

Browse files
committed
feat: conversion between NumPy and igraph attribute types
1 parent 07d9f54 commit 3a052c6

File tree

2 files changed

+40
-27
lines changed

2 files changed

+40
-27
lines changed

src/igraph_ctypes/_internal/conversion.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
VertexPair,
6969
VertexSelector,
7070
)
71-
from .utils import bytes_to_str
71+
from .utils import bytes_to_str, igraph_to_numpy_attribute_type
7272
from .wrappers import (
7373
_EdgeSelector,
7474
_Matrix,
@@ -100,6 +100,7 @@
100100
"edge_weights_to_igraph_vector_t_view",
101101
"igraph_matrix_t_to_numpy_array",
102102
"igraph_matrix_int_t_to_numpy_array",
103+
"igraph_to_numpy_attribute_type",
103104
"igraph_vector_t_to_list",
104105
"igraph_vector_bool_t_to_list",
105106
"igraph_vector_int_t_to_list",

src/igraph_ctypes/_internal/utils.py

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from numpy.typing import DTypeLike
66
from typing import Any, Callable, Iterable, Union
77

8+
from .enums import AttributeType
89
from .errors import python_exception_to_igraph_error_t
910
from .types import (
1011
np_type_of_igraph_bool_t,
@@ -29,19 +30,11 @@ def bytes_to_str(
2930
return value.decode(encoding, errors)
3031

3132

32-
def get_numpy_attribute_type_from_iterable( # noqa: C901
33+
def get_igraph_attribute_type_from_iterable( # noqa: C901
3334
it: Iterable[Any],
34-
) -> DTypeLike:
35-
"""Determines the appropriate NumPy datatype to store all the items found in
36-
the given iterable as an attribute.
37-
38-
This means that this function basically classifies the iterable into one of
39-
the following data types:
40-
41-
- np_type_of_igraph_bool_t for Boolean attributes
42-
- np_type_of_igraph_real_t for numeric attributes
43-
- np_type_of_igraph_string for string attributes
44-
- np.object_ for any other (mixed) attribute type
35+
) -> AttributeType:
36+
"""Determines the appropriate igraph attribute type to store all the items
37+
found in the given iterable as an attribute.
4538
4639
When the iterable is empty, a numeric attribute will be assumed.
4740
"""
@@ -50,41 +43,60 @@ def get_numpy_attribute_type_from_iterable( # noqa: C901
5043
item = next(it)
5144
except StopIteration:
5245
# Iterable empty
53-
return np_type_of_igraph_real_t
46+
return AttributeType.NUMERIC
5447

55-
best_fit: DTypeLike
48+
best_fit: AttributeType
5649
if isinstance(item, bool):
57-
best_fit = np_type_of_igraph_bool_t
50+
best_fit = AttributeType.BOOLEAN
5851
elif isinstance(item, (int, float, np.number)):
59-
best_fit = np_type_of_igraph_real_t
52+
best_fit = AttributeType.NUMERIC
6053
elif isinstance(item, str):
61-
best_fit = np_type_of_igraph_string
54+
best_fit = AttributeType.STRING
6255
else:
63-
return np.object_
56+
return AttributeType.OBJECT
6457

6558
for item in it:
6659
if isinstance(item, bool):
67-
if best_fit == np_type_of_igraph_string:
68-
return np.object_
60+
if best_fit == AttributeType.STRING:
61+
return AttributeType.OBJECT
6962
elif isinstance(item, (int, float, np.number)):
70-
if best_fit == np_type_of_igraph_string:
71-
return np.object_
63+
if best_fit == AttributeType.STRING:
64+
return AttributeType.OBJECT
7265
else:
73-
best_fit = np_type_of_igraph_real_t
66+
best_fit = AttributeType.NUMERIC
7467
elif isinstance(item, str):
75-
if best_fit != np_type_of_igraph_string:
76-
return np.object_
68+
if best_fit != AttributeType.STRING:
69+
return AttributeType.OBJECT
7770
else:
78-
return np.object_
71+
return AttributeType.OBJECT
7972

8073
return best_fit
8174

8275

76+
def get_numpy_attribute_type_from_iterable( # noqa: C901
77+
it: Iterable[Any],
78+
) -> DTypeLike:
79+
attr_type = get_igraph_attribute_type_from_iterable(it)
80+
return igraph_to_numpy_attribute_type(attr_type)
81+
82+
8383
def get_raw_memory_view(obj):
8484
"""Returns a view into the raw bytes of a ctypes object."""
8585
return cast(byref(obj), POINTER(c_ubyte * sizeof(obj))).contents
8686

8787

88+
def igraph_to_numpy_attribute_type(type: AttributeType) -> DTypeLike:
89+
"""Converts an igraph attribute type to an equivalent NumPy data type."""
90+
if type is AttributeType.BOOLEAN:
91+
return np_type_of_igraph_bool_t
92+
elif type is AttributeType.NUMERIC:
93+
return np_type_of_igraph_real_t
94+
elif type is AttributeType.STRING:
95+
return np_type_of_igraph_string
96+
else:
97+
return np.object_
98+
99+
88100
def nop(*args, **kwds) -> None:
89101
"""Function placeholder that does nothing."""
90102
pass

0 commit comments

Comments
 (0)