Get rid of the patched/ module

This may fix #1669.
This commit is contained in:
Lonami Exo 2021-01-14 22:56:01 +01:00
parent c0738a7ae1
commit cd51c9e47c
3 changed files with 22 additions and 57 deletions

1
.gitignore vendored
View File

@ -1,7 +1,6 @@
# Generated code
/telethon/tl/functions/
/telethon/tl/types/
/telethon/tl/patched/
/telethon/tl/alltlobjects.py
/telethon/errors/rpcerrorlist.py

View File

@ -1,16 +1,15 @@
import abc
from .chatgetter import ChatGetter
from .sendergetter import SenderGetter
from .messagebutton import MessageButton
from .forward import Forward
from .file import File
from .. import TLObject, types, functions
from .. import TLObject, types, functions, alltlobjects
from ... import utils, errors
# TODO Figure out a way to have the code generator error on missing fields
# Maybe parsing the init function alone if that's possible.
class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
class _Message(ChatGetter, SenderGetter):
"""
This custom class aggregates both :tl:`Message` and
:tl:`MessageService` to ease accessing their members.
@ -1105,3 +1104,18 @@ class Message(ChatGetter, SenderGetter, TLObject, abc.ABC):
return None
# endregion Private Methods
def _patch(cls):
# Create new types (classes) for all messages to combine `_Message` in them.
# `_Message` comes first so we get its `__init__`.
newtype = type(cls.__name__, (_Message, cls), {})
setattr(types, cls.__name__, newtype)
# `BinaryReader` directly imports this dictionary, but we're mutating it
# in-place, not replacing it, so it works out to deserialize `newtype`.
alltlobjects.tlobjects[cls.CONSTRUCTOR_ID] = newtype
return newtype
_patch(types.MessageEmpty)
Message = _patch(types.Message)
_patch(types.MessageService)

View File

@ -50,13 +50,6 @@ NAMED_BLACKLIST = {
BASE_TYPES = ('string', 'bytes', 'int', 'long', 'int128',
'int256', 'double', 'Bool', 'true', 'date')
# Patched types {fullname: custom.ns.Name}
PATCHED_TYPES = {
'messageEmpty': 'message.Message',
'message': 'message.Message',
'messageService': 'message.Message'
}
def _write_modules(
out_dir, depth, kind, namespace_tlobjects, type_constructors):
@ -157,9 +150,6 @@ def _write_modules(
# Generate the class for every TLObject
for t in tlobjects:
if t.fullname in PATCHED_TYPES:
builder.writeln('{} = None # Patched', t.class_name)
else:
_write_source_code(t, kind, builder, type_constructors)
builder.current_indent = 0
@ -645,41 +635,11 @@ def _write_arg_read_code(builder, arg, args, name):
arg.is_flag = True
def _write_patched(out_dir, namespace_tlobjects):
out_dir.mkdir(parents=True, exist_ok=True)
for ns, tlobjects in namespace_tlobjects.items():
file = out_dir / '{}.py'.format(ns or '__init__')
with file.open('w') as f, SourceBuilder(f) as builder:
builder.writeln(AUTO_GEN_NOTICE)
builder.writeln('import struct')
builder.writeln('from .. import TLObject, types, custom')
builder.writeln()
for t in tlobjects:
builder.writeln('class {}(custom.{}):', t.class_name,
PATCHED_TYPES[t.fullname])
builder.writeln('CONSTRUCTOR_ID = {:#x}', t.id)
builder.writeln('SUBCLASS_OF_ID = {:#x}',
crc32(t.result.encode('ascii')))
_write_to_dict(t, builder)
_write_to_bytes(t, builder)
_write_from_reader(t, builder)
builder.current_indent = 0
builder.writeln()
builder.writeln(
'types.{1}{0} = {0}', t.class_name,
'{}.'.format(t.namespace) if t.namespace else ''
)
builder.writeln()
def _write_all_tlobjects(tlobjects, layer, builder):
builder.writeln(AUTO_GEN_NOTICE)
builder.writeln()
builder.writeln('from . import types, functions, patched')
builder.writeln('from . import types, functions')
builder.writeln()
# Create a constant variable to indicate which layer this is
@ -693,10 +653,6 @@ def _write_all_tlobjects(tlobjects, layer, builder):
# Fill the dictionary (0x1a2b3c4f: tl.full.type.path.Class)
for tlobject in tlobjects:
builder.write('{:#010x}: ', tlobject.id)
# TODO Probably circular dependency
if tlobject.fullname in PATCHED_TYPES:
builder.write('patched')
else:
builder.write('functions' if tlobject.is_function else 'types')
if tlobject.namespace:
@ -712,7 +668,6 @@ def generate_tlobjects(tlobjects, layer, import_depth, output_dir):
# Group everything by {namespace: [tlobjects]} to generate __init__.py
namespace_functions = defaultdict(list)
namespace_types = defaultdict(list)
namespace_patched = defaultdict(list)
# Group {type: [constructors]} to generate the documentation
type_constructors = defaultdict(list)
@ -722,14 +677,11 @@ def generate_tlobjects(tlobjects, layer, import_depth, output_dir):
else:
namespace_types[tlobject.namespace].append(tlobject)
type_constructors[tlobject.result].append(tlobject)
if tlobject.fullname in PATCHED_TYPES:
namespace_patched[tlobject.namespace].append(tlobject)
_write_modules(output_dir / 'functions', import_depth, 'TLRequest',
namespace_functions, type_constructors)
_write_modules(output_dir / 'types', import_depth, 'TLObject',
namespace_types, type_constructors)
_write_patched(output_dir / 'patched', namespace_patched)
filename = output_dir / 'alltlobjects.py'
with filename.open('w') as file:
@ -738,7 +690,7 @@ def generate_tlobjects(tlobjects, layer, import_depth, output_dir):
def clean_tlobjects(output_dir):
for d in ('functions', 'types', 'patched'):
for d in ('functions', 'types'):
d = output_dir / d
if d.is_dir():
shutil.rmtree(str(d))