chunklet-py 2.3.0__tar.gz → 2.3.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.
Files changed (61) hide show
  1. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/LICENSE +1 -1
  2. {chunklet_py-2.3.0/src/chunklet_py.egg-info → chunklet_py-2.3.2}/PKG-INFO +3 -4
  3. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/pyproject.toml +4 -5
  4. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/base_chunker.py +1 -1
  5. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/code_chunker/code_chunker.py +1 -1
  6. chunklet_py-2.3.2/src/chunklet/common/dotdict.py +106 -0
  7. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/_plain_text_chunker.py +2 -2
  8. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/document_chunker.py +3 -3
  9. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/sentence_splitter/_universal_splitter.py +5 -0
  10. {chunklet_py-2.3.0 → chunklet_py-2.3.2/src/chunklet_py.egg-info}/PKG-INFO +3 -4
  11. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet_py.egg-info/SOURCES.txt +1 -0
  12. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet_py.egg-info/requires.txt +2 -3
  13. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/README.md +0 -0
  14. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/setup.cfg +0 -0
  15. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/__init__.py +0 -0
  16. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/cli.py +0 -0
  17. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/code_chunker/__init__.py +0 -0
  18. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/code_chunker/_code_structure_extractor.py +0 -0
  19. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/code_chunker/patterns.py +0 -0
  20. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/code_chunker/utils.py +0 -0
  21. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/common/__init__.py +0 -0
  22. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/common/batch_runner.py +0 -0
  23. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/common/deprecation.py +0 -0
  24. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/common/logging_utils.py +0 -0
  25. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/common/path_utils.py +0 -0
  26. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/common/token_utils.py +0 -0
  27. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/common/validation.py +0 -0
  28. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/__init__.py +0 -0
  29. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/converters/__init__.py +0 -0
  30. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/converters/html_2_md.py +0 -0
  31. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/converters/latex_2_md.py +0 -0
  32. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/converters/rst_2_md.py +0 -0
  33. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/converters/table_2_md.py +0 -0
  34. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/processors/__init__.py +0 -0
  35. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/processors/base_processor.py +0 -0
  36. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/processors/docx_processor.py +0 -0
  37. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/processors/epub_processor.py +0 -0
  38. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/processors/odt_processor.py +0 -0
  39. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/processors/pdf_processor.py +0 -0
  40. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/registry.py +0 -0
  41. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/document_chunker/span_finder.py +0 -0
  42. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/exceptions.py +0 -0
  43. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/sentence_splitter/__init__.py +0 -0
  44. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/sentence_splitter/languages.py +0 -0
  45. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/sentence_splitter/registry.py +0 -0
  46. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/sentence_splitter/sentence_splitter.py +0 -0
  47. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/sentence_splitter/terminators.py +0 -0
  48. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/visualizer/__init__.py +0 -0
  49. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/visualizer/static/css/style.css +0 -0
  50. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/visualizer/static/index.html +0 -0
  51. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/visualizer/static/js/app.js +0 -0
  52. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/visualizer/static/js/utils.js +0 -0
  53. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet/visualizer/visualizer.py +0 -0
  54. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet_py.egg-info/dependency_links.txt +0 -0
  55. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet_py.egg-info/entry_points.txt +0 -0
  56. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/src/chunklet_py.egg-info/top_level.txt +0 -0
  57. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/tests/test_code_chunking.py +0 -0
  58. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/tests/test_document_chunking.py +0 -0
  59. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/tests/test_plain_text_chunking.py +0 -0
  60. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/tests/test_sentence_splitting.py +0 -0
  61. {chunklet_py-2.3.0 → chunklet_py-2.3.2}/tests/test_visualization.py +0 -0
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
18
  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
19
  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
20
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
21
+ SOFTWARE.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chunklet-py
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: High-fidelity context-aware chunking and interactive visualization for RAG. Advanced segmentation for code and documents, because your LLM is only as smart as the fragments you feed it.
5
5
  Author-email: speedyk_005 <speedy40115719@gmail.com>
6
6
  License-Expression: MIT
@@ -28,12 +28,11 @@ License-File: LICENSE
28
28
  Requires-Dist: loguru<1.0,>=0.7.3
29
29
  Requires-Dist: pysbd<1.0,>=0.3.4
30
30
  Requires-Dist: sentsplit<2.0,>=1.0.8
31
- Requires-Dist: sentencex<2.0,>=1.0.0; platform_system != "Android"
32
- Requires-Dist: sentencex<=0.6.1; platform_system == "Android"
31
+ Requires-Dist: sentencex<=0.6.1; sys_platform == "linux" and (platform_machine == "aarch64" or platform_machine == "armv7l")
32
+ Requires-Dist: sentencex<2.0,>=1.0.0; sys_platform != "linux" or (platform_machine != "aarch64" and platform_machine != "armv7l")
33
33
  Requires-Dist: indic-nlp-library<1.0,>=0.92
34
34
  Requires-Dist: py3langid<1.0,>=0.3.0
35
35
  Requires-Dist: mpire<3.0,>=2.10.2
36
- Requires-Dist: dotdict3<2.0,>=1.1.0
37
36
  Requires-Dist: more-itertools<12.0,>=10.6.0
38
37
  Requires-Dist: regex>=2025.7.29
39
38
  Requires-Dist: pydantic<3.0,>=2.11.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "chunklet-py"
3
- version = "2.3.0"
3
+ version = "2.3.2"
4
4
  description = "High-fidelity context-aware chunking and interactive visualization for RAG. Advanced segmentation for code and documents, because your LLM is only as smart as the fragments you feed it."
5
5
  authors = [
6
6
  { name = "speedyk_005", email = "speedy40115719@gmail.com" }
@@ -38,14 +38,13 @@ dependencies = [
38
38
  "pysbd>=0.3.4,<1.0",
39
39
  "sentsplit>=1.0.8,<2.0",
40
40
 
41
- # Rust binding (1.0+) for faster performance on supported platforms, legacy for Android.
42
- "sentencex>=1.0.0,<2.0; platform_system != 'Android'",
43
- "sentencex<=0.6.1; platform_system == 'Android'",
41
+ # Rust binding (1.0+) for faster performance on supported platforms, legacy for Android temporarily.
42
+ "sentencex<=0.6.1; sys_platform == 'linux' and (platform_machine == 'aarch64' or platform_machine == 'armv7l')",
43
+ "sentencex>=1.0.0,<2.0; sys_platform != 'linux' or (platform_machine != 'aarch64' and platform_machine != 'armv7l')",
44
44
 
45
45
  "indic-nlp-library>=0.92,<1.0",
46
46
  "py3langid>=0.3.0,<1.0",
47
47
  "mpire>=2.10.2,<3.0",
48
- "dotdict3>=1.1.0,<2.0",
49
48
  "more-itertools>=10.6.0,<12.0",
50
49
  "regex>=2025.7.29",
51
50
  "pydantic>=2.11.0,<3.0",
@@ -7,7 +7,7 @@ Defines the interface for chunkers.
7
7
  from abc import ABC, abstractmethod
8
8
  from collections.abc import Generator
9
9
 
10
- from dotdict3 import DotDict
10
+ from chunklet.common.dotdict import DotDict
11
11
  from loguru import logger
12
12
 
13
13
 
@@ -29,7 +29,7 @@ from itertools import chain
29
29
  from pathlib import Path
30
30
  from typing import Annotated, Any, Callable, Generator, Literal
31
31
 
32
- from dotdict3 import DotDict
32
+ from chunklet.common.dotdict import DotDict
33
33
  from more_itertools import unique_everseen
34
34
  from pydantic import Field
35
35
 
@@ -0,0 +1,106 @@
1
+ """
2
+ DotDict/DotList with Box-compatible serialization.
3
+
4
+ This module embeds code originally from ``dotdict3`` (MIT License).
5
+ Co-authored by:
6
+ - speedyk-005
7
+ - Patrick Elmer <patrick@elmer.ws> (https://github.com/dotdict/dotdict3)
8
+
9
+ Modifications: added ``to_dict()``, ``to_json()``, ``to_yaml()``,
10
+ ``to_msgpack()``, ``to_toml()``, ``to_csv()`` for backward compatibility
11
+ with the python-box API.
12
+ """
13
+
14
+ import json
15
+
16
+
17
+ class DotDict(dict):
18
+ def __init__(self, data=None):
19
+ if data is not None:
20
+ for key, value in data.items():
21
+ self[key] = value
22
+
23
+ def __setitem__(self, key, value):
24
+ return super().__setitem__(key, _convert(value))
25
+
26
+ # Redirect attribute operations to dictionary methods
27
+ __delattr__ = dict.__delitem__
28
+ __getattr__ = dict.__getitem__
29
+ __setattr__ = __setitem__
30
+
31
+ def to_dict(self):
32
+ return {k: _to_plain(v) for k, v in self.items()}
33
+
34
+ def to_json(self, filename=None, **kwargs):
35
+ if filename:
36
+ with open(filename, "w", encoding="utf-8") as f:
37
+ json.dump(self.to_dict(), f, ensure_ascii=False, **kwargs)
38
+ else:
39
+ return json.dumps(self.to_dict(), ensure_ascii=False, **kwargs)
40
+
41
+ def to_yaml(self, filename=None, default_flow_style=False, **kwargs):
42
+ try:
43
+ import yaml
44
+ except ImportError:
45
+ raise ImportError("pyyaml required: pip install pyyaml") from None
46
+ if filename:
47
+ with open(filename, "w", encoding="utf-8") as f:
48
+ yaml.dump(self.to_dict(), f, default_flow_style=default_flow_style, **kwargs)
49
+ else:
50
+ return yaml.dump(self.to_dict(), default_flow_style=default_flow_style, **kwargs)
51
+
52
+ def to_toml(self, filename=None):
53
+ try:
54
+ import toml
55
+ except ImportError:
56
+ raise ImportError("toml required: pip install toml") from None
57
+ if filename:
58
+ with open(filename, "w", encoding="utf-8") as f:
59
+ toml.dump(self.to_dict(), f)
60
+ else:
61
+ return toml.dumps(self.to_dict())
62
+
63
+ def to_msgpack(self, filename=None, **kwargs):
64
+ try:
65
+ import msgpack
66
+ except ImportError:
67
+ raise ImportError("msgpack required: pip install msgpack") from None
68
+ if filename:
69
+ with open(filename, "wb") as f:
70
+ msgpack.pack(self.to_dict(), f, **kwargs)
71
+ else:
72
+ return msgpack.packb(self.to_dict(), **kwargs)
73
+
74
+
75
+ class DotList(list):
76
+ def __init__(self, items=None):
77
+ if items is not None:
78
+ for item in items:
79
+ self.append(item)
80
+
81
+ def append(self, items):
82
+ return super().append(_convert(items))
83
+
84
+ def insert(self, index, items):
85
+ return super().insert(index, _convert(items))
86
+
87
+ def to_dict(self):
88
+ return [_to_plain(v) for v in self]
89
+
90
+
91
+ def _convert(obj):
92
+ """Recursively converts dicts/lists to DotDict/DotList if not already converted."""
93
+ if isinstance(obj, dict) and not isinstance(obj, DotDict):
94
+ return DotDict(obj)
95
+ if isinstance(obj, list) and not isinstance(obj, DotList):
96
+ return DotList(obj)
97
+ return obj
98
+
99
+
100
+ def _to_plain(obj):
101
+ """Recursively converts DotDict/DotList back to plain dict/list."""
102
+ if isinstance(obj, DotDict):
103
+ return {k: _to_plain(v) for k, v in obj.items()}
104
+ if isinstance(obj, (DotList, tuple)):
105
+ return [_to_plain(v) for v in obj]
106
+ return obj
@@ -5,7 +5,7 @@ from collections.abc import Iterable
5
5
  from functools import partial
6
6
  from typing import Annotated, Any, Callable, Generator, Literal
7
7
 
8
- from dotdict3 import DotDict
8
+ from chunklet.common.dotdict import DotDict
9
9
  from loguru import logger
10
10
  from pydantic import Field
11
11
 
@@ -120,7 +120,7 @@ class PlainTextChunker:
120
120
  """
121
121
  chunks_out = []
122
122
  for i, chunk_str in enumerate(chunks, start=1):
123
- chunk = DotDict()
123
+ chunk = DotDict({})
124
124
  chunk.content = chunk_str.strip()
125
125
  chunk.metadata = copy.deepcopy(base_metadata)
126
126
  chunk.metadata["chunk_num"] = i
@@ -3,7 +3,7 @@ from itertools import chain, tee
3
3
  from pathlib import Path
4
4
  from typing import Annotated, Any, Callable, Generator, Iterable, Literal
5
5
 
6
- from dotdict3 import DotDict
6
+ from chunklet.common.dotdict import DotDict
7
7
  from loguru import logger
8
8
  from more_itertools import ilen, split_at
9
9
  from pydantic import Field
@@ -607,7 +607,7 @@ class DocumentChunker(BaseChunker):
607
607
  sections_per_path[curr_path] -= 1
608
608
 
609
609
  @deprecated_callable(
610
- use_instead="chunk_file", deprecated_in="2.2.0", removed_in="3.0.0"
610
+ use_instead="chunk_file or chunk_text", deprecated_in="2.2.0", removed_in="3.0.0"
611
611
  )
612
612
  def chunk( # pragma: no cover
613
613
  self,
@@ -632,7 +632,7 @@ class DocumentChunker(BaseChunker):
632
632
  return self.chunk_file(**params)
633
633
 
634
634
  @deprecated_callable(
635
- use_instead="chunk_files", deprecated_in="2.2.0", removed_in="3.0.0"
635
+ use_instead="chunk_files or chunk_texts", deprecated_in="2.2.0", removed_in="3.0.0"
636
636
  )
637
637
  def batch_chunk( # pragma: no cover
638
638
  self,
@@ -36,6 +36,11 @@ class UniversalSplitter:
36
36
  self.numbered_list_pattern = re.compile(r"[\n:]\s*\p{N}\.")
37
37
 
38
38
  # Core sentence split regex
39
+ # NOTE: Acronyms like "U.S.A" are protected primarily by the lookahead (?=\s+...).
40
+ # Since "U.S.A," has no space after it (just punctuation), the lookahead fails
41
+ # and no split occurs. The negative lookbehind handles other abbreviations like "Dr."
42
+ # This means acronym protection is *not* dependent on masking—it's explicit in the
43
+ # lookahead requirement for whitespace or newline before the next uppercase letter.
39
44
  self.sentence_end_pattern = re.compile(
40
45
  rf"""
41
46
  (?<!\b(\p{{Lu}}\p{{Ll}}{{1, 4}}\.)*) # Latin-only abbreviation
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: chunklet-py
3
- Version: 2.3.0
3
+ Version: 2.3.2
4
4
  Summary: High-fidelity context-aware chunking and interactive visualization for RAG. Advanced segmentation for code and documents, because your LLM is only as smart as the fragments you feed it.
5
5
  Author-email: speedyk_005 <speedy40115719@gmail.com>
6
6
  License-Expression: MIT
@@ -28,12 +28,11 @@ License-File: LICENSE
28
28
  Requires-Dist: loguru<1.0,>=0.7.3
29
29
  Requires-Dist: pysbd<1.0,>=0.3.4
30
30
  Requires-Dist: sentsplit<2.0,>=1.0.8
31
- Requires-Dist: sentencex<2.0,>=1.0.0; platform_system != "Android"
32
- Requires-Dist: sentencex<=0.6.1; platform_system == "Android"
31
+ Requires-Dist: sentencex<=0.6.1; sys_platform == "linux" and (platform_machine == "aarch64" or platform_machine == "armv7l")
32
+ Requires-Dist: sentencex<2.0,>=1.0.0; sys_platform != "linux" or (platform_machine != "aarch64" and platform_machine != "armv7l")
33
33
  Requires-Dist: indic-nlp-library<1.0,>=0.92
34
34
  Requires-Dist: py3langid<1.0,>=0.3.0
35
35
  Requires-Dist: mpire<3.0,>=2.10.2
36
- Requires-Dist: dotdict3<2.0,>=1.1.0
37
36
  Requires-Dist: more-itertools<12.0,>=10.6.0
38
37
  Requires-Dist: regex>=2025.7.29
39
38
  Requires-Dist: pydantic<3.0,>=2.11.0
@@ -13,6 +13,7 @@ src/chunklet/code_chunker/utils.py
13
13
  src/chunklet/common/__init__.py
14
14
  src/chunklet/common/batch_runner.py
15
15
  src/chunklet/common/deprecation.py
16
+ src/chunklet/common/dotdict.py
16
17
  src/chunklet/common/logging_utils.py
17
18
  src/chunklet/common/path_utils.py
18
19
  src/chunklet/common/token_utils.py
@@ -4,7 +4,6 @@ sentsplit<2.0,>=1.0.8
4
4
  indic-nlp-library<1.0,>=0.92
5
5
  py3langid<1.0,>=0.3.0
6
6
  mpire<3.0,>=2.10.2
7
- dotdict3<2.0,>=1.1.0
8
7
  more-itertools<12.0,>=10.6.0
9
8
  regex>=2025.7.29
10
9
  pydantic<3.0,>=2.11.0
@@ -12,10 +11,10 @@ typer<1.0,>=0.19.0
12
11
  charset-normalizer<4.0,>=3.4.2
13
12
  setuptools<81
14
13
 
15
- [:platform_system != "Android"]
14
+ [:sys_platform != "linux" or (platform_machine != "aarch64" and platform_machine != "armv7l")]
16
15
  sentencex<2.0,>=1.0.0
17
16
 
18
- [:platform_system == "Android"]
17
+ [:sys_platform == "linux" and (platform_machine == "aarch64" or platform_machine == "armv7l")]
19
18
  sentencex<=0.6.1
20
19
 
21
20
  [all]
File without changes
File without changes