mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2024-12-02 06:13:45 +03:00
Add stringify back to custom Message
This commit is contained in:
parent
8de375323e
commit
b566e59036
|
@ -526,6 +526,39 @@ If you still want the old behaviour, wrap the list inside another list:
|
||||||
#+
|
#+
|
||||||
|
|
||||||
|
|
||||||
|
Changes to the string and to_dict representation
|
||||||
|
------------------------------------------------
|
||||||
|
|
||||||
|
The string representation of raw API objects will now have its "printing depth" limited, meaning
|
||||||
|
very large and nested objects will be easier to read.
|
||||||
|
|
||||||
|
If you want to see the full object's representation, you should instead use Python's builtin
|
||||||
|
``repr`` method.
|
||||||
|
|
||||||
|
The ``.stringify`` method remains unchanged.
|
||||||
|
|
||||||
|
Here's a comparison table for a convenient overview:
|
||||||
|
|
||||||
|
+-------------------+---------------------------------------------+---------------------------------------------+
|
||||||
|
| | Telethon v1.x | Telethon v2.x |
|
||||||
|
+-------------------+-------------+--------------+----------------+-------------+--------------+----------------+
|
||||||
|
| | ``__str__`` | ``__repr__`` | ``.stringify`` | ``__str__`` | ``__repr__`` | ``.stringify`` |
|
||||||
|
+-------------------+-------------+--------------+----------------+-------------+--------------+----------------+
|
||||||
|
| Useful? | ✅ | ❌ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
+-------------------+-------------+--------------+----------------+-------------+--------------+----------------+
|
||||||
|
| Multiline? | ❌ | ❌ | ✅ | ❌ | ❌ | ✅ |
|
||||||
|
+-------------------+-------------+--------------+----------------+-------------+--------------+----------------+
|
||||||
|
| Shows everything? | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
|
||||||
|
+-------------------+-------------+--------------+----------------+-------------+--------------+----------------+
|
||||||
|
|
||||||
|
Both of the string representations may still change in the future without warning, as Telegram
|
||||||
|
adds, changes or removes fields. It should only be used for debugging. If you need a persistent
|
||||||
|
string representation, it is your job to decide which fields you care about and their format.
|
||||||
|
|
||||||
|
The ``Message`` representation now contains different properties, which should be more useful and
|
||||||
|
less confusing.
|
||||||
|
|
||||||
|
|
||||||
Changes on how to configure a different connection mode
|
Changes on how to configure a different connection mode
|
||||||
-------------------------------------------------------
|
-------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -200,6 +200,73 @@ def _entity_type(entity):
|
||||||
# 'Empty' in name or not found, we don't care, not a valid entity.
|
# 'Empty' in name or not found, we don't care, not a valid entity.
|
||||||
raise TypeError('{} does not have any entity type'.format(entity))
|
raise TypeError('{} does not have any entity type'.format(entity))
|
||||||
|
|
||||||
|
|
||||||
|
def pretty_print(obj, indent=None, max_depth=float('inf')):
|
||||||
|
max_depth -= 1
|
||||||
|
if max_depth < 0:
|
||||||
|
return '...'
|
||||||
|
|
||||||
|
to_d = getattr(obj, '_to_dict', None) or getattr(obj, 'to_dict', None)
|
||||||
|
if callable(to_d):
|
||||||
|
obj = to_d()
|
||||||
|
|
||||||
|
if indent is None:
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
return '{}({})'.format(obj.get('_', 'dict'), ', '.join(
|
||||||
|
'{}={}'.format(k, pretty_print(v, indent, max_depth))
|
||||||
|
for k, v in obj.items() if k != '_'
|
||||||
|
))
|
||||||
|
elif isinstance(obj, str) or isinstance(obj, bytes):
|
||||||
|
return repr(obj)
|
||||||
|
elif hasattr(obj, '__iter__'):
|
||||||
|
return '[{}]'.format(
|
||||||
|
', '.join(pretty_print(x, indent, max_depth) for x in obj)
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return repr(obj)
|
||||||
|
else:
|
||||||
|
result = []
|
||||||
|
|
||||||
|
if isinstance(obj, dict):
|
||||||
|
result.append(obj.get('_', 'dict'))
|
||||||
|
result.append('(')
|
||||||
|
if obj:
|
||||||
|
result.append('\n')
|
||||||
|
indent += 1
|
||||||
|
for k, v in obj.items():
|
||||||
|
if k == '_':
|
||||||
|
continue
|
||||||
|
result.append('\t' * indent)
|
||||||
|
result.append(k)
|
||||||
|
result.append('=')
|
||||||
|
result.append(pretty_print(v, indent, max_depth))
|
||||||
|
result.append(',\n')
|
||||||
|
result.pop() # last ',\n'
|
||||||
|
indent -= 1
|
||||||
|
result.append('\n')
|
||||||
|
result.append('\t' * indent)
|
||||||
|
result.append(')')
|
||||||
|
|
||||||
|
elif isinstance(obj, str) or isinstance(obj, bytes):
|
||||||
|
result.append(repr(obj))
|
||||||
|
|
||||||
|
elif hasattr(obj, '__iter__'):
|
||||||
|
result.append('[\n')
|
||||||
|
indent += 1
|
||||||
|
for x in obj:
|
||||||
|
result.append('\t' * indent)
|
||||||
|
result.append(pretty_print(x, indent, max_depth))
|
||||||
|
result.append(',\n')
|
||||||
|
indent -= 1
|
||||||
|
result.append('\t' * indent)
|
||||||
|
result.append(']')
|
||||||
|
|
||||||
|
else:
|
||||||
|
result.append(repr(obj))
|
||||||
|
|
||||||
|
return ''.join(result)
|
||||||
|
|
||||||
|
|
||||||
# endregion
|
# endregion
|
||||||
|
|
||||||
# region Cryptographic related utils
|
# region Cryptographic related utils
|
||||||
|
|
|
@ -3,6 +3,7 @@ import json
|
||||||
import struct
|
import struct
|
||||||
from datetime import datetime, date, timedelta, timezone
|
from datetime import datetime, date, timedelta, timezone
|
||||||
import time
|
import time
|
||||||
|
from .helpers import pretty_print
|
||||||
|
|
||||||
_EPOCH_NAIVE = datetime(*time.gmtime(0)[:6])
|
_EPOCH_NAIVE = datetime(*time.gmtime(0)[:6])
|
||||||
_EPOCH_NAIVE_LOCAL = datetime(*time.localtime(0)[:6])
|
_EPOCH_NAIVE_LOCAL = datetime(*time.localtime(0)[:6])
|
||||||
|
@ -36,73 +37,6 @@ class TLObject:
|
||||||
CONSTRUCTOR_ID = None
|
CONSTRUCTOR_ID = None
|
||||||
SUBCLASS_OF_ID = None
|
SUBCLASS_OF_ID = None
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def pretty_format(obj, indent=None):
|
|
||||||
"""
|
|
||||||
Pretty formats the given object as a string which is returned.
|
|
||||||
If indent is None, a single line will be returned.
|
|
||||||
"""
|
|
||||||
if indent is None:
|
|
||||||
if isinstance(obj, TLObject):
|
|
||||||
obj = obj.to_dict()
|
|
||||||
|
|
||||||
if isinstance(obj, dict):
|
|
||||||
return '{}({})'.format(obj.get('_', 'dict'), ', '.join(
|
|
||||||
'{}={}'.format(k, TLObject.pretty_format(v))
|
|
||||||
for k, v in obj.items() if k != '_'
|
|
||||||
))
|
|
||||||
elif isinstance(obj, str) or isinstance(obj, bytes):
|
|
||||||
return repr(obj)
|
|
||||||
elif hasattr(obj, '__iter__'):
|
|
||||||
return '[{}]'.format(
|
|
||||||
', '.join(TLObject.pretty_format(x) for x in obj)
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
return repr(obj)
|
|
||||||
else:
|
|
||||||
result = []
|
|
||||||
if isinstance(obj, TLObject):
|
|
||||||
obj = obj.to_dict()
|
|
||||||
|
|
||||||
if isinstance(obj, dict):
|
|
||||||
result.append(obj.get('_', 'dict'))
|
|
||||||
result.append('(')
|
|
||||||
if obj:
|
|
||||||
result.append('\n')
|
|
||||||
indent += 1
|
|
||||||
for k, v in obj.items():
|
|
||||||
if k == '_':
|
|
||||||
continue
|
|
||||||
result.append('\t' * indent)
|
|
||||||
result.append(k)
|
|
||||||
result.append('=')
|
|
||||||
result.append(TLObject.pretty_format(v, indent))
|
|
||||||
result.append(',\n')
|
|
||||||
result.pop() # last ',\n'
|
|
||||||
indent -= 1
|
|
||||||
result.append('\n')
|
|
||||||
result.append('\t' * indent)
|
|
||||||
result.append(')')
|
|
||||||
|
|
||||||
elif isinstance(obj, str) or isinstance(obj, bytes):
|
|
||||||
result.append(repr(obj))
|
|
||||||
|
|
||||||
elif hasattr(obj, '__iter__'):
|
|
||||||
result.append('[\n')
|
|
||||||
indent += 1
|
|
||||||
for x in obj:
|
|
||||||
result.append('\t' * indent)
|
|
||||||
result.append(TLObject.pretty_format(x, indent))
|
|
||||||
result.append(',\n')
|
|
||||||
indent -= 1
|
|
||||||
result.append('\t' * indent)
|
|
||||||
result.append(']')
|
|
||||||
|
|
||||||
else:
|
|
||||||
result.append(repr(obj))
|
|
||||||
|
|
||||||
return ''.join(result)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def serialize_bytes(data):
|
def serialize_bytes(data):
|
||||||
"""Write bytes by using Telegram guidelines"""
|
"""Write bytes by using Telegram guidelines"""
|
||||||
|
@ -164,11 +98,14 @@ class TLObject:
|
||||||
def __ne__(self, o):
|
def __ne__(self, o):
|
||||||
return not isinstance(o, type(self)) or self.to_dict() != o.to_dict()
|
return not isinstance(o, type(self)) or self.to_dict() != o.to_dict()
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return pretty_print(self)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return TLObject.pretty_format(self)
|
return pretty_print(self, max_depth=2)
|
||||||
|
|
||||||
def stringify(self):
|
def stringify(self):
|
||||||
return TLObject.pretty_format(self, indent=0)
|
return pretty_print(self, indent=0)
|
||||||
|
|
||||||
def to_dict(self):
|
def to_dict(self):
|
||||||
res = {}
|
res = {}
|
||||||
|
|
|
@ -9,7 +9,7 @@ from .file import File
|
||||||
from .inputfile import InputFile
|
from .inputfile import InputFile
|
||||||
from .inputmessage import InputMessage
|
from .inputmessage import InputMessage
|
||||||
from .button import build_reply_markup
|
from .button import build_reply_markup
|
||||||
from ..._misc import utils, tlobject
|
from ..._misc import utils, helpers, tlobject
|
||||||
from ... import _tl, _misc
|
from ... import _tl, _misc
|
||||||
|
|
||||||
|
|
||||||
|
@ -1366,5 +1366,50 @@ class Message(ChatGetter, SenderGetter):
|
||||||
|
|
||||||
# endregion Private Methods
|
# endregion Private Methods
|
||||||
|
|
||||||
|
def to_dict(self):
|
||||||
|
return self._message.to_dict()
|
||||||
|
|
||||||
|
def _to_dict(self):
|
||||||
|
return {
|
||||||
|
'_': 'Message',
|
||||||
|
'id': self.id,
|
||||||
|
'out': self.out,
|
||||||
|
'date': self.date,
|
||||||
|
'text': self.text,
|
||||||
|
'sender': self.sender,
|
||||||
|
'chat': self.chat,
|
||||||
|
'mentioned': self.mentioned,
|
||||||
|
'media_unread': self.media_unread,
|
||||||
|
'silent': self.silent,
|
||||||
|
'post': self.post,
|
||||||
|
'from_scheduled': self.from_scheduled,
|
||||||
|
'legacy': self.legacy,
|
||||||
|
'edit_hide': self.edit_hide,
|
||||||
|
'pinned': self.pinned,
|
||||||
|
'forward': self.forward,
|
||||||
|
'via_bot': self.via_bot,
|
||||||
|
'reply_to': self.reply_to,
|
||||||
|
'reply_markup': self.reply_markup,
|
||||||
|
'views': self.views,
|
||||||
|
'forwards': self.forwards,
|
||||||
|
'replies': self.replies,
|
||||||
|
'edit_date': self.edit_date,
|
||||||
|
'post_author': self.post_author,
|
||||||
|
'grouped_id': self.grouped_id,
|
||||||
|
'ttl_period': self.ttl_period,
|
||||||
|
'action': self.action,
|
||||||
|
'media': self.media,
|
||||||
|
'action_entities': self.action_entities,
|
||||||
|
}
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return helpers.pretty_print(self)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return helpers.pretty_print(self, max_depth=2)
|
||||||
|
|
||||||
|
def stringify(self):
|
||||||
|
return helpers.pretty_print(self, indent=0)
|
||||||
|
|
||||||
|
|
||||||
# TODO set md by default if commonmark is installed else nothing
|
# TODO set md by default if commonmark is installed else nothing
|
||||||
|
|
Loading…
Reference in New Issue
Block a user