iterflat 0.0.0.dev0__tar.gz → 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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iterflat
3
- Version: 0.0.0.dev0
3
+ Version: 0.1.0
4
4
  Summary: iterflat
5
5
  Author-email: Johannes <johannes.programming@gmail.com>
6
6
  License: The MIT License (MIT)
@@ -27,7 +27,8 @@ License: The MIT License (MIT)
27
27
  Project-URL: Download, https://pypi.org/project/iterflat/#files
28
28
  Project-URL: Index, https://pypi.org/project/iterflat/
29
29
  Project-URL: Source, https://github.com/johannes-programming/iterflat/
30
- Classifier: Development Status :: 1 - Planning
30
+ Project-URL: Website, https://iterflat.johannes-programming.online/
31
+ Classifier: Development Status :: 3 - Alpha
31
32
  Classifier: License :: OSI Approved :: MIT License
32
33
  Classifier: Natural Language :: English
33
34
  Classifier: Operating System :: OS Independent
@@ -9,7 +9,7 @@ authors = [
9
9
  { email = "johannes.programming@gmail.com", name = "Johannes" },
10
10
  ]
11
11
  classifiers = [
12
- "Development Status :: 1 - Planning",
12
+ "Development Status :: 3 - Alpha",
13
13
  "License :: OSI Approved :: MIT License",
14
14
  "Natural Language :: English",
15
15
  "Operating System :: OS Independent",
@@ -24,7 +24,7 @@ keywords = []
24
24
  name = "iterflat"
25
25
  readme = "README.rst"
26
26
  requires-python = ">=3.11"
27
- version = "0.0.0.dev0"
27
+ version = "0.1.0"
28
28
 
29
29
  [project.license]
30
30
  file = "LICENSE.txt"
@@ -33,3 +33,4 @@ file = "LICENSE.txt"
33
33
  Download = "https://pypi.org/project/iterflat/#files"
34
34
  Index = "https://pypi.org/project/iterflat/"
35
35
  Source = "https://github.com/johannes-programming/iterflat/"
36
+ Website = "https://iterflat.johannes-programming.online/"
@@ -1,5 +1,2 @@
1
1
  from iterflat.core import *
2
2
  from iterflat.tests import *
3
-
4
- if __name__ == "__main__":
5
- main()
@@ -0,0 +1,21 @@
1
+ import operator
2
+ from typing import *
3
+
4
+ __all__ = ["iterflat"]
5
+
6
+
7
+ def iterflat(data: Any, *, depth: SupportsIndex = 1) -> Generator[Any, None, None]:
8
+ n: int
9
+ x: Iterable
10
+ n = operator.index(depth)
11
+ if n < -1:
12
+ yield iterflat(data, depth=n + 1)
13
+ return
14
+ if n == -1:
15
+ yield data
16
+ return
17
+ if n == 0:
18
+ yield from data
19
+ return
20
+ for x in data:
21
+ yield from iterflat(x, depth=n - 1)
@@ -0,0 +1,80 @@
1
+ import types
2
+ import unittest
3
+
4
+ from iterflat.core import iterflat
5
+
6
+
7
+ class TestIterflat(unittest.TestCase):
8
+ def test_depth_1_flattens_one_level(self):
9
+ data = [[1, 2], [3], []]
10
+ self.assertEqual(list(iterflat(data, depth=1)), [1, 2, 3])
11
+
12
+ def test_depth_2_flattens_two_levels(self):
13
+ data = [[[1], [2, 3]], [[4]], []]
14
+ self.assertEqual(list(iterflat(data, depth=2)), [1, 2, 3, 4])
15
+
16
+ def test_inv(self):
17
+ data = [[[1], [2, 3]], [[4]], []]
18
+ for n in range(5):
19
+ self.assertEqual(list(iterflat(iterflat(data, depth=-n), depth=n)), data)
20
+
21
+ def test_depth_0_iterates_input(self):
22
+ data = (1, 2, 3)
23
+ self.assertEqual(list(iterflat(data, depth=0)), [1, 2, 3])
24
+
25
+ def test_depth_minus_1_yields_data_as_single_element(self):
26
+ data = [1, 2, 3]
27
+ out = list(iterflat(data, depth=-1))
28
+ self.assertEqual(out, [data]) # data yielded as a single item
29
+
30
+ def test_depth_less_than_minus_1_wraps_again(self):
31
+ data = [1, 2]
32
+ out = list(iterflat(data, depth=-2))
33
+ # Should yield exactly one element, which itself is a generator
34
+ self.assertEqual(len(out), 1)
35
+ self.assertIsInstance(out[0], types.GeneratorType)
36
+ # Iterating that inner generator should give [data]
37
+ inner = list(out[0])
38
+ self.assertEqual(inner, [data])
39
+
40
+ def test_supports_index_custom_type(self):
41
+ class DepthLike:
42
+ def __index__(self):
43
+ return 1 # act like depth=1
44
+
45
+ data = [[10], [20, 30]]
46
+ self.assertEqual(list(iterflat(data, depth=DepthLike())), [10, 20, 30])
47
+
48
+ def test_generator_input_with_depth_0(self):
49
+ def gen():
50
+ for i in range(3):
51
+ yield i
52
+
53
+ self.assertEqual(list(iterflat(gen(), depth=0)), [0, 1, 2])
54
+
55
+ def test_strings(self):
56
+ # depth=0 iterates the string
57
+ self.assertEqual(list(iterflat("ab", depth=0)), ["a", "b"])
58
+ # depth=-1 treats the whole string as a single element
59
+ self.assertEqual(list(iterflat("ab", depth=-1)), ["ab"])
60
+ # depth=1 over a list of strings flattens one level into characters
61
+ self.assertEqual(list(iterflat(["ab", "c"], depth=1)), ["a", "b", "c"])
62
+
63
+ def test_type_error_when_nested_item_not_iterable_for_positive_depth(self):
64
+ # For depth=1, inner items must be iterable; ints are not, so this should raise
65
+ with self.assertRaises(TypeError):
66
+ list(iterflat([1, 2], depth=1))
67
+
68
+ def test_empty_input(self):
69
+ self.assertEqual(list(iterflat([], depth=0)), [])
70
+ self.assertEqual(list(iterflat([], depth=1)), [])
71
+ self.assertEqual(list(iterflat([], depth=2)), [])
72
+
73
+ def test_large_depth_exact(self):
74
+ # Perfectly nested 3 levels
75
+ data = [[[[1], [2]], [[3]]]]
76
+ self.assertEqual(list(iterflat(data, depth=3)), [1, 2, 3])
77
+
78
+
79
+ if __name__ == "__main__":
80
+ unittest.main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: iterflat
3
- Version: 0.0.0.dev0
3
+ Version: 0.1.0
4
4
  Summary: iterflat
5
5
  Author-email: Johannes <johannes.programming@gmail.com>
6
6
  License: The MIT License (MIT)
@@ -27,7 +27,8 @@ License: The MIT License (MIT)
27
27
  Project-URL: Download, https://pypi.org/project/iterflat/#files
28
28
  Project-URL: Index, https://pypi.org/project/iterflat/
29
29
  Project-URL: Source, https://github.com/johannes-programming/iterflat/
30
- Classifier: Development Status :: 1 - Planning
30
+ Project-URL: Website, https://iterflat.johannes-programming.online/
31
+ Classifier: Development Status :: 3 - Alpha
31
32
  Classifier: License :: OSI Approved :: MIT License
32
33
  Classifier: Natural Language :: English
33
34
  Classifier: Operating System :: OS Independent
@@ -4,10 +4,9 @@ README.rst
4
4
  pyproject.toml
5
5
  setup.cfg
6
6
  src/iterchain/__init__.py
7
- src/iterchain/__main__.py
8
7
  src/iterchain/core/__init__.py
9
8
  src/iterchain/tests/__init__.py
10
- src/iterchain/tests/test_1984.py
9
+ src/iterchain/tests/test_0.py
11
10
  src/iterflat.egg-info/PKG-INFO
12
11
  src/iterflat.egg-info/SOURCES.txt
13
12
  src/iterflat.egg-info/dependency_links.txt
@@ -1,4 +0,0 @@
1
- from iterflat import main
2
-
3
- if __name__ == "__main__":
4
- main()
@@ -1,8 +0,0 @@
1
- from typing import *
2
-
3
- __all__ = ["main"]
4
-
5
-
6
- def main(args: Optional[Iterable] = None) -> None:
7
- "This function prints 'Hello World!'."
8
- print("Hello World!")
@@ -1,11 +0,0 @@
1
- import unittest
2
- from typing import *
3
-
4
-
5
- class Test1984(unittest.TestCase):
6
- def test_1984(self: Self) -> None:
7
- self.assertEqual(2 + 2, 4, "Ignorance is Strength")
8
-
9
-
10
- if __name__ == "__main__":
11
- unittest.main()
File without changes
File without changes
File without changes
File without changes