-
Notifications
You must be signed in to change notification settings - Fork 926
Set up type hinting: C extension stubs + typing for serializing_producer + deserializing_consumer #2041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
🎉 All Contributor License Agreements have been signed. Ready to merge. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR introduces initial type hinting support for the confluent_kafka Python package by adding type stubs for the C extension and typing annotations to core serialization classes.
- Establishes type safety foundation with C extension stubs and centralized type definitions
- Adds comprehensive type annotations to producer and consumer serialization classes
- Creates type-aware error handling hierarchy
Reviewed Changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
File | Description |
---|---|
src/confluent_kafka/cimpl.pyi | Type stubs for C extension classes and functions |
src/confluent_kafka/_types.py | Centralized type aliases for the package |
src/confluent_kafka/py.typed | Marker file indicating package supports typing |
src/confluent_kafka/serializing_producer.py | Type annotations for SerializingProducer class |
src/confluent_kafka/deserializing_consumer.py | Type annotations for DeserializingConsumer class |
src/confluent_kafka/error.py | Type annotations for error classes |
src/confluent_kafka/init.py | Type annotations for utility classes |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
||
super(DeserializingConsumer, self).__init__(conf_copy) | ||
|
||
def poll(self, timeout=-1): | ||
def poll(self, timeout: float = -1) -> Optional['Message']: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The return type annotation uses forward reference quotes around 'Message' but Message is already imported on line 21. Remove the quotes to use the directly imported type.
def poll(self, timeout: float = -1) -> Optional['Message']: | |
def poll(self, timeout: float = -1) -> Optional[Message]: |
Copilot uses AI. Check for mistakes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would like to spend some time over zoom talking through the work on this PR but overall looks reasonable as a solution PR
@@ -60,7 +61,7 @@ class ConsumerGroupTopicPartitions: | |||
List of topic partitions information. | |||
""" | |||
|
|||
def __init__(self, group_id, topic_partitions=None): | |||
def __init__(self, group_id: str, topic_partitions: Optional[List['cimpl.TopicPartition']] = None) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why'd this need the cimpl path prefix to work here? Curious to chat about how the cbinding type errors were worked out in development
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are only importing the module from .. import cimpl
so the type checker would not find the directly referenced TopicPartition. We can switch to from ..cimpl import TopicPartition
to make the code a bit cleaner
from enum import Enum | ||
|
||
# Generic type for enum conversion | ||
E = TypeVar('E', bound=Enum) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this? Can't we just use type[Enum]
below?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes I think we can just leave it type[Enum]
. I think Type[E]
creates a stricter type relationship with the specific enum class, but it overcomplicates the code a bit and I don't think this function (meant to handle types itself) can benefit from it
self.cluster_id = cluster_id | ||
self.controller = controller | ||
self.nodes = nodes | ||
self.authorized_operations = None | ||
self.authorized_operations: Optional[List[AclOperation]] = None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the hint here and why does it differ from the hint in the def?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Also update authorized_operations to be more specific: Optional[List[Union[str, int, AclOperation]]]
, as those 3 types are handled in ConversionUtil.convert_to_enum
from enum import Enum | ||
|
||
from .. import cimpl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the move?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Honestly I think cursor moved it during the first pass and I didn't notice it. But after some investigation, I think the move makes sense as it adheres to the pep8 import rule: https://peps.python.org/pep-0008/#imports
@@ -0,0 +1,443 @@ | |||
""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do dislike how we'll have two locations for type/actual definitions we need to maintain now. However it may be the ideal solution for now. This really makes me want to try a pass on converting the c files to Cython and then getting the type hinting for free while avoiding manually defining so many Python things in C binding calls. Not in scope for this PR though it would eliminate the above dual definition problem. For now let's add a warning comment to the C code files to update this file when/if editing interfaces therein
What
First PR to set up type hinting for this repo. This PR includes:
Type hinting for other python files will be covered in follow-up PRs
Checklist
References
JIRA: https://confluentinc.atlassian.net/browse/DGS-22076
Test & Review
Open questions / Follow-ups