Skip to content

RuslanUC/utl

Repository files navigation

uTL

A small Telegram Type Language reflection-based implementation in C heavily inspired by Google's upb.

Caution

This project is in development and (since it is also my one of the first python c extensions without using libraries like nanobind) may contain critical bugs such as memory leaks. Use at your own risk!

Installation

pip install <TODO: package on PyPI>

Or install from git:

pip install git+https://github.com/RuslanUC/utl

Quick start

TL object definition, serialization, deserialization

from io import BytesIO
import pyutl

SomeConstructor = pyutl.parse_tl("SomeConstructor#12345678 some_string_field:string = SomeType;", 1, pyutl.TLSection.TYPES)
obj = SomeConstructor(some_string_field="this is a string in SomeConstructor object!")
print(obj)
# SomeConstructor(some_string_field="this is a string in SomeConstructor object!")
serialized = obj.write()
print(obj)
# b"xV4\x12+this is a string in SomeConstructor object!"

# Skipping first 4 bytes because it is tl id, and it is not needed when .read_bytes is called on known type
new_obj = SomeConstructor.read_bytes(serialized[4:])
# or
new_obj2 = SomeConstructor.read(BytesIO(serialized[4:]))
# or
# Here we are not skipping first 4 bytes since we are deserializing object with TLObject (type is unknown)
new_obj3 = pyutl.TLObject.read_bytes(serialized)
# or
new_obj4 = pyutl.TLObject.read(BytesIO(serialized))

print(new_obj)
# SomeConstructor(some_string_field="this is a string in SomeConstructor object!")

print(obj == new_obj)
# True
print(obj == new_obj2)
# True
print(obj == new_obj3)
# True
print(obj == new_obj4)
# True

TL object definition via pyutl.parse_tl

You can define tl object type with tl definition string like this:

import pyutl
SomeConstructor = pyutl.parse_tl("SomeConstructor#12345678 some_string_field:string = SomeType;", 1, pyutl.TLSection.TYPES)

TL object definition via python type-annotated class

Also, you can define tl object using python type-annotated class:

import pyutl

# TL type inside AnnotatedTLObject[...] may be string or TLType subclass that you got from pyutl.create_type or pyutl.get_type
class SomeConstructor(pyutl.AnnotatedTLObject["SomeType"]):
    __tl_id__ = 0x12345678
    __layer__ = 1
    __section__ = pyutl.TLSection.TYPES  # Optional, pyutl.TLSection.TYPES by default
    # Optional, may be tl definition to skip annotations parsing,
    # if None - then after parsing it will be set to generated tl definition so you can set or reuse it later
    __tl__ = None

    some_string_field: str

TODOs

  • Implement __eq__ for TLVector and list
  • Decref/dealloc old values when setting new in tlobjects and tlvectors
  • Publish on PyPI
  • Add more methods to TLVector
  • Add tool to compile existing .tl files to .py and .pyi files with classes definition via .parse_tl or .py files with classes definition via type-annotated classes

About

A small Telegram Type Language implementation in C.

Topics

Resources

License

Stars

Watchers

Forks

Contributors