[py] generate the internal BiDi protocol layer from the shared binding-neutral schema#17761
[py] generate the internal BiDi protocol layer from the shared binding-neutral schema#17761titusfortner wants to merge 5 commits into
Conversation
PR Summary by QodoAdd generated internal Python BiDi protocol layer (selenium.webdriver._bidi)
AI Description
Diagram
High-Level Assessment
Files changed (26)
|
There was a problem hiding this comment.
Pull request overview
This PR adds a new internal Python WebDriver BiDi protocol layer under selenium.webdriver._bidi, generated from the shared binding-neutral BiDi schema, plus a small handwritten runtime (serialization + transport seam) and Bazel/CI wiring to keep checked-in generated files in sync.
Changes:
- Introduces the generated internal
_bidiprotocol package (domains, types, commands/events metadata) and a handwritten runtime (serialization.py,transport.py). - Wires
RemoteWebDriverto create a per-session_bidi_transportlazily when BiDi is started. - Adds unit + end-to-end tests, plus a
verify-bidi-protocolBazel target and CI step to detect drift/hand-edits.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
py/verify_bidi_protocol.py |
Verifies checked-in _bidi files match generator output. |
py/test/unit/selenium/webdriver/common/bidi_transport_tests.py |
Unit coverage for the handwritten transport/domain seam. |
py/test/unit/selenium/webdriver/common/bidi_serialization_tests.py |
Unit coverage for strict (de)serialization runtime rules. |
py/test/unit/selenium/webdriver/common/bidi_protocol_command_tests.py |
Exercises generated command surfaces over a stand-in transport. |
py/test/selenium/webdriver/common/bidi_protocol_tests.py |
Browser-level sanity checks that generated types round-trip against a real BiDi session. |
py/selenium/webdriver/remote/webdriver.py |
Adds _bidi_transport lifecycle + lazy import/creation in _start_bidi(). |
py/selenium/webdriver/_bidi/__init__.py |
Generated package initializer exporting domain classes. |
py/selenium/webdriver/_bidi/serialization.py |
Handwritten serialization runtime used by generated records/unions (plus registry). |
py/selenium/webdriver/_bidi/transport.py |
Handwritten websocket seam (Transport) and base domain (Domain). |
py/selenium/webdriver/_bidi/browsing_context.py |
Generated browsingContext domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/bluetooth.py |
Generated bluetooth domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/browser.py |
Generated browser domain (types + commands). |
py/selenium/webdriver/_bidi/emulation.py |
Generated emulation domain (types + commands). |
py/selenium/webdriver/_bidi/input.py |
Generated input domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/log.py |
Generated log domain (types + event metadata). |
py/selenium/webdriver/_bidi/network.py |
Generated network domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/permissions.py |
Generated permissions domain (types + commands). |
py/selenium/webdriver/_bidi/script.py |
Generated script domain (types + commands + event metadata). |
py/selenium/webdriver/_bidi/session.py |
Generated session domain (types + commands). |
py/selenium/webdriver/_bidi/speculation.py |
Generated speculation domain (types + event metadata). |
py/selenium/webdriver/_bidi/storage.py |
Generated storage domain (types + commands). |
py/selenium/webdriver/_bidi/user_agent_client_hints.py |
Generated userAgentClientHints domain (types + commands). |
py/selenium/webdriver/_bidi/web_extension.py |
Generated webExtension domain (types + commands). |
py/BUILD.bazel |
Adds generator target, _bidi library, and verify test; packages _bidi. |
.github/workflows/ci-python.yml |
Runs //py:verify-bidi-protocol in CI alongside unit tests. |
Code Review by Qodo
Context used✅ Compliance rules (platform):
17 rules 1.
|
| # bazel run //py:generate-bidi-protocol | ||
|
|
||
|
|
||
| from __future__ import annotations |
There was a problem hiding this comment.
We should not be checking in generated code
There was a problem hiding this comment.
My original thought was to check it in until we used it to implement the user facing code, but we can change it to build only now after we've agreed that this is the right shape for the generated code.
Do you have any concerns with the conventions or naming of the output?
|
The direction of this looks ok so far but need to see how this will be used as that code isn't here |
0760b9a to
ae297f2
Compare
|
PR has a lot of unnecessary files in it now in case you're not aware |
|
@AutomatedTester yes, to work with the latest schema it pulled in #17784 which should merge soon |
1101797 to
7c6c1b5
Compare
…into bidi/ and _bidi/
7c6c1b5 to
6057552
Compare
🔗 Related Issues
objectOnly/preserveExtras/scalarsignals from [rb] add objectOnly/preserveExtras/scalar-primitive BiDi schema signals #17784 (now on trunk).py:local_devrework) — that PR is the base branch; this addscommon/_bidito its local-dev copy so the build-time-generated modules land in the source tree. Merge [build] update py:local_dev task to ensure all files are generated and symlinks are always resolved #17789 first; the diff resolves to just the BiDi layer once it lands on trunk.💥 What does this PR do?
selenium.webdriver.common._bidipackage, generated at build time from the shared binding-neutral schema (projected once from the CDDL). The domain modules are not checked in.Domainbase, and the package__init__. These four are the only tracked files in the package; the domain modules are generated and gitignored.✅ Compliance with the behavioral contract (#17786)
This branch meets every behavior in the ADR's conformance table for
py 17761. The two thesnapshot had it failing are now closed by consuming #17784's derived signals, each backed by an
executed test that feeds malformed input and asserts the raise/round-trip (the ADR is
runtime-not-declaration):
(
Union._OBJECT_ONLY, from the schema'sobjectOnly), while a union with a real scalar arm(
input.Origin) still passes scalars through. Map[key, value]entries keep round-trippingbecause the
scalarsignal lets a bare-string key through, checked against its primitive.preserveExtras(extensible ∩ re-sendable), so a received-only type (network.Cookie,session.NewResultCapabilities,storage.PartitionKey) drops unknowns while a re-sendable type(
storage.PartialCookie, proxy configs, …) stores and echoes them.The other ten behaviors were already met and are unchanged.
🔧 Implementation Notes
common/bidicode and its CDDL generator are left untouched — retiring or migrating that is out of scope.common/_bidi/; onlyserialization.py,transport.py,domain.py, and__init__.pyare hand-written and tracked. Regenerate the checked-out tree for local development withbazel run //py:generate-bidi-protocol.common/alongside the existing generatedcommon/bidiandcommon/devtoolspackages, matching the established structure.Transportis built per session and owned by theWebDriver(imported lazily so non-BiDi sessions don't load the generated package).Domainbase (the class each generated domain subclasses) lives in its owncommon/_bidi/domain.pymodule.🤖 AI assistance
💡 Additional Considerations
🔄 Types of changes