ga-graph 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. ga_graph-0.1.0/CHANGELOG.md +11 -0
  2. ga_graph-0.1.0/LICENSE +21 -0
  3. ga_graph-0.1.0/MANIFEST.in +2 -0
  4. ga_graph-0.1.0/PKG-INFO +200 -0
  5. ga_graph-0.1.0/README.md +164 -0
  6. ga_graph-0.1.0/docs/api.md +67 -0
  7. ga_graph-0.1.0/docs/index.md +8 -0
  8. ga_graph-0.1.0/pyproject.toml +86 -0
  9. ga_graph-0.1.0/setup.cfg +4 -0
  10. ga_graph-0.1.0/src/ga_graph.egg-info/PKG-INFO +200 -0
  11. ga_graph-0.1.0/src/ga_graph.egg-info/SOURCES.txt +35 -0
  12. ga_graph-0.1.0/src/ga_graph.egg-info/dependency_links.txt +1 -0
  13. ga_graph-0.1.0/src/ga_graph.egg-info/requires.txt +13 -0
  14. ga_graph-0.1.0/src/ga_graph.egg-info/top_level.txt +1 -0
  15. ga_graph-0.1.0/src/graph/__init__.py +39 -0
  16. ga_graph-0.1.0/src/graph/_version.py +3 -0
  17. ga_graph-0.1.0/src/graph/algorithms/TD_LBSP.py +302 -0
  18. ga_graph-0.1.0/src/graph/algorithms/__init__.py +3 -0
  19. ga_graph-0.1.0/src/graph/graphs/__init__.py +28 -0
  20. ga_graph-0.1.0/src/graph/graphs/action_policy.py +27 -0
  21. ga_graph-0.1.0/src/graph/graphs/exceptions.py +35 -0
  22. ga_graph-0.1.0/src/graph/graphs/graph.py +446 -0
  23. ga_graph-0.1.0/src/graph/graphs/link.py +52 -0
  24. ga_graph-0.1.0/src/graph/graphs/node.py +40 -0
  25. ga_graph-0.1.0/src/graph/graphs/turn.py +194 -0
  26. ga_graph-0.1.0/src/graph/paths/__init__.py +13 -0
  27. ga_graph-0.1.0/src/graph/paths/k_path_container.py +83 -0
  28. ga_graph-0.1.0/src/graph/paths/k_path_list.py +178 -0
  29. ga_graph-0.1.0/src/graph/paths/path.py +83 -0
  30. ga_graph-0.1.0/src/graph/paths/path_container.py +109 -0
  31. ga_graph-0.1.0/src/graph/paths/path_list.py +126 -0
  32. ga_graph-0.1.0/src/graph/py.typed +1 -0
  33. ga_graph-0.1.0/tests/test_graph.py +96 -0
  34. ga_graph-0.1.0/tests/test_paths.py +47 -0
  35. ga_graph-0.1.0/tests/test_time_dependent_shortest_path.py +73 -0
  36. ga_graph-0.1.0/tests/test_turns.py +30 -0
  37. ga_graph-0.1.0/tests/test_version.py +28 -0
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ ## 0.1.0 - 2026-09-01
6
+
7
+ - Prepared the package for GitHub and PyPI publication as `ga-graph`.
8
+ - Added README, documentation, changelog, MIT license, gitignore, manifest, and typed package marker.
9
+ - Corrected packaging metadata, project URLs, coverage source, and GitHub Actions imports.
10
+ - Added a focused `pytest` suite for graph operations, path containers, turn helpers, routing, and version exports.
11
+ - Fixed graph neighbor filtering, cascade removals, redundant cleanup, filtered removals, k-path lookup, and time-dependent routing turn handling.
ga_graph-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 GA Graph contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,2 @@
1
+ include CHANGELOG.md
2
+ recursive-include docs *.md
@@ -0,0 +1,200 @@
1
+ Metadata-Version: 2.4
2
+ Name: ga-graph
3
+ Version: 0.1.0
4
+ Summary: Lightweight graph, turn, path, and time-dependent routing utilities.
5
+ Author: GA Graph contributors
6
+ License-Expression: MIT
7
+ Project-URL: Documentation, https://github.com/andreagemma/graph#readme
8
+ Project-URL: Issues, https://github.com/andreagemma/graph/issues
9
+ Project-URL: Source, https://github.com/andreagemma/graph
10
+ Keywords: ga-graph,graph,routing,shortest-path,transport-network
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Typing :: Typed
21
+ Requires-Python: >=3.10
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: dill>=0.3.8
25
+ Provides-Extra: test
26
+ Requires-Dist: pytest>=8.0; extra == "test"
27
+ Requires-Dist: pytest-cov>=5.0; extra == "test"
28
+ Provides-Extra: dev
29
+ Requires-Dist: build>=1.2; extra == "dev"
30
+ Requires-Dist: mypy>=1.10; extra == "dev"
31
+ Requires-Dist: pytest>=8.0; extra == "dev"
32
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
33
+ Requires-Dist: ruff>=0.5; extra == "dev"
34
+ Requires-Dist: twine>=5.1; extra == "dev"
35
+ Dynamic: license-file
36
+
37
+ # GA Graph
38
+
39
+ [![CI](https://github.com/andreagemma/graph/actions/workflows/ci.yml/badge.svg)](https://github.com/andreagemma/graph/actions/workflows/ci.yml)
40
+ [![PyPI](https://img.shields.io/pypi/v/ga-graph.svg)](https://pypi.org/project/ga-graph/)
41
+ [![Python](https://img.shields.io/pypi/pyversions/ga-graph.svg)](https://pypi.org/project/ga-graph/)
42
+
43
+ GA Graph provides lightweight dictionary-backed graph containers, path
44
+ collections, turn classification helpers, and a link-based time-dependent
45
+ shortest-path router.
46
+
47
+ The PyPI distribution is named `ga-graph`; the import package is named `graph`.
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ python -m pip install ga-graph
53
+ ```
54
+
55
+ Development and test tools are available as extras:
56
+
57
+ ```bash
58
+ python -m pip install -e ".[test]"
59
+ python -m pip install -e ".[dev]"
60
+ ```
61
+
62
+ ## Quick Start
63
+
64
+ ```python
65
+ from graph import Graph
66
+
67
+ network = Graph(total_time=60, delta_t=15)
68
+ network.add_node("A")
69
+ network.add_node("B")
70
+ network.add_link("ab", "A", "B", cost=5)
71
+
72
+ assert network.get_link("ab").i == "A"
73
+ assert network.get_node_degree("A", include_in_links=False) == 1
74
+ ```
75
+
76
+ ## Graphs
77
+
78
+ `Graph` stores nodes, directed links, and turns in dictionary-backed containers.
79
+ Each entity keeps a required identifier plus arbitrary extra attributes.
80
+
81
+ ```python
82
+ from graph import ActionPolicy, Graph
83
+
84
+ network = Graph()
85
+ network.add_link(
86
+ "ab",
87
+ "A",
88
+ "B",
89
+ on_missing_node=ActionPolicy.REPLACE,
90
+ capacity=1200,
91
+ )
92
+ network.add_turn("ab_bc", "ab", "bc", on_missing_link=ActionPolicy.IGNORE)
93
+ ```
94
+
95
+ Duplicate and missing references can be handled with `ActionPolicy.RAISE`,
96
+ `WARN`, `IGNORE`, `REPLACE`, or `SKIP`, depending on the method.
97
+
98
+ ## Paths
99
+
100
+ `Path` stores a source, target, departure time, optional mode, link sequence, and
101
+ cumulative costs. `PathList` stores one path per `(source, target, t_start,
102
+ mode)` key. `KPathList` stores multiple ranked paths for the same key.
103
+
104
+ ```python
105
+ from graph import KPathList, Path
106
+
107
+ paths = KPathList()
108
+ paths.add_path(Path("A", "C", 0, links=["ab", "bc"], costs=[5, 9], mode="car"))
109
+ paths.add_path(Path("A", "C", 0, links=["ac"], costs=[12], mode="car"))
110
+
111
+ best = paths.path("A", "C", 0, "car", k=0)
112
+ second = paths.path("A", "C", 0, "car", k=1)
113
+ ```
114
+
115
+ ## Time-Dependent Routing
116
+
117
+ `TimeDependentLinkBasedShortestPath` builds a dense routing view from a `Graph`.
118
+ Scalar costs are expanded across the graph time horizon; sequence costs are used
119
+ as piecewise-constant time profiles.
120
+
121
+ ```python
122
+ from graph import Graph, TimeDependentLinkBasedShortestPath
123
+
124
+ network = Graph(total_time=60, delta_t=15)
125
+ for node in ["A", "B", "C"]:
126
+ network.add_node(node, cost=0)
127
+
128
+ network.add_link("ab", "A", "B", cost=1)
129
+ network.add_link("bc", "B", "C", cost=1)
130
+ network.add_link("ac", "A", "C", cost=10)
131
+
132
+ router = TimeDependentLinkBasedShortestPath.from_graph(network, link_cost_field="cost")
133
+ path = router.shortest_paths("A", "C").path("A", "C", 0, None)
134
+
135
+ assert path.get_links() == ("ab", "bc")
136
+ assert path["tot_cost"] == 2
137
+ ```
138
+
139
+ The router supports optional mode fields, node costs, turn costs, and prohibited
140
+ turn fields.
141
+
142
+ ## API Summary
143
+
144
+ - `Graph(t0=0, total_time=60, delta_t=15, **kwargs)`
145
+ - `Graph.add_node(idx, on_existing=ActionPolicy.RAISE, **kwargs)`
146
+ - `Graph.add_link(idx, i, j, on_existing=..., on_missing_node=..., **kwargs)`
147
+ - `Graph.add_turn(idx, in_link, out_link, on_existing=..., on_missing_link=..., **kwargs)`
148
+ - `Graph.get_node(idx)`, `Graph.get_link(idx)`, `Graph.get_turn(idx)`
149
+ - `Graph.remove_node(idx, cascade=False)`, `Graph.remove_link(idx, cascade=False)`
150
+ - `Graph.remove_redundants()`
151
+ - `Path(source, target, t_start, links=None, costs=None, mode=None, ...)`
152
+ - `PathList()`
153
+ - `KPathList()`
154
+ - `TurnType.parse(value)` and `TurnType.classify_turn(...)`
155
+ - `TimeDependentLinkBasedShortestPath.from_graph(graph, ...)`
156
+ - `TimeDependentLinkBasedShortestPath.shortest_paths(source, targets=None, t_start=0)`
157
+
158
+ ## Development
159
+
160
+ GA Graph supports Python 3.10 and newer.
161
+
162
+ ```bash
163
+ python -m pip install -e ".[dev]"
164
+ python -m compileall -q src
165
+ python -m pytest --cov=graph --cov-report=term-missing
166
+ ruff format --check .
167
+ ruff check .
168
+ mypy
169
+ python -m pip check
170
+ python -m build
171
+ python -m twine check dist/*
172
+ ```
173
+
174
+ ## GitHub Repository Setup
175
+
176
+ This project is prepared for the future repository `andreagemma/graph`.
177
+
178
+ 1. Create the empty repository on GitHub.
179
+ 2. Initialize the local repository if needed and push the project to `main`.
180
+ 3. Confirm the CI workflow passes on GitHub.
181
+ 4. Configure the PyPI Trusted Publisher for project `ga-graph`, owner
182
+ `andreagemma`, repository `graph`, workflow `release.yml`, and environment
183
+ `pypi`.
184
+
185
+ ## Releases
186
+
187
+ `src/graph/_version.py` is the only version source. To publish a release:
188
+
189
+ 1. Update `__version__` in `_version.py` and commit the release changes.
190
+ 2. Push `main` and wait for CI to pass.
191
+ 3. Run the **Create release** GitHub Actions workflow. With no override it
192
+ creates the `v<version>` tag, creates release notes, and dispatches the build
193
+ and PyPI publication workflow.
194
+
195
+ PyPI versions are immutable. Increment `_version.py` before publishing different
196
+ content.
197
+
198
+ ## License
199
+
200
+ GA Graph is distributed under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,164 @@
1
+ # GA Graph
2
+
3
+ [![CI](https://github.com/andreagemma/graph/actions/workflows/ci.yml/badge.svg)](https://github.com/andreagemma/graph/actions/workflows/ci.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/ga-graph.svg)](https://pypi.org/project/ga-graph/)
5
+ [![Python](https://img.shields.io/pypi/pyversions/ga-graph.svg)](https://pypi.org/project/ga-graph/)
6
+
7
+ GA Graph provides lightweight dictionary-backed graph containers, path
8
+ collections, turn classification helpers, and a link-based time-dependent
9
+ shortest-path router.
10
+
11
+ The PyPI distribution is named `ga-graph`; the import package is named `graph`.
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ python -m pip install ga-graph
17
+ ```
18
+
19
+ Development and test tools are available as extras:
20
+
21
+ ```bash
22
+ python -m pip install -e ".[test]"
23
+ python -m pip install -e ".[dev]"
24
+ ```
25
+
26
+ ## Quick Start
27
+
28
+ ```python
29
+ from graph import Graph
30
+
31
+ network = Graph(total_time=60, delta_t=15)
32
+ network.add_node("A")
33
+ network.add_node("B")
34
+ network.add_link("ab", "A", "B", cost=5)
35
+
36
+ assert network.get_link("ab").i == "A"
37
+ assert network.get_node_degree("A", include_in_links=False) == 1
38
+ ```
39
+
40
+ ## Graphs
41
+
42
+ `Graph` stores nodes, directed links, and turns in dictionary-backed containers.
43
+ Each entity keeps a required identifier plus arbitrary extra attributes.
44
+
45
+ ```python
46
+ from graph import ActionPolicy, Graph
47
+
48
+ network = Graph()
49
+ network.add_link(
50
+ "ab",
51
+ "A",
52
+ "B",
53
+ on_missing_node=ActionPolicy.REPLACE,
54
+ capacity=1200,
55
+ )
56
+ network.add_turn("ab_bc", "ab", "bc", on_missing_link=ActionPolicy.IGNORE)
57
+ ```
58
+
59
+ Duplicate and missing references can be handled with `ActionPolicy.RAISE`,
60
+ `WARN`, `IGNORE`, `REPLACE`, or `SKIP`, depending on the method.
61
+
62
+ ## Paths
63
+
64
+ `Path` stores a source, target, departure time, optional mode, link sequence, and
65
+ cumulative costs. `PathList` stores one path per `(source, target, t_start,
66
+ mode)` key. `KPathList` stores multiple ranked paths for the same key.
67
+
68
+ ```python
69
+ from graph import KPathList, Path
70
+
71
+ paths = KPathList()
72
+ paths.add_path(Path("A", "C", 0, links=["ab", "bc"], costs=[5, 9], mode="car"))
73
+ paths.add_path(Path("A", "C", 0, links=["ac"], costs=[12], mode="car"))
74
+
75
+ best = paths.path("A", "C", 0, "car", k=0)
76
+ second = paths.path("A", "C", 0, "car", k=1)
77
+ ```
78
+
79
+ ## Time-Dependent Routing
80
+
81
+ `TimeDependentLinkBasedShortestPath` builds a dense routing view from a `Graph`.
82
+ Scalar costs are expanded across the graph time horizon; sequence costs are used
83
+ as piecewise-constant time profiles.
84
+
85
+ ```python
86
+ from graph import Graph, TimeDependentLinkBasedShortestPath
87
+
88
+ network = Graph(total_time=60, delta_t=15)
89
+ for node in ["A", "B", "C"]:
90
+ network.add_node(node, cost=0)
91
+
92
+ network.add_link("ab", "A", "B", cost=1)
93
+ network.add_link("bc", "B", "C", cost=1)
94
+ network.add_link("ac", "A", "C", cost=10)
95
+
96
+ router = TimeDependentLinkBasedShortestPath.from_graph(network, link_cost_field="cost")
97
+ path = router.shortest_paths("A", "C").path("A", "C", 0, None)
98
+
99
+ assert path.get_links() == ("ab", "bc")
100
+ assert path["tot_cost"] == 2
101
+ ```
102
+
103
+ The router supports optional mode fields, node costs, turn costs, and prohibited
104
+ turn fields.
105
+
106
+ ## API Summary
107
+
108
+ - `Graph(t0=0, total_time=60, delta_t=15, **kwargs)`
109
+ - `Graph.add_node(idx, on_existing=ActionPolicy.RAISE, **kwargs)`
110
+ - `Graph.add_link(idx, i, j, on_existing=..., on_missing_node=..., **kwargs)`
111
+ - `Graph.add_turn(idx, in_link, out_link, on_existing=..., on_missing_link=..., **kwargs)`
112
+ - `Graph.get_node(idx)`, `Graph.get_link(idx)`, `Graph.get_turn(idx)`
113
+ - `Graph.remove_node(idx, cascade=False)`, `Graph.remove_link(idx, cascade=False)`
114
+ - `Graph.remove_redundants()`
115
+ - `Path(source, target, t_start, links=None, costs=None, mode=None, ...)`
116
+ - `PathList()`
117
+ - `KPathList()`
118
+ - `TurnType.parse(value)` and `TurnType.classify_turn(...)`
119
+ - `TimeDependentLinkBasedShortestPath.from_graph(graph, ...)`
120
+ - `TimeDependentLinkBasedShortestPath.shortest_paths(source, targets=None, t_start=0)`
121
+
122
+ ## Development
123
+
124
+ GA Graph supports Python 3.10 and newer.
125
+
126
+ ```bash
127
+ python -m pip install -e ".[dev]"
128
+ python -m compileall -q src
129
+ python -m pytest --cov=graph --cov-report=term-missing
130
+ ruff format --check .
131
+ ruff check .
132
+ mypy
133
+ python -m pip check
134
+ python -m build
135
+ python -m twine check dist/*
136
+ ```
137
+
138
+ ## GitHub Repository Setup
139
+
140
+ This project is prepared for the future repository `andreagemma/graph`.
141
+
142
+ 1. Create the empty repository on GitHub.
143
+ 2. Initialize the local repository if needed and push the project to `main`.
144
+ 3. Confirm the CI workflow passes on GitHub.
145
+ 4. Configure the PyPI Trusted Publisher for project `ga-graph`, owner
146
+ `andreagemma`, repository `graph`, workflow `release.yml`, and environment
147
+ `pypi`.
148
+
149
+ ## Releases
150
+
151
+ `src/graph/_version.py` is the only version source. To publish a release:
152
+
153
+ 1. Update `__version__` in `_version.py` and commit the release changes.
154
+ 2. Push `main` and wait for CI to pass.
155
+ 3. Run the **Create release** GitHub Actions workflow. With no override it
156
+ creates the `v<version>` tag, creates release notes, and dispatches the build
157
+ and PyPI publication workflow.
158
+
159
+ PyPI versions are immutable. Increment `_version.py` before publishing different
160
+ content.
161
+
162
+ ## License
163
+
164
+ GA Graph is distributed under the MIT License. See [LICENSE](LICENSE).
@@ -0,0 +1,67 @@
1
+ # API Reference
2
+
3
+ ## `Graph`
4
+
5
+ ```python
6
+ Graph(t0=0, total_time=60, delta_t=15, **kwargs)
7
+ ```
8
+
9
+ Stores nodes, directed links, and turns. Nodes, links, and turns are dictionary
10
+ subclasses, so custom attributes can be attached directly.
11
+
12
+ Main methods:
13
+
14
+ - `add_node(idx, on_existing=ActionPolicy.RAISE, **kwargs)`
15
+ - `add_link(idx, i, j, on_existing=..., on_missing_node=..., **kwargs)`
16
+ - `add_turn(idx, in_link, out_link, on_existing=..., on_missing_link=..., **kwargs)`
17
+ - `get_node(idx)`, `get_link(idx)`, `get_turn(idx)`
18
+ - `get_all_nodes()`, `get_all_links()`, `get_all_turns()`
19
+ - `remove_node(idx, cascade=False)`, `remove_link(idx, cascade=False)`
20
+ - `remove_redundants()`
21
+ - `resize_attributes(new_total_time=None, new_delta_t=None)`
22
+
23
+ ## `Path`, `PathList`, and `KPathList`
24
+
25
+ ```python
26
+ Path(source, target, t_start, links=None, costs=None, tot_cost=0.0, mode=None)
27
+ PathList()
28
+ KPathList()
29
+ ```
30
+
31
+ `Path` stores the labels and cumulative costs for a route. `PathList` keeps one
32
+ path per `(source, target, t_start, mode)` key. `KPathList` keeps multiple
33
+ k-ranked paths for the same key.
34
+
35
+ Main methods:
36
+
37
+ - `Path.key()`
38
+ - `Path.get_links()`
39
+ - `Path.get_costs()`
40
+ - `Path.has_link(id_link)`
41
+ - `Path.counts_link(id_link)`
42
+ - `PathList.add_path(path)`
43
+ - `PathList.path(source, target, t_start=0, mode=None)`
44
+ - `KPathList.add_path(path, k=None)`
45
+ - `KPathList.path(source, target, t_start=None, mode=None, k=0)`
46
+ - `KPathList.paths(source, target, t_start, mode=None)`
47
+
48
+ ## `TurnType`
49
+
50
+ ```python
51
+ TurnType.parse(value)
52
+ TurnType.classify_turn(in_edge_geometry, out_edge_geometry, angles=(30, 60, 120, 150))
53
+ ```
54
+
55
+ Provides semantic labels for straight, left, right, sharp, and U-turn
56
+ movements. Geometries must expose a `.coords` sequence.
57
+
58
+ ## `TimeDependentLinkBasedShortestPath`
59
+
60
+ ```python
61
+ TimeDependentLinkBasedShortestPath.from_graph(graph, ...)
62
+ router.shortest_paths(source, targets=None, t_start=0)
63
+ ```
64
+
65
+ Builds a dense link-based routing view from `Graph`. It supports scalar or
66
+ sequence cost fields on nodes, links, and turns, mode filters, and prohibited
67
+ turn fields.
@@ -0,0 +1,8 @@
1
+ # GA Graph Documentation
2
+
3
+ GA Graph contains lightweight graph containers, path collections, turn helpers,
4
+ and a link-based time-dependent shortest-path router.
5
+
6
+ - See [API Reference](api.md) for the public classes and methods.
7
+ - See the project [README](../README.md) for installation, quick start, and
8
+ release instructions.
@@ -0,0 +1,86 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "ga-graph"
7
+ dynamic = ["version"]
8
+ description = "Lightweight graph, turn, path, and time-dependent routing utilities."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ { name = "GA Graph contributors" }
15
+ ]
16
+ keywords = ["ga-graph", "graph", "routing", "shortest-path", "transport-network"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
25
+ "Programming Language :: Python :: 3.14",
26
+ "Topic :: Software Development :: Libraries :: Python Modules",
27
+ "Typing :: Typed"
28
+ ]
29
+ dependencies = [
30
+ "dill>=0.3.8"
31
+ ]
32
+
33
+ [project.optional-dependencies]
34
+ test = [
35
+ "pytest>=8.0",
36
+ "pytest-cov>=5.0"
37
+ ]
38
+ dev = [
39
+ "build>=1.2",
40
+ "mypy>=1.10",
41
+ "pytest>=8.0",
42
+ "pytest-cov>=5.0",
43
+ "ruff>=0.5",
44
+ "twine>=5.1"
45
+ ]
46
+
47
+ [project.urls]
48
+ Documentation = "https://github.com/andreagemma/graph#readme"
49
+ Issues = "https://github.com/andreagemma/graph/issues"
50
+ Source = "https://github.com/andreagemma/graph"
51
+
52
+ [tool.setuptools]
53
+ package-dir = {"" = "src"}
54
+
55
+ [tool.setuptools.packages.find]
56
+ where = ["src"]
57
+
58
+ [tool.setuptools.package-data]
59
+ graph = ["py.typed"]
60
+
61
+ [tool.setuptools.dynamic]
62
+ version = {attr = "graph._version.__version__"}
63
+
64
+ [tool.pytest.ini_options]
65
+ testpaths = ["tests"]
66
+ addopts = "-ra --strict-markers"
67
+
68
+ [tool.coverage.run]
69
+ branch = true
70
+ source = ["graph"]
71
+
72
+ [tool.ruff]
73
+ line-length = 100
74
+ target-version = "py310"
75
+
76
+ [tool.ruff.lint]
77
+ select = ["E", "F", "I", "UP", "B", "SIM"]
78
+
79
+ [tool.mypy]
80
+ python_version = "3.10"
81
+ files = ["src"]
82
+ warn_unused_configs = true
83
+ check_untyped_defs = true
84
+ follow_imports = "skip"
85
+ no_site_packages = true
86
+ ignore_missing_imports = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+