From 399f24fceb604afc3bbfb9a66a2ab02309c695fd Mon Sep 17 00:00:00 2001 From: Max Schmitt Date: Thu, 25 Aug 2022 20:45:30 +0200 Subject: [PATCH] chore: add support for Python 3.11 (#1533) --- .github/workflows/ci.yml | 9 +++++++++ meta.yaml | 2 +- scripts/generate_api.py | 36 ++++++++++++++++++++++++++++++++++- scripts/generate_async_api.py | 3 ++- scripts/generate_sync_api.py | 3 ++- setup.py | 3 ++- 6 files changed, 51 insertions(+), 5 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b89f8cf2..876865996 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,6 +83,15 @@ jobs: - os: macos-11.0 python-version: '3.10' browser: chromium + - os: windows-latest + python-version: '3.11.0-rc.1' + browser: chromium + - os: macos-latest + python-version: '3.11.0-rc.1' + browser: chromium + - os: ubuntu-latest + python-version: '3.11.0-rc.1' + browser: chromium runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 diff --git a/meta.yaml b/meta.yaml index 7050f0014..8f320bd09 100644 --- a/meta.yaml +++ b/meta.yaml @@ -23,7 +23,7 @@ requirements: - setuptools_scm run: - python - - greenlet ==1.1.2 + - greenlet ==1.1.3 - pyee ==8.1.0 - websockets ==10.1 - typing_extensions # [py<39] diff --git a/scripts/generate_api.py b/scripts/generate_api.py index 891370f80..a1f4e69a1 100644 --- a/scripts/generate_api.py +++ b/scripts/generate_api.py @@ -13,17 +13,20 @@ # limitations under the License. import re +import sys from types import FunctionType from typing import ( # type: ignore Any, + Dict, List, Match, + Optional, Union, cast, get_args, get_origin, - get_type_hints, ) +from typing import get_type_hints as typing_get_type_hints from playwright._impl._accessibility import Accessibility from playwright._impl._assertions import ( @@ -287,3 +290,34 @@ def return_value(value: Any) -> List[str]: api_globals = globals() assert Serializable + +# Python 3.11+ does not treat default args with None as Optional anymore, this wrapper will still wrap them. +# https://github.com/python/cpython/issues/90353 +def get_type_hints(func: Any, globalns: Any) -> Dict[str, Any]: + original_value = typing_get_type_hints(func, globalns) + if sys.version_info < (3, 11): + return original_value + for key, value in _get_defaults(func).items(): + if value is None and original_value[key] is not Optional: + original_value[key] = Optional[original_value[key]] + return original_value + + +def _get_defaults(func: Any) -> Dict[str, Any]: + """Internal helper to extract the default arguments, by name.""" + try: + code = func.__code__ + except AttributeError: + # Some built-in functions don't have __code__, __defaults__, etc. + return {} + pos_count = code.co_argcount + arg_names = code.co_varnames + arg_names = arg_names[:pos_count] + defaults = func.__defaults__ or () + kwdefaults = func.__kwdefaults__ + res = dict(kwdefaults) if kwdefaults else {} + pos_offset = pos_count - len(defaults) + for name, value in zip(arg_names[pos_offset:], defaults): + assert name not in res + res[name] = value + return res diff --git a/scripts/generate_async_api.py b/scripts/generate_async_api.py index 30e506e5f..eafc4ab7e 100755 --- a/scripts/generate_async_api.py +++ b/scripts/generate_async_api.py @@ -16,13 +16,14 @@ import inspect import re from types import FunctionType -from typing import Any, get_type_hints +from typing import Any from scripts.documentation_provider import DocumentationProvider from scripts.generate_api import ( all_types, api_globals, arguments, + get_type_hints, header, process_type, return_type, diff --git a/scripts/generate_sync_api.py b/scripts/generate_sync_api.py index 76647c1ab..44e0b7f43 100755 --- a/scripts/generate_sync_api.py +++ b/scripts/generate_sync_api.py @@ -17,13 +17,14 @@ import re import sys from types import FunctionType -from typing import Any, get_type_hints +from typing import Any from scripts.documentation_provider import DocumentationProvider from scripts.generate_api import ( all_types, api_globals, arguments, + get_type_hints, header, process_type, return_type, diff --git a/setup.py b/setup.py index 40afca263..bb602c013 100644 --- a/setup.py +++ b/setup.py @@ -209,7 +209,7 @@ def _download_and_extract_local_driver( include_package_data=True, install_requires=[ "websockets==10.1", - "greenlet==1.1.2", + "greenlet==1.1.3", "pyee==8.1.0", "typing-extensions;python_version<='3.8'", ], @@ -222,6 +222,7 @@ def _download_and_extract_local_driver( "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", "License :: OSI Approved :: Apache Software License", "Operating System :: OS Independent", ],