1- from abc import ABC , abstractmethod
2- from ctypes import (
3- pointer ,
4- py_object ,
5- )
6- from dataclasses import dataclass , field
1+ from ctypes import pointer
72from math import nan
8- from typing import Any , Callable , MutableMapping , Optional
3+ from typing import Any , Callable , Optional
94
10- from .conversion import igraph_vector_int_t_to_numpy_array_view
11- from .lib import (
5+ from igraph_ctypes . _internal .conversion import igraph_vector_int_t_to_numpy_array_view
6+ from igraph_ctypes . _internal .lib import (
127 igraph_error ,
138 igraph_vector_resize ,
149 igraph_vector_set ,
1914 igraph_strvector_resize ,
2015 igraph_strvector_set ,
2116)
22- from .refcount import incref , decref
23- from .types import igraph_attribute_table_t , IntArray
24- from .utils import nop , protect_with
25-
26- __all__ = ("AttributeHandlerBase" , "AttributeHandler" , "AttributeStorage" )
27-
17+ from igraph_ctypes ._internal .types import igraph_attribute_table_t
18+ from igraph_ctypes ._internal .utils import nop , protect_with
19+
20+ from .storage import (
21+ DictAttributeStorage ,
22+ assign_storage_to_graph ,
23+ detach_storage_from_graph ,
24+ get_storage_from_graph ,
25+ )
2826
29- ################################################################################
27+ __all__ = (
28+ "AttributeHandlerBase" ,
29+ "AttributeHandler" ,
30+ )
3031
3132
3233def _trigger_error (error : int ) -> int :
@@ -66,130 +67,20 @@ def _as_parameter_(self):
6667 return self ._table_ptr
6768
6869
69- class AttributeStorage (ABC ):
70- """Interface specification for objects that store graph, vertex and edge
71- attributes.
72- """
73-
74- @abstractmethod
75- def add_vertices (self , graph , n : int ) -> None :
76- """Notifies the attribute storage object that the given number of
77- new vertices were added to the graph.
78- """
79- raise NotImplementedError
80-
81- @abstractmethod
82- def add_edges (self , graph , edges ) -> None :
83- """Notifies the attribute storage object that the given edges were
84- added to the graph.
85- """
86- raise NotImplementedError
87-
88- @abstractmethod
89- def clear (self ):
90- """Clears the storage area, removing all attributes."""
91- raise NotImplementedError
92-
93- @abstractmethod
94- def copy (
95- self ,
96- copy_graph_attributes : bool = True ,
97- copy_vertex_attributes : bool = True ,
98- copy_edge_attributes : bool = True ,
99- ):
100- """Creates a shallow copy of the storage area."""
101- raise NotImplementedError
102-
103- @abstractmethod
104- def get_graph_attribute_map (self ) -> MutableMapping [str , Any ]:
105- """Returns a mutable mapping into the storage area that stores the graph
106- attributes.
107- """
108- raise NotImplementedError
109-
110-
111- @dataclass (frozen = True )
112- class DictAttributeStorage (AttributeStorage ):
113- """dictionary-based storage area for the graph, vertex and edge attributes
114- of a graph.
115- """
116-
117- graph_attributes : dict [str , Any ] = field (default_factory = dict )
118- vertex_attributes : dict [str , list [Any ]] = field (default_factory = dict )
119- edge_attributes : dict [str , list [Any ]] = field (default_factory = dict )
120-
121- def add_vertices (self , graph , n : int ) -> None :
122- pass
123-
124- def add_edges (self , graph , edges : IntArray ) -> None :
125- pass
126-
127- def clear (self ) -> None :
128- self .graph_attributes .clear ()
129- self .vertex_attributes .clear ()
130- self .edge_attributes .clear ()
131-
132- def copy (
133- self ,
134- copy_graph_attributes : bool = True ,
135- copy_vertex_attributes : bool = True ,
136- copy_edge_attributes : bool = True ,
137- ):
138- return self .__class__ (
139- self .graph_attributes .copy () if copy_graph_attributes else {},
140- self .vertex_attributes .copy () if copy_vertex_attributes else {},
141- self .edge_attributes .copy () if copy_edge_attributes else {},
142- )
143-
144- def get_graph_attribute_map (self ) -> MutableMapping [str , Any ]:
145- return self .graph_attributes
146-
147-
148- def _assign_storage_to_graph (graph , storage : Optional [AttributeStorage ] = None ) -> None :
149- """Assigns an attribute storage object to a graph, taking care of
150- increasing or decreasing the reference count of the storage object if needed.
151- """
152- try :
153- old_storage = graph .contents .attr
154- except ValueError :
155- # No storage yet, this is OK
156- old_storage = None
157-
158- if old_storage is storage :
159- # Nothing to do
160- return
161-
162- if old_storage is not None :
163- decref (old_storage )
164-
165- if storage is not None :
166- graph .contents .attr = py_object (incref (storage ))
167- else :
168- graph .contents .attr = py_object ()
169-
170-
171- def _get_storage_from_graph (graph ) -> AttributeStorage :
172- return graph .contents .attr
173-
174-
175- def _detach_storage_from_graph (graph ) -> None :
176- return _assign_storage_to_graph (graph , None )
177-
178-
17970class AttributeHandler (AttributeHandlerBase ):
18071 """Attribute handler implementation that uses a DictAttributeStorage_
18172 as its storage backend.
18273 """
18374
18475 def init (self , graph , attr ):
185- _assign_storage_to_graph (graph , DictAttributeStorage ())
76+ assign_storage_to_graph (graph , DictAttributeStorage ())
18677
18778 def destroy (self , graph ) -> None :
188- storage = _get_storage_from_graph (graph )
79+ storage = get_storage_from_graph (graph )
18980 if storage :
19081 storage .clear ()
19182
192- _detach_storage_from_graph (graph )
83+ detach_storage_from_graph (graph )
19384
19485 def copy (
19586 self ,
@@ -199,11 +90,11 @@ def copy(
19990 copy_vertex_attributes : bool ,
20091 copy_edge_attributes : bool ,
20192 ):
202- storage = _get_storage_from_graph (graph )
93+ storage = get_storage_from_graph (graph )
20394 new_storage = storage .copy (
20495 copy_graph_attributes , copy_vertex_attributes , copy_edge_attributes
20596 )
206- _assign_storage_to_graph (to , new_storage )
97+ assign_storage_to_graph (to , new_storage )
20798
20899 def add_vertices (self , graph , n : int , attr ) -> None :
209100 # attr will only ever be NULL here so raise an error if it is not
@@ -214,7 +105,7 @@ def add_vertices(self, graph, n: int, attr) -> None:
214105 )
215106
216107 # Extend the existing attribute containers
217- _get_storage_from_graph (graph ).add_vertices (graph , n )
108+ get_storage_from_graph (graph ).add_vertices (graph , n )
218109
219110 def permute_vertices (self , graph , to , mapping ):
220111 pass
@@ -232,7 +123,7 @@ def add_edges(self, graph, edges, attr) -> None:
232123
233124 # Extend the existing attribute containers
234125 edge_array = igraph_vector_int_t_to_numpy_array_view (edges ).reshape ((- 1 , 2 ))
235- _get_storage_from_graph (graph ).add_edges (graph , edge_array )
126+ get_storage_from_graph (graph ).add_edges (graph , edge_array )
236127
237128 def permute_edges (self , graph , to , mapping ):
238129 pass
@@ -264,7 +155,7 @@ def get_numeric_graph_attr(self, graph, name, value):
264155 vec ,
265156 0 ,
266157 self ._to_numeric (
267- _get_storage_from_graph (graph ).get_graph_attribute_map ()[name ]
158+ get_storage_from_graph (graph ).get_graph_attribute_map ()[name ]
268159 ),
269160 )
270161
@@ -275,7 +166,7 @@ def get_string_graph_attr(self, graph, name, value):
275166 vec ,
276167 0 ,
277168 self ._to_bytes (
278- _get_storage_from_graph (graph ).get_graph_attribute_map ()[name ]
169+ get_storage_from_graph (graph ).get_graph_attribute_map ()[name ]
279170 ),
280171 )
281172
@@ -285,7 +176,7 @@ def get_bool_graph_attr(self, graph, name, value):
285176 igraph_vector_bool_set (
286177 vec ,
287178 0 ,
288- bool (_get_storage_from_graph (graph ).get_graph_attribute_map ()[name ]),
179+ bool (get_storage_from_graph (graph ).get_graph_attribute_map ()[name ]),
289180 )
290181
291182 def get_numeric_vertex_attr (self , graph , name , vs , value ):
0 commit comments