verysimpletree 2.0.1__tar.gz → 2.0.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: verysimpletree
3
- Version: 2.0.1
3
+ Version: 2.0.2
4
4
  Summary: lightweight tree data structure
5
5
  Author: Alex Gorji
6
6
  Author-email: Alex Gorji <aligorji@hotmail.com>
@@ -20,6 +20,29 @@ An abstract lightweight tree class for managing tree structures.
20
20
 
21
21
  Requires Python 3.11 or newer.
22
22
 
23
+ ## Typed list representations
24
+
25
+ `TreeNodeListRepresentation[ValueT]` describes `[value, child, ...]` recursively.
26
+ `create_tree_from_list()` accepts the same value type as
27
+ `get_list_representation()`, including scalar values for a single attribute:
28
+
29
+ ```python
30
+ from verysimpletree.tree import TreeNodeListRepresentation
31
+
32
+ representation: TreeNodeListRepresentation[int] = [
33
+ 10,
34
+ [3, [2, [1], [1]], [1]],
35
+ [7, [4], [3]],
36
+ ]
37
+ # For a concrete Tree subclass whose constructor accepts value:
38
+ tree = MyTree.create_tree_from_list(representation, "value")
39
+ ```
40
+
41
+ For multiple attributes, each node value is a list of attribute values, ordered
42
+ to match `represented_attribute_names`. Child representations must be lists.
43
+ The value type checks the representation's contents; it does not verify that
44
+ attribute names or values match the subclass constructor.
45
+
23
46
  ## Development
24
47
 
25
48
  Use a current uv release; development and package builds are verified with
@@ -2,6 +2,29 @@ An abstract lightweight tree class for managing tree structures.
2
2
 
3
3
  Requires Python 3.11 or newer.
4
4
 
5
+ ## Typed list representations
6
+
7
+ `TreeNodeListRepresentation[ValueT]` describes `[value, child, ...]` recursively.
8
+ `create_tree_from_list()` accepts the same value type as
9
+ `get_list_representation()`, including scalar values for a single attribute:
10
+
11
+ ```python
12
+ from verysimpletree.tree import TreeNodeListRepresentation
13
+
14
+ representation: TreeNodeListRepresentation[int] = [
15
+ 10,
16
+ [3, [2, [1], [1]], [1]],
17
+ [7, [4], [3]],
18
+ ]
19
+ # For a concrete Tree subclass whose constructor accepts value:
20
+ tree = MyTree.create_tree_from_list(representation, "value")
21
+ ```
22
+
23
+ For multiple attributes, each node value is a list of attribute values, ordered
24
+ to match `represented_attribute_names`. Child representations must be lists.
25
+ The value type checks the representation's contents; it does not verify that
26
+ attribute names or values match the subclass constructor.
27
+
5
28
  ## Development
6
29
 
7
30
  Use a current uv release; development and package builds are verified with
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "verysimpletree"
3
- version = "2.0.1"
3
+ version = "2.0.2"
4
4
  description = "lightweight tree data structure"
5
5
  requires-python = ">=3.11"
6
6
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "verysimpletree"
3
- version = "2.0.1"
3
+ version = "2.0.2"
4
4
  description = "lightweight tree data structure"
5
5
  authors = [{ name = "Alex Gorji", email = "aligorji@hotmail.com" }]
6
6
  requires-python = ">=3.11"
@@ -4,6 +4,7 @@ from unittest import TestCase
4
4
  from verysimpletree.tree import (
5
5
  ChildNotFoundError,
6
6
  Tree,
7
+ TreeNodeListRepresentation,
7
8
  TreeReferenceError,
8
9
  grandchild1,
9
10
  )
@@ -68,6 +69,23 @@ class C(Tree[Any]):
68
69
  return True
69
70
 
70
71
 
72
+ class IntegerTree(Tree["IntegerTree"]):
73
+ def __init__(self, value: int) -> None:
74
+ super().__init__()
75
+ self.value = value
76
+
77
+ def _check_child_to_be_added(self, child: "IntegerTree") -> bool:
78
+ if not isinstance(child, IntegerTree):
79
+ raise TypeError("Expected an IntegerTree node")
80
+ return True
81
+
82
+
83
+ def _node_value(node: Tree[Any]) -> int:
84
+ if not isinstance(node, IntegerTree):
85
+ raise TypeError("Expected an IntegerTree node")
86
+ return node.value
87
+
88
+
71
89
  def _node_name(node: Tree[Any]) -> str:
72
90
  if not isinstance(node, (A, B, C)):
73
91
  raise TypeError("Expected an A, B, or C node")
@@ -460,6 +478,41 @@ class Test(TreeTestCase):
460
478
 
461
479
 
462
480
  class TreeListRepresentationTestCase(TreeTestCase):
481
+ def test_create_tree_from_typed_nested_integer_list(self) -> None:
482
+ representation: TreeNodeListRepresentation[int] = [
483
+ 10,
484
+ [3, [2, [1], [1]], [1]],
485
+ [7, [4], [3, [2], [1]]],
486
+ ]
487
+ tree = IntegerTree.create_tree_from_list(representation, "value")
488
+ assert tree.get_list_representation(key=_node_value) == representation
489
+ assert [node.value for node in tree.traverse()] == [
490
+ 10,
491
+ 3,
492
+ 2,
493
+ 1,
494
+ 1,
495
+ 1,
496
+ 7,
497
+ 4,
498
+ 3,
499
+ 2,
500
+ 1,
501
+ ]
502
+
503
+ def test_create_tree_from_typed_integer_root(self) -> None:
504
+ representation: TreeNodeListRepresentation[int] = [10]
505
+ tree = IntegerTree.create_tree_from_list(representation, "value")
506
+ assert tree.value == 10
507
+ assert tree.is_leaf
508
+
509
+ def test_create_tree_from_list_rejects_scalar_child(self) -> None:
510
+ representation: TreeNodeListRepresentation[int] = [10, 3]
511
+ with self.assertRaisesRegex(
512
+ TypeError, "Each child representation must be a list"
513
+ ):
514
+ IntegerTree.create_tree_from_list(representation, "value")
515
+
463
516
  def test_get_list_representation_all(self) -> None:
464
517
  assert self.root.get_list_representation(key=_node_name) == [
465
518
  "root",
@@ -221,7 +221,7 @@ class Tree(ABC, Generic[T]):
221
221
  @classmethod
222
222
  def create_tree_from_list(
223
223
  cls,
224
- tree_list_representation: TreeNodeListRepresentation[list[Any]],
224
+ tree_list_representation: TreeNodeListRepresentation[ValueT],
225
225
  represented_attribute_names: str | list[str],
226
226
  ) -> T:
227
227
  represented_attribute_names = make_list(represented_attribute_names)
@@ -239,6 +239,8 @@ class Tree(ABC, Generic[T]):
239
239
 
240
240
  node = _create_node(make_list(tree_list_representation[0]))
241
241
  for child_list_representation in tree_list_representation[1:]:
242
+ if not isinstance(child_list_representation, list):
243
+ raise TypeError("Each child representation must be a list.")
242
244
  child = cls.create_tree_from_list(
243
245
  child_list_representation, represented_attribute_names
244
246
  )