k3pattern 0.1.4__tar.gz → 0.1.5__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,22 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: k3pattern
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: Find common prefix of strings, tuples, and nested structures
5
5
  Author-email: Zhang Yanpo <drdr.xp@gmail.com>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/pykit3/k3pattern
8
8
  Project-URL: Documentation, https://k3pattern.readthedocs.io
9
9
  Keywords: prefix,common-prefix,string,pattern
10
10
  Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: Topic :: Software Development :: Libraries
13
- Classifier: License :: OSI Approved :: MIT License
14
13
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.9
16
14
  Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
18
16
  Classifier: Programming Language :: Python :: 3.12
19
- Requires-Python: >=3.9
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: >=3.10
20
19
  Description-Content-Type: text/markdown
21
20
  License-File: LICENSE
22
21
  Provides-Extra: dev
@@ -59,14 +58,13 @@ pip install k3pattern
59
58
  # Synopsis
60
59
 
61
60
  ```python
62
-
63
61
  import k3pattern
64
62
 
65
- k3pattern.common_prefix('abc', 'abd') # 'ab'
66
- k3pattern.common_prefix((1, 2, 'abc'), (1, 2, 'abd')) # (1, 2, 'ab')
67
- k3pattern.common_prefix((1, 2, 'abc'), (1, 2, 'xyz')) # (1, 2); empty prefix of 'abc' and 'xyz' is removed
68
- k3pattern.common_prefix((1, 2, (5, 6)), (1, 2, (5, 7))) # (1, 2, (5,) )
69
- k3pattern.common_prefix('abc', 'abd', 'abe') # 'ab'; common prefix of more than two
63
+ k3pattern.common_prefix("abc", "abd") # 'ab'
64
+ k3pattern.common_prefix((1, 2, "abc"), (1, 2, "abd")) # (1, 2, 'ab')
65
+ k3pattern.common_prefix((1, 2, "abc"), (1, 2, "xyz")) # (1, 2); empty prefix of 'abc' and 'xyz' is removed
66
+ k3pattern.common_prefix((1, 2, (5, 6)), (1, 2, (5, 7))) # (1, 2, (5,) )
67
+ k3pattern.common_prefix("abc", "abd", "abe") # 'ab'; common prefix of more than two
70
68
  ```
71
69
 
72
70
  # Author
@@ -23,14 +23,13 @@ pip install k3pattern
23
23
  # Synopsis
24
24
 
25
25
  ```python
26
-
27
26
  import k3pattern
28
27
 
29
- k3pattern.common_prefix('abc', 'abd') # 'ab'
30
- k3pattern.common_prefix((1, 2, 'abc'), (1, 2, 'abd')) # (1, 2, 'ab')
31
- k3pattern.common_prefix((1, 2, 'abc'), (1, 2, 'xyz')) # (1, 2); empty prefix of 'abc' and 'xyz' is removed
32
- k3pattern.common_prefix((1, 2, (5, 6)), (1, 2, (5, 7))) # (1, 2, (5,) )
33
- k3pattern.common_prefix('abc', 'abd', 'abe') # 'ab'; common prefix of more than two
28
+ k3pattern.common_prefix("abc", "abd") # 'ab'
29
+ k3pattern.common_prefix((1, 2, "abc"), (1, 2, "abd")) # (1, 2, 'ab')
30
+ k3pattern.common_prefix((1, 2, "abc"), (1, 2, "xyz")) # (1, 2); empty prefix of 'abc' and 'xyz' is removed
31
+ k3pattern.common_prefix((1, 2, (5, 6)), (1, 2, (5, 7))) # (1, 2, (5,) )
32
+ k3pattern.common_prefix("abc", "abd", "abe") # 'ab'; common prefix of more than two
34
33
  ```
35
34
 
36
35
  # Author
@@ -11,7 +11,6 @@ from .strutil import (
11
11
  common_prefix,
12
12
  )
13
13
 
14
-
15
14
  __all__ = [
16
15
  "common_prefix",
17
16
  ]
@@ -1,22 +1,21 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: k3pattern
3
- Version: 0.1.4
3
+ Version: 0.1.5
4
4
  Summary: Find common prefix of strings, tuples, and nested structures
5
5
  Author-email: Zhang Yanpo <drdr.xp@gmail.com>
6
- License: MIT
6
+ License-Expression: MIT
7
7
  Project-URL: Homepage, https://github.com/pykit3/k3pattern
8
8
  Project-URL: Documentation, https://k3pattern.readthedocs.io
9
9
  Keywords: prefix,common-prefix,string,pattern
10
10
  Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Intended Audience :: Developers
12
12
  Classifier: Topic :: Software Development :: Libraries
13
- Classifier: License :: OSI Approved :: MIT License
14
13
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.9
16
14
  Classifier: Programming Language :: Python :: 3.10
17
15
  Classifier: Programming Language :: Python :: 3.11
18
16
  Classifier: Programming Language :: Python :: 3.12
19
- Requires-Python: >=3.9
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Requires-Python: >=3.10
20
19
  Description-Content-Type: text/markdown
21
20
  License-File: LICENSE
22
21
  Provides-Extra: dev
@@ -59,14 +58,13 @@ pip install k3pattern
59
58
  # Synopsis
60
59
 
61
60
  ```python
62
-
63
61
  import k3pattern
64
62
 
65
- k3pattern.common_prefix('abc', 'abd') # 'ab'
66
- k3pattern.common_prefix((1, 2, 'abc'), (1, 2, 'abd')) # (1, 2, 'ab')
67
- k3pattern.common_prefix((1, 2, 'abc'), (1, 2, 'xyz')) # (1, 2); empty prefix of 'abc' and 'xyz' is removed
68
- k3pattern.common_prefix((1, 2, (5, 6)), (1, 2, (5, 7))) # (1, 2, (5,) )
69
- k3pattern.common_prefix('abc', 'abd', 'abe') # 'ab'; common prefix of more than two
63
+ k3pattern.common_prefix("abc", "abd") # 'ab'
64
+ k3pattern.common_prefix((1, 2, "abc"), (1, 2, "abd")) # (1, 2, 'ab')
65
+ k3pattern.common_prefix((1, 2, "abc"), (1, 2, "xyz")) # (1, 2); empty prefix of 'abc' and 'xyz' is removed
66
+ k3pattern.common_prefix((1, 2, (5, 6)), (1, 2, (5, 7))) # (1, 2, (5,) )
67
+ k3pattern.common_prefix("abc", "abd", "abe") # 'ab'; common prefix of more than two
70
68
  ```
71
69
 
72
70
  # Author
@@ -1,14 +1,14 @@
1
1
  [build-system]
2
- requires = ["setuptools>=61.0"]
2
+ requires = ["setuptools>=77.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "k3pattern"
7
- version = "0.1.4"
7
+ version = "0.1.5"
8
8
  description = "Find common prefix of strings, tuples, and nested structures"
9
9
  readme = "README.md"
10
- license = {text = "MIT"}
11
- requires-python = ">=3.9"
10
+ license = "MIT"
11
+ requires-python = ">=3.10"
12
12
  authors = [
13
13
  { name = "Zhang Yanpo", email = "drdr.xp@gmail.com" }
14
14
  ]
@@ -17,12 +17,11 @@ classifiers = [
17
17
  "Development Status :: 4 - Beta",
18
18
  "Intended Audience :: Developers",
19
19
  "Topic :: Software Development :: Libraries",
20
- "License :: OSI Approved :: MIT License",
21
20
  "Programming Language :: Python :: 3",
22
- "Programming Language :: Python :: 3.9",
23
21
  "Programming Language :: Python :: 3.10",
24
22
  "Programming Language :: Python :: 3.11",
25
23
  "Programming Language :: Python :: 3.12",
24
+ "Programming Language :: Python :: 3.13",
26
25
  ]
27
26
  dependencies = []
28
27
 
@@ -1,7 +1,9 @@
1
1
  import os
2
+ import random
2
3
  import unittest
3
4
 
4
5
  import k3ut
6
+
5
7
  import k3pattern
6
8
 
7
9
  dd = k3ut.dd
@@ -9,6 +11,25 @@ dd = k3ut.dd
9
11
  this_base = os.path.dirname(__file__)
10
12
 
11
13
 
14
+ def _rand_str(rnd):
15
+ return "".join(rnd.choice("ab") for _ in range(rnd.randint(0, 3)))
16
+
17
+
18
+ def _vary(rnd, base):
19
+ # Cut the tail or change values, but keep the element type at each position.
20
+ rst = []
21
+ for elt in base:
22
+ if rnd.random() < 0.15:
23
+ break
24
+ if rnd.random() < 0.7:
25
+ rst.append(elt)
26
+ elif isinstance(elt, str):
27
+ rst.append(_rand_str(rnd))
28
+ else:
29
+ rst.append(_vary(rnd, elt))
30
+ return tuple(rst)
31
+
32
+
12
33
  class TestK3pattern(unittest.TestCase):
13
34
  def test_common_prefix_invalid_arg(self):
14
35
  cases = (
@@ -240,3 +261,55 @@ class TestK3pattern(unittest.TestCase):
240
261
  dd("rst: ", rst)
241
262
 
242
263
  self.assertEqual(expected, rst)
264
+
265
+ def test_common_prefix_nested_type_mismatch(self):
266
+ cases = (
267
+ (("x", ("a", 1)), ("x", ("a", "b"))),
268
+ ((1, (2, ("a", 3))), (1, (2, ("a", "b")))),
269
+ (("x", ("a", [1])), ("x", ("a", (1,)))),
270
+ ([1, [2, "a"]], [1, [2, 3]]),
271
+ )
272
+
273
+ for a, b in cases:
274
+ dd("wrong nested type: ", repr(a), " ", repr(b))
275
+ self.assertRaises(TypeError, k3pattern.common_prefix, a, b)
276
+
277
+ def test_common_prefix_random_tuples_of_str(self):
278
+ # Reference model: the common elements, then the common prefix of the
279
+ # first differing str elements if it is not empty.
280
+ rnd = random.Random(0)
281
+
282
+ for _ in range(1000):
283
+ base = tuple(_rand_str(rnd) for _ in range(4))
284
+ inputs = [_vary(rnd, base) for _ in range(rnd.randint(1, 4))]
285
+
286
+ flat = os.path.commonprefix(inputs)
287
+ k = len(flat)
288
+ expected = flat
289
+ if all(k < len(x) for x in inputs):
290
+ tail = os.path.commonprefix([x[k] for x in inputs])
291
+ if tail:
292
+ expected = flat + (tail,)
293
+
294
+ rst = k3pattern.common_prefix(*inputs)
295
+ self.assertEqual(expected, rst, inputs)
296
+
297
+ rst = k3pattern.common_prefix(*inputs, recursive=False)
298
+ self.assertEqual(flat, rst, inputs)
299
+
300
+ def test_common_prefix_random_nested(self):
301
+ # The result is a common prefix of every input, whatever the input order.
302
+ rnd = random.Random(0)
303
+
304
+ for _ in range(1000):
305
+ base = tuple(_rand_str(rnd) if rnd.random() < 0.5 else (_rand_str(rnd), _rand_str(rnd)) for _ in range(4))
306
+ inputs = [_vary(rnd, base) for _ in range(rnd.randint(1, 4))]
307
+ rst = k3pattern.common_prefix(*inputs)
308
+
309
+ rnd.shuffle(inputs)
310
+ shuffled_rst = k3pattern.common_prefix(*inputs)
311
+ self.assertEqual(rst, shuffled_rst, inputs)
312
+
313
+ for x in inputs:
314
+ prefix_of_x = k3pattern.common_prefix(rst, x)
315
+ self.assertEqual(rst, prefix_of_x, (rst, x))
File without changes
File without changes
File without changes
File without changes