Skip to content

Commit 1ef4250

Browse files
v0.1.2: Python 3.8 compatibility and PyPI publication
- Fixed type annotations for Python 3.8 compatibility - Updated package structure and configuration - Published to PyPI - Added comprehensive test suite with 94% coverage - Updated documentation and badges
1 parent 923f691 commit 1ef4250

File tree

8 files changed

+31
-15
lines changed

8 files changed

+31
-15
lines changed

.coverage

0 Bytes
Binary file not shown.

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
## [0.1.2] - 2025-12-18
11+
12+
### Fixed
13+
- Python 3.8 compatibility by replacing modern type annotations (`list[type]`) with `typing.List[Type]`
14+
- Type annotations throughout the codebase now compatible with Python 3.8+
15+
- Pytest configuration updated to use correct package name for coverage
16+
1017
## [0.1.1] - 2025-12-18
1118

1219
### Fixed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# SteinerPy
22

33
[![PyPI version](https://badge.fury.io/py/steinerpy.svg)](https://badge.fury.io/py/steinerpy)
4-
[![Python 3.8+](https://img.shields.io/badge/python-3.8+-blue.svg)](https://www.python.org/downloads/)
4+
[![PyPI - Downloads](https://img.shields.io/pypi/dm/steinerpy)](https://pypi.org/project/steinerpy/)
5+
[![Python 3.8+](https://img.shields.io/pypi/pyversions/steinerpy.svg)](https://pypi.org/project/steinerpy/)
56
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
67
[![CI/CD](https://github.com/berendmarkhorst/SteinerPy/workflows/CI%2FCD%20Pipeline/badge.svg)](https://github.com/berendmarkhorst/SteinerPy/actions)
78
[![codecov](https://codecov.io/gh/berendmarkhorst/SteinerPy/branch/main/graph/badge.svg)](https://codecov.io/gh/berendmarkhorst/SteinerPy)
@@ -10,7 +11,7 @@ A Python package for solving Steiner Tree and Steiner Forest Problems using the
1011

1112
## Installation
1213

13-
Install SteinerPy using pip:
14+
Install SteinerPy from PyPI:
1415

1516
```bash
1617
pip install steinerpy
@@ -22,6 +23,12 @@ Or using uv:
2223
uv add steinerpy
2324
```
2425

26+
### Requirements
27+
28+
- Python 3.8+
29+
- NetworkX
30+
- HiGHS Solver (via highspy)
31+
2532
## Quick Start
2633

2734
```python

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
44

55
[project]
66
name = "steinerpy"
7-
version = "0.1.1"
7+
version = "0.1.2"
88
description = "Package to solve Steiner Tree and Steiner Forest Problems with the HiGHS solver"
99
readme = "README.md"
1010
license = "MIT"
@@ -96,7 +96,7 @@ testpaths = ["tests"]
9696
python_files = "test_*.py"
9797
python_classes = "Test*"
9898
python_functions = "test_*"
99-
addopts = "-v --cov=src --cov-report=html --cov-report=term-missing"
99+
addopts = "-v --cov=steinerpy --cov-report=html --cov-report=term-missing"
100100

101101
[dependency-groups]
102102
dev = [

steinerpy/_version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
"""Version information for SteinerPy."""
22

3-
__version__ = "0.1.1"
3+
__version__ = "0.1.2"

steinerpy/mathematical_model.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import highspy as hp
22
import logging
33
import time
4+
from typing import List, Set, Tuple, Dict
45

56
# Configure logging
67
logging.basicConfig(level=logging.INFO)
@@ -26,15 +27,15 @@ def make_model(time_limit: float, logfile: str = "") -> hp.HighsModel:
2627
return model
2728

2829

29-
def get_terminals(terminal_group: list[list]) -> list:
30+
def get_terminals(terminal_group: List[List]) -> List:
3031
"""
3132
Turns a nested list of terminals into a list of terminals.
3233
:param terminal_group: nested list of terminals.
3334
:return: list of terminals.
3435
"""
3536
return [t for group in terminal_group for t in group]
3637

37-
def terminal_groups_without_root(terminal_group: list[list], roots: list, group_index: int) -> set:
38+
def terminal_groups_without_root(terminal_group: List[List], roots: List, group_index: int) -> Set:
3839
"""
3940
Get terminal groups until index k without kth root.
4041
:param terminal_group: nested list of terminals.
@@ -47,7 +48,7 @@ def terminal_groups_without_root(terminal_group: list[list], roots: list, group_
4748
else:
4849
return set()
4950

50-
def get_terminal_groups_until_k(terminal_groups: list[list], group_index: int) -> set:
51+
def get_terminal_groups_until_k(terminal_groups: List[List], group_index: int) -> Set:
5152
"""
5253
Get terminal groups until index k.
5354
:param terminal_groups: nested list of terminals.
@@ -56,7 +57,7 @@ def get_terminal_groups_until_k(terminal_groups: list[list], group_index: int) -
5657
"""
5758
return set(get_terminals(terminal_groups[:group_index]))
5859

59-
def add_directed_constraints(model: hp.HighsModel, steiner_problem: 'SteinerProblem') -> tuple[hp.HighsModel, dict[hp.HighsVarType]]:
60+
def add_directed_constraints(model: hp.HighsModel, steiner_problem: 'SteinerProblem') -> Tuple[hp.HighsModel, Dict[str, hp.HighsVarType]]:
6061
"""
6162
Adds DO-D constraints to the model (see Markhorst et al. 2025)
6263
:param model: HiGHS model.
@@ -150,7 +151,7 @@ def demand_and_supply_directed(steiner_problem: 'SteinerProblem', group_id_k: in
150151
return 0
151152

152153

153-
def add_flow_constraints(model: hp.HighsModel, steiner_problem: 'SteinerProblem', z: hp.HighsVarType, y2: hp.HighsVarType) -> tuple[hp.HighsModel, dict[hp.HighsVarType]]:
154+
def add_flow_constraints(model: hp.HighsModel, steiner_problem: 'SteinerProblem', z: hp.HighsVarType, y2: hp.HighsVarType) -> Tuple[hp.HighsModel, Dict[str, hp.HighsVarType]]:
154155
"""
155156
We add the flow constraints to the HiGHS model.
156157
:param model: HiGHS model.
@@ -192,7 +193,7 @@ def add_flow_constraints(model: hp.HighsModel, steiner_problem: 'SteinerProblem'
192193
return model, f
193194

194195

195-
def build_model(steiner_problem: 'SteinerProblem', time_limit: float = 300, logfile: str = "") -> tuple[hp.HighsModel, float]:
196+
def build_model(steiner_problem: 'SteinerProblem', time_limit: float = 300, logfile: str = "") -> Tuple[hp.HighsModel, hp.HighsVarType, hp.HighsVarType, hp.HighsVarType, hp.HighsVarType, Dict[str, hp.HighsVarType]]:
196197
"""
197198
Returns the deterministic directed model.
198199
:param steiner_problem: SteinerProblem-object.
@@ -221,7 +222,7 @@ def build_model(steiner_problem: 'SteinerProblem', time_limit: float = 300, logf
221222
return model, x, y1, y2, z, f
222223

223224

224-
def run_model(model: hp.HighsModel, steiner_problem: 'SteinerProblem', x: hp.HighsVarType) -> tuple[float, float, float, list[tuple]]:
225+
def run_model(model: hp.HighsModel, steiner_problem: 'SteinerProblem', x: hp.HighsVarType) -> Tuple[float, float, float, List[Tuple]]:
225226
"""
226227
Solves the model and returns the result.
227228
:param model: highspy model.

steinerpy/objects.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import networkx as nx
22
import highspy as hp
3+
from typing import List, Tuple
34
from .mathematical_model import build_model, run_model
45

56
class SteinerProblem:
6-
def __init__(self, graph: nx.Graph, terminal_groups: list[list], weight="weight"):
7+
def __init__(self, graph: nx.Graph, terminal_groups: List[List], weight="weight"):
78
"""
89
Initialize the SteinerProblem (can be tree or forest).
910
:param graph: networkx graph.
@@ -39,7 +40,7 @@ def get_solution(self, time_limit: float = 300, log_file: str = "") -> 'Solution
3940
return solution
4041

4142
class Solution:
42-
def __init__(self, gap: float, runtime: float, objective: float, selected_edges: list[tuple]):
43+
def __init__(self, gap: float, runtime: float, objective: float, selected_edges: List[Tuple]):
4344
self.gap = gap
4445
self.runtime = runtime
4546
self.objective = objective

uv.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)