diff --git a/.github/workflows/ci-python.yml b/.github/workflows/ci-python.yml index db5ac26dee7c6..e0f9442d15224 100644 --- a/.github/workflows/ci-python.yml +++ b/.github/workflows/ci-python.yml @@ -38,23 +38,10 @@ jobs: typing: name: Type Checker - runs-on: ubuntu-latest - steps: - - name: Checkout source tree - uses: actions/checkout@v4 - - name: Set up Python 3.10 - uses: actions/setup-python@v6 - with: - python-version: '3.10' - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install tox - - name: Run type checking - run: | - tox -c py/tox.ini - env: - TOXENV: typecheck + uses: ./.github/workflows/bazel.yml + with: + name: Type Checker + run: bazel run //py:mypy unit-tests: name: Unit Tests diff --git a/Rakefile b/Rakefile index 1065dca8018f3..52f0d33d68a56 100644 --- a/Rakefile +++ b/Rakefile @@ -1494,6 +1494,7 @@ namespace :all do raise "Formatting updated files:\n#{changed_files}\nPlease review, stage, and commit the changes." end + Bazel.execute('run', [], '//py:mypy') Bazel.execute('run', [], '//rb:steep') shellcheck = Bazel.execute('build', [], '@multitool//tools/shellcheck') Bazel.execute('run', ['--', '-shellcheck', shellcheck], '@multitool//tools/actionlint:cwd') diff --git a/py/BUILD.bazel b/py/BUILD.bazel index 665936f0ff53b..9e91f7f0797aa 100644 --- a/py/BUILD.bazel +++ b/py/BUILD.bazel @@ -647,3 +647,17 @@ sphinx_docs( formats = ["html"], sphinx = ":sphinx-build", ) + +py_binary( + name = "mypy", + srcs = ["run_mypy.py"], + data = [ + "pyproject.toml", + ":selenium", + ], + main = "run_mypy.py", + deps = [ + ":selenium", + requirement("mypy"), + ], +) diff --git a/py/pyproject.toml b/py/pyproject.toml index 0c389a0dffd31..c1e60557185a2 100644 --- a/py/pyproject.toml +++ b/py/pyproject.toml @@ -46,9 +46,6 @@ issues = "https://github.com/SeleniumHQ/selenium/issues" lint = [ "ruff==0.14.10", ] -typecheck = [ - "mypy==1.19.1", -] validate = [ "validate-pyproject==0.24.1", "packaging==25.0", diff --git a/py/requirements.txt b/py/requirements.txt index 6253e8a9fab7b..1ad000bec1364 100644 --- a/py/requirements.txt +++ b/py/requirements.txt @@ -28,6 +28,7 @@ keyring==25.7.0 markdown-it-py==4.0.0 mdurl==0.1.2 more-itertools==10.8.0 +mypy==1.19.1 mypy_extensions==1.1.0 nh3==0.3.2 outcome==1.3.0.post0 diff --git a/py/requirements_lock.txt b/py/requirements_lock.txt index 6b03b352ee87d..8b06583026343 100644 --- a/py/requirements_lock.txt +++ b/py/requirements_lock.txt @@ -421,7 +421,6 @@ jeepney==0.9.0 \ --hash=sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732 # via # -r py/requirements.txt - # keyring # secretstorage jinja2==3.1.6 \ --hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \ @@ -435,6 +434,84 @@ keyring==25.7.0 \ # via # -r py/requirements.txt # twine +librt==0.7.8 \ + --hash=sha256:00105e7d541a8f2ee5be52caacea98a005e0478cfe78c8080fbb7b5d2b340c63 \ + --hash=sha256:0241a6ed65e6666236ea78203a73d800dbed896cf12ae25d026d75dc1fcd1dac \ + --hash=sha256:03679b9856932b8c8f674e87aa3c55ea11c9274301f76ae8dc4d281bda55cf62 \ + --hash=sha256:047164e5f68b7a8ebdf9fae91a3c2161d3192418aadd61ddd3a86a56cbe3dc85 \ + --hash=sha256:171ca3a0a06c643bd0a2f62a8944e1902c94aa8e5da4db1ea9a8daf872685365 \ + --hash=sha256:1a4ede613941d9c3470b0368be851df6bb78ab218635512d0370b27a277a0862 \ + --hash=sha256:20e3946863d872f7cabf7f77c6c9d370b8b3d74333d3a32471c50d3a86c0a232 \ + --hash=sha256:2991b6c3775383752b3ca0204842743256f3ad3deeb1d0adc227d56b78a9a850 \ + --hash=sha256:31724b93baa91512bd0a376e7cf0b59d8b631ee17923b1218a65456fa9bda2e7 \ + --hash=sha256:3469e1af9f1380e093ae06bedcbdd11e407ac0b303a56bbe9afb1d6824d4982d \ + --hash=sha256:389bd25a0db916e1d6bcb014f11aa9676cedaa485e9ec3752dfe19f196fd377b \ + --hash=sha256:3968762fec1b2ad34ce57458b6de25dbb4142713e9ca6279a0d352fa4e9f452b \ + --hash=sha256:39a4c76fee41007070f872b648cc2f711f9abf9a13d0c7162478043377b52c8e \ + --hash=sha256:3d1322800771bee4a91f3b4bd4e49abc7d35e65166821086e5afd1e6c0d9be44 \ + --hash=sha256:41d7bb1e07916aeb12ae4a44e3025db3691c4149ab788d0315781b4d29b86afb \ + --hash=sha256:43d4e71b50763fcdcf64725ac680d8cfa1706c928b844794a7aa0fa9ac8e5f09 \ + --hash=sha256:445b7304145e24c60288a2f172b5ce2ca35c0f81605f5299f3fa567e189d2e32 \ + --hash=sha256:44e0c2cbc9bebd074cf2cdbe472ca185e824be4e74b1c63a8e934cea674bebf2 \ + --hash=sha256:451e7ffcef8f785831fdb791bd69211f47e95dc4c6ddff68e589058806f044c6 \ + --hash=sha256:46ef1f4b9b6cc364b11eea0ecc0897314447a66029ee1e55859acb3dd8757c93 \ + --hash=sha256:4864045f49dc9c974dadb942ac56a74cd0479a2aafa51ce272c490a82322ea3c \ + --hash=sha256:4adc73614f0d3c97874f02f2c7fd2a27854e7e24ad532ea6b965459c5b757eca \ + --hash=sha256:4c3995abbbb60b3c129490fa985dfe6cac11d88fc3c36eeb4fb1449efbbb04fc \ + --hash=sha256:4d2f1e492cae964b3463a03dc77a7fe8742f7855d7258c7643f0ee32b6651dd3 \ + --hash=sha256:535929b6eff670c593c34ff435d5440c3096f20fa72d63444608a5aef64dd581 \ + --hash=sha256:5363427bc6a8c3b1719f8f3845ea53553d301382928a86e8fab7984426949bce \ + --hash=sha256:54feb7b4f2f6706bb82325e836a01be805770443e2400f706e824e91f6441dde \ + --hash=sha256:57175aa93f804d2c08d2edb7213e09276bd49097611aefc37e3fa38d1fb99ad0 \ + --hash=sha256:5bcaaf624fd24e6a0cb14beac37677f90793a96864c67c064a91458611446e83 \ + --hash=sha256:60c299e555f87e4c01b2eca085dfccda1dde87f5a604bb45c2906b8305819a93 \ + --hash=sha256:631599598e2c76ded400c0a8722dec09217c89ff64dc54b060f598ed68e7d2a8 \ + --hash=sha256:63937bd0f4d1cb56653dc7ae900d6c52c41f0015e25aaf9902481ee79943b33a \ + --hash=sha256:66daa6ac5de4288a5bbfbe55b4caa7bf0cd26b3269c7a476ffe8ce45f837f87d \ + --hash=sha256:6938cc2de153bc927ed8d71c7d2f2ae01b4e96359126c602721340eb7ce1a92d \ + --hash=sha256:6d772edc6a5f7835635c7562f6688e031f0b97e31d538412a852c49c9a6c92d5 \ + --hash=sha256:6db5faf064b5bab9675c32a873436b31e01d66ca6984c6f7f92621656033a708 \ + --hash=sha256:73fd300f501a052f2ba52ede721232212f3b06503fa12665408ecfc9d8fd149c \ + --hash=sha256:79feb4d00b2a4e0e05c9c56df707934f41fcb5fe53fd9efb7549068d0495b758 \ + --hash=sha256:7aa7d5457b6c542ecaed79cec4ad98534373c9757383973e638ccced0f11f46d \ + --hash=sha256:7b0803e9008c62a7ef79058233db7ff6f37a9933b8f2573c05b07ddafa226611 \ + --hash=sha256:7e03bea66af33c95ce3addf87a9bf1fcad8d33e757bc479957ddbc0e4f7207ac \ + --hash=sha256:864c4b7083eeee250ed55135d2127b260d7eb4b5e953a9e5df09c852e327961b \ + --hash=sha256:8766ece9de08527deabcd7cb1b4f1a967a385d26e33e536d6d8913db6ef74f06 \ + --hash=sha256:87808a8d1e0bd62a01cafc41f0fd6818b5a5d0ca0d8a55326a81643cdda8f873 \ + --hash=sha256:907ad09cfab21e3c86e8f1f87858f7049d1097f77196959c033612f532b4e592 \ + --hash=sha256:95b67aa7eff150f075fda09d11f6bfb26edffd300f6ab1666759547581e8f666 \ + --hash=sha256:978e8b5f13e52cf23a9e80f3286d7546baa70bc4ef35b51d97a709d0b28e537c \ + --hash=sha256:9b6943885b2d49c48d0cff23b16be830ba46b0152d98f62de49e735c6e655a63 \ + --hash=sha256:9c1ba843ae20db09b9d5c80475376168feb2640ce91cd9906414f23cc267a1ff \ + --hash=sha256:a14229ac62adcf1b90a15992f1ab9c69ae8b99ffb23cb64a90878a6e8a2f5b81 \ + --hash=sha256:a36515b1328dc5b3ffce79fe204985ca8572525452eacabee2166f44bb387b2c \ + --hash=sha256:ac9c8a458245c7de80bc1b9765b177055efff5803f08e548dd4bb9ab9a8d789b \ + --hash=sha256:ad64a14b1e56e702e19b24aae108f18ad1bf7777f3af5fcd39f87d0c5a814449 \ + --hash=sha256:b09c52ed43a461994716082ee7d87618096851319bf695d57ec123f2ab708951 \ + --hash=sha256:b45306a1fc5f53c9330fbee134d8b3227fe5da2ab09813b892790400aa49352d \ + --hash=sha256:b5b007bb22ea4b255d3ee39dfd06d12534de2fcc3438567d9f48cdaf67ae1ae3 \ + --hash=sha256:b7e7f140c5169798f90b80d6e607ed2ba5059784968a004107c88ad61fb3641d \ + --hash=sha256:b9122094e3f24aa759c38f46bd8863433820654927370250f460ae75488b66ea \ + --hash=sha256:bb7a7807523a31f03061288cc4ffc065d684c39db7644c676b47d89553c0d714 \ + --hash=sha256:be927c3c94c74b05128089a955fba86501c3b544d1d300282cc1b4bd370cb418 \ + --hash=sha256:bfde8a130bd0f239e45503ab39fab239ace094d63ee1d6b67c25a63d741c0f71 \ + --hash=sha256:c6f8947d3dfd7f91066c5b4385812c18be26c9d5a99ca56667547f2c39149d94 \ + --hash=sha256:c7e8f88f79308d86d8f39c491773cbb533d6cb7fa6476f35d711076ee04fceb6 \ + --hash=sha256:ca916919793a77e4a98d4a1701e345d337ce53be4a16620f063191f7322ac80f \ + --hash=sha256:cf243da9e42d914036fd362ac3fa77d80a41cadcd11ad789b1b5eec4daaf67ca \ + --hash=sha256:d6f254d096d84156a46a84861183c183d30734e52383602443292644d895047c \ + --hash=sha256:dbd79caaf77a3f590cbe32dc2447f718772d6eea59656a7dcb9311161b10fa75 \ + --hash=sha256:ddb52499d0b3ed4aa88746aaf6f36a08314677d5c346234c3987ddc506404eac \ + --hash=sha256:e90a8e237753c83b8e484d478d9a996dc5e39fd5bd4c6ce32563bc8123f132be \ + --hash=sha256:e9c0afebbe6ce177ae8edba0c7c4d626f2a0fc12c33bb993d163817c41a7a05c \ + --hash=sha256:f11b300027ce19a34f6d24ebb0a25fd0e24a9d53353225a5c1e6cadbf2916b2e \ + --hash=sha256:f1ade7f31675db00b514b98f9ab9a7698c7282dad4be7492589109471852d398 \ + --hash=sha256:f8f4a901a3fa28969d6e4519deceab56c55a09d691ea7b12ca830e2fa3461e34 \ + --hash=sha256:fdec6e2368ae4f796fc72fad7fd4bd1753715187e6d870932b0904609e7c878e \ + --hash=sha256:ff3e9c11aa260c31493d4b3197d1e28dd07768594a4f92bec4506849d736248f \ + --hash=sha256:ff71447cb778a4f772ddc4ce360e6ba9c95527ed84a52096bd1bbf9fee2ec7c0 + # via mypy lxml==6.0.2 \ --hash=sha256:058027e261afed589eddcfe530fcc6f3402d7fd7e89bfd0532df82ebc1563dba \ --hash=sha256:063eccf89df5b24e361b123e257e437f9e9878f425ee9aae3144c77faf6da6d8 \ @@ -687,11 +764,52 @@ more-itertools==10.8.0 \ # -r py/requirements.txt # jaraco-classes # jaraco-functools +mypy==1.19.1 \ + --hash=sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd \ + --hash=sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b \ + --hash=sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1 \ + --hash=sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba \ + --hash=sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b \ + --hash=sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045 \ + --hash=sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac \ + --hash=sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6 \ + --hash=sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a \ + --hash=sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24 \ + --hash=sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957 \ + --hash=sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042 \ + --hash=sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e \ + --hash=sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec \ + --hash=sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3 \ + --hash=sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718 \ + --hash=sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f \ + --hash=sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331 \ + --hash=sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1 \ + --hash=sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1 \ + --hash=sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13 \ + --hash=sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67 \ + --hash=sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2 \ + --hash=sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a \ + --hash=sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b \ + --hash=sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8 \ + --hash=sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376 \ + --hash=sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef \ + --hash=sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288 \ + --hash=sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75 \ + --hash=sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74 \ + --hash=sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250 \ + --hash=sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab \ + --hash=sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6 \ + --hash=sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247 \ + --hash=sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925 \ + --hash=sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e \ + --hash=sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e + # via -r py/requirements.txt mypy-extensions==1.1.0 \ --hash=sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505 \ --hash=sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558 # via # -r py/requirements.txt + # mypy # trio-typing nh3==0.3.2 \ --hash=sha256:019ecbd007536b67fdf76fab411b648fb64e2257ca3262ec80c3425c24028c80 \ @@ -742,6 +860,10 @@ packaging==25.0 \ # tox # trio-typing # twine +pathspec==1.0.3 \ + --hash=sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d \ + --hash=sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c + # via mypy platformdirs==4.5.1 \ --hash=sha256:61d5cdcc6065745cdd94f0f878977f8de9437be93de97c1c12f853c9c0cdcbda \ --hash=sha256:d03afa3963c806a9bed9d5125c8f4cb2fdaf74a55ab60e5d59b3fde758104d31 @@ -848,9 +970,7 @@ rich==14.2.0 \ secretstorage==3.5.0 \ --hash=sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137 \ --hash=sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be - # via - # -r py/requirements.txt - # keyring + # via -r py/requirements.txt sniffio==1.3.1 \ --hash=sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 \ --hash=sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc @@ -959,6 +1079,7 @@ tomli==2.4.0 \ --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087 # via # -r py/requirements.txt + # mypy # pyproject-api # pytest # sphinx @@ -1003,6 +1124,7 @@ typing-extensions==4.15.0 \ # beautifulsoup4 # cryptography # exceptiongroup + # mypy # tox # trio-typing # virtualenv diff --git a/py/run_mypy.py b/py/run_mypy.py new file mode 100755 index 0000000000000..7a3602891d88e --- /dev/null +++ b/py/run_mypy.py @@ -0,0 +1,55 @@ +# Licensed to the Software Freedom Conservancy (SFC) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The SFC licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + + +"""Run mypy type checker for Selenium Python bindings. + +This script is used by Bazel to run mypy type checking. +""" + +import os +import sys + +from mypy import api + + +def main(): + # Find the workspace root - Bazel sets BUILD_WORKSPACE_DIRECTORY when using 'bazel run' + workspace = os.environ.get("BUILD_WORKSPACE_DIRECTORY") + if workspace: + py_dir = os.path.join(workspace, "py") + else: + # Fallback for direct execution + py_dir = os.path.dirname(os.path.abspath(__file__)) + + os.chdir(py_dir) + + # Run mypy on the selenium package + # Configuration is read from pyproject.toml [tool.mypy] section + args = ["selenium", *sys.argv[1:]] + stdout, stderr, exit_code = api.run(args) + + if stdout: + print(stdout, end="") + if stderr: + print(stderr, end="", file=sys.stderr) + + sys.exit(exit_code) + + +if __name__ == "__main__": + main() diff --git a/py/run_sphinx_autogen.py b/py/run_sphinx_autogen.py old mode 100644 new mode 100755 diff --git a/py/tox.ini b/py/tox.ini index eb61ec3c8b3aa..bfbea1ee4753e 100644 --- a/py/tox.ini +++ b/py/tox.ini @@ -31,7 +31,6 @@ setenv = skip_install = true deps = -r {toxinidir}/requirements.txt -dependency_groups = typecheck commands = mypy --install-types selenium {posargs}