Skip to content

Commit 00f88a5

Browse files
authored
Upgrade Python min version to >=3.10 (#403)
* feat: nested_key_dict to tree to support child_key=None * feat: tree to nested_key_dict to support child_key=None * feat: use ruff in precommit, remove black flake8 isort * fix: use | instead of Union * fix: use | instead of Optional * fix: use | instead of Optional * fix: redundant ruff * fix: add black * fix: add flake8 and isort * feat: upgrade type annotation to Python 3.10
1 parent 7501fd7 commit 00f88a5

39 files changed

+378
-415
lines changed

.pre-commit-config.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,11 @@ repos:
1414
rev: v3.18.3
1515
hooks:
1616
- id: commitizen
17+
- repo: https://github.com/astral-sh/ruff-pre-commit
18+
rev: v0.13.0
19+
hooks:
20+
- id: ruff
21+
args: [--fix]
1722
- repo: https://github.com/pycqa/isort
1823
rev: 5.13.2
1924
hooks:

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
- General: Switch to use Python 3.10 conventions.
89

910
## [0.31.0] - 2025-09-11
1011
### Changed:

bigtree/binarytree/construct.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import Sequence, Type, TypeVar
1+
from typing import Sequence, TypeVar
22

33
from bigtree.node import binarynode
44
from bigtree.utils import assertions
@@ -10,7 +10,7 @@
1010

1111
def list_to_binarytree(
1212
heapq_list: Sequence[int],
13-
node_type: Type[T] = binarynode.BinaryNode, # type: ignore[assignment]
13+
node_type: type[T] = binarynode.BinaryNode, # type: ignore[assignment]
1414
) -> T:
1515
"""Construct tree from a list of numbers (int or float) in heapq format.
1616

bigtree/dag/construct.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any, Collection, Dict, List, Mapping, Optional, Tuple, Type, TypeVar
3+
from typing import Any, Collection, Mapping, TypeVar
44

55
from bigtree.node import dagnode
66
from bigtree.utils import assertions, common, exceptions
@@ -18,8 +18,8 @@
1818

1919

2020
def list_to_dag(
21-
relations: Collection[Tuple[str, str]],
22-
node_type: Type[T] = dagnode.DAGNode, # type: ignore[assignment]
21+
relations: Collection[tuple[str, str]],
22+
node_type: type[T] = dagnode.DAGNode, # type: ignore[assignment]
2323
) -> T:
2424
"""Construct DAG from list of tuples containing parent-child names. Note that node names must be unique.
2525
@@ -39,7 +39,7 @@ def list_to_dag(
3939
"""
4040
assertions.assert_length_not_empty(relations, "Input list", "relations")
4141

42-
node_dict: Dict[str, T] = dict()
42+
node_dict: dict[str, T] = dict()
4343
parent_name: str = ""
4444

4545
for parent_name, child_name in relations:
@@ -53,7 +53,7 @@ def list_to_dag(
5353
def dict_to_dag(
5454
relation_attrs: Mapping[str, Any],
5555
parent_key: str = "parents",
56-
node_type: Type[T] = dagnode.DAGNode, # type: ignore[assignment]
56+
node_type: type[T] = dagnode.DAGNode, # type: ignore[assignment]
5757
) -> T:
5858
"""Construct DAG from nested dictionary, ``key``: child name, ``value``: dictionary of parent names and attributes.
5959
Note that node names must be unique.
@@ -82,8 +82,8 @@ def dict_to_dag(
8282
"""
8383
assertions.assert_length_not_empty(relation_attrs, "Dictionary", "relation_attrs")
8484

85-
node_dict: Dict[str, T] = dict()
86-
_parent_name: Optional[str] = None
85+
node_dict: dict[str, T] = dict()
86+
_parent_name: str | None = None
8787

8888
for child_name, node_attrs in relation_attrs.items():
8989
node_attrs = node_attrs.copy()
@@ -109,10 +109,10 @@ def dict_to_dag(
109109
@exceptions.optional_dependencies_pandas
110110
def dataframe_to_dag(
111111
data: pd.DataFrame,
112-
child_col: Optional[str] = None,
113-
parent_col: Optional[str] = None,
114-
attribute_cols: Optional[List[str]] = None,
115-
node_type: Type[T] = dagnode.DAGNode, # type: ignore[assignment]
112+
child_col: str | None = None,
113+
parent_col: str | None = None,
114+
attribute_cols: list[str] | None = None,
115+
node_type: type[T] = dagnode.DAGNode, # type: ignore[assignment]
116116
) -> T:
117117
"""Construct DAG from pandas DataFrame. Note that node names must be unique.
118118
@@ -178,8 +178,8 @@ def dataframe_to_dag(
178178
if sum(data[child_col].isnull()):
179179
raise ValueError(f"Child name cannot be empty, check column: {child_col}")
180180

181-
node_dict: Dict[str, T] = dict()
182-
_parent_name: Optional[str] = None
181+
node_dict: dict[str, T] = dict()
182+
_parent_name: str | None = None
183183

184184
for row in data.reset_index(drop=True).to_dict(orient="index").values():
185185
child_name = row[child_col]

bigtree/dag/export.py

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from __future__ import annotations
22

3-
from typing import Any, Dict, List, Mapping, Optional, Tuple, TypeVar, Union
3+
from typing import Any, Mapping, TypeVar
44

55
from bigtree.node import dagnode
66
from bigtree.utils import assertions, common, exceptions, iterators
@@ -27,7 +27,7 @@
2727

2828
def dag_to_list(
2929
dag: T,
30-
) -> List[Tuple[str, str]]:
30+
) -> list[tuple[str, str]]:
3131
"""Export DAG to list of tuples containing parent-child names.
3232
3333
Examples:
@@ -55,9 +55,9 @@ def dag_to_list(
5555
def dag_to_dict(
5656
dag: T,
5757
parent_key: str = "parents",
58-
attr_dict: Optional[Mapping[str, str]] = None,
58+
attr_dict: Mapping[str, str] | None = None,
5959
all_attrs: bool = False,
60-
) -> Dict[str, Any]:
60+
) -> dict[str, Any]:
6161
"""Export DAG to dictionary. Exported dictionary will have key as child name, and values as a dictionary of parent
6262
names and node attributes.
6363
@@ -106,7 +106,7 @@ def dag_to_dataframe(
106106
dag: T,
107107
name_col: str = "name",
108108
parent_col: str = "parent",
109-
attr_dict: Optional[Mapping[str, str]] = None,
109+
attr_dict: Mapping[str, str] | None = None,
110110
all_attrs: bool = False,
111111
) -> pd.DataFrame:
112112
"""Export DAG to pandas DataFrame.
@@ -139,7 +139,7 @@ def dag_to_dataframe(
139139
pandas DataFrame of DAG information
140140
"""
141141
dag = dag.copy()
142-
data_list: List[Dict[str, Any]] = []
142+
data_list: list[dict[str, Any]] = []
143143

144144
for parent_node, child_node in iterators.dag_iterator(dag):
145145
if parent_node.is_root:
@@ -165,14 +165,14 @@ def dag_to_dataframe(
165165

166166
@exceptions.optional_dependencies_image("pydot")
167167
def dag_to_dot(
168-
dag: Union[T, List[T]],
168+
dag: T | list[T],
169169
rankdir: str = "TB",
170-
bg_colour: Optional[str] = None,
171-
node_colour: Optional[str] = None,
172-
node_shape: Optional[str] = None,
173-
edge_colour: Optional[str] = None,
174-
node_attr: Optional[str] = None,
175-
edge_attr: Optional[str] = None,
170+
bg_colour: str | None = None,
171+
node_colour: str | None = None,
172+
node_shape: str | None = None,
173+
edge_colour: str | None = None,
174+
node_attr: str | None = None,
175+
edge_attr: str | None = None,
176176
) -> pydot.Dot:
177177
r"""Export DAG or list of DAGs to image. Note that node names must be unique. Possible node attributes include style,
178178
fillcolor, or shape.

bigtree/dag/parsing.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from typing import List, Optional, TypeVar
1+
from typing import TypeVar
22

33
from bigtree.node import dagnode
44
from bigtree.utils import exceptions
@@ -10,7 +10,7 @@
1010
T = TypeVar("T", bound=dagnode.DAGNode)
1111

1212

13-
def get_path_dag(from_node: T, to_node: T) -> List[List[T]]:
13+
def get_path_dag(from_node: T, to_node: T) -> list[list[T]]:
1414
"""Get path from origin node to destination node. Path is inclusive of origin and destination nodes.
1515
1616
Examples:
@@ -52,9 +52,9 @@ def get_path_dag(from_node: T, to_node: T) -> List[List[T]]:
5252
if to_node not in from_node.descendants:
5353
raise exceptions.TreeError(f"It is not possible to go to {to_node}")
5454

55-
paths: List[List[T]] = []
55+
paths: list[list[T]] = []
5656

57-
def _recursive_path(_node: T, _path: List[T]) -> Optional[List[T]]:
57+
def _recursive_path(_node: T, _path: list[T]) -> list[T] | None:
5858
"""Get path to specified node.
5959
6060
Args:

bigtree/node/basenode.py

Lines changed: 14 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,7 @@
22

33
import copy
44
import heapq
5-
from typing import (
6-
Any,
7-
Generator,
8-
Iterable,
9-
List,
10-
Mapping,
11-
Optional,
12-
Set,
13-
Tuple,
14-
TypeVar,
15-
)
5+
from typing import Any, Generator, Iterable, Mapping, TypeVar
166

177
from bigtree.globals import ASSERTIONS
188
from bigtree.utils import exceptions, iterators
@@ -126,7 +116,7 @@ class BaseNode:
126116
3. ``set_attrs(attrs: dict)``: Set node attribute name(s) and value(s)
127117
4. ``go_to(node: Self)``: Get a path from own node to another node from same tree
128118
5. ``append(node: Self)``: Add child to node
129-
6. ``extend(nodes: List[Self])``: Add multiple children to node
119+
6. ``extend(nodes: list[Self])``: Add multiple children to node
130120
7. ``copy()``: Deep copy self
131121
8. ``sort()``: Sort child nodes
132122
9. ``plot()``: Plot tree in line form
@@ -138,12 +128,12 @@ class BaseNode:
138128

139129
def __init__(
140130
self,
141-
parent: Optional[T] = None,
142-
children: Optional[List[T]] = None,
131+
parent: T | None = None,
132+
children: list[T] | None = None,
143133
**kwargs: Any,
144134
):
145-
self.__parent: Optional[T] = None
146-
self.__children: List[T] = []
135+
self.__parent: T | None = None
136+
self.__children: list[T] = []
147137
if children is None:
148138
children = []
149139
self.parent = parent
@@ -187,7 +177,7 @@ def __check_parent_loop(self, new_parent: T) -> None:
187177
)
188178

189179
@property
190-
def parent(self: T) -> Optional[T]:
180+
def parent(self: T) -> T | None:
191181
"""Get parent node.
192182
193183
Returns:
@@ -330,7 +320,7 @@ def __check_children_loop(self: T, new_children: Iterable[T]) -> None:
330320
seen_children.append(id(new_child))
331321

332322
@property
333-
def children(self: T) -> Tuple[T, ...]:
323+
def children(self: T) -> tuple[T, ...]:
334324
"""Get child nodes.
335325
336326
Returns:
@@ -339,7 +329,7 @@ def children(self: T) -> Tuple[T, ...]:
339329
return tuple(self.__children)
340330

341331
@children.setter
342-
def children(self: T, new_children: List[T] | Tuple[T] | Set[T]) -> None:
332+
def children(self: T, new_children: list[T] | tuple[T] | set[T]) -> None:
343333
"""Set child nodes.
344334
345335
Args:
@@ -457,7 +447,7 @@ def siblings(self: T) -> Iterable[T]:
457447
return tuple(child for child in self.parent.children if child is not self)
458448

459449
@property
460-
def left_sibling(self: T) -> Optional[T]:
450+
def left_sibling(self: T) -> T | None:
461451
"""Get sibling left of self.
462452
463453
Returns:
@@ -470,7 +460,7 @@ def left_sibling(self: T) -> Optional[T]:
470460
return self.parent.children[child_idx - 1]
471461

472462
@property
473-
def right_sibling(self: T) -> Optional[T]:
463+
def right_sibling(self: T) -> T | None:
474464
"""Get sibling right of self.
475465
476466
Returns:
@@ -594,7 +584,7 @@ def from_dict(cls, input_dict: Mapping[str, Any]) -> BaseNode:
594584

595585
def describe(
596586
self, exclude_attributes: Iterable[str] = (), exclude_prefix: str = ""
597-
) -> List[Tuple[str, Any]]:
587+
) -> list[tuple[str, Any]]:
598588
"""Get node information sorted by attribute name, returns list of tuples.
599589
600590
Examples:
@@ -679,7 +669,7 @@ def append(self: T, other: T) -> T:
679669
other.parent = self
680670
return self
681671

682-
def extend(self: T, others: List[T]) -> T:
672+
def extend(self: T, others: list[T]) -> T:
683673
"""Add others as children of self. Can be chained.
684674
685675
Args:
@@ -743,7 +733,7 @@ def plot(self, *args: Any, **kwargs: Any) -> plt.Figure:
743733
reingold_tilford(self)
744734
return plot_tree(self, *args, **kwargs)
745735

746-
def query(self, query: str, debug: bool = False) -> List[T]:
736+
def query(self, query: str, debug: bool = False) -> list[T]:
747737
"""Query tree using Tree Definition Language.
748738
749739
Examples:

0 commit comments

Comments
 (0)