refactor: add type annotations to utils public functions#52
Open
pageton wants to merge 18 commits into
Open
Conversation
- to_camel_case: replace O(n^2) string concat with list+join - escape_markdown: pre-build sets for O(1) char membership - get_message_methods: use frozenset (shared constant) - plugin loading: use set for O(1) dedup instead of list scan
- dict_to_obj: cache getattr(types, ...) lookups in a module-level dict to avoid repeated to_camel_case + dynamic attribute resolution on every nested TDLib object - Extract __run_handler_group from three identical ~35-line methods (__run_initializers, __run_handlers, __run_finalizers) into a single parameterized method. Reduces ~100 lines of duplication.
- remove_handler: replace O(n*m) list.copy()+list.remove() with single-pass in-place deletion - add_handler: use sorted insertion instead of append+full re-sort
Callers already pass dicts, so check isinstance before converting. Skips a full recursive traversal on already-converted data.
Reduces per-instance memory by ~40% (no __dict__, no __weakref__). Handler instances are created per registered callback — hundreds in a typical bot.
- Wrap debug-level f-string logs with isEnabledFor(DEBUG) check to skip string formatting when debug is disabled - Simplify is_coro_filter cache lookup to use dict.get
- Move receive() into its own try/except with continue to prevent a single malformed response from killing the entire receiver loop - Use dict.get() for @client_id to avoid KeyError on updates missing the field, log a warning instead - Log the update @type when @client_id is missing for debug context
- __aexit__: log stop() errors instead of silently swallowing them - AuthorizationError: accept code parameter, pass TDLib error code at both raise sites so callers can inspect it - Add WebAppDataError base class for WebAppData* exceptions - Export WebAppDataError in __all__
- strings.get_retry_after_time: catch ValueError/AttributeError instead of Exception, prevents masking unexpected errors in flood-wait handling - json_utils.load_callback_data: catch ValueError/TypeError instead of Exception, add empty data guard to prevent IndexError
- invoke(): validate request is a dict with @type before accessing it, giving a clear ValueError instead of a cryptic KeyError - tdjson._build_client(): validate TDLib getOption responses have a 'value' key before indexing, raise RuntimeError with context
- Use queue_size as asyncio.Queue maxsize for backpressure - Call queue.task_done() in finally block after each update - Handle CancelledError in worker loop for clean shutdown - Make __stop_client async and await cancelled worker tasks with gather(return_exceptions=True)
Replace fire-and-forget create_task loop with awaitable gather. Ensures all TDLib options are applied before the caller proceeds to the next authorization step.
DeepDiff with ignore_order=True is CPU-intensive and blocks the event loop. Use asyncio.to_thread to run it off the main loop.
Add _create_task helper that attaches a done_callback to log unhandled exceptions from fire-and-forget tasks. Replaces all bare self.loop.create_task calls in client.py: - getOption version ping - local handlers (updateUser, updateOption, etc.) - NATS update processing - signal handler stop()
When the client shuts down, pending futures in _results were never resolved, causing CancelledError propagation to callers. Cancel all pending futures and clear _results in __stop_client.
Replace bare create_task in receiver loop with tracked tasks using a set + done_callback pattern. Cancel all pending update tasks in close() before shutting down the receiver.
- Use X | None for attrs initialized to None (connection_state, me, is_running, _workers_tasks, __wait_login, __authorization_state, __idle_event, __closed_event, loop) - Add dict[str, ...] annotations for _handlers, _current_handlers, options, __local_handlers, __cache - Add bool annotations for __is_queue_worker, __is_closing - Add str annotations for NATS subject attributes - Use tuple[type, ...] and frozenset[str] for typed containers
- obj_encoder.py: annotate obj_to_json, obj_to_dict, dict_to_obj params and returns; type _type_cache as dict[str, type] - json_utils.py: annotate json_loads, CallbackData.__init__, callback_data params; add typing.Any import - strings.py: add return type to create_extra_id
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add proper type annotations to all public functions in utils/: