1515
1616
1717def _iter_edges (G : Graph ) -> Iterable [Tuple [int , int , float ]]:
18- """Yield all edges ``(u, v, w)`` from ``G``."""
18+ """
19+ Iterates over all edges in the given graph.
20+
21+ Args:
22+ G (Graph): The graph object containing adjacency information.
23+
24+ Yields:
25+ Tuple[int, int, float]: A tuple representing an edge in the graph,
26+ where the first element is the source node index (u),
27+ the second element is the destination node index (v),
28+ and the third element is the edge weight (w).
29+ """
1930 for u in range (G .n ):
2031 for v , w in G .adj [u ]:
2132 yield u , v , w
2233
2334
2435def _read_csv (path : Path ) -> Tuple [int , EdgeList ]:
25- """Parse a CSV/TSV edges file."""
36+ """
37+ Reads a CSV file containing edge data and returns the number of nodes and the edge list.
38+
39+ Each line in the file should contain at least three columns: source node, target node, and edge weight.
40+ Lines starting with '#' or empty lines are ignored. Columns can be separated by commas or tabs.
41+
42+ Args:
43+ path (Path): The path to the CSV file.
44+
45+ Returns:
46+ Tuple[int, EdgeList]: A tuple containing the number of nodes (max node id + 1) and a list of edges,
47+ where each edge is represented as a tuple (u, v, w).
48+
49+ Raises:
50+ GraphFormatError: If no edges are parsed from the file.
51+ """
2652 edges : EdgeList = []
2753 max_id = - 1
2854 with path .open ("r" , encoding = "utf-8" ) as fh :
@@ -47,14 +73,41 @@ def _read_csv(path: Path) -> Tuple[int, EdgeList]:
4773
4874
4975def _write_csv (path : Path , G : Graph ) -> None :
50- """Write ``G`` as a CSV edges file."""
76+ """
77+ Writes the edges of a graph to a CSV file.
78+
79+ Each row in the CSV file represents an edge in the graph, with columns for the source node, target node, and edge weight.
80+
81+ Args:
82+ path (Path): The file path where the CSV will be written.
83+ G (Graph): The graph whose edges will be written to the CSV file.
84+
85+ Returns:
86+ None
87+ """
5188 with path .open ("w" , encoding = "utf-8" ) as fh :
5289 for u , v , w in _iter_edges (G ):
5390 fh .write (f"{ u } ,{ v } ,{ w } \n " )
5491
5592
5693def _read_jsonl (path : Path ) -> Tuple [int , EdgeList ]:
57- """Parse a JSON Lines edges file."""
94+ """
95+ Reads a JSON Lines (JSONL) file containing graph edges and returns the
96+ number of nodes and the edge list.
97+
98+ Each line in the file should be a JSON object with keys "u", "v", and "w",
99+ representing the source node, target node, and edge weight, respectively.
100+
101+ Args:
102+ path (Path): Path to the JSONL file.
103+
104+ Returns:
105+ Tuple[int, EdgeList]: A tuple containing the number of nodes
106+ (max node id + 1) and a list of edges as (u, v, w) tuples.
107+
108+ Raises:
109+ GraphFormatError: If no edges are parsed from the file.
110+ """
58111 edges : EdgeList = []
59112 max_id = - 1
60113 with path .open ("r" , encoding = "utf-8" ) as fh :
@@ -74,14 +127,42 @@ def _read_jsonl(path: Path) -> Tuple[int, EdgeList]:
74127
75128
76129def _write_jsonl (path : Path , G : Graph ) -> None :
77- """Write ``G`` as a JSON Lines edges file."""
130+ """
131+ Writes the edges of a graph to a file in JSON Lines (JSONL) format.
132+
133+ Each line in the output file represents an edge as a JSON object
134+ with keys 'u', 'v', and 'w', corresponding to the source node, target node,
135+ and edge weight, respectively.
136+
137+ Args:
138+ path (Path): The file path where the JSONL data will be written.
139+ G (Graph): The graph object containing the edges to be serialized.
140+
141+ Returns:
142+ None
143+ """
78144 with path .open ("w" , encoding = "utf-8" ) as fh :
79145 for u , v , w in _iter_edges (G ):
80146 fh .write (json .dumps ({"u" : u , "v" : v , "w" : w }) + "\n " )
81147
82148
83149def _read_mtx (path : Path ) -> Tuple [int , EdgeList ]:
84- """Parse a MatrixMarket edges file."""
150+ """
151+ Reads a Matrix Market (.mtx) file and extracts the edge list.
152+
153+ Args:
154+ path (Path): Path to the Matrix Market file.
155+
156+ Returns:
157+ Tuple[int, EdgeList]: A tuple containing the number of nodes (n) and the edge list.
158+ The edge list is a list of tuples (u, v, w), where u and v are zero-based node indices,
159+ and w is the edge weight.
160+
161+ Notes:
162+ - Lines starting with '%' are treated as comments and skipped.
163+ - Assumes the file contains at least three columns: source, target, and weight.
164+ - Node indices in the file are assumed to be 1-based and are converted to 0-based.
165+ """
85166 edges : EdgeList = []
86167 it = path .open ("r" , encoding = "utf-8" )
87168 with it as fh :
@@ -105,7 +186,20 @@ def _read_mtx(path: Path) -> Tuple[int, EdgeList]:
105186
106187
107188def _write_mtx (path : Path , G : Graph ) -> None :
108- """Write ``G`` as a MatrixMarket edges file."""
189+ """
190+ Writes the given graph `G` to a Matrix Market (.mtx) file at the specified path.
191+
192+ The output file will contain the graph's adjacency matrix in coordinate format,
193+ where each line represents an edge with its source node, target node, and weight.
194+ Node indices are written as 1-based (Matrix Market convention).
195+
196+ Args:
197+ path (Path): The file path where the Matrix Market file will be written.
198+ G (Graph): The graph object containing nodes and weighted edges.
199+
200+ Returns:
201+ None
202+ """
109203 edges = list (_iter_edges (G ))
110204 with path .open ("w" , encoding = "utf-8" ) as fh :
111205 fh .write ("%%MatrixMarket matrix coordinate real general\n " )
@@ -117,7 +211,7 @@ def _write_mtx(path: Path, G: Graph) -> None:
117211def _read_graphml (path : Path ) -> Tuple [int , EdgeList ]:
118212 """
119213 Parse a GraphML file and extract the edge list.
120-
214+
121215 Args:
122216 path (Path): Path to the GraphML file.
123217 Returns:
@@ -134,7 +228,7 @@ def _read_graphml(path: Path) -> Tuple[int, EdgeList]:
134228 max_id = - 1
135229 for edge in root .findall (f".//{ ns } edge" ):
136230 u_str = edge .attrib .get ("source" , "" )
137- v_str = edge .attrib .get ("target" , "" )
231+ v_str = edge .attrib .get ("target" , "" )
138232 # Convert string IDs to integers
139233 if u_str .startswith ("n" ):
140234 u = int (u_str [1 :])
@@ -143,7 +237,7 @@ def _read_graphml(path: Path) -> Tuple[int, EdgeList]:
143237 if v_str .startswith ("n" ):
144238 v = int (v_str [1 :])
145239 else :
146- v = int (v_str )
240+ v = int (v_str )
147241 w_attr = edge .attrib .get ("weight" )
148242 if w_attr is None :
149243 data = edge .find (f"{ ns } data[@key='w']" )
@@ -188,7 +282,16 @@ def _write_graphml(path: Path, G: Graph) -> None:
188282
189283
190284def _detect_format (path : Path ) -> Optional [str ]:
191- """Infer graph format from ``path`` extension."""
285+ """
286+ Detects the file format based on the file extension.
287+
288+ Args:
289+ path (Path): The path to the file whose format is to be detected.
290+
291+ Returns:
292+ Optional[str]: The detected format as a string ("csv", "jsonl", "mtx", "graphml"),
293+ or None if the format is not recognized.
294+ """
192295 ext = path .suffix .lower ()
193296 if ext in {".csv" , ".tsv" }:
194297 return "csv"
@@ -202,7 +305,19 @@ def _detect_format(path: Path) -> Optional[str]:
202305
203306
204307def read_graph (path : str , fmt : Optional [str ] = None ) -> Graph :
205- """Read a graph from ``path`` in the given format."""
308+ """
309+ Reads a graph from a file in the specified format.
310+
311+ Args:
312+ path (str): The path to the graph file.
313+ fmt (Optional[str], optional): The format of the graph file. If None, the format is auto-detected.
314+
315+ Returns:
316+ Graph: The graph object constructed from the file.
317+
318+ Raises:
319+ GraphFormatError: If the graph format is unknown or unsupported.
320+ """
206321 p = Path (path )
207322 fmt = fmt or _detect_format (p )
208323 if fmt is None or fmt not in _FMT_READERS :
@@ -212,7 +327,17 @@ def read_graph(path: str, fmt: Optional[str] = None) -> Graph:
212327
213328
214329def write_graph (G : Graph , path : str , fmt : Optional [str ] = None ) -> None :
215- """Write ``G`` to ``path`` in the given format."""
330+ """
331+ Writes a graph to a file in the specified format.
332+
333+ Parameters:
334+ G (Graph): The graph object to be written.
335+ path (str): The file path where the graph will be saved.
336+ fmt (Optional[str], optional): The format to use for writing the graph. If None, the format is auto-detected from the file extension.
337+
338+ Raises:
339+ GraphFormatError: If the format is unknown or unsupported.
340+ """
216341 p = Path (path )
217342 fmt = fmt or _detect_format (p )
218343 if fmt is None or fmt not in _FMT_WRITERS :
@@ -221,7 +346,21 @@ def write_graph(G: Graph, path: str, fmt: Optional[str] = None) -> None:
221346
222347
223348def load_graph (path : str , fmt : Optional [str ] = None ) -> Graph :
224- """Deprecated alias for :func:`read_graph`."""
349+ """
350+ Loads a graph from the specified file path.
351+
352+ This function is deprecated; use `read_graph` instead.
353+
354+ Args:
355+ path (str): The path to the graph file.
356+ fmt (Optional[str], optional): The format of the graph file. Defaults to None.
357+
358+ Returns:
359+ Graph: The loaded graph object.
360+
361+ Deprecated:
362+ Since version 0.1.0. Will be removed in version 0.2.0. Use `read_graph` instead.
363+ """
225364 warn_once (
226365 "load_graph is deprecated; use read_graph" ,
227366 since = "0.1.0" ,
0 commit comments