pymojis 1.0.1__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 (28) hide show
  1. pymojis-1.0.1/LICENSE +21 -0
  2. pymojis-1.0.1/PKG-INFO +220 -0
  3. pymojis-1.0.1/README.md +177 -0
  4. pymojis-1.0.1/pyproject.toml +148 -0
  5. pymojis-1.0.1/setup.cfg +4 -0
  6. pymojis-1.0.1/src/pymojis/__init__.py +5 -0
  7. pymojis-1.0.1/src/pymojis/application/__init__.py +0 -0
  8. pymojis-1.0.1/src/pymojis/application/pymojis_manager.py +103 -0
  9. pymojis-1.0.1/src/pymojis/domain/__init__.py +0 -0
  10. pymojis-1.0.1/src/pymojis/domain/entities/__init__.py +0 -0
  11. pymojis-1.0.1/src/pymojis/domain/entities/emojis.py +66 -0
  12. pymojis-1.0.1/src/pymojis/domain/repositories/__init__.py +0 -0
  13. pymojis-1.0.1/src/pymojis/domain/repositories/repository.py +43 -0
  14. pymojis-1.0.1/src/pymojis/infrastructure/__init__.py +0 -0
  15. pymojis-1.0.1/src/pymojis/infrastructure/data/__init__.py +0 -0
  16. pymojis-1.0.1/src/pymojis/infrastructure/data/emoji_data.json +9828 -0
  17. pymojis-1.0.1/src/pymojis/infrastructure/data_loader/__init__.py +0 -0
  18. pymojis-1.0.1/src/pymojis/infrastructure/data_loader/emojis_loader.py +33 -0
  19. pymojis-1.0.1/src/pymojis/infrastructure/data_loader/file_loader.py +24 -0
  20. pymojis-1.0.1/src/pymojis/infrastructure/exceptions.py +2 -0
  21. pymojis-1.0.1/src/pymojis/infrastructure/pymojis_repository.py +161 -0
  22. pymojis-1.0.1/src/pymojis/infrastructure/utils.py +11 -0
  23. pymojis-1.0.1/src/pymojis/py.typed +0 -0
  24. pymojis-1.0.1/src/pymojis.egg-info/PKG-INFO +220 -0
  25. pymojis-1.0.1/src/pymojis.egg-info/SOURCES.txt +26 -0
  26. pymojis-1.0.1/src/pymojis.egg-info/dependency_links.txt +1 -0
  27. pymojis-1.0.1/src/pymojis.egg-info/requires.txt +18 -0
  28. pymojis-1.0.1/src/pymojis.egg-info/top_level.txt +1 -0
pymojis-1.0.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pallandir
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
pymojis-1.0.1/PKG-INFO ADDED
@@ -0,0 +1,220 @@
1
+ Metadata-Version: 2.4
2
+ Name: pymojis
3
+ Version: 1.0.1
4
+ Summary: A lightweight, type-safe Python library for emoji search, transformation, and detection.
5
+ Author-email: Pallandir <pallandir2@gmail.com>
6
+ Maintainer-email: Pallandir <pallandir2@gmail.com>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/pallandir/pymojis
9
+ Project-URL: Repository, https://github.com/pallandir/pymojis
10
+ Project-URL: Issues, https://github.com/pallandir/pymojis/issues
11
+ Project-URL: Changelog, https://github.com/pallandir/pymojis/releases
12
+ Keywords: emoji,unicode,text,utilities
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3 :: Only
19
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
+ Classifier: Topic :: Text Processing
21
+ Classifier: Topic :: Utilities
22
+ Classifier: Typing :: Typed
23
+ Classifier: Natural Language :: English
24
+ Requires-Python: >=3.12
25
+ Description-Content-Type: text/markdown
26
+ License-File: LICENSE
27
+ Provides-Extra: full
28
+ Requires-Dist: pymojis-fulldata==1.0.1; extra == "full"
29
+ Provides-Extra: dev
30
+ Requires-Dist: build~=1.2; extra == "dev"
31
+ Requires-Dist: pre-commit~=4.2; extra == "dev"
32
+ Requires-Dist: pytest~=8.4; extra == "dev"
33
+ Requires-Dist: pytest-cov~=6.0; extra == "dev"
34
+ Requires-Dist: pytest-mock~=3.10; extra == "dev"
35
+ Requires-Dist: twine~=6.1; extra == "dev"
36
+ Requires-Dist: mypy~=1.0; extra == "dev"
37
+ Requires-Dist: ruff~=0.8; extra == "dev"
38
+ Provides-Extra: test
39
+ Requires-Dist: pytest~=8.4; extra == "test"
40
+ Requires-Dist: pytest-cov~=6.0; extra == "test"
41
+ Requires-Dist: pytest-mock~=3.10; extra == "test"
42
+ Dynamic: license-file
43
+
44
+ # pymojis
45
+
46
+ [![PyPI version](https://img.shields.io/pypi/v/pymojis.svg)](https://pypi.org/project/pymojis/)
47
+ [![Python versions](https://img.shields.io/pypi/pyversions/pymojis.svg)](https://pypi.org/project/pymojis/)
48
+ [![License: MIT](https://img.shields.io/pypi/l/pymojis.svg)](https://github.com/pallandir/pymojis/blob/main/LICENSE)
49
+ [![CI](https://github.com/pallandir/pymojis/actions/workflows/github_ci.yaml/badge.svg)](https://github.com/pallandir/pymojis/actions/workflows/github_ci.yaml)
50
+
51
+ A small, type-safe Python library for working with emojis: search them by
52
+ name / code / character, transform text, detect emojis in strings, and
53
+ convert to HTML.
54
+
55
+ - **Zero runtime dependencies.**
56
+ - **Two install sizes**: a tiny default (~230 KB of data) or the full
57
+ Unicode dataset (~1 MB) via the `[full]` extra.
58
+ - **Strict typing** — `py.typed`, full mypy strict compliance.
59
+ - **Fail-fast API** — bad input raises immediately, no silent `None`
60
+ returns or warnings.
61
+
62
+ ## Install
63
+
64
+ ```bash
65
+ pip install pymojis # lightweight: ~1900 emojis
66
+ pip install 'pymojis[full]' # full Unicode coverage: ~3790 emojis
67
+ ```
68
+
69
+ Requires **Python 3.12+**.
70
+
71
+ ## Quick start
72
+
73
+ ```python
74
+ from pymojis import PymojisManager
75
+
76
+ manager = PymojisManager()
77
+
78
+ # Pick random emojis
79
+ print([e.emoji for e in manager.get_random(length=3)])
80
+ # → ['😊', '🎉', '🌟']
81
+
82
+ # Look up by name / code / character
83
+ manager.get_by_name("grinning face with smiling eyes") # → '😄'
84
+ manager.get_by_code("1F604") # → '😄'
85
+ manager.get_by_emoji("😊") # → Emoji(...)
86
+
87
+ # Replace whole-word matches in text
88
+ manager.emojifie("I'm sleepy")
89
+ # → "I'm 😪"
90
+
91
+ # Detection
92
+ manager.contains_emojis("hello 👋") # → True
93
+ manager.is_emoji("😄") # → True
94
+ manager.is_emoji("😄😊") # → False
95
+
96
+ # HTML hex references
97
+ manager.to_html("😵‍💫")
98
+ # → "&#x1F635;&#x200D;&#x1F4AB;"
99
+ ```
100
+
101
+ To use the full Unicode dataset:
102
+
103
+ ```python
104
+ manager = PymojisManager(use_full_dataset=True)
105
+ # Requires `pip install 'pymojis[full]'`. Raises DatasetNotFoundError
106
+ # with installation instructions otherwise.
107
+ ```
108
+
109
+ ## API
110
+
111
+ | Method | Returns | Notes |
112
+ |---|---|---|
113
+ | `get_random(categories=None, length=1, exclude=None)` | `list[Emoji]` | `categories` takes precedence over `exclude`. |
114
+ | `get_all_emojis(exclude=None)` | `list[Emoji]` | `exclude` accepts `"complex"` or a list of categories. |
115
+ | `get_by_code(code)` | `str \| None` | Single-codepoint lookup. Case-insensitive. |
116
+ | `get_by_name(name)` | `str \| None` | Full-name lookup. Case-insensitive. |
117
+ | `get_by_category(category)` | `list[str]` | All emojis in a category. |
118
+ | `get_by_emoji(emoji)` | `Emoji \| None` | Reverse lookup from character to record. |
119
+ | `contains_emojis(text)` | `bool` | True if `text` contains at least one known emoji. |
120
+ | `is_emoji(text)` | `bool` | True if `text.strip()` is a single known emoji. |
121
+ | `emojifie(text)` | `str` | Replace whole words with emojis (whose name *contains* that word). |
122
+ | `to_html(emoji)` | `str` | Encode each codepoint as `&#xHEX;`. |
123
+
124
+ All methods raise `TypeError` on non-`str` arguments — no silent `None`.
125
+
126
+ ### Categories
127
+
128
+ ```python
129
+ from pymojis import Categories
130
+
131
+ Categories # type alias of all valid categories:
132
+ # "Smileys & Emotion", "People & Body", "Animals & Nature",
133
+ # "Food & Drink", "Activities", "Travel & Places", "Objects",
134
+ # "Symbols", "Flags", "Component"
135
+ ```
136
+
137
+ ### `Emoji` data model
138
+
139
+ ```python
140
+ from pymojis import Emoji
141
+
142
+ @dataclass-like
143
+ class Emoji:
144
+ id: str # auto-generated UUID
145
+ emoji: str # the character itself, e.g. "😄"
146
+ name: str # e.g. "grinning face with smiling eyes"
147
+ code: list[str] # one or more Unicode codepoints, e.g. ["1F604"]
148
+ # (multi-codepoint emojis like ZWJ sequences have len > 1)
149
+ category: str # e.g. "Smileys & Emotion"
150
+ sub_category: str # e.g. "face-smiling"
151
+ ```
152
+
153
+ ## Notes on `emojifie`
154
+
155
+ `emojifie` does whole-word matching. Each word in the input is looked up in
156
+ an index of emoji-name tokens. Tokens shorter than 3 characters are skipped
157
+ (otherwise pronouns like "I" and "m" would be replaced by ℹ and Ⓜ). When a
158
+ word matches multiple emojis, the first one (in dataset order) wins.
159
+
160
+ ```python
161
+ manager.emojifie("I'm sleepy") # → "I'm 😪" (sleepy → "sleepy face")
162
+ manager.emojifie("zzzz xyzzy") # → "zzzz xyzzy" (no match, unchanged)
163
+ ```
164
+
165
+ ## Releases (maintainer notes)
166
+
167
+ This repo publishes **two** packages on every git tag: `pymojis` and
168
+ `pymojis-fulldata`. Both must share the same version.
169
+
170
+ To cut a release:
171
+
172
+ ```bash
173
+ # 1. Bump version in BOTH pyproject files
174
+ $EDITOR pyproject.toml # version = "X.Y.Z"
175
+ $EDITOR packages/pymojis-fulldata/pyproject.toml # version = "X.Y.Z"
176
+ # Also bump the [full] extra dependency pin in pyproject.toml.
177
+
178
+ # 2. Commit, tag, push
179
+ git commit -am "Release vX.Y.Z"
180
+ git tag vX.Y.Z
181
+ git push origin main --tags
182
+ ```
183
+
184
+ CI runs the full `make ci` pipeline (lint, format, typecheck, tests,
185
+ build both wheels, twine check) and publishes via PyPI Trusted Publishing
186
+ (OIDC — no API tokens). One-time setup: register both projects as
187
+ Trusted Publishers on https://pypi.org pointing at this repo and the
188
+ workflow `.github/workflows/github_ci.yaml`.
189
+
190
+ ## Development
191
+
192
+ A `Makefile` wraps the common workflows:
193
+
194
+ ```bash
195
+ make install # uv sync --extra dev --frozen
196
+ make lint # ruff check
197
+ make format-check # ruff format --check
198
+ make typecheck # mypy src
199
+ make test # pytest
200
+ make build # build both wheels into dist/
201
+ make twine-check # twine check dist/*
202
+ make ci # lint + format-check + typecheck + test + build + twine-check
203
+ make clean # remove dist/, build/, *.egg-info
204
+ ```
205
+
206
+ `pre-commit` is configured: `uv run pre-commit install` once, and the same
207
+ checks run on every commit.
208
+
209
+ ## Contributing
210
+
211
+ Issues and PRs welcome. Please run the full check suite above before
212
+ opening a PR.
213
+
214
+ ## License
215
+
216
+ MIT — see [LICENSE](LICENSE).
217
+
218
+ The bundled emoji metadata derives from the work of
219
+ [Chalda Pnuzig](https://github.com/chalda-pnuzig/emojis.json) (ISC License,
220
+ see `third_party/`).
@@ -0,0 +1,177 @@
1
+ # pymojis
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/pymojis.svg)](https://pypi.org/project/pymojis/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/pymojis.svg)](https://pypi.org/project/pymojis/)
5
+ [![License: MIT](https://img.shields.io/pypi/l/pymojis.svg)](https://github.com/pallandir/pymojis/blob/main/LICENSE)
6
+ [![CI](https://github.com/pallandir/pymojis/actions/workflows/github_ci.yaml/badge.svg)](https://github.com/pallandir/pymojis/actions/workflows/github_ci.yaml)
7
+
8
+ A small, type-safe Python library for working with emojis: search them by
9
+ name / code / character, transform text, detect emojis in strings, and
10
+ convert to HTML.
11
+
12
+ - **Zero runtime dependencies.**
13
+ - **Two install sizes**: a tiny default (~230 KB of data) or the full
14
+ Unicode dataset (~1 MB) via the `[full]` extra.
15
+ - **Strict typing** — `py.typed`, full mypy strict compliance.
16
+ - **Fail-fast API** — bad input raises immediately, no silent `None`
17
+ returns or warnings.
18
+
19
+ ## Install
20
+
21
+ ```bash
22
+ pip install pymojis # lightweight: ~1900 emojis
23
+ pip install 'pymojis[full]' # full Unicode coverage: ~3790 emojis
24
+ ```
25
+
26
+ Requires **Python 3.12+**.
27
+
28
+ ## Quick start
29
+
30
+ ```python
31
+ from pymojis import PymojisManager
32
+
33
+ manager = PymojisManager()
34
+
35
+ # Pick random emojis
36
+ print([e.emoji for e in manager.get_random(length=3)])
37
+ # → ['😊', '🎉', '🌟']
38
+
39
+ # Look up by name / code / character
40
+ manager.get_by_name("grinning face with smiling eyes") # → '😄'
41
+ manager.get_by_code("1F604") # → '😄'
42
+ manager.get_by_emoji("😊") # → Emoji(...)
43
+
44
+ # Replace whole-word matches in text
45
+ manager.emojifie("I'm sleepy")
46
+ # → "I'm 😪"
47
+
48
+ # Detection
49
+ manager.contains_emojis("hello 👋") # → True
50
+ manager.is_emoji("😄") # → True
51
+ manager.is_emoji("😄😊") # → False
52
+
53
+ # HTML hex references
54
+ manager.to_html("😵‍💫")
55
+ # → "&#x1F635;&#x200D;&#x1F4AB;"
56
+ ```
57
+
58
+ To use the full Unicode dataset:
59
+
60
+ ```python
61
+ manager = PymojisManager(use_full_dataset=True)
62
+ # Requires `pip install 'pymojis[full]'`. Raises DatasetNotFoundError
63
+ # with installation instructions otherwise.
64
+ ```
65
+
66
+ ## API
67
+
68
+ | Method | Returns | Notes |
69
+ |---|---|---|
70
+ | `get_random(categories=None, length=1, exclude=None)` | `list[Emoji]` | `categories` takes precedence over `exclude`. |
71
+ | `get_all_emojis(exclude=None)` | `list[Emoji]` | `exclude` accepts `"complex"` or a list of categories. |
72
+ | `get_by_code(code)` | `str \| None` | Single-codepoint lookup. Case-insensitive. |
73
+ | `get_by_name(name)` | `str \| None` | Full-name lookup. Case-insensitive. |
74
+ | `get_by_category(category)` | `list[str]` | All emojis in a category. |
75
+ | `get_by_emoji(emoji)` | `Emoji \| None` | Reverse lookup from character to record. |
76
+ | `contains_emojis(text)` | `bool` | True if `text` contains at least one known emoji. |
77
+ | `is_emoji(text)` | `bool` | True if `text.strip()` is a single known emoji. |
78
+ | `emojifie(text)` | `str` | Replace whole words with emojis (whose name *contains* that word). |
79
+ | `to_html(emoji)` | `str` | Encode each codepoint as `&#xHEX;`. |
80
+
81
+ All methods raise `TypeError` on non-`str` arguments — no silent `None`.
82
+
83
+ ### Categories
84
+
85
+ ```python
86
+ from pymojis import Categories
87
+
88
+ Categories # type alias of all valid categories:
89
+ # "Smileys & Emotion", "People & Body", "Animals & Nature",
90
+ # "Food & Drink", "Activities", "Travel & Places", "Objects",
91
+ # "Symbols", "Flags", "Component"
92
+ ```
93
+
94
+ ### `Emoji` data model
95
+
96
+ ```python
97
+ from pymojis import Emoji
98
+
99
+ @dataclass-like
100
+ class Emoji:
101
+ id: str # auto-generated UUID
102
+ emoji: str # the character itself, e.g. "😄"
103
+ name: str # e.g. "grinning face with smiling eyes"
104
+ code: list[str] # one or more Unicode codepoints, e.g. ["1F604"]
105
+ # (multi-codepoint emojis like ZWJ sequences have len > 1)
106
+ category: str # e.g. "Smileys & Emotion"
107
+ sub_category: str # e.g. "face-smiling"
108
+ ```
109
+
110
+ ## Notes on `emojifie`
111
+
112
+ `emojifie` does whole-word matching. Each word in the input is looked up in
113
+ an index of emoji-name tokens. Tokens shorter than 3 characters are skipped
114
+ (otherwise pronouns like "I" and "m" would be replaced by ℹ and Ⓜ). When a
115
+ word matches multiple emojis, the first one (in dataset order) wins.
116
+
117
+ ```python
118
+ manager.emojifie("I'm sleepy") # → "I'm 😪" (sleepy → "sleepy face")
119
+ manager.emojifie("zzzz xyzzy") # → "zzzz xyzzy" (no match, unchanged)
120
+ ```
121
+
122
+ ## Releases (maintainer notes)
123
+
124
+ This repo publishes **two** packages on every git tag: `pymojis` and
125
+ `pymojis-fulldata`. Both must share the same version.
126
+
127
+ To cut a release:
128
+
129
+ ```bash
130
+ # 1. Bump version in BOTH pyproject files
131
+ $EDITOR pyproject.toml # version = "X.Y.Z"
132
+ $EDITOR packages/pymojis-fulldata/pyproject.toml # version = "X.Y.Z"
133
+ # Also bump the [full] extra dependency pin in pyproject.toml.
134
+
135
+ # 2. Commit, tag, push
136
+ git commit -am "Release vX.Y.Z"
137
+ git tag vX.Y.Z
138
+ git push origin main --tags
139
+ ```
140
+
141
+ CI runs the full `make ci` pipeline (lint, format, typecheck, tests,
142
+ build both wheels, twine check) and publishes via PyPI Trusted Publishing
143
+ (OIDC — no API tokens). One-time setup: register both projects as
144
+ Trusted Publishers on https://pypi.org pointing at this repo and the
145
+ workflow `.github/workflows/github_ci.yaml`.
146
+
147
+ ## Development
148
+
149
+ A `Makefile` wraps the common workflows:
150
+
151
+ ```bash
152
+ make install # uv sync --extra dev --frozen
153
+ make lint # ruff check
154
+ make format-check # ruff format --check
155
+ make typecheck # mypy src
156
+ make test # pytest
157
+ make build # build both wheels into dist/
158
+ make twine-check # twine check dist/*
159
+ make ci # lint + format-check + typecheck + test + build + twine-check
160
+ make clean # remove dist/, build/, *.egg-info
161
+ ```
162
+
163
+ `pre-commit` is configured: `uv run pre-commit install` once, and the same
164
+ checks run on every commit.
165
+
166
+ ## Contributing
167
+
168
+ Issues and PRs welcome. Please run the full check suite above before
169
+ opening a PR.
170
+
171
+ ## License
172
+
173
+ MIT — see [LICENSE](LICENSE).
174
+
175
+ The bundled emoji metadata derives from the work of
176
+ [Chalda Pnuzig](https://github.com/chalda-pnuzig/emojis.json) (ISC License,
177
+ see `third_party/`).
@@ -0,0 +1,148 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pymojis"
7
+ version = "1.0.1"
8
+ description = "A lightweight, type-safe Python library for emoji search, transformation, and detection."
9
+ readme = "README.md"
10
+ requires-python = ">=3.12"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ {name = "Pallandir", email = "pallandir2@gmail.com"}
15
+ ]
16
+ maintainers = [
17
+ {name = "Pallandir", email = "pallandir2@gmail.com"}
18
+ ]
19
+ keywords = ["emoji", "unicode", "text", "utilities"]
20
+ classifiers = [
21
+ "Development Status :: 5 - Production/Stable",
22
+ "Intended Audience :: Developers",
23
+ "Operating System :: OS Independent",
24
+ "Programming Language :: Python :: 3",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3 :: Only",
27
+ "Topic :: Software Development :: Libraries :: Python Modules",
28
+ "Topic :: Text Processing",
29
+ "Topic :: Utilities",
30
+ "Typing :: Typed",
31
+ "Natural Language :: English",
32
+ ]
33
+ dependencies = []
34
+
35
+ [project.optional-dependencies]
36
+ full = ["pymojis-fulldata==1.0.1"]
37
+ dev = [
38
+ "build~=1.2",
39
+ "pre-commit~=4.2",
40
+ "pytest~=8.4",
41
+ "pytest-cov~=6.0",
42
+ "pytest-mock~=3.10",
43
+ "twine~=6.1",
44
+ "mypy~=1.0",
45
+ "ruff~=0.8",
46
+ ]
47
+ test = [
48
+ "pytest~=8.4",
49
+ "pytest-cov~=6.0",
50
+ "pytest-mock~=3.10",
51
+ ]
52
+
53
+ [project.urls]
54
+ Homepage = "https://github.com/pallandir/pymojis"
55
+ Repository = "https://github.com/pallandir/pymojis"
56
+ Issues = "https://github.com/pallandir/pymojis/issues"
57
+ Changelog = "https://github.com/pallandir/pymojis/releases"
58
+
59
+ [tool.setuptools.packages.find]
60
+ where = ["src"]
61
+ include = ["pymojis*"]
62
+ exclude = ["tests*"]
63
+
64
+ [tool.setuptools.package-data]
65
+ pymojis = ["py.typed", "infrastructure/data/*.json"]
66
+
67
+ [tool.uv.workspace]
68
+ members = ["packages/*"]
69
+
70
+ [tool.uv.sources]
71
+ pymojis-fulldata = { workspace = true }
72
+
73
+ [tool.pytest.ini_options]
74
+ pythonpath = ["src"]
75
+ testpaths = ["tests"]
76
+ python_files = ["test_*.py", "*_test.py"]
77
+ python_classes = ["Test*"]
78
+ python_functions = ["test_*"]
79
+ addopts = [
80
+ "--strict-markers",
81
+ "--strict-config",
82
+ "-v",
83
+ ]
84
+ markers = [
85
+ "slow: marks tests as slow (deselect with '-m \"not slow\"')",
86
+ "integration: marks tests as integration tests",
87
+ ]
88
+
89
+ [tool.ruff]
90
+ target-version = "py312"
91
+ line-length = 88
92
+
93
+ [tool.ruff.lint]
94
+ select = [
95
+ "E", # pycodestyle errors
96
+ "W", # pycodestyle warnings
97
+ "F", # pyflakes
98
+ "I", # isort
99
+ "B", # flake8-bugbear
100
+ "C4", # flake8-comprehensions
101
+ "UP", # pyupgrade
102
+ "T20", # print found
103
+ "N", # pep8-naming
104
+ "S", # bandit security checks
105
+ ]
106
+ ignore = [
107
+ "E501", # line too long (handled by formatter)
108
+ "B008", # function calls in argument defaults
109
+ ]
110
+
111
+ [tool.ruff.lint.per-file-ignores]
112
+ "tests/*" = ["S101"] # allow asserts in tests
113
+ "scripts/*" = ["T20"] # CI scripts may print
114
+
115
+ [tool.mypy]
116
+ python_version = "3.12"
117
+ strict = true
118
+ warn_unreachable = true
119
+
120
+ [[tool.mypy.overrides]]
121
+ module = "tests.*"
122
+ disallow_untyped_defs = false
123
+
124
+ [tool.coverage.run]
125
+ source = ["src"]
126
+ branch = true
127
+ omit = [
128
+ "tests/*",
129
+ "*/tests/*",
130
+ "*/test_*",
131
+ "*/conftest.py",
132
+ ]
133
+
134
+ [tool.coverage.report]
135
+ precision = 2
136
+ show_missing = true
137
+ skip_covered = false
138
+ exclude_lines = [
139
+ "pragma: no cover",
140
+ "def __repr__",
141
+ "raise AssertionError",
142
+ "raise NotImplementedError",
143
+ "if __name__ == .__main__.:",
144
+ "if TYPE_CHECKING:",
145
+ "if typing.TYPE_CHECKING:",
146
+ "@overload",
147
+ ]
148
+ fail_under = 80
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ from .application.pymojis_manager import PymojisManager
2
+ from .domain.entities.emojis import Categories, Emoji
3
+
4
+ __version__ = "1.0.1"
5
+ __all__ = ["Categories", "Emoji", "PymojisManager", "__version__"]
File without changes
@@ -0,0 +1,103 @@
1
+ from typing import Literal
2
+
3
+ from pymojis.domain.entities.emojis import Categories, Emoji
4
+ from pymojis.infrastructure.pymojis_repository import PymojisRepositoryImpl
5
+
6
+
7
+ class PymojisManager:
8
+ """High-level facade for emoji search, transformation, and detection.
9
+
10
+ By default the manager loads the lightweight bundled dataset (~228 KB).
11
+ Pass ``use_full_dataset=True`` to load the full dataset, which requires
12
+ the optional ``pymojis-fulldata`` package (``pip install 'pymojis[full]'``).
13
+ """
14
+
15
+ def __init__(self, *, use_full_dataset: bool = False) -> None:
16
+ self.repository = PymojisRepositoryImpl()
17
+ self.repository.load_emojis(kind="full" if use_full_dataset else "light")
18
+
19
+ def get_random(
20
+ self,
21
+ categories: list[Categories] | None = None,
22
+ length: int = 1,
23
+ exclude: Literal["complex"] | list[Categories] | None = None,
24
+ ) -> list[Emoji]:
25
+ """Return ``length`` random ``Emoji`` objects, optionally filtered.
26
+
27
+ Args:
28
+ categories: If provided, only emojis from these categories are
29
+ considered. Takes precedence over ``exclude``.
30
+ length: Number of emojis to return. Capped at the size of the pool.
31
+ exclude: ``"complex"`` to exclude multi-codepoint emojis (skin
32
+ tones, ZWJ sequences), or a list of categories to skip.
33
+
34
+ Example:
35
+ >>> manager = PymojisManager()
36
+ >>> [e.emoji for e in manager.get_random(length=2)] # doctest: +SKIP
37
+ ['😊', '🌟']
38
+ """
39
+ return self.repository.get_random_emojis(categories, length, exclude)
40
+
41
+ def get_all_emojis(
42
+ self, exclude: Literal["complex"] | list[Categories] | None = None
43
+ ) -> list[Emoji]:
44
+ """Return every loaded ``Emoji``, optionally filtered by ``exclude``."""
45
+ return self.repository.get_all(exclude)
46
+
47
+ def get_by_code(self, code: str) -> str | None:
48
+ """Return the emoji character matching the given Unicode codepoint.
49
+
50
+ Only single-codepoint emojis are addressable this way. Returns
51
+ ``None`` if no match.
52
+ """
53
+ return self.repository.get_by_code(code)
54
+
55
+ def get_by_name(self, name: str) -> str | None:
56
+ """Return the emoji character whose full name equals ``name``.
57
+
58
+ Matching is case-insensitive. Returns ``None`` if no match.
59
+ """
60
+ return self.repository.get_by_name(name)
61
+
62
+ def get_by_category(self, category: Categories) -> list[str]:
63
+ """Return all emoji characters in the given category."""
64
+ return self.repository.get_by_category(category)
65
+
66
+ def get_by_emoji(self, emoji: str) -> Emoji | None:
67
+ """Return the ``Emoji`` object whose character equals ``emoji``."""
68
+ return self.repository.get_by_emoji(emoji)
69
+
70
+ def contains_emojis(self, text: str) -> bool:
71
+ """Return ``True`` if ``text`` contains at least one known emoji."""
72
+ return self.repository.contains_emojis(text)
73
+
74
+ def is_emoji(self, text: str) -> bool:
75
+ """Return ``True`` if ``text`` (after stripping) is a single known emoji."""
76
+ return self.repository.is_emoji(text)
77
+
78
+ def emojifie(self, text: str) -> str:
79
+ """Replace each whole word in ``text`` whose lowercase form is a token
80
+ of an emoji name with that emoji.
81
+
82
+ Tokens are matched against the first word of any emoji's name (e.g.
83
+ ``"sleepy"`` matches the emoji named ``"sleepy face"``). Words that
84
+ match no emoji are left unchanged.
85
+
86
+ Example:
87
+ >>> manager = PymojisManager()
88
+ >>> manager.emojifie("I'm sleepy") # doctest: +SKIP
89
+ "I'm 😪"
90
+ """
91
+ return self.repository.emojifie(text)
92
+
93
+ def to_html(self, emoji: str) -> str:
94
+ """Return ``emoji`` as a sequence of HTML hex character references.
95
+
96
+ Multi-codepoint emojis (ZWJ sequences, variation selectors) are
97
+ encoded codepoint by codepoint.
98
+
99
+ Example:
100
+ >>> PymojisManager().to_html("😪") # doctest: +SKIP
101
+ '&#x1F62A;'
102
+ """
103
+ return self.repository.to_html(emoji)
File without changes
File without changes