iker-python-common 1.0.18__tar.gz → 1.0.19__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 (71) hide show
  1. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/PKG-INFO +1 -1
  2. iker_python_common-1.0.19/resources/unittest/config/config.cfg +10 -0
  3. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/config.py +4 -1
  4. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/sequtils.py +8 -4
  5. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker_python_common.egg-info/PKG-INFO +1 -1
  6. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker_python_common.egg-info/SOURCES.txt +1 -0
  7. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/config_test.py +53 -1
  8. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/dbutils_test.py +18 -18
  9. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/sequtils_test.py +239 -22
  10. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/.editorconfig +0 -0
  11. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/.github/workflows/pr.yml +0 -0
  12. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/.github/workflows/push.yml +0 -0
  13. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/.gitignore +0 -0
  14. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/MANIFEST.in +0 -0
  15. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/README.md +0 -0
  16. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/VERSION +0 -0
  17. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/pyproject.toml +0 -0
  18. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/csv/data.csv +0 -0
  19. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/csv/data.tsv +0 -0
  20. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.baz/file.bar.baz +0 -0
  21. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.baz/file.foo.bar +0 -0
  22. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.baz/file.foo.baz +0 -0
  23. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
  24. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
  25. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
  26. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
  27. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.foo/file.bar +0 -0
  28. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.foo/file.baz +0 -0
  29. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/resources/unittest/shutils/dir.foo/file.foo +0 -0
  30. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/setup.cfg +0 -0
  31. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/setup.py +0 -0
  32. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/__init__.py +0 -0
  33. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/__init__.py +0 -0
  34. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/argutils.py +0 -0
  35. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/csv.py +0 -0
  36. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/dbutils.py +0 -0
  37. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/dockerutils.py +0 -0
  38. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/dtutils.py +0 -0
  39. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/funcutils.py +0 -0
  40. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/jsonutils.py +0 -0
  41. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/logger.py +0 -0
  42. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/numutils.py +0 -0
  43. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/randutils.py +0 -0
  44. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/retry.py +0 -0
  45. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/s3utils.py +0 -0
  46. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/shutils.py +0 -0
  47. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/span.py +0 -0
  48. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/strutils.py +0 -0
  49. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker/common/utils/testutils.py +0 -0
  50. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker_python_common.egg-info/dependency_links.txt +0 -0
  51. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker_python_common.egg-info/not-zip-safe +0 -0
  52. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker_python_common.egg-info/requires.txt +0 -0
  53. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/src/iker_python_common.egg-info/top_level.txt +0 -0
  54. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/__init__.py +0 -0
  55. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/argutils_test.py +0 -0
  56. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/csv_test.py +0 -0
  57. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/dockerutils_test.py +0 -0
  58. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/dtutils_test.py +0 -0
  59. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/funcutils_test.py +0 -0
  60. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/jsonutils_test.py +0 -0
  61. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/logger_test.py +0 -0
  62. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/numutils_test.py +0 -0
  63. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/randutils_test.py +0 -0
  64. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/retry_test.py +0 -0
  65. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/s3utils_test.py +0 -0
  66. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/shutils_test.py +0 -0
  67. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/span_test.py +0 -0
  68. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/strutils_test.py +0 -0
  69. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/common/utils/testutils_test.py +0 -0
  70. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/docker_fixtures.py +0 -0
  71. {iker_python_common-1.0.18 → iker_python_common-1.0.19}/test/iker_tests/iker_test.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: iker-python-common
3
- Version: 1.0.18
3
+ Version: 1.0.19
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.11
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -0,0 +1,10 @@
1
+ [dummy_section_1]
2
+ dummy_option_1 = True
3
+ dummy_option_2 = False
4
+ dummy_option_3 = 1
5
+ dummy_option_4 = -1
6
+ dummy_option_5 = 1.0
7
+ dummy_option_6 = -1.0
8
+ dummy_option_7 = 1.e+0
9
+ dummy_option_8 = -1.e-0
10
+ dummy_option_9 = dummy_value_alpha
@@ -1,4 +1,5 @@
1
1
  import configparser
2
+ import os.path
2
3
  from typing import Self
3
4
 
4
5
  from iker.common.utils import logger
@@ -25,7 +26,9 @@ class Config(object):
25
26
  if is_blank(self.config_path):
26
27
  return False
27
28
  try:
28
- self.config_parser.read(self.config_path)
29
+ if not os.path.exists(self.config_path):
30
+ raise IOError("file not found")
31
+ self.config_parser.read(self.config_path, encoding="utf-8")
29
32
  return True
30
33
  except IOError as e:
31
34
  logger.exception("Failed to restore config from file <%s>", self.config_path)
@@ -234,9 +234,13 @@ class Seq(Generic[Tco], Sequence[Tco], Sized):
234
234
  return Seq(self.data + other.data)
235
235
 
236
236
  def take_left(self, n: int) -> Self:
237
+ if n <= 0:
238
+ return Seq([])
237
239
  return self[:n]
238
240
 
239
241
  def take_right(self, n: int) -> Self:
242
+ if n <= 0:
243
+ return Seq([])
240
244
  return self[-n:]
241
245
 
242
246
  take = take_left
@@ -319,14 +323,14 @@ class Seq(Generic[Tco], Sequence[Tco], Sized):
319
323
  def map_values(self, func: Callable[[Tco], U]) -> Self:
320
324
  return Seq((key, func(value)) for key, value in self.data)
321
325
 
322
- def flatten(self):
326
+ def flat_map(self, func: Callable[[Tco], Iterable[U]]) -> "Seq[U]":
323
327
  data = []
324
328
  for d in self.data:
325
- data.extend(d)
329
+ data.extend(func(d))
326
330
  return Seq(data)
327
331
 
328
- def flat_map(self, func: Callable[[Tco], U]) -> "Seq[U]":
329
- return self.flatten().map(func)
332
+ def flatten(self):
333
+ return self.flat_map(lambda x: list(x))
330
334
 
331
335
  def group_map(self, group_func: Callable[[Tco], K], map_func: Callable[[Tco], U]) -> "Seq[tuple[K, list[U]]]":
332
336
  return self.group(group_func).map_values(lambda x: list(map(map_func, x)))
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: iker-python-common
3
- Version: 1.0.18
3
+ Version: 1.0.19
4
4
  Classifier: Programming Language :: Python :: 3
5
5
  Classifier: Programming Language :: Python :: 3.11
6
6
  Classifier: Programming Language :: Python :: 3.12
@@ -7,6 +7,7 @@ pyproject.toml
7
7
  setup.py
8
8
  .github/workflows/pr.yml
9
9
  .github/workflows/push.yml
10
+ resources/unittest/config/config.cfg
10
11
  resources/unittest/csv/data.csv
11
12
  resources/unittest/csv/data.tsv
12
13
  resources/unittest/shutils/dir.baz/file.bar.baz
@@ -1,8 +1,10 @@
1
+ import os.path
1
2
  import unittest
2
3
 
3
4
  import ddt
4
5
 
5
6
  from iker.common.utils.config import Config, ConfigVisitor
7
+ from iker_tests import resources_directory
6
8
 
7
9
 
8
10
  @ddt.ddt
@@ -12,6 +14,29 @@ class ConfigTest(unittest.TestCase):
12
14
  config = Config()
13
15
  self.assertEqual(len(config), 0)
14
16
 
17
+ def test_set(self):
18
+ config = Config()
19
+
20
+ tuples = [
21
+ ("dummy_section_1", "dummy_option_1", "True"),
22
+ ("dummy_section_1", "dummy_option_2", "False"),
23
+ ("dummy_section_1", "dummy_option_3", "1"),
24
+ ("dummy_section_1", "dummy_option_4", "-1"),
25
+ ("dummy_section_1", "dummy_option_5", "1.0"),
26
+ ("dummy_section_1", "dummy_option_6", "-1.0"),
27
+ ("dummy_section_1", "dummy_option_7", "1.e+0"),
28
+ ("dummy_section_1", "dummy_option_8", "-1.e-0"),
29
+ ("dummy_section_1", "dummy_option_9", "dummy_value_alpha"),
30
+ ]
31
+
32
+ for section, option, value in tuples:
33
+ config.set(section, option, value)
34
+
35
+ for section, option, value in tuples:
36
+ self.assertTrue(config.has_section(section))
37
+ self.assertTrue(config.has(section, option))
38
+ self.assertEqual(config.get(section, option), value)
39
+
15
40
  def test_update(self):
16
41
  config = Config()
17
42
 
@@ -271,7 +296,35 @@ class ConfigTest(unittest.TestCase):
271
296
  self.assertEqual(config.get("dummy_section_1", "dummy_option_9"), "dummy_value_alpha")
272
297
 
273
298
  self.assertFalse(config.restore())
299
+ self.assertEqual(len(config), 0)
300
+
301
+ def test_restore__from_file(self):
302
+ config = Config(os.path.join(resources_directory, "unittest/config/config.cfg"))
274
303
 
304
+ tuples = [
305
+ ("dummy_section_1", "dummy_option_1", "True"),
306
+ ("dummy_section_1", "dummy_option_2", "False"),
307
+ ("dummy_section_1", "dummy_option_3", "1"),
308
+ ("dummy_section_1", "dummy_option_4", "-1"),
309
+ ("dummy_section_1", "dummy_option_5", "1.0"),
310
+ ("dummy_section_1", "dummy_option_6", "-1.0"),
311
+ ("dummy_section_1", "dummy_option_7", "1.e+0"),
312
+ ("dummy_section_1", "dummy_option_8", "-1.e-0"),
313
+ ("dummy_section_1", "dummy_option_9", "dummy_value_alpha"),
314
+ ]
315
+
316
+ self.assertTrue(config.restore())
317
+ self.assertEqual(len(config), len(tuples))
318
+
319
+ for section, option, value in tuples:
320
+ self.assertTrue(config.has_section(section))
321
+ self.assertTrue(config.has(section, option))
322
+ self.assertEqual(config.get(section, option), value)
323
+
324
+ def test_restore__file_not_found(self):
325
+ config = Config(os.path.join(resources_directory, "unittest/config/missing_config.cfg"))
326
+
327
+ self.assertFalse(config.restore())
275
328
  self.assertEqual(len(config), 0)
276
329
 
277
330
  def test_persist(self):
@@ -302,7 +355,6 @@ class ConfigTest(unittest.TestCase):
302
355
  self.assertEqual(config.get("dummy_section_1", "dummy_option_9"), "dummy_value_alpha")
303
356
 
304
357
  self.assertFalse(config.persist())
305
-
306
358
  self.assertEqual(len(config), len(tuples))
307
359
 
308
360
 
@@ -108,15 +108,15 @@ class PostgresqlDummyRecord(PostgresqlBaseModel):
108
108
 
109
109
  @pytest.mark.skipif(sys.platform == "win32", reason="Test not applicable on Windows")
110
110
  def test_mysql_connection_maker(fixture_mysql_test_proc, fixture_mysql_test):
111
- maker = ConnectionMaker(ConnectionMaker.Drivers.Mysql,
112
- "127.0.0.1",
113
- fixture_mysql_test_proc.port,
114
- fixture_mysql_test_proc.user,
115
- None,
116
- "test",
117
- session_opts=dict(
118
- expire_on_commit=False,
119
- ))
111
+ scheme = ConnectionMaker.Drivers.Mysql
112
+ host = "127.0.0.1"
113
+ port = fixture_mysql_test_proc.port
114
+ user = fixture_mysql_test_proc.user
115
+ database = "test"
116
+
117
+ maker = ConnectionMaker.from_url(scheme,
118
+ f"{scheme}://{user}@{host}:{port}/{database}",
119
+ session_opts=dict(expire_on_commit=False))
120
120
 
121
121
  maker.create_model(MysqlBaseModel)
122
122
 
@@ -220,15 +220,15 @@ def test_mysql_connection_maker(fixture_mysql_test_proc, fixture_mysql_test):
220
220
 
221
221
  @pytest.mark.skipif(sys.platform == "win32", reason="Test not applicable on Windows")
222
222
  def test_postgresql_connection_maker(fixture_postgresql_test_proc, fixture_postgresql_test):
223
- maker = ConnectionMaker(ConnectionMaker.Drivers.Postgresql,
224
- fixture_postgresql_test.info.host,
225
- fixture_postgresql_test.info.port,
226
- fixture_postgresql_test.info.user,
227
- None,
228
- fixture_postgresql_test.info.dbname,
229
- session_opts=dict(
230
- expire_on_commit=False,
231
- ))
223
+ scheme = ConnectionMaker.Drivers.Postgresql
224
+ host = fixture_postgresql_test.info.host
225
+ port = fixture_postgresql_test.info.port
226
+ user = fixture_postgresql_test.info.user
227
+ database = fixture_postgresql_test.info.dbname
228
+
229
+ maker = ConnectionMaker.from_url(scheme,
230
+ f"{scheme}://{user}@{host}:{port}/{database}",
231
+ session_opts=dict(expire_on_commit=False))
232
232
 
233
233
  maker.create_model(PostgresqlBaseModel)
234
234
 
@@ -1,6 +1,7 @@
1
1
  import unittest
2
2
 
3
3
  import ddt
4
+ import pytest
4
5
 
5
6
  from iker.common.utils.sequtils import batch_yield
6
7
  from iker.common.utils.sequtils import chunk, chunk_between, chunk_with_key, merge_chunks
@@ -789,6 +790,43 @@ class SeqUtilsTest(unittest.TestCase):
789
790
  def test_merge_chunks__drop_exclusive_end(self, data, merge_func, expect):
790
791
  self.assertEqual(expect, merge_chunks(data, merge_func=merge_func, drop_exclusive_end=True))
791
792
 
793
+
794
+ @ddt.ddt
795
+ class SeqTest(unittest.TestCase):
796
+
797
+ @ddt.data(
798
+ ([], []),
799
+ (seq([]), []),
800
+ (seq(seq([])), []),
801
+ ([0], [0]),
802
+ (seq([0]), [0]),
803
+ (seq(seq([0])), [0]),
804
+ ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]),
805
+ (seq([1, 2, 3, 4, 5]), [1, 2, 3, 4, 5]),
806
+ (seq(seq([1, 2, 3, 4, 5])), [1, 2, 3, 4, 5]),
807
+ (range(1, 6), [1, 2, 3, 4, 5]),
808
+ (seq(range(1, 6)), [1, 2, 3, 4, 5]),
809
+ (seq(seq(range(1, 6))), [1, 2, 3, 4, 5]),
810
+ )
811
+ @ddt.unpack
812
+ def test_builtin_init(self, data, expect):
813
+ self.assertEqual(seq(data).data, expect)
814
+
815
+ def test_builtin_init__unsupported_data_type(self):
816
+ with pytest.raises(ValueError):
817
+ seq(object())
818
+
819
+ @ddt.data(
820
+ ([], [], []),
821
+ ([0], [], [0]),
822
+ ([], [0], [0]),
823
+ ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5], [1, 2, 3, 4, 5, 1, 2, 3, 4, 5]),
824
+ )
825
+ @ddt.unpack
826
+ def test_builtin_add(self, a, b, expect):
827
+ actual = seq(a) + seq(b)
828
+ self.assertEqual(actual.data, expect)
829
+
792
830
  @ddt.data(
793
831
  ([0], 0, [0]),
794
832
  ([1, 2, 3, 4, 5], 0, [1]),
@@ -801,17 +839,21 @@ class SeqUtilsTest(unittest.TestCase):
801
839
  ([1, 2, 3, 4, 5], slice(1, -1, 2), [2, 4]),
802
840
  )
803
841
  @ddt.unpack
804
- def test_seq_builtin_getitem(self, data, item, expect):
842
+ def test_builtin_getitem(self, data, item, expect):
805
843
  actual = seq(data)[item]
806
844
  self.assertEqual(actual.data, expect)
807
845
 
846
+ def test_builtin_getitem__unsupported_index_type(self):
847
+ with pytest.raises(ValueError):
848
+ seq([])[object()]
849
+
808
850
  @ddt.data(
809
851
  ([], 0),
810
852
  ([0], 1),
811
853
  ([1, 2, 3, 4, 5], 5),
812
854
  )
813
855
  @ddt.unpack
814
- def test_seq_builtin_len(self, data, expect):
856
+ def test_builtin_len(self, data, expect):
815
857
  actual = len(seq(data))
816
858
  self.assertEqual(actual, expect)
817
859
 
@@ -824,7 +866,7 @@ class SeqUtilsTest(unittest.TestCase):
824
866
  ([1, 2, 3, 4, 5], -1, False),
825
867
  )
826
868
  @ddt.unpack
827
- def test_seq_builtin_contains(self, data, item, expect):
869
+ def test_builtin_contains(self, data, item, expect):
828
870
  actual = item in seq(data)
829
871
  self.assertEqual(actual, expect)
830
872
 
@@ -834,7 +876,7 @@ class SeqUtilsTest(unittest.TestCase):
834
876
  ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]),
835
877
  )
836
878
  @ddt.unpack
837
- def test_seq_builtin_iter(self, data, expect):
879
+ def test_builtin_iter(self, data, expect):
838
880
  actual = list(x for x in seq(data))
839
881
  self.assertEqual(actual, expect)
840
882
 
@@ -844,7 +886,7 @@ class SeqUtilsTest(unittest.TestCase):
844
886
  ([1, 2, 3, 4, 5], [5, 4, 3, 2, 1]),
845
887
  )
846
888
  @ddt.unpack
847
- def test_seq_builtin_reversed(self, data, expect):
889
+ def test_builtin_reversed(self, data, expect):
848
890
  actual = list(x for x in reversed(seq(data)))
849
891
  self.assertEqual(actual, expect)
850
892
 
@@ -859,7 +901,7 @@ class SeqUtilsTest(unittest.TestCase):
859
901
  ([1, 2, 3, 4, 5], -1, 0),
860
902
  )
861
903
  @ddt.unpack
862
- def test_seq_count(self, data, item, expect):
904
+ def test_count(self, data, item, expect):
863
905
  actual = seq(data).count(item)
864
906
  self.assertEqual(actual, expect)
865
907
 
@@ -879,10 +921,65 @@ class SeqUtilsTest(unittest.TestCase):
879
921
  ([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5], lambda x: x % 2 == 1, 9),
880
922
  )
881
923
  @ddt.unpack
882
- def test_seq_count_if(self, data, func, expect):
924
+ def test_count_if(self, data, func, expect):
883
925
  actual = seq(data).count_if(func)
884
926
  self.assertEqual(actual, expect)
885
927
 
928
+ @ddt.data(
929
+ ([], 0, []),
930
+ ([], 1, []),
931
+ ([0], 0, []),
932
+ ([0], 1, [0]),
933
+ ([0], 2, [0]),
934
+ ([1, 2, 3, 4, 5], 0, []),
935
+ ([1, 2, 3, 4, 5], 1, [1]),
936
+ ([1, 2, 3, 4, 5], 5, [1, 2, 3, 4, 5]),
937
+ ([1, 2, 3, 4, 5], 6, [1, 2, 3, 4, 5]),
938
+ )
939
+ @ddt.unpack
940
+ def test_take_left(self, data, n, expect):
941
+ actual = seq(data).take_left(n)
942
+ self.assertEqual(actual.data, expect)
943
+
944
+ @ddt.data(
945
+ ([], 0, []),
946
+ ([], 1, []),
947
+ ([0], 0, []),
948
+ ([0], 1, [0]),
949
+ ([0], 2, [0]),
950
+ ([1, 2, 3, 4, 5], 0, []),
951
+ ([1, 2, 3, 4, 5], 1, [5]),
952
+ ([1, 2, 3, 4, 5], 5, [1, 2, 3, 4, 5]),
953
+ ([1, 2, 3, 4, 5], 6, [1, 2, 3, 4, 5]),
954
+ )
955
+ @ddt.unpack
956
+ def test_take_right(self, data, n, expect):
957
+ actual = seq(data).take_right(n)
958
+ self.assertEqual(actual.data, expect)
959
+
960
+ @ddt.data(
961
+ ([], []),
962
+ ([0], [0]),
963
+ ([0, 0, 0], [0, 0, 0]),
964
+ ([1, 2, 3, 4, 5], [5, 4, 3, 2, 1]),
965
+ )
966
+ @ddt.unpack
967
+ def test_reverse(self, data, expect):
968
+ actual = seq(data).reverse()
969
+ self.assertEqual(actual.data, expect)
970
+
971
+ @ddt.data(
972
+ ([], []),
973
+ ([0], [0]),
974
+ ([0, 0, 0], [0]),
975
+ ([1, 2, 3, 4, 5], [1, 2, 3, 4, 5]),
976
+ ([1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 2, 3, 1, 2, 1], [1, 2, 3, 4, 5]),
977
+ )
978
+ @ddt.unpack
979
+ def test_distinct(self, data, expect):
980
+ actual = seq(data).distinct()
981
+ self.assertEqual(actual.data, expect)
982
+
886
983
  @ddt.data(
887
984
  ([], 0, lambda x, y: x, []),
888
985
  ([], None, lambda x, y: x, []),
@@ -892,7 +989,7 @@ class SeqUtilsTest(unittest.TestCase):
892
989
  ([1, 2, 3, 4, 5], 0, lambda x, y: x * 10 + y, [1, 12, 123, 1234, 12345]),
893
990
  )
894
991
  @ddt.unpack
895
- def test_seq_scan_left(self, data, zero, func, expect):
992
+ def test_scan_left(self, data, zero, func, expect):
896
993
  actual = seq(data).scan_left(zero, func)
897
994
  self.assertEqual(actual.data, expect)
898
995
 
@@ -905,7 +1002,7 @@ class SeqUtilsTest(unittest.TestCase):
905
1002
  ([1, 2, 3, 4, 5], 0, lambda x, y: x * 10 + y, [54321, 5432, 543, 54, 5]),
906
1003
  )
907
1004
  @ddt.unpack
908
- def test_seq_scan_right(self, data, zero, func, expect):
1005
+ def test_scan_right(self, data, zero, func, expect):
909
1006
  actual = seq(data).scan_right(zero, func)
910
1007
  self.assertEqual(actual.data, expect)
911
1008
 
@@ -916,7 +1013,7 @@ class SeqUtilsTest(unittest.TestCase):
916
1013
  ([1, 2, 3, 4, 5], lambda x: x ** 2, [1, 4, 9, 16, 25]),
917
1014
  )
918
1015
  @ddt.unpack
919
- def test_seq_map(self, data, func, expect):
1016
+ def test_map(self, data, func, expect):
920
1017
  actual = seq(data).map(func)
921
1018
  self.assertEqual(actual.data, expect)
922
1019
 
@@ -929,7 +1026,7 @@ class SeqUtilsTest(unittest.TestCase):
929
1026
  ([1, 2, 3, 4, 5], 0, lambda x, y: x * 10 + y, [12345]),
930
1027
  )
931
1028
  @ddt.unpack
932
- def test_seq_fold_left(self, data, zero, func, expect):
1029
+ def test_fold_left(self, data, zero, func, expect):
933
1030
  actual = seq(data).fold_left(zero, func)
934
1031
  self.assertEqual(actual.data, expect)
935
1032
 
@@ -941,7 +1038,7 @@ class SeqUtilsTest(unittest.TestCase):
941
1038
  ([1, 2, 3, 4, 5], 0, lambda x, y: x * 10 + y, [54321]),
942
1039
  )
943
1040
  @ddt.unpack
944
- def test_seq_fold_right(self, data, zero, func, expect):
1041
+ def test_fold_right(self, data, zero, func, expect):
945
1042
  actual = seq(data).fold_right(zero, func)
946
1043
  self.assertEqual(actual.data, expect)
947
1044
 
@@ -952,7 +1049,7 @@ class SeqUtilsTest(unittest.TestCase):
952
1049
  ([1, 2, 3, 4, 5], lambda x, y: y, [5]),
953
1050
  )
954
1051
  @ddt.unpack
955
- def test_seq_reduce(self, data, func, expect):
1052
+ def test_reduce(self, data, func, expect):
956
1053
  actual = seq(data).reduce(func)
957
1054
  self.assertEqual(actual.data, expect)
958
1055
 
@@ -964,7 +1061,7 @@ class SeqUtilsTest(unittest.TestCase):
964
1061
  ([1, 2, 3, 4, 5], lambda x, y: False, [5]),
965
1062
  )
966
1063
  @ddt.unpack
967
- def test_seq_max(self, data, func, expect):
1064
+ def test_max(self, data, func, expect):
968
1065
  actual = seq(data).max(func)
969
1066
  self.assertEqual(actual.data, expect)
970
1067
 
@@ -976,7 +1073,7 @@ class SeqUtilsTest(unittest.TestCase):
976
1073
  ([1, 2, 3, 4, 5], lambda x, y: False, [5]),
977
1074
  )
978
1075
  @ddt.unpack
979
- def test_seq_min(self, data, func, expect):
1076
+ def test_min(self, data, func, expect):
980
1077
  actual = seq(data).min(func)
981
1078
  self.assertEqual(actual.data, expect)
982
1079
 
@@ -987,7 +1084,7 @@ class SeqUtilsTest(unittest.TestCase):
987
1084
  ([1, 2, 3, 4, 5], lambda x: x * 2, [(2, [1]), (4, [2]), (6, [3]), (8, [4]), (10, [5])]),
988
1085
  )
989
1086
  @ddt.unpack
990
- def test_seq_group(self, data, func, expect):
1087
+ def test_group(self, data, func, expect):
991
1088
  actual = seq(data).group(func)
992
1089
  self.assertEqual(actual.data, expect)
993
1090
 
@@ -997,7 +1094,7 @@ class SeqUtilsTest(unittest.TestCase):
997
1094
  ([(1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e")], [1, 2, 3, 4, 5]),
998
1095
  )
999
1096
  @ddt.unpack
1000
- def test_seq_keys(self, data, expect):
1097
+ def test_keys(self, data, expect):
1001
1098
  actual = seq(data).keys()
1002
1099
  self.assertEqual(actual.data, expect)
1003
1100
 
@@ -1007,7 +1104,7 @@ class SeqUtilsTest(unittest.TestCase):
1007
1104
  ([(1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e")], ["a", "b", "c", "d", "e"]),
1008
1105
  )
1009
1106
  @ddt.unpack
1010
- def test_seq_values(self, data, expect):
1107
+ def test_values(self, data, expect):
1011
1108
  actual = seq(data).values()
1012
1109
  self.assertEqual(actual.data, expect)
1013
1110
 
@@ -1017,10 +1114,64 @@ class SeqUtilsTest(unittest.TestCase):
1017
1114
  ([(1, "a"), (2, "b"), (3, "c"), (4, "d"), (5, "e")], [("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5)]),
1018
1115
  )
1019
1116
  @ddt.unpack
1020
- def test_seq_swap(self, data, expect):
1117
+ def test_swap(self, data, expect):
1021
1118
  actual = seq(data).swap()
1022
1119
  self.assertEqual(actual.data, expect)
1023
1120
 
1121
+ @ddt.data(
1122
+ ([], lambda x: x, []),
1123
+ ([(0, "0")], lambda x: x * 2, [(0, "0")]),
1124
+ ([(0, "0")], str, [("0", "0")]),
1125
+ (
1126
+ [(1, "1"), (2, "2"), (3, "3"), (4, "4"), (5, "5")],
1127
+ lambda x: x * 2,
1128
+ [(2, "1"), (4, "2"), (6, "3"), (8, "4"), (10, "5")],
1129
+ ),
1130
+ (
1131
+ [(1, "1"), (2, "2"), (3, "3"), (4, "4"), (5, "5")],
1132
+ str,
1133
+ [("1", "1"), ("2", "2"), ("3", "3"), ("4", "4"), ("5", "5")],
1134
+ ),
1135
+ )
1136
+ @ddt.unpack
1137
+ def test_map_keys(self, data, func, expect):
1138
+ actual = seq(data).map_keys(func)
1139
+ self.assertEqual(actual.data, expect)
1140
+
1141
+ @ddt.data(
1142
+ ([], lambda x: x, []),
1143
+ ([(0, "0")], lambda x: x * 2, [(0, "00")]),
1144
+ ([(0, "0")], int, [(0, 0)]),
1145
+ (
1146
+ [(1, "1"), (2, "2"), (3, "3"), (4, "4"), (5, "5")],
1147
+ lambda x: x * 2,
1148
+ [(1, "11"), (2, "22"), (3, "33"), (4, "44"), (5, "55")],
1149
+ ),
1150
+ (
1151
+ [(1, "1"), (2, "2"), (3, "3"), (4, "4"), (5, "5")],
1152
+ int,
1153
+ [(1, 1), (2, 2), (3, 3), (4, 4), (5, 5)],
1154
+ ),
1155
+ )
1156
+ @ddt.unpack
1157
+ def test_map_values(self, data, func, expect):
1158
+ actual = seq(data).map_values(func)
1159
+ self.assertEqual(actual.data, expect)
1160
+
1161
+ @ddt.data(
1162
+ ([], lambda x: x, []),
1163
+ ([[]], lambda x: x, []),
1164
+ ([[0]], lambda x: x, [0]),
1165
+ ([[1, 2, 3, 4, 5]], lambda x: x, [1, 2, 3, 4, 5]),
1166
+ ([[], [1], [2], [3], [4], [5], []], lambda x: x, [1, 2, 3, 4, 5]),
1167
+ ([[], [1, 2, 3, 4, 5], []], lambda x: x, [1, 2, 3, 4, 5]),
1168
+ ([1, 2, 3, 4, 5], lambda x: list(range(x)), [0, 0, 1, 0, 1, 2, 0, 1, 2, 3, 0, 1, 2, 3, 4]),
1169
+ )
1170
+ @ddt.unpack
1171
+ def test_flat_map(self, data, func, expect):
1172
+ actual = seq(data).flat_map(func)
1173
+ self.assertEqual(actual.data, expect)
1174
+
1024
1175
  @ddt.data(
1025
1176
  ([], []),
1026
1177
  ([[]], []),
@@ -1030,10 +1181,76 @@ class SeqUtilsTest(unittest.TestCase):
1030
1181
  ([[], [1, 2, 3, 4, 5], []], [1, 2, 3, 4, 5]),
1031
1182
  )
1032
1183
  @ddt.unpack
1033
- def test_seq_flatten(self, data, expect):
1184
+ def test_flatten(self, data, expect):
1034
1185
  actual = seq(data).flatten()
1035
1186
  self.assertEqual(actual.data, expect)
1036
1187
 
1188
+ @ddt.data(
1189
+ ([], lambda x: x % 2, lambda x: x ** 2, []),
1190
+ ([0], lambda x: x % 2, lambda x: x ** 2, [(0, [0])]),
1191
+ ([1, 2, 3, 4, 5], lambda x: x % 2, lambda x: x ** 2, [(0, [4, 16]), (1, [1, 9, 25])]),
1192
+ ([1, 2, 3, 4, 5], lambda x: x, lambda x: x ** 2, [(1, [1]), (2, [4]), (3, [9]), (4, [16]), (5, [25])]),
1193
+ )
1194
+ @ddt.unpack
1195
+ def test_group_map(self, data, group_func, map_func, expect):
1196
+ actual = seq(data).group_map(group_func, map_func)
1197
+ self.assertEqual(actual.data, expect)
1198
+
1199
+ @ddt.data(
1200
+ ([], lambda x: True, []),
1201
+ ([0], lambda x: True, [0]),
1202
+ ([0], lambda x: False, []),
1203
+ ([0], lambda x: x % 2 == 0, [0]),
1204
+ ([0], lambda x: x % 2 == 1, []),
1205
+ ([0, 0, 0], lambda x: True, [0, 0, 0]),
1206
+ ([0, 0, 0], lambda x: False, []),
1207
+ ([0, 0, 0], lambda x: x % 2 == 0, [0, 0, 0]),
1208
+ ([0, 0, 0], lambda x: x % 2 == 1, []),
1209
+ ([1, 2, 3, 4, 5], lambda x: x % 2 == 0, [2, 4]),
1210
+ ([1, 2, 3, 4, 5], lambda x: x % 2 == 1, [1, 3, 5]),
1211
+ ([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5], lambda x: x % 2 == 0, [2, 2, 4, 4, 4, 4]),
1212
+ ([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5], lambda x: x % 2 == 1, [1, 3, 3, 3, 5, 5, 5, 5, 5]),
1213
+ )
1214
+ @ddt.unpack
1215
+ def test_filter(self, data, func, expect):
1216
+ actual = seq(data).filter(func)
1217
+ self.assertEqual(actual.data, expect)
1218
+
1219
+ @ddt.data(
1220
+ ([], lambda x: True, []),
1221
+ ([0], lambda x: True, []),
1222
+ ([0], lambda x: False, [0]),
1223
+ ([0], lambda x: x % 2 == 0, []),
1224
+ ([0], lambda x: x % 2 == 1, [0]),
1225
+ ([0, 0, 0], lambda x: True, []),
1226
+ ([0, 0, 0], lambda x: False, [0, 0, 0]),
1227
+ ([0, 0, 0], lambda x: x % 2 == 0, []),
1228
+ ([0, 0, 0], lambda x: x % 2 == 1, [0, 0, 0]),
1229
+ ([1, 2, 3, 4, 5], lambda x: x % 2 == 0, [1, 3, 5]),
1230
+ ([1, 2, 3, 4, 5], lambda x: x % 2 == 1, [2, 4]),
1231
+ ([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5], lambda x: x % 2 == 0, [1, 3, 3, 3, 5, 5, 5, 5, 5]),
1232
+ ([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5], lambda x: x % 2 == 1, [2, 2, 4, 4, 4, 4]),
1233
+ )
1234
+ @ddt.unpack
1235
+ def test_filter_not(self, data, func, expect):
1236
+ actual = seq(data).filter_not(func)
1237
+ self.assertEqual(actual.data, expect)
1238
+
1239
+ @ddt.data(
1240
+ ([], lambda x: x, []),
1241
+ ([0], lambda x: x, [0]),
1242
+ ([0, 0, 0], lambda x: x, [0, 0, 0]),
1243
+ ([1, 2, 3, 4, 5], lambda x: x, [1, 2, 3, 4, 5]),
1244
+ ([5, 4, 3, 2, 1], lambda x: x, [1, 2, 3, 4, 5]),
1245
+ ([1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5], lambda x: x, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]),
1246
+ ([1, 2, 3, 4, 5, 2, 3, 4, 5, 3, 4, 5, 4, 5, 5], lambda x: x, [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5]),
1247
+ ([1, 2, 3, 4, 5, 2, 3, 4, 5, 3, 4, 5, 4, 5, 5], lambda x: -x, [5, 5, 5, 5, 5, 4, 4, 4, 4, 3, 3, 3, 2, 2, 1]),
1248
+ )
1249
+ @ddt.unpack
1250
+ def test_sort(self, data, func, expect):
1251
+ actual = (seq(data).sort(func))
1252
+ self.assertEqual(actual.data, expect)
1253
+
1037
1254
  @ddt.data(
1038
1255
  ([], [], []),
1039
1256
  ([0], [], []),
@@ -1047,7 +1264,7 @@ class SeqUtilsTest(unittest.TestCase):
1047
1264
  (["a", "b", "c", "d", "e"], [1, 2, 3, 4, 5], [("a", 1), ("b", 2), ("c", 3), ("d", 4), ("e", 5)]),
1048
1265
  )
1049
1266
  @ddt.unpack
1050
- def test_seq_zip(self, a, b, expect):
1267
+ def test_zip(self, a, b, expect):
1051
1268
  actual = seq(a).zip(seq(b))
1052
1269
  self.assertEqual(actual.data, expect)
1053
1270
 
@@ -1096,6 +1313,6 @@ class SeqUtilsTest(unittest.TestCase):
1096
1313
  ),
1097
1314
  )
1098
1315
  @ddt.unpack
1099
- def test_seq_zip_fill(self, a, b, fill, expect):
1316
+ def test_zip_fill(self, a, b, fill, expect):
1100
1317
  actual = seq(a).zip_fill(seq(b), fill)
1101
1318
  self.assertEqual(actual.data, expect)