From 39d9f94d132a69432f91eaaf893e38bc162623ad Mon Sep 17 00:00:00 2001 From: Sean Lip Date: Sat, 2 Nov 2024 03:13:38 +0800 Subject: [PATCH] Fix part of #21020: Upgrade Python to 3.9 (#21215) * Update to python 3.9 * Fix isAlive * Fix import ordering * Fix import ordering * Fix test * use python3.9.20 for docker * Fix lint errors, remove spurious changes * Fix lint issues * Address review comment. --- .../backend_associated_test_file_check.yml | 4 +- .github/workflows/backend_tests.yml | 12 +-- .../workflows/check_test_suites_to_run.yml | 4 +- ...ighthouse_performance_acceptance_tests.yml | 20 ++-- .github/workflows/eslint_tests.yml | 4 +- .github/workflows/frontend_tests.yml | 4 +- .../workflows/lighthouse_accessibility.yml | 8 +- .github/workflows/lint.yml | 4 +- .../workflows/pending-review-notification.yml | 4 +- .github/workflows/prettier.yml | 4 +- .github/workflows/python_type_checks.yml | 4 +- ...typescript_and_e2e_acceptance_coverage.yml | 4 +- app_dev.yaml | 2 +- core/tests/test_utils.py | 99 +++---------------- docker/Dockerfile.backend | 2 +- docker/dev-server.entrypoint.sh | 2 +- mypy.ini | 2 +- requirements.txt | 2 +- requirements_dev.txt | 2 +- scripts/concurrent_task_utils.py | 2 +- scripts/install_python_prod_dependencies.py | 4 +- .../install_python_prod_dependencies_test.py | 4 +- scripts/linters/run_lint_checks.py | 8 +- scripts/pre_commit_hook.py | 19 ++-- scripts/pre_push_hook.py | 13 ++- .../repo_specific_changes_fetcher.py | 8 +- scripts/run_e2e_tests.py | 15 +-- scripts/run_frontend_tests.py | 16 ++- scripts/run_lighthouse_tests.py | 15 +-- scripts/run_portserver.py | 8 +- scripts/run_typescript_checks.py | 14 +-- scripts/setup.py | 4 +- scripts/setup_test.py | 8 +- scripts/third_party_size_check.py | 10 +- stubs/threading/__init__.pyi | 8 +- 35 files changed, 123 insertions(+), 220 deletions(-) diff --git a/.github/workflows/backend_associated_test_file_check.yml b/.github/workflows/backend_associated_test_file_check.yml index 08af0ae96535..bacec7c69677 100644 --- a/.github/workflows/backend_associated_test_file_check.yml +++ b/.github/workflows/backend_associated_test_file_check.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge diff --git a/.github/workflows/backend_tests.yml b/.github/workflows/backend_tests.yml index 22e3a126ecbc..535a3f0e3998 100644 --- a/.github/workflows/backend_tests.yml +++ b/.github/workflows/backend_tests.yml @@ -22,10 +22,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Initialize Containers if: startsWith(github.head_ref, 'update-changelog-for-release') == false @@ -60,10 +60,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Install coverage if: startsWith(github.head_ref, 'update-changelog-for-release') == false @@ -130,10 +130,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Download time report for shard 1 uses: actions/download-artifact@v3 diff --git a/.github/workflows/check_test_suites_to_run.yml b/.github/workflows/check_test_suites_to_run.yml index 7c466631249d..33d10fdbf5ac 100644 --- a/.github/workflows/check_test_suites_to_run.yml +++ b/.github/workflows/check_test_suites_to_run.yml @@ -22,10 +22,10 @@ jobs: fetch-depth: 0 - name: Merge develop branch into the current branch uses: ./.github/actions/merge - - name: Setup Python 3.8 with pip cache + - name: Setup Python 3.9.20 with pip cache uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' cache: 'pip' cache-dependency-path: | diff --git a/.github/workflows/e2e_lighthouse_performance_acceptance_tests.yml b/.github/workflows/e2e_lighthouse_performance_acceptance_tests.yml index e4f716c13066..bdf1693a66d2 100644 --- a/.github/workflows/e2e_lighthouse_performance_acceptance_tests.yml +++ b/.github/workflows/e2e_lighthouse_performance_acceptance_tests.yml @@ -26,10 +26,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 with pip cache + - name: Setup Python 3.9.20 with pip cache uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' cache: 'pip' cache-dependency-path: | @@ -84,10 +84,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 with pip cache + - name: Setup Python 3.9.20 with pip cache uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' cache: 'pip' cache-dependency-path: | @@ -200,10 +200,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge @@ -290,10 +290,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 with pip cache + - name: Setup Python 3.9.20 with pip cache uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' cache: 'pip' cache-dependency-path: | @@ -393,10 +393,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge diff --git a/.github/workflows/eslint_tests.yml b/.github/workflows/eslint_tests.yml index 1e29e958211c..3494d4f2c7ea 100644 --- a/.github/workflows/eslint_tests.yml +++ b/.github/workflows/eslint_tests.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge diff --git a/.github/workflows/frontend_tests.yml b/.github/workflows/frontend_tests.yml index f8f153a655b5..0448dbc3db00 100644 --- a/.github/workflows/frontend_tests.yml +++ b/.github/workflows/frontend_tests.yml @@ -50,10 +50,10 @@ jobs: ls /home/runner/work/oppia ls /home/runner/work/oppia/oppia echo $GITHUB_WORKSPACE - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge diff --git a/.github/workflows/lighthouse_accessibility.yml b/.github/workflows/lighthouse_accessibility.yml index ffa7912d6865..716d83ba9cff 100644 --- a/.github/workflows/lighthouse_accessibility.yml +++ b/.github/workflows/lighthouse_accessibility.yml @@ -26,10 +26,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge @@ -91,10 +91,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 9acd447ef900..4af3b5e81fc9 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 with pip cache + - name: Setup Python 3.9.20 with pip cache uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Free disk space run: | diff --git a/.github/workflows/pending-review-notification.yml b/.github/workflows/pending-review-notification.yml index 6324dd6ce775..c66f2d55943b 100644 --- a/.github/workflows/pending-review-notification.yml +++ b/.github/workflows/pending-review-notification.yml @@ -19,10 +19,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' # SHA1 hash of the develop commit. - name: Notify reviewers diff --git a/.github/workflows/prettier.yml b/.github/workflows/prettier.yml index 5f9749fd7600..f041203d83bc 100644 --- a/.github/workflows/prettier.yml +++ b/.github/workflows/prettier.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge diff --git a/.github/workflows/python_type_checks.yml b/.github/workflows/python_type_checks.yml index afa09bbd3110..d8518286f581 100644 --- a/.github/workflows/python_type_checks.yml +++ b/.github/workflows/python_type_checks.yml @@ -21,10 +21,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Merge develop branch into the current branch uses: ./.github/actions/merge diff --git a/.github/workflows/typescript_and_e2e_acceptance_coverage.yml b/.github/workflows/typescript_and_e2e_acceptance_coverage.yml index 81edd6e54a51..4bd63e401947 100644 --- a/.github/workflows/typescript_and_e2e_acceptance_coverage.yml +++ b/.github/workflows/typescript_and_e2e_acceptance_coverage.yml @@ -20,10 +20,10 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v3 - - name: Setup Python 3.8 + - name: Setup Python 3.9.20 uses: actions/setup-python@v4 with: - python-version: '3.8.15' + python-version: '3.9.20' architecture: 'x64' - name: Free disk space run: | diff --git a/app_dev.yaml b/app_dev.yaml index ad8f2fbb48d4..9d329d610393 100644 --- a/app_dev.yaml +++ b/app_dev.yaml @@ -1,4 +1,4 @@ -runtime: python38 +runtime: python39 instance_class: F2 # The "version" line is added here so that MR jobs can run locally (see issue # #6534 on oppia/oppia). diff --git a/core/tests/test_utils.py b/core/tests/test_utils.py index bd7ef38a1fec..4091d1fce02c 100644 --- a/core/tests/test_utils.py +++ b/core/tests/test_utils.py @@ -25,6 +25,7 @@ import datetime import functools import inspect +import io import itertools import json import logging @@ -33,7 +34,6 @@ import random import re import string -from types import TracebackType import unittest from core import feature_flag_list @@ -87,9 +87,9 @@ import elasticsearch import requests_mock from typing import ( - IO, Any, Callable, Collection, Dict, Final, Iterable, Iterator, List, - Literal, Mapping, Optional, OrderedDict, Pattern, Sequence, Set, Tuple, - Type, TypedDict, TypeVar, Union, cast, overload + Any, Callable, Collection, Dict, Final, Iterable, Iterator, List, + Literal, Mapping, Optional, OrderedDict, Pattern, Sequence, Set, + Tuple, Type, TypedDict, TypeVar, Union, cast, overload ) import webapp2 import webtest @@ -1505,94 +1505,25 @@ def capture_logging( """ captured_logs: List[str] = [] - class ListStream(IO[str]): + class ListStream(io.StringIO): """Stream-like object that appends writes to the captured logs.""" - # Here we use MyPy ignore because the signature of this - # method doesn't match with IO's write(). - def write(self, msg: str) -> None: # type: ignore[override] - """Appends stripped messages to captured logs.""" + def write(self, msg: str) -> int: + """Appends stripped messages to captured logs. + + Args: + msg: str. The string to be written. + + Returns: + int. The length of the written string in bytes. + """ captured_logs.append(msg.strip()) + return len(msg.strip()) def flush(self) -> None: """Does nothing.""" pass - # Here, class ListStream inherits from IO and making an instance - # below but due to the absence of some methods MyPy throws an error - # that 'Cannot instantiate abstract class 'ListStream' with abstract - # attributes'. So, to suppress the error, we defined all the methods - # that was present in super class. Since these are just added for - # type checking, we don't need to test them and so have excluded - # them from the coverage checks. - @property - def mode(self) -> str: - pass # pragma: no cover - - @property - def name(self) -> str: - pass # pragma: no cover - - def close(self) -> None: - pass # pragma: no cover - - @property - def closed(self) -> bool: - pass # pragma: no cover - - def fileno(self) -> int: - pass # pragma: no cover - - def isatty(self) -> bool: - pass # pragma: no cover - - def read(self, n: int = -1) -> str: - pass # pragma: no cover - - def readable(self) -> bool: - pass # pragma: no cover - - def readline(self, limit: int = -1) -> str: - pass # pragma: no cover - - def readlines(self, hint: int = -1) -> List[str]: - pass # pragma: no cover - - def seek(self, offset: int, whence: int = 0) -> int: - pass # pragma: no cover - - def seekable(self) -> bool: - pass # pragma: no cover - - def tell(self) -> int: - pass # pragma: no cover - - def truncate(self, size: Optional[int] = None) -> int: - pass # pragma: no cover - - def writable(self) -> bool: - pass # pragma: no cover - - def writelines(self, lines: Iterable[str]) -> None: - pass # pragma: no cover - - def __enter__(self) -> IO[str]: - pass # pragma: no cover - - def __exit__( - self, - type: Optional[Type[BaseException]], # pylint: disable=redefined-builtin - value: Optional[BaseException], - traceback: Optional[TracebackType] - ) -> None: - pass # pragma: no cover - - def __iter__(self) -> Iterator[str]: - pass # pragma: no cover - - def __next__(self) -> str: - pass # pragma: no cover - list_stream_handler = logging.StreamHandler(ListStream()) logger = logging.getLogger() diff --git a/docker/Dockerfile.backend b/docker/Dockerfile.backend index 4112fcd83aa6..1c3c1e39de8f 100644 --- a/docker/Dockerfile.backend +++ b/docker/Dockerfile.backend @@ -1,5 +1,5 @@ # Added platform flag here because -- https://stackoverflow.com/questions/71040681/qemu-x86-64-could-not-open-lib64-ld-linux-x86-64-so-2-no-such-file-or-direc -FROM --platform=linux/amd64 python:3.8.17-slim-buster AS backend +FROM --platform=linux/amd64 python:3.9.20-bullseye AS backend ENV OPPIA_IS_DOCKERIZED="true" diff --git a/docker/dev-server.entrypoint.sh b/docker/dev-server.entrypoint.sh index ffe054af5208..d7843d3bad49 100644 --- a/docker/dev-server.entrypoint.sh +++ b/docker/dev-server.entrypoint.sh @@ -15,7 +15,7 @@ build_cmd="python -m scripts.build" dev_appserver_cmd="/app/vm_deps/google-cloud-sdk/bin/dev_appserver.py \ ---runtime=python38 \ +--runtime=python39 \ --host=0.0.0.0 \ --port=8181 \ --admin_host=0.0.0.0 \ diff --git a/mypy.ini b/mypy.ini index 676ad5c03293..955a986302af 100644 --- a/mypy.ini +++ b/mypy.ini @@ -1,5 +1,5 @@ [mypy] -python_version = 3.8 +python_version = 3.9 # Ignore if stubs of a third-party library is missing. ignore_missing_imports = True diff --git a/requirements.txt b/requirements.txt index 637775c8b877..2100082e8974 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,7 +3,7 @@ # please change the `requirements.in` file, and then follow # the instructions there to regenerate this file. # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.9 # by the following command: # # pip-compile --generate-hashes --no-emit-index-url --output-file=requirements.txt requirements.in diff --git a/requirements_dev.txt b/requirements_dev.txt index bb69ecd380a1..b749ba284a00 100644 --- a/requirements_dev.txt +++ b/requirements_dev.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.8 +# This file is autogenerated by pip-compile with Python 3.9 # by the following command: # # pip-compile --generate-hashes --no-emit-index-url --output-file=requirements_dev.txt requirements_dev.in diff --git a/scripts/concurrent_task_utils.py b/scripts/concurrent_task_utils.py index 37eb8aabf55f..31a6f1aa73d6 100644 --- a/scripts/concurrent_task_utils.py +++ b/scripts/concurrent_task_utils.py @@ -152,7 +152,7 @@ def _check_all_tasks(tasks: List[TaskThread]) -> None: running_tasks_data = [] for task in tasks: - if task.isAlive(): + if task.is_alive(): running_tasks_data.append(' %s (started %s)' % ( task.name, time.strftime('%H:%M:%S', time.localtime(task.start_time)) diff --git a/scripts/install_python_prod_dependencies.py b/scripts/install_python_prod_dependencies.py index 1e3ff48f6942..d3e98c924a6d 100644 --- a/scripts/install_python_prod_dependencies.py +++ b/scripts/install_python_prod_dependencies.py @@ -432,9 +432,9 @@ def _get_possible_normalized_metadata_directory_names( '%s-%s.egg-info' % ( library_name.replace('-', '_'), version_string)), normalize_directory_name( - '%s-%s-py3.8.egg-info' % (library_name, version_string)), + '%s-%s-py3.9.egg-info' % (library_name, version_string)), normalize_directory_name( - '%s-%s-py3.8.egg-info' % ( + '%s-%s-py3.9.egg-info' % ( library_name.replace('-', '_'), version_string)) } diff --git a/scripts/install_python_prod_dependencies_test.py b/scripts/install_python_prod_dependencies_test.py index 7db00693418e..21a2ba1f766f 100644 --- a/scripts/install_python_prod_dependencies_test.py +++ b/scripts/install_python_prod_dependencies_test.py @@ -629,8 +629,8 @@ def mock_list_dir(unused_path: str) -> List[str]: return [ 'dependency-1-1.5.1.dist-info', 'dependency2-5.0.0.egg-info', - 'dependency-5-0.5.3-py3.8.egg-info', - 'dependency_6-0.5.3-py3.8.egg-info', + 'dependency-5-0.5.3-py3.9.egg-info', + 'dependency_6-0.5.3-py3.9.egg-info', ] def mock_is_dir(unused_path: str) -> bool: diff --git a/scripts/linters/run_lint_checks.py b/scripts/linters/run_lint_checks.py index 2a47e0a69fb0..f99aecb8bf45 100644 --- a/scripts/linters/run_lint_checks.py +++ b/scripts/linters/run_lint_checks.py @@ -63,13 +63,9 @@ import sys import threading +from core import utils +from scripts import common from typing import Dict, List, Optional, Set, Tuple -# TODO(#15567): This can be removed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. -from scripts import common # isort:skip pylint: disable=wrong-import-position - -from core import utils # isort:skip # Install third party dependencies before proceeding. from . import codeowner_linter # isort:skip diff --git a/scripts/pre_commit_hook.py b/scripts/pre_commit_hook.py index 12a893138195..fee4909600ff 100755 --- a/scripts/pre_commit_hook.py +++ b/scripts/pre_commit_hook.py @@ -34,13 +34,20 @@ import subprocess import sys -from typing import Final, List, Optional, Tuple - -# TODO(#15567): The order can be fixed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. +# When executing Python scripts using `python -m ...` from oppia/oppia, +# Python adds the repository root to sys.path. See the documentation at +# +# https://docs.python.org/3.9/library/sys.html#sys.path +# +# However, when git executes pre_commit_hook.py from its symlink in +# /.git/hooks, the shebang #!/usr/bin/env python at the top of this file +# causes the python interpreter to execute this hook directly rather than +# as a discovered module. So, Python instead adds /.git/hooks to sys.path, +# rather than the opipa/oppia root. To correct this problem, we add the +# current working directory to sys.path. sys.path.append(os.getcwd()) -from scripts import common # isort:skip # pylint: disable=wrong-import-position +from scripts import common # isort:skip # pylint: disable=wrong-import-position +from typing import Final, List, Optional, Tuple # isort:skip # pylint: disable=wrong-import-position FECONF_FILEPATH: Final = os.path.join('core', 'feconf.py') CONSTANTS_FILEPATH: Final = os.path.join('.', 'assets', 'constants.ts') diff --git a/scripts/pre_push_hook.py b/scripts/pre_push_hook.py index 3eaf0c984776..a70319beab7e 100755 --- a/scripts/pre_push_hook.py +++ b/scripts/pre_push_hook.py @@ -39,8 +39,17 @@ from types import TracebackType from typing import Final, List, Optional, Type -# `pre_push_hook.py` is symlinked into `/.git/hooks`, so we explicitly import -# the current working directory so that Git knows where to find python_utils. +# When executing Python scripts using `python -m ...` from oppia/oppia, +# Python adds the repository root to sys.path. See the documentation at +# +# https://docs.python.org/3.9/library/sys.html#sys.path +# +# However, when git executes pre_push_hook.py from its symlink in +# /.git/hooks, the shebang #!/usr/bin/env python at the top of this file +# causes the python interpreter to execute this hook directly rather than +# as a discovered module. So, Python instead adds /.git/hooks to sys.path, +# rather than the opipa/oppia root. To correct this problem, we add the +# current working directory to sys.path. sys.path.append(os.getcwd()) from scripts import common # isort:skip # pylint: disable=wrong-import-position from scripts import install_python_prod_dependencies # isort:skip # pylint: disable=wrong-import-position diff --git a/scripts/release_scripts/repo_specific_changes_fetcher.py b/scripts/release_scripts/repo_specific_changes_fetcher.py index 833b89f10384..3d11526d8365 100644 --- a/scripts/release_scripts/repo_specific_changes_fetcher.py +++ b/scripts/release_scripts/repo_specific_changes_fetcher.py @@ -24,14 +24,10 @@ import os import re +from core import utils +from scripts import common from typing import Dict, Final, List, Optional -# TODO(#15567): The order can be fixed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. -from scripts import common # isort:skip # pylint: disable=wrong-import-position -from core import utils # isort:skip # pylint: disable=wrong-import-position - GIT_CMD_DIFF_NAMES_ONLY_FORMAT_STRING: Final = 'git diff --name-only %s %s' GIT_CMD_SHOW_FORMAT_STRING: Final = 'git show %s:core/feconf.py' VERSION_RE_FORMAT_STRING: Final = r'%s\s*=\s*(\d+|\.)+' diff --git a/scripts/run_e2e_tests.py b/scripts/run_e2e_tests.py index 375e9ccf4ee1..6a86a58d05da 100644 --- a/scripts/run_e2e_tests.py +++ b/scripts/run_e2e_tests.py @@ -22,18 +22,13 @@ import subprocess import sys +from core.constants import constants +from scripts import build +from scripts import common +from scripts import install_third_party_libs +from scripts import servers from typing import Final, List, Optional, Tuple -# TODO(#15567): This can be removed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. -from scripts import common # isort:skip pylint: disable=wrong-import-position, unused-import - -from core.constants import constants # isort:skip -from scripts import build # isort:skip -from scripts import install_third_party_libs # isort:skip -from scripts import servers # isort:skip - MAX_RETRY_COUNT: Final = 3 _PARSER: Final = argparse.ArgumentParser( diff --git a/scripts/run_frontend_tests.py b/scripts/run_frontend_tests.py index ab91b5b2f442..32bc36671b8a 100644 --- a/scripts/run_frontend_tests.py +++ b/scripts/run_frontend_tests.py @@ -21,17 +21,13 @@ import subprocess import sys -# TODO(#15567): This can be removed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. -from scripts import common # isort:skip pylint: disable=wrong-import-position, unused-import -from scripts import git_changes_utils # isort:skip pylint: disable=wrong-import-position, unused-import +from scripts import common +from scripts import git_changes_utils +from typing import Optional, Sequence, Set -from typing import Optional, Sequence, Set # isort:skip - -from . import build # isort:skip -from . import check_frontend_test_coverage # isort:skip -from . import install_third_party_libs # isort:skip +from . import build +from . import check_frontend_test_coverage +from . import install_third_party_libs # These is a relative path from the oppia/ folder. They are relative because the # dtslint command prepends the current working directory to the path, even if diff --git a/scripts/run_lighthouse_tests.py b/scripts/run_lighthouse_tests.py index 61a1831abc96..13d4457804b5 100644 --- a/scripts/run_lighthouse_tests.py +++ b/scripts/run_lighthouse_tests.py @@ -25,18 +25,13 @@ import subprocess import sys +from core import feconf +from core.constants import constants +from scripts import build +from scripts import common +from scripts import servers from typing import Final, List, Optional -# TODO(#15567): This can be removed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. -from scripts import common # isort:skip pylint: disable=wrong-import-position - -from core import feconf # isort:skip -from core.constants import constants # isort:skip -from scripts import build # isort:skip -from scripts import servers # isort:skip - LIGHTHOUSE_MODE_PERFORMANCE: Final = 'performance' LIGHTHOUSE_MODE_ACCESSIBILITY: Final = 'accessibility' SERVER_MODE_PROD: Final = 'dev' diff --git a/scripts/run_portserver.py b/scripts/run_portserver.py index dbf41972be92..1908d537b500 100644 --- a/scripts/run_portserver.py +++ b/scripts/run_portserver.py @@ -57,15 +57,9 @@ import sys import threading +from core import utils from typing import Callable, Deque, Final, List, Optional, Sequence -# TODO(#15567): This can be removed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. -from scripts import common # isort:skip pylint: disable=wrong-import-position, unused-import - -from core import utils # isort:skip - _PROTOCOLS: Final = [ (socket.SOCK_STREAM, socket.IPPROTO_TCP), (socket.SOCK_DGRAM, socket.IPPROTO_UDP) diff --git a/scripts/run_typescript_checks.py b/scripts/run_typescript_checks.py index 3faed844dc3a..ed1fa708669b 100644 --- a/scripts/run_typescript_checks.py +++ b/scripts/run_typescript_checks.py @@ -23,18 +23,12 @@ import subprocess import sys +from core import utils +from scripts import common from typing import List, Optional, Sequence +import yaml -# TODO(#15567): This can be removed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. -from scripts import common # isort:skip pylint: disable=wrong-import-position, unused-import -from . import build # isort:skip pylint: disable=wrong-import-position, wrong-import-order - -from core import utils # isort:skip - -import yaml # isort:skip - +from . import build # Contains the name of all files that are not strictly typed. # This list must be kept up-to-date; the changes (only remove) should be done diff --git a/scripts/setup.py b/scripts/setup.py index ae71f3bf7226..ed38f00f842c 100644 --- a/scripts/setup.py +++ b/scripts/setup.py @@ -50,8 +50,8 @@ def create_directory(directory_path: str) -> None: # if it does not match the expected prefix. def test_python_version() -> None: running_python_version = '{0[0]}.{0[1]}.{0[2]}'.format(sys.version_info) - if running_python_version != '3.8.15': - print('Please use Python 3.8.15. Exiting...') + if running_python_version != '3.9.20': + print('Please use Python 3.9.20. Exiting...') # If OS is Windows, print helpful error message about adding Python to # path. if common.is_windows_os(): diff --git a/scripts/setup_test.py b/scripts/setup_test.py index 806164737e66..0094540fac55 100644 --- a/scripts/setup_test.py +++ b/scripts/setup_test.py @@ -122,8 +122,8 @@ def mock_get(unused_var: str) -> None: self.cd_swap = self.swap(common, 'CD', MockCD) version_info = collections.namedtuple( 'version_info', ['major', 'minor', 'micro']) - self.version_info_py38_swap = self.swap( - sys, 'version_info', version_info(major=3, minor=8, micro=15) + self.version_info_py39_swap = self.swap( + sys, 'version_info', version_info(major=3, minor=9, micro=20) ) self.python2_print_swap = self.swap_with_checks( builtins, @@ -161,7 +161,7 @@ def mock_makedirs(unused_path: str) -> None: self.assertFalse(check_function_calls['makedirs_is_called']) def test_python_version_testing_with_correct_version(self) -> None: - with self.version_info_py38_swap: + with self.version_info_py39_swap: setup.test_python_version() def test_python_version_testing_with_incorrect_version_and_linux_os( @@ -224,7 +224,7 @@ def mock_print(msg_list: List[str]) -> None: def test_python_version_testing_with_python2_wrong_code(self) -> None: check_call_swap = self.swap_to_always_return(subprocess, 'call', 1) - with self.python2_print_swap, self.version_info_py38_swap: + with self.python2_print_swap, self.version_info_py39_swap: with check_call_swap, self.assertRaisesRegex(SystemExit, '1'): setup.test_python_version() diff --git a/scripts/third_party_size_check.py b/scripts/third_party_size_check.py index f7c7f6265bf3..9cf12da35990 100644 --- a/scripts/third_party_size_check.py +++ b/scripts/third_party_size_check.py @@ -25,14 +25,8 @@ import os import sys -# TODO(#15567): This can be removed after Literal in utils.py is loaded -# from typing instead of typing_extensions, this will be possible after -# we migrate to Python 3.8. -from scripts import common # isort:skip pylint: disable=wrong-import-position, unused-import - -from core import utils # isort:skip - -from typing import List # isort:skip +from core import utils +from typing import List THIRD_PARTY_PATH = os.path.join(os.getcwd(), 'third_party') THIRD_PARTY_SIZE_LIMIT = 15000 diff --git a/stubs/threading/__init__.pyi b/stubs/threading/__init__.pyi index 8ec4a97e6deb..9e9f79f3fe39 100644 --- a/stubs/threading/__init__.pyi +++ b/stubs/threading/__init__.pyi @@ -80,13 +80,9 @@ class Thread: def start(self) -> None: ... def run(self) -> None: ... def join(self, timeout: Optional[float] = ...) -> None: ... - if sys.version_info >= (3, 8): - @property - def native_id(self) -> Optional[int]: ... # only available on some platforms - + @property + def native_id(self) -> Optional[int]: ... # only available on some platforms def is_alive(self) -> bool: ... - if sys.version_info < (3, 9): - def isAlive(self) -> bool: ... class _DummyThread(Thread): def __init__(self) -> None: ...