Skip to content

Commit

Permalink
Add purely_emoji()
Browse files Browse the repository at this point in the history
  • Loading branch information
marmistrz committed Jun 25, 2023
1 parent 4e1299f commit 791a7f2
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 3 deletions.
2 changes: 2 additions & 0 deletions docs/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ API Reference
+-------------------------------+--------------------------------------------------------------+
| :func:`is_emoji` | Check if a string/character is a single emoji |
+-------------------------------+--------------------------------------------------------------+
| :func:`purely_emoji` | Check if a string contains only emojis |
+-------------------------------+--------------------------------------------------------------+
| :func:`version` | Find Unicode/Emoji version of an emoji |
+-------------------------------+--------------------------------------------------------------+
| **Module variables:** | |
Expand Down
20 changes: 20 additions & 0 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,24 @@ You can check if a string is a single, valid emoji with :func:`is_emoji`

..
While dealing with emojis, it is generally a bad idea to look at individual characters.
Unicode contains modifier characters, such as variation selectors, which are not emojis themselves
and modify the preceding emoji instead. You can check if a string has only emojis in it with :func:`purely_emoji`

.. doctest::

>>> '\U0001f600\ufe0f'
'πŸ˜€'
>>> emoji.is_emoji('\U0001f600\ufe0f')
False
>>> emoji.is_emoji('\U0001f600')
True
>>> emoji.is_emoji('\ufe0f')
False
>>> emoji.purely_emoji('\U0001f600\ufe0f')
True

..
To get more information about an emoji, you can look it up in the :data:`EMOJI_DATA` dict:

Expand Down Expand Up @@ -404,6 +422,8 @@ Reference documentation of all functions and properties in the module:
+-------------------------------+--------------------------------------------------------------+
| :func:`is_emoji` | Check if a string/character is a single emoji |
+-------------------------------+--------------------------------------------------------------+
| :func:`purely_emoji` | Check if a string contains only emojis |
+-------------------------------+--------------------------------------------------------------+
| :func:`version` | Find Unicode/Emoji version of an emoji |
+-------------------------------+--------------------------------------------------------------+
| **Module variables:** | |
Expand Down
2 changes: 1 addition & 1 deletion emoji/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# emoji.core
'emojize', 'demojize', 'analyze', 'config',
'emoji_list', 'distinct_emoji_list', 'emoji_count',
'replace_emoji', 'is_emoji', 'version',
'replace_emoji', 'is_emoji', 'purely_emoji', 'version',
'Token', 'EmojiMatch', 'EmojiMatchZWJ', 'EmojiMatchZWJNonRGI',
# emoji.unicode_codes
'EMOJI_DATA', 'STATUS', 'LANGUAGES',
Expand Down
13 changes: 11 additions & 2 deletions emoji/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
__all__ = [
'emojize', 'demojize', 'analyze', 'config',
'emoji_list', 'distinct_emoji_list', 'emoji_count',
'replace_emoji', 'is_emoji', 'version',
'replace_emoji', 'is_emoji', 'purely_emoji', 'version',
'Token', 'EmojiMatch', 'EmojiMatchZWJ', 'EmojiMatchZWJNonRGI',
]

Expand Down Expand Up @@ -314,12 +314,21 @@ def emoji_count(string, unique=False):

def is_emoji(string):
"""
Returns True if the string is an emoji, and it is "recommended for
Returns True if the string is a single emoji, and it is "recommended for
general interchange" by Unicode.org.
"""
return string in unicode_codes.EMOJI_DATA


def purely_emoji(string: str) -> bool:
"""
Returns True if the string contains only emojis.
This might not imply that `is_emoji` for all the characters, for example,
if the string contains variation selectors.
"""
return all(isinstance(m.value, EmojiMatch) for m in analyze(string, non_emoji=True))


def version(string):
"""
Returns the Emoji Version of the emoji.
Expand Down
18 changes: 18 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ def test_is_emoji():
assert emoji.is_emoji('😁')
assert not emoji.is_emoji('H')
assert emoji.is_emoji('πŸ‡«πŸ‡·')
assert not emoji.is_emoji('πŸ‡«πŸ‡·πŸ‡«πŸ‡·')
assert not emoji.is_emoji('\ufe0f') # variation selector


def test_long_emoji():
Expand Down Expand Up @@ -512,3 +514,19 @@ def test_combine_with_component():
combined = emoji.emojize(text % ":woman_dark_skin_tone_white_hair:")
seperated = emoji.emojize(text % ":woman::dark_skin_tone:\u200d:white_hair:")
assert combined == seperated, "%r != %r" % (ascii(combined), ascii(seperated))


purely_emoji_testdata = [
('\U0001f600\ufe0f', True),
('\U0001f600', True),
('\U0001f600\U0001f600\U0001f600', True),
('abc', False),
('abc\U0001f600', False),
('\U0001f600c', False),
('\u270a\U0001f3fe', True),
]


@pytest.mark.parametrize("string,expected", purely_emoji_testdata)
def test_purely_emoji(string: str, expected: bool):
assert emoji.purely_emoji(string) == expected

0 comments on commit 791a7f2

Please sign in to comment.