mirror of
				https://github.com/LonamiWebs/Telethon.git
				synced 2025-11-04 01:47:27 +03:00 
			
		
		
		
	Infer the object ID from its TL definition when not given
This commit is contained in:
		
							parent
							
								
									83c8e98448
								
							
						
					
					
						commit
						79ee98a4dd
					
				| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
 | 
					from zlib import crc32
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TLObject:
 | 
					class TLObject:
 | 
				
			||||||
| 
						 | 
					@ -24,12 +25,18 @@ class TLObject:
 | 
				
			||||||
            self.namespace = None
 | 
					            self.namespace = None
 | 
				
			||||||
            self.name = fullname
 | 
					            self.name = fullname
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # The ID should be an hexadecimal string
 | 
					 | 
				
			||||||
        self.id = int(object_id, base=16)
 | 
					 | 
				
			||||||
        self.args = args
 | 
					        self.args = args
 | 
				
			||||||
        self.result = result
 | 
					        self.result = result
 | 
				
			||||||
        self.is_function = is_function
 | 
					        self.is_function = is_function
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # The ID should be an hexadecimal string or None to be inferred
 | 
				
			||||||
 | 
					        if object_id is None:
 | 
				
			||||||
 | 
					            self.id = self.infer_id()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.id = int(object_id, base=16)
 | 
				
			||||||
 | 
					            assert self.id == self.infer_id(),\
 | 
				
			||||||
 | 
					                'Invalid inferred ID for ' + repr(self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def from_tl(tl, is_function):
 | 
					    def from_tl(tl, is_function):
 | 
				
			||||||
        """Returns a TL object from the given TL scheme line"""
 | 
					        """Returns a TL object from the given TL scheme line"""
 | 
				
			||||||
| 
						 | 
					@ -38,8 +45,10 @@ class TLObject:
 | 
				
			||||||
        match = re.match(r'''
 | 
					        match = re.match(r'''
 | 
				
			||||||
            ^                  # We want to match from the beginning to the end
 | 
					            ^                  # We want to match from the beginning to the end
 | 
				
			||||||
            ([\w.]+)           # The .tl object can contain alpha_name or namespace.alpha_name
 | 
					            ([\w.]+)           # The .tl object can contain alpha_name or namespace.alpha_name
 | 
				
			||||||
            \#                 # After the name, comes the ID of the object
 | 
					            (?:
 | 
				
			||||||
            ([0-9a-f]+)        # The constructor ID is in hexadecimal form
 | 
					                \#             # After the name, comes the ID of the object
 | 
				
			||||||
 | 
					                ([0-9a-f]+)    # The constructor ID is in hexadecimal form
 | 
				
			||||||
 | 
					            )?                 # If no constructor ID was given, CRC32 the 'tl' to determine it
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            (?:\s              # After that, we want to match its arguments (name:type)
 | 
					            (?:\s              # After that, we want to match its arguments (name:type)
 | 
				
			||||||
                {?             # For handling the start of the '{X:Type}' case
 | 
					                {?             # For handling the start of the '{X:Type}' case
 | 
				
			||||||
| 
						 | 
					@ -91,16 +100,39 @@ class TLObject:
 | 
				
			||||||
           (and thus should be embedded in the generated code) or not"""
 | 
					           (and thus should be embedded in the generated code) or not"""
 | 
				
			||||||
        return self.id in TLObject.CORE_TYPES
 | 
					        return self.id in TLObject.CORE_TYPES
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __repr__(self):
 | 
					    def __repr__(self, ignore_id=False):
 | 
				
			||||||
        fullname = ('{}.{}'.format(self.namespace, self.name)
 | 
					        fullname = ('{}.{}'.format(self.namespace, self.name)
 | 
				
			||||||
                    if self.namespace is not None else self.name)
 | 
					                    if self.namespace is not None else self.name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        hex_id = hex(self.id)[2:].rjust(8,
 | 
					        if getattr(self, 'id', None) is None or ignore_id:
 | 
				
			||||||
                                        '0')  # Skip 0x and add 0's for padding
 | 
					            hex_id = ''
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            # Skip 0x and add 0's for padding
 | 
				
			||||||
 | 
					            hex_id = '#' + hex(self.id)[2:].rjust(8, '0')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return '{}#{} {} = {}'.format(
 | 
					        if self.args:
 | 
				
			||||||
            fullname, hex_id, ' '.join([str(arg) for arg in self.args]),
 | 
					            args = ' ' + ' '.join([repr(arg) for arg in self.args])
 | 
				
			||||||
            self.result)
 | 
					        else:
 | 
				
			||||||
 | 
					            args = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return '{}{}{} = {}'.format(fullname, hex_id, args, self.result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def infer_id(self):
 | 
				
			||||||
 | 
					        representation = self.__repr__(ignore_id=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Clean the representation
 | 
				
			||||||
 | 
					        representation = representation\
 | 
				
			||||||
 | 
					            .replace(':bytes ', ':string ')\
 | 
				
			||||||
 | 
					            .replace('?bytes ', '?string ')\
 | 
				
			||||||
 | 
					            .replace('<', ' ').replace('>', '')\
 | 
				
			||||||
 | 
					            .replace('{', '').replace('}', '')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        representation = re.sub(
 | 
				
			||||||
 | 
					            r' \w+:flags\.\d+\?true',
 | 
				
			||||||
 | 
					            r'',
 | 
				
			||||||
 | 
					            representation
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					        return crc32(representation.encode('ascii'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __str__(self):
 | 
					    def __str__(self):
 | 
				
			||||||
        fullname = ('{}.{}'.format(self.namespace, self.name)
 | 
					        fullname = ('{}.{}'.format(self.namespace, self.name)
 | 
				
			||||||
| 
						 | 
					@ -214,3 +246,9 @@ class TLArg:
 | 
				
			||||||
            return '{{{}:{}}}'.format(self.name, real_type)
 | 
					            return '{{{}:{}}}'.format(self.name, real_type)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return '{}:{}'.format(self.name, real_type)
 | 
					            return '{}:{}'.format(self.name, real_type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        # Get rid of our special type
 | 
				
			||||||
 | 
					        return str(self)\
 | 
				
			||||||
 | 
					            .replace(':date', ':int')\
 | 
				
			||||||
 | 
					            .replace('?date', '?int')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user