-
-
Notifications
You must be signed in to change notification settings - Fork 8.6k
[py] Add type annotations to BiDi module #16895
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: trunk
Are you sure you want to change the base?
Conversation
PR Compliance Guide 🔍Below is a summary of compliance checks for this PR:
Compliance status legend🟢 - Fully Compliant🟡 - Partial Compliant 🔴 - Not Compliant ⚪ - Requires Further Human Verification 🏷️ - Compliance label |
||||||||||||||||||||||||
PR Code Suggestions ✨Explore these optional code suggestions:
|
|||||||||
cgoldberg
left a comment
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 don't understand the assertions.
For example:
if not self._websocket_connection:
self._start_bidi()
assert self._websocket_connection is not None
Since _start_bidi() sets the WebSocket connection, there is no way this assertion could ever fail. Is mypy complaining about that?
In general, we should almost never use assert in code that is not in the test suite. It just raises an unhelpful exception. If something has an invalid type or there is a situation where something can't run, we should be raising TypeError or some other exception along with a useful message. I don't like the idea of just sprinkling around assertions to keep the type checker happy.
|
Yes, mypy complains because it doesn't understand that selenium/webdriver/remote/webdriver.py:1161: error: Argument 1 to "Session" has incompatible type "WebSocketConnection | None"; expected "WebSocketConnection" [arg-type]I agree that assert isn't ideal here. I could use cast() instead: self._bidi_session = Session(cast(WebSocketConnection, self._websocket_connection))Alternatively, |
|
@cgoldberg I replaced asserts with "cast" in |
User description
🔗 Related Issues
Improves type coverage for the BiDi browser module to pass
mypy --strict.💥 What does this PR do?
Adds type annotations to
selenium/webdriver/common/bidi/Also adds type narrowing assertions in
webdriver.pyfor properties that passWebSocketConnectionto now-typed BiDi classes.🔧 Implementation Notes
TYPE_CHECKING pattern:
WebSocketConnectionis imported underTYPE_CHECKINGto avoid runtime circular imports while still providing type hints. This matches the pattern used in sibling modules (session.py,script.py,input.py).cast() usage: The
conn.execute()method returnsAny(untyped upstream). Usingcast(str, result["userContext"])documents the expected type per BiDi spec and satisfiesmypy --strict.💡 Additional Considerations
Decision needed: Should the assertions be moved outside the if block? Example:
Current (inside if):
Alternative:
Both pass mypy and tox checks. The "outside" pattern is slightly more defensive but adds an assertion on every property access, so I decided to go with the first one.
🔄 Types of changes
PR Type
Enhancement
Description
Add comprehensive type annotations to BiDi module for mypy --strict compliance
Import WebSocketConnection under TYPE_CHECKING to avoid circular imports
Use cast() for untyped upstream results to document expected types per BiDi spec
Add type narrowing assertions in webdriver.py properties for WebSocketConnection
Improve type hints for dataclass methods, callbacks, and dictionary parameters
Diagram Walkthrough
File Walkthrough
browser.py
Add type annotations to Browser classpy/selenium/webdriver/common/bidi/browser.py
from __future__ import annotationsand TYPE_CHECKING import forWebSocketConnection
__init__method with WebSocketConnection parameter andNone return type
from_dictclassmethod to usedict[str, Any]instead of genericdictcast(str, result["userContext"])for untyped upstream resultdestination_folderparameter tostr |os.PathLike[str]input.py
Add comprehensive type annotations to Input modulepy/selenium/webdriver/common/bidi/input.py
from __future__ import annotationsand TYPE_CHECKING import forWebSocketConnection
Callablefrom collections.abc for callback type hints__init__andto_dictmethods with returntypes
dict[str, Any]throughout__init__, callbacks, and handler methodswith proper Callable signatures
script.py
Add type annotations to Script modulepy/selenium/webdriver/common/bidi/script.py
from __future__ import annotationsand TYPE_CHECKING imports forWebDriver and WebSocketConnection
Callablefrom collections.abc for handler type hints__init__with WebDriver optional parameterconsole and error handlers
cast(str, result["script"])for untyped upstream result in preloadscript
parameters
session.py
Add type annotations to Session modulepy/selenium/webdriver/common/bidi/session.py
from __future__ import annotationsand TYPE_CHECKING import forWebSocketConnection
Generatorfrom collections.abc for subscribe/unsubscribe returntypes
__init__with WebSocketConnection parameterdict[str, Any]optional browsing_contexts
webdriver.py
Add type narrowing assertions for BiDi propertiespy/selenium/webdriver/remote/webdriver.py
_start_bidi()calls in script,browser, _session, and input properties
typed BiDi classes
checker