Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 14 additions & 6 deletions telebot/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -14688,20 +14688,28 @@ def de_json(cls, json_string):
if json_string is None: return None
if isinstance(json_string, str):
# "...can be either a String for plain text..."
# Only a JSON object is a serialized RichText. Plain text can look
# like JSON too, e.g. a "[56]" footnote mark, and stays text.
# Only a JSON object that resolves to a known RichText is serialized
# RichText. Plain text can look like JSON too, e.g. a "[56]" footnote
# mark or a {"foo": "bar"} code sample, and has to stay text.
original = json_string
if not (json_string.startswith('{') and json_string.endswith('}')):
return json_string
return original
try:
parsed = json.loads(json_string)
except (ValueError, TypeError):
return json_string
return original
if not isinstance(parsed, dict):
return json_string
json_string = parsed
return original
result = cls._from_dict(parsed)
return original if result is None else result
elif isinstance(json_string, list):
# "...an Array of :class:`RichText`..."
return [RichText.de_json(item) for item in json_string]
return cls._from_dict(json_string)

@classmethod
def _from_dict(cls, json_string):
"""Resolve a parsed RichText dict, or None when its type is unknown."""
# "...or any of the following types..."
obj = cls.check_json(json_string)
type = obj.pop('type', None)
Expand Down
13 changes: 13 additions & 0 deletions tests/test_types.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,19 @@ def test_json_richtext_plain_text_that_looks_like_json():
assert types.RichText.de_json(text) == text


def test_json_richtext_plain_json_object_stays_text():
# issue #2646: a preformatted block whose text is a JSON object is still text
for text in ['{"foo": "bar"}', '{}', '{"a": [1, 2]}', '{"type": "not_a_richtext"}']:
block = types.RichBlockPreformatted.de_json({'text': text, 'language': 'json'})
assert block.text == text
assert types.RichText.de_json(text) == text

# a serialized RichText still deserializes
bold = types.RichText.de_json('{"type": "bold", "text": "hi"}')
assert isinstance(bold, types.RichTextBold)
assert bold.text == 'hi'


def test_json_richtextitalic():
json_str = r'{"type": "italic", "text": "Test"}'
result = types.RichText.de_json(json_str)
Expand Down
Loading