jenkins-bot has submitted this change. (
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1361157?usp=email )
Change subject: tests: enable TypeChecking linter and update affected codes
......................................................................
tests: enable TypeChecking linter and update affected codes
Checks for unquoted type expressions in typing.cast() calls:
This rule enforces consistent quoting of type expressions passed to
cast(). Quoting is often necessary for forward references or symbols
imported only in typing.TYPE_CHECKING blocks. It also avoids repeated
evaluation of complex type expressions at runtime, which can be
beneficial in hot loops.
Checks for imports that are only used for type annotations:
Imports used only for type annotations can add runtime overhead and
contribute to import cycles. Use if TYPE_CHECKING: to avoid importing
them at runtime.
Change-Id: Ie8dd6f071f2b06c983765dc3c183782461d6d803
---
M pyproject.toml
M pywikibot/__init__.py
M pywikibot/_wbtypes.py
M pywikibot/backports.py
M pywikibot/bot_choice.py
M pywikibot/comms/eventstreams.py
M pywikibot/config.py
M pywikibot/cosmetic_changes.py
M pywikibot/data/api/_generators.py
M pywikibot/data/api/_optionset.py
M pywikibot/data/citoid.py
M pywikibot/data/sparql.py
M pywikibot/date.py
M pywikibot/diff.py
M pywikibot/editor.py
M pywikibot/family.py
M pywikibot/logentries.py
M pywikibot/logging.py
M pywikibot/login.py
M pywikibot/page/_basepage.py
M pywikibot/page/_category.py
M pywikibot/page/_filepage.py
M pywikibot/page/_user.py
M pywikibot/pagegenerators/__init__.py
M pywikibot/pagegenerators/_factory.py
M pywikibot/pagegenerators/_filters.py
M pywikibot/pagegenerators/_generators.py
M pywikibot/proofreadpage.py
M pywikibot/scripts/generate_user_files.py
M pywikibot/site/_apisite.py
M pywikibot/site/_datasite.py
M pywikibot/site/_extensions.py
M pywikibot/site/_generators.py
M pywikibot/site/_siteinfo.py
M pywikibot/specialbots/_upload.py
M pywikibot/tools/__init__.py
M pywikibot/tools/chars.py
M pywikibot/tools/djvu.py
M pywikibot/tools/itertools.py
M pywikibot/userinterfaces/buffer_interface.py
M pywikibot/userinterfaces/terminal_interface_base.py
M pywikibot/xmlreader.py
M scripts/add_text.py
M scripts/category.py
M scripts/checkimages.py
M scripts/harvest_template.py
M scripts/interwiki.py
M scripts/misspelling.py
M scripts/pagefromfile.py
M scripts/patrol.py
M scripts/redirect.py
M scripts/revertbot.py
M scripts/solve_disambiguation.py
M scripts/templatecount.py
M scripts/welcome.py
M tests/hooks/copyright_fixer.py
M tests/script_tests.py
M tests/utils.py
58 files changed, 252 insertions(+), 97 deletions(-)
Approvals:
jenkins-bot: Verified
Mahveotm: Looks good to me, approved
diff --git a/pyproject.toml b/pyproject.toml
index 9f78143..7ea8932 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -201,7 +201,7 @@
[tool.ruff.lint]
-select = ["C4", "COM818", "COM819", "D", "Q", "RSE"]
+select = ["C4", "COM818", "COM819", "D", "Q", "RSE", "TC"]
ignore = ["D105", "D211", "D213", "D214", "D301", "D401", "D404", "D406",
"D407", "D412", "D413", "D416", "D417"]
[tool.ruff.lint.per-file-ignores]
diff --git a/pywikibot/__init__.py b/pywikibot/__init__.py
index 67f083a..faa2796 100644
--- a/pywikibot/__init__.py
+++ b/pywikibot/__init__.py
@@ -12,7 +12,6 @@
import sys
import threading
import warnings
-from collections.abc import Callable
from contextlib import suppress
from functools import cache
from queue import Queue
@@ -70,6 +69,8 @@
if TYPE_CHECKING:
+ from collections.abc import Callable
+
from pywikibot.site import APISite
if PYTHON_VERSION >= (3, 13):
@@ -244,7 +245,7 @@
if not isinstance(fam, Family):
fam = Family.load(fam)
- fam = cast(Family, fam)
+ fam = cast('Family', fam)
interface = interface or fam.interface(code)
# config.usernames is initialised with a defaultdict for each family name
@@ -261,7 +262,7 @@
if not isinstance(interface, type):
# If it isn't a class, assume it is a string
- interface = cast(str, interface)
+ interface = cast('str', interface)
try:
tmp = __import__('pywikibot.site', fromlist=[interface])
except ImportError:
diff --git a/pywikibot/_wbtypes.py b/pywikibot/_wbtypes.py
index 9efd083..818748f 100644
--- a/pywikibot/_wbtypes.py
+++ b/pywikibot/_wbtypes.py
@@ -534,7 +534,7 @@
and precision in self.PRECISION.values()):
prec = precision
elif isinstance(precision, str) and precision in self.PRECISION:
- prec = self.PRECISION[cast(str, precision)]
+ prec = self.PRECISION[cast('str', precision)]
else:
raise ValueError(f'Invalid precision: "{precision}"')
diff --git a/pywikibot/backports.py b/pywikibot/backports.py
index 91a708d..bbbeb96 100644
--- a/pywikibot/backports.py
+++ b/pywikibot/backports.py
@@ -313,4 +313,6 @@
return Union[other, self]
else:
- from builtins import sentinel # type: ignore[no-redef, attr-defined]
+ from builtins import ( # type: ignore[no-redef, attr-defined] # noqa:
TC003, E501
+ sentinel,
+ )
diff --git a/pywikibot/bot_choice.py b/pywikibot/bot_choice.py
index 46ca97b..463ad1e 100644
--- a/pywikibot/bot_choice.py
+++ b/pywikibot/bot_choice.py
@@ -8,7 +8,6 @@
import re
from abc import ABC, abstractmethod
-from collections.abc import Iterable, Mapping, Sequence
from textwrap import fill
from typing import TYPE_CHECKING
@@ -39,6 +38,7 @@
if TYPE_CHECKING:
+ from collections.abc import Iterable, Mapping, Sequence
from typing import Any, Literal
from pywikibot.page import BaseLink, Link, Page
diff --git a/pywikibot/comms/eventstreams.py b/pywikibot/comms/eventstreams.py
index 93af5ad..d331896 100644
--- a/pywikibot/comms/eventstreams.py
+++ b/pywikibot/comms/eventstreams.py
@@ -21,18 +21,21 @@
from datetime import timedelta
from functools import partial
from types import NoneType
-from typing import Any
+from typing import TYPE_CHECKING, Any
from requests.packages.urllib3.exceptions import ProtocolError
from requests.packages.urllib3.util.response import httplib
from pywikibot import Site, Timestamp, config, debug, warning
from pywikibot.comms.http import user_agent
-from pywikibot.site import BaseSite
from pywikibot.tools import cached, deprecated_args
from pywikibot.tools.collections import GeneratorWrapper
+if TYPE_CHECKING:
+ from pywikibot.site import BaseSite
+
+
try:
from requests_sse import EventSource
except ModuleNotFoundError as e:
diff --git a/pywikibot/config.py b/pywikibot/config.py
index c5e2f09..7f10d0e 100644
--- a/pywikibot/config.py
+++ b/pywikibot/config.py
@@ -52,7 +52,6 @@
import stat
import sys
import types
-from collections.abc import Mapping
from locale import getlocale
from os import environ, getenv
from pathlib import Path
@@ -66,6 +65,7 @@
if TYPE_CHECKING:
+ from collections.abc import Mapping
_DabComDict = collections.defaultdict[str, dict[str, str]]
_ValueType = TypeVar('_ValueType')
diff --git a/pywikibot/cosmetic_changes.py b/pywikibot/cosmetic_changes.py
index 4242ad0..fb8dc89 100644
--- a/pywikibot/cosmetic_changes.py
+++ b/pywikibot/cosmetic_changes.py
@@ -57,10 +57,9 @@
from __future__ import annotations
import re
-from collections.abc import Callable
from contextlib import suppress
from enum import IntEnum
-from typing import Any, cast
+from typing import TYPE_CHECKING, Any, cast
from urllib.parse import urlparse, urlunparse
import pywikibot
@@ -71,6 +70,10 @@
from pywikibot.userinterfaces.transliteration import NON_ASCII_DIGITS
+if TYPE_CHECKING:
+ from collections.abc import Callable
+
+
try:
import stdnum.isbn as stdnum_isbn
except ImportError:
@@ -522,7 +525,7 @@
replaced = '|'.join(cache.get(p.strip(), p) for p in parts)
# extract namespace
- m = cast(re.Match[str],
+ m = cast('re.Match[str]',
re.match(r'\[\[\s*(?P<namespace>[^:]+)\s*:', linktext))
return f'[[{m["namespace"]}:{match["filename"]}{replaced}]]'
diff --git a/pywikibot/data/api/_generators.py
b/pywikibot/data/api/_generators.py
index 4fb0a31..7ff9221 100644
--- a/pywikibot/data/api/_generators.py
+++ b/pywikibot/data/api/_generators.py
@@ -12,9 +12,8 @@
from __future__ import annotations
from abc import ABC, abstractmethod
-from collections.abc import Callable, Iterable
from contextlib import suppress
-from typing import Any, cast
+from typing import TYPE_CHECKING, Any, cast
from warnings import warn
import pywikibot
@@ -29,6 +28,10 @@
from pywikibot.tools.collections import GeneratorWrapper
+if TYPE_CHECKING:
+ from collections.abc import Callable, Iterable
+
+
__all__ = (
'APIGenerator',
'ListGenerator',
@@ -527,7 +530,7 @@
# mypy cannot infer that support_namespace() guarantees
# self.limited_module is not None; therefore use cast here.
param = self.site._paraminfo.parameter(
- 'query+' + cast(str, self.limited_module),
+ 'query+' + cast('str', self.limited_module),
'namespace'
)
if isinstance(namespaces, str):
diff --git a/pywikibot/data/api/_optionset.py b/pywikibot/data/api/_optionset.py
index 600638a..ccf53cc 100644
--- a/pywikibot/data/api/_optionset.py
+++ b/pywikibot/data/api/_optionset.py
@@ -7,8 +7,11 @@
from __future__ import annotations
from collections.abc import MutableMapping
+from typing import TYPE_CHECKING
-import pywikibot
+
+if TYPE_CHECKING:
+ import pywikibot
__all__ = ['OptionSet']
diff --git a/pywikibot/data/citoid.py b/pywikibot/data/citoid.py
index 99afefc..3602924 100644
--- a/pywikibot/data/citoid.py
+++ b/pywikibot/data/citoid.py
@@ -11,11 +11,14 @@
import urllib.parse
from dataclasses import dataclass
-from typing import Any
+from typing import TYPE_CHECKING, Any
from pywikibot.comms import http
from pywikibot.exceptions import ApiNotAvailableError, CitoidError
-from pywikibot.site import BaseSite
+
+
+if TYPE_CHECKING:
+ from pywikibot.site import BaseSite
VALID_FORMAT = [
diff --git a/pywikibot/data/sparql.py b/pywikibot/data/sparql.py
index 1f8a494..1137daf 100644
--- a/pywikibot/data/sparql.py
+++ b/pywikibot/data/sparql.py
@@ -156,7 +156,7 @@
url = endpoint._replace(query=query_string).geturl()
while True:
try:
- self.last_response = cast(Response,
+ self.last_response = cast('Response',
http.fetch(url, headers=headers))
except Timeout:
pass
diff --git a/pywikibot/date.py b/pywikibot/date.py
index b974576..46693f0 100644
--- a/pywikibot/date.py
+++ b/pywikibot/date.py
@@ -17,13 +17,14 @@
from typing import TYPE_CHECKING, Any
from pywikibot import Site
-from pywikibot.site import BaseSite
from pywikibot.tools import first_lower, first_upper
from pywikibot.userinterfaces.transliteration import NON_ASCII_DIGITS
if TYPE_CHECKING:
from typing import Union
+
+ from pywikibot.site import BaseSite
tuplst_type = list[tuple[Callable[[Union[int, str]], Any],
Callable[[Union[int, str]], bool]]]
encf_type = Callable[[int], Union[int, Sequence[int]]]
diff --git a/pywikibot/diff.py b/pywikibot/diff.py
index ede0860..0bc5edd 100644
--- a/pywikibot/diff.py
+++ b/pywikibot/diff.py
@@ -9,16 +9,20 @@
import difflib
import math
from collections import abc
-from collections.abc import Iterable, Sequence
from difflib import SequenceMatcher
from difflib import _format_range_unified # type: ignore[attr-defined]
from heapq import nlargest
from itertools import zip_longest
+from typing import TYPE_CHECKING
import pywikibot
from pywikibot.tools import chars, deprecated_signature
+if TYPE_CHECKING:
+ from collections.abc import Iterable, Sequence
+
+
__all__ = [
'Hunk',
'PatchManager', 'cherry_pick',
diff --git a/pywikibot/editor.py b/pywikibot/editor.py
index fe656e2..75d5feb 100644
--- a/pywikibot/editor.py
+++ b/pywikibot/editor.py
@@ -15,16 +15,19 @@
import subprocess
import sys
import tempfile
-from collections.abc import Sequence
from pathlib import Path
from sys import platform
from textwrap import fill
-from typing import Protocol, cast, no_type_check
+from typing import TYPE_CHECKING, Protocol, cast, no_type_check
import pywikibot
from pywikibot import config
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+
try:
from pywikibot.userinterfaces import gui # noqa: F401
GUI_ERROR = None
@@ -157,7 +160,7 @@
' separately on your platform.') + '\n')
assert pywikibot.ui is not None
- return cast(EditableUI, pywikibot.ui).editText(
+ return cast('EditableUI', pywikibot.ui).editText(
text, jumpIndex=jumpIndex, highlight=highlight)
@staticmethod
diff --git a/pywikibot/family.py b/pywikibot/family.py
index b5613ae..74e2f47 100644
--- a/pywikibot/family.py
+++ b/pywikibot/family.py
@@ -14,7 +14,6 @@
import types
import urllib.parse as urlparse
import warnings
-from collections.abc import Mapping, Sequence
from importlib import import_module
from itertools import chain
from os.path import basename, dirname, splitext
@@ -31,6 +30,7 @@
logger = logging.getLogger('pywiki.wiki.family')
if TYPE_CHECKING:
+ from collections.abc import Mapping, Sequence
CrossnamespaceType = collections.defaultdict[str, dict[str, list[int]]]
# Legal characters for Family.name and Family.langs keys
diff --git a/pywikibot/logentries.py b/pywikibot/logentries.py
index 9a4c230..c83b264 100644
--- a/pywikibot/logentries.py
+++ b/pywikibot/logentries.py
@@ -6,15 +6,18 @@
"""Objects representing MediaWiki log entries."""
from __future__ import annotations
-import datetime
from collections import UserDict
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pywikibot
from pywikibot.exceptions import Error, HiddenKeyError
from pywikibot.tools import cached
+if TYPE_CHECKING:
+ import datetime
+
+
class LogEntry(UserDict):
"""Generic log entry.
diff --git a/pywikibot/logging.py b/pywikibot/logging.py
index 17ceb80..bcc4798 100644
--- a/pywikibot/logging.py
+++ b/pywikibot/logging.py
@@ -42,11 +42,14 @@
import logging
import os
import sys
-from collections.abc import Callable
# logging levels
from logging import CRITICAL, DEBUG, ERROR, INFO, WARNING
-from typing import Any
+from typing import TYPE_CHECKING, Any
+
+
+if TYPE_CHECKING:
+ from collections.abc import Callable
STDOUT = 16 #:
diff --git a/pywikibot/login.py b/pywikibot/login.py
index 6ae3747..5e58ffa 100644
--- a/pywikibot/login.py
+++ b/pywikibot/login.py
@@ -98,7 +98,7 @@
:raises pywikibot.exceptions.NoUsernameError: No username is
configured for the requested site.
"""
- site = cast(pywikibot.site.APISite, site or pywikibot.Site())
+ site = cast('pywikibot.site.APISite', site or pywikibot.Site())
if not user:
config_names = config.usernames
diff --git a/pywikibot/page/_basepage.py b/pywikibot/page/_basepage.py
index 0078684..ba160cd 100644
--- a/pywikibot/page/_basepage.py
+++ b/pywikibot/page/_basepage.py
@@ -9,7 +9,6 @@
import itertools
import re
from collections import Counter
-from collections.abc import Generator, Iterable
from contextlib import suppress
from itertools import islice
from textwrap import shorten, wrap
@@ -48,6 +47,7 @@
if TYPE_CHECKING:
+ from collections.abc import Generator, Iterable
from typing import Any, Literal, NoReturn
from pywikibot.page import Revision
diff --git a/pywikibot/page/_category.py b/pywikibot/page/_category.py
index 8422500..b43a114 100644
--- a/pywikibot/page/_category.py
+++ b/pywikibot/page/_category.py
@@ -7,13 +7,16 @@
from __future__ import annotations
from collections import defaultdict
-from collections.abc import Generator
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pywikibot
from pywikibot.page._page import Page
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
__all__ = ('Category', )
diff --git a/pywikibot/page/_filepage.py b/pywikibot/page/_filepage.py
index 5dfd7b5b..94e2155 100644
--- a/pywikibot/page/_filepage.py
+++ b/pywikibot/page/_filepage.py
@@ -12,10 +12,10 @@
"""
from __future__ import annotations
-from collections.abc import Iterable
from http import HTTPStatus
from os import PathLike
from pathlib import Path
+from typing import TYPE_CHECKING
from urllib.parse import urlparse
import pywikibot
@@ -25,6 +25,10 @@
from pywikibot.tools import compute_file_hash
+if TYPE_CHECKING:
+ from collections.abc import Iterable
+
+
__all__ = (
'FileInfo',
'FilePage',
diff --git a/pywikibot/page/_user.py b/pywikibot/page/_user.py
index 3d838e0..cef46ed 100644
--- a/pywikibot/page/_user.py
+++ b/pywikibot/page/_user.py
@@ -6,8 +6,7 @@
"""Object representing a Wiki user."""
from __future__ import annotations
-from collections.abc import Generator, Iterable
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pywikibot
from pywikibot.exceptions import (
@@ -26,6 +25,10 @@
from pywikibot.tools.collections import DataRecord
+if TYPE_CHECKING:
+ from collections.abc import Generator, Iterable
+
+
__all__ = ('Contribution', 'User')
diff --git a/pywikibot/pagegenerators/__init__.py
b/pywikibot/pagegenerators/__init__.py
index dcc9d4d..def7264 100644
--- a/pywikibot/pagegenerators/__init__.py
+++ b/pywikibot/pagegenerators/__init__.py
@@ -19,7 +19,6 @@
"""
from __future__ import annotations
-from collections.abc import Callable, Generator, Iterable
from typing import TYPE_CHECKING, Any
import pywikibot
@@ -595,6 +594,7 @@
docuReplacements = {'¶ms;': parameterHelp} # noqa: N816
if TYPE_CHECKING:
+ from collections.abc import Callable, Generator, Iterable
PRELOAD_SITE_TYPE = dict[pywikibot.site.BaseSite,
list[pywikibot.page.Page]]
diff --git a/pywikibot/pagegenerators/_factory.py
b/pywikibot/pagegenerators/_factory.py
index 0ea0450..1920bc1 100644
--- a/pywikibot/pagegenerators/_factory.py
+++ b/pywikibot/pagegenerators/_factory.py
@@ -9,7 +9,6 @@
import itertools
import re
import sys
-from collections.abc import Callable, Iterable, Sequence
from datetime import timedelta
from functools import partial
from itertools import zip_longest
@@ -59,6 +58,7 @@
if TYPE_CHECKING:
+ from collections.abc import Callable, Iterable, Sequence
from typing import Any, Literal, Optional
from pywikibot.site import BaseSite, Namespace
diff --git a/pywikibot/pagegenerators/_filters.py
b/pywikibot/pagegenerators/_filters.py
index 87aa4b6..dcab8ab 100644
--- a/pywikibot/pagegenerators/_filters.py
+++ b/pywikibot/pagegenerators/_filters.py
@@ -8,7 +8,6 @@
import datetime
import re
-from collections.abc import Generator, Iterable, Sequence
from functools import partial
from typing import TYPE_CHECKING, NamedTuple
@@ -21,6 +20,7 @@
if TYPE_CHECKING:
+ from collections.abc import Generator, Iterable, Sequence
from typing import Union
from pywikibot.site import BaseSite, Namespace
diff --git a/pywikibot/pagegenerators/_generators.py
b/pywikibot/pagegenerators/_generators.py
index 3a0338b..3eca383 100644
--- a/pywikibot/pagegenerators/_generators.py
+++ b/pywikibot/pagegenerators/_generators.py
@@ -11,7 +11,6 @@
import re
import typing
from collections import abc
-from collections.abc import Callable, Generator, Iterable, Iterator, Sequence
from functools import partial
from http import HTTPStatus
from typing import TYPE_CHECKING, Any
@@ -31,6 +30,14 @@
if TYPE_CHECKING:
+ from collections.abc import (
+ Callable,
+ Generator,
+ Iterable,
+ Iterator,
+ Sequence,
+ )
+
from pywikibot.site import BaseSite, NamespaceArgType
from pywikibot.site._namespace import SingleNamespaceType
from pywikibot.time import Timestamp
diff --git a/pywikibot/proofreadpage.py b/pywikibot/proofreadpage.py
index 80aa945..741dca4 100644
--- a/pywikibot/proofreadpage.py
+++ b/pywikibot/proofreadpage.py
@@ -20,11 +20,10 @@
import json
import re
import time
-from collections.abc import Callable, Iterable, Sequence
from functools import partial
from http import HTTPStatus
from itertools import pairwise
-from typing import Any
+from typing import TYPE_CHECKING, Any
from urllib.parse import unquote
from weakref import WeakKeyDictionary
@@ -35,10 +34,15 @@
from pywikibot.comms import http
from pywikibot.data.api import ListGenerator, Request
from pywikibot.exceptions import Error, InvalidTitleError, OtherPageSaveError
-from pywikibot.page import PageSourceType
from pywikibot.tools import MediaWikiVersion, cached
+if TYPE_CHECKING:
+ from collections.abc import Callable, Iterable, Sequence
+
+ from pywikibot.page import PageSourceType
+
+
try:
from bs4 import BeautifulSoup
except ImportError as e:
diff --git a/pywikibot/scripts/generate_user_files.py
b/pywikibot/scripts/generate_user_files.py
index 395127a..c03dd1e 100755
--- a/pywikibot/scripts/generate_user_files.py
+++ b/pywikibot/scripts/generate_user_files.py
@@ -22,14 +22,17 @@
import os
import re
-from collections.abc import Callable
from pathlib import Path
from textwrap import fill
-from typing import NamedTuple
+from typing import TYPE_CHECKING, NamedTuple
from pywikibot.scripts import _import_with_no_user_config
+if TYPE_CHECKING:
+ from collections.abc import Callable
+
+
# DISABLED_SECTIONS cannot be copied; variables must be set manually
DISABLED_SECTIONS = {
'USER INTERFACE SETTINGS', # uses sys
diff --git a/pywikibot/site/_apisite.py b/pywikibot/site/_apisite.py
index 3667887..ed772d2 100644
--- a/pywikibot/site/_apisite.py
+++ b/pywikibot/site/_apisite.py
@@ -11,7 +11,6 @@
import time
import webbrowser
from collections import defaultdict
-from collections.abc import Iterable
from contextlib import suppress
from textwrap import fill
from typing import TYPE_CHECKING, Any, Literal, NamedTuple, TypeVar
@@ -84,6 +83,8 @@
if TYPE_CHECKING:
+ from collections.abc import Iterable
+
from pywikibot.page import BasePage
_CompType = int | str | pywikibot.page.Page | pywikibot.page.Revision
diff --git a/pywikibot/site/_datasite.py b/pywikibot/site/_datasite.py
index c48fdf6..36a907c 100644
--- a/pywikibot/site/_datasite.py
+++ b/pywikibot/site/_datasite.py
@@ -9,9 +9,8 @@
import datetime
import json
import uuid
-from collections.abc import Generator, Iterable
from contextlib import suppress
-from typing import Any
+from typing import TYPE_CHECKING, Any
from warnings import warn
import pywikibot
@@ -29,6 +28,10 @@
from pywikibot.tools import merge_unique_dicts
+if TYPE_CHECKING:
+ from collections.abc import Generator, Iterable
+
+
__all__ = ('DataSite', )
diff --git a/pywikibot/site/_extensions.py b/pywikibot/site/_extensions.py
index e2f9dbd..7dd69df 100644
--- a/pywikibot/site/_extensions.py
+++ b/pywikibot/site/_extensions.py
@@ -7,7 +7,6 @@
from __future__ import annotations
import re
-from collections.abc import Generator, Iterable
from ipaddress import ip_network
from typing import TYPE_CHECKING, Any, Protocol
@@ -23,12 +22,14 @@
UnexpectedAPIDataError,
)
from pywikibot.site._decorators import need_extension, need_right
-from pywikibot.site._namespace import NamespaceArgType
from pywikibot.tools import merge_unique_dicts
if TYPE_CHECKING:
+ from collections.abc import Generator, Iterable
+
from pywikibot.site import NamespacesDict
+ from pywikibot.site._namespace import NamespaceArgType
class BaseSiteProtocol(Protocol):
diff --git a/pywikibot/site/_generators.py b/pywikibot/site/_generators.py
index fda0abc..33c0b61 100644
--- a/pywikibot/site/_generators.py
+++ b/pywikibot/site/_generators.py
@@ -9,7 +9,6 @@
import heapq
import itertools
import typing
-from collections.abc import Callable, Generator, Iterable
from contextlib import suppress
from itertools import zip_longest
from typing import Any
@@ -27,7 +26,6 @@
UserRightsError,
)
from pywikibot.site._decorators import need_right
-from pywikibot.site._namespace import NamespaceArgType
from pywikibot.tools import (
deprecated_args,
deprecated_signature,
@@ -38,10 +36,15 @@
if typing.TYPE_CHECKING:
+ from collections.abc import Callable, Generator, Iterable
from datetime import datetime
from pywikibot.data.api import ParamInfo, Request
- from pywikibot.site._namespace import NamespacesDict, SingleNamespaceType
+ from pywikibot.site._namespace import (
+ NamespaceArgType,
+ NamespacesDict,
+ SingleNamespaceType,
+ )
from pywikibot.site._tokenwallet import TokenWallet
from pywikibot.tools import MediaWikiVersion
diff --git a/pywikibot/site/_siteinfo.py b/pywikibot/site/_siteinfo.py
index 1d085bd..4f3dadf 100644
--- a/pywikibot/site/_siteinfo.py
+++ b/pywikibot/site/_siteinfo.py
@@ -95,22 +95,22 @@
# query this method to actually get the version number
if prop == 'general':
- data = cast(dict[str, Any], data)
+ data = cast('dict[str, Any]', data)
for key in 'thumblimits', 'imagelimits':
data[key] = list(data[key].values())
data['magiclinks'] = [k for k, v in data['magiclinks'].items()
if v]
elif prop == 'namespaces':
- data = cast(dict[str, Any], data)
+ data = cast('dict[str, Any]', data)
for ns_info in data.values():
ns_info['*'] = ns_info['name']
elif prop in ('languages', 'namespacealiases'):
- data = cast(list[dict[str, Any]], data)
+ data = cast('list[dict[str, Any]]', data)
for ns_info in data:
key = 'name' if 'name' in ns_info else 'alias'
ns_info['*'] = ns_info[key]
elif prop == 'skins':
- data = cast(list[dict[str, Any]], data)
+ data = cast('list[dict[str, Any]]', data)
for ns_info in data:
ns_info['*'] = ns_info['name']
for key in 'default', 'unusable':
diff --git a/pywikibot/specialbots/_upload.py b/pywikibot/specialbots/_upload.py
index 7dc3735..370ff3d 100644
--- a/pywikibot/specialbots/_upload.py
+++ b/pywikibot/specialbots/_upload.py
@@ -11,10 +11,10 @@
import os
import tempfile
-from collections.abc import Callable
from contextlib import suppress
from http import HTTPStatus
from pathlib import Path
+from typing import TYPE_CHECKING
from urllib.parse import urlparse
import requests
@@ -26,6 +26,10 @@
from pywikibot.exceptions import APIError, FatalServerError, NoPageError
+if TYPE_CHECKING:
+ from collections.abc import Callable
+
+
class UploadRobot(BaseBot):
"""Upload bot."""
diff --git a/pywikibot/tools/__init__.py b/pywikibot/tools/__init__.py
index dcf271c..ee8cf87 100644
--- a/pywikibot/tools/__init__.py
+++ b/pywikibot/tools/__init__.py
@@ -17,12 +17,10 @@
import stat
import subprocess
import sys
-from collections.abc import Callable
from contextlib import suppress
from functools import total_ordering, wraps
from pathlib import Path
-from types import TracebackType
-from typing import IO, Any, Literal
+from typing import IO, TYPE_CHECKING, Any, Literal
from warnings import catch_warnings, showwarning, warn
import packaging.version
@@ -45,6 +43,11 @@
from pywikibot.tools._unidata import _first_upper_exception
+if TYPE_CHECKING:
+ from collections.abc import Callable
+ from types import TracebackType
+
+
try: # Python 3.14+
from compression import bz2, gzip, lzma
except ModuleNotFoundError:
diff --git a/pywikibot/tools/chars.py b/pywikibot/tools/chars.py
index c49d8a4..6a4be54 100644
--- a/pywikibot/tools/chars.py
+++ b/pywikibot/tools/chars.py
@@ -7,14 +7,17 @@
from __future__ import annotations
import re
-from collections.abc import Iterable
from contextlib import suppress
-from typing import cast
+from typing import TYPE_CHECKING, cast
from urllib.parse import unquote
from pywikibot.tools._unidata import _category_cf
+if TYPE_CHECKING:
+ from collections.abc import Iterable
+
+
# This is a set of all invisible characters
# At the moment we've only added the characters from the Cf category
_invisible_chars = _category_cf
@@ -135,4 +138,4 @@
first_exception = e
# Couldn't convert, raise the first exception
- raise cast(BaseException, first_exception)
+ raise cast('BaseException', first_exception)
diff --git a/pywikibot/tools/djvu.py b/pywikibot/tools/djvu.py
index f9cfd73..d7672b4 100644
--- a/pywikibot/tools/djvu.py
+++ b/pywikibot/tools/djvu.py
@@ -10,11 +10,15 @@
import re
import subprocess
from collections import Counter
-from collections.abc import Sequence
+from typing import TYPE_CHECKING
import pywikibot
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+
def _call_cmd(args: str | Sequence[str],
lib: str = 'djvulibre') -> tuple[bool, str]:
"""Tiny wrapper around subprocess.Popen().
diff --git a/pywikibot/tools/itertools.py b/pywikibot/tools/itertools.py
index 1270bff..25d02be 100644
--- a/pywikibot/tools/itertools.py
+++ b/pywikibot/tools/itertools.py
@@ -9,13 +9,22 @@
import collections
import heapq
import itertools
-from collections.abc import Callable, Generator, Hashable, Iterable, Iterator
from contextlib import suppress
-from typing import Any
+from typing import TYPE_CHECKING, Any
from pywikibot.logging import debug
+if TYPE_CHECKING:
+ from collections.abc import (
+ Callable,
+ Generator,
+ Hashable,
+ Iterable,
+ Iterator,
+ )
+
+
__all__ = (
'filter_unique',
'intersect_generators',
diff --git a/pywikibot/userinterfaces/buffer_interface.py
b/pywikibot/userinterfaces/buffer_interface.py
index 3de6098..af7285f 100644
--- a/pywikibot/userinterfaces/buffer_interface.py
+++ b/pywikibot/userinterfaces/buffer_interface.py
@@ -11,14 +11,17 @@
import logging
import queue
-from collections.abc import Sequence
-from typing import Any
+from typing import TYPE_CHECKING, Any
from pywikibot import config
from pywikibot.logging import INFO, VERBOSE
from pywikibot.userinterfaces._interface_base import ABUIC
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+
class UI(ABUIC):
"""Collects output into an unseen buffer.
diff --git a/pywikibot/userinterfaces/terminal_interface_base.py
b/pywikibot/userinterfaces/terminal_interface_base.py
index 28a8ba6..d1e0f16 100644
--- a/pywikibot/userinterfaces/terminal_interface_base.py
+++ b/pywikibot/userinterfaces/terminal_interface_base.py
@@ -11,8 +11,7 @@
import re
import sys
import threading
-from collections.abc import Iterable, Sequence
-from typing import Any, Literal, NoReturn, TextIO
+from typing import TYPE_CHECKING, Any, Literal, NoReturn, TextIO
import pywikibot
from pywikibot import config
@@ -29,6 +28,10 @@
from pywikibot.userinterfaces._interface_base import ABUIC
+if TYPE_CHECKING:
+ from collections.abc import Iterable, Sequence
+
+
transliterator = transliteration.Transliterator(config.console_encoding)
#: Colors supported by Pywikibot
diff --git a/pywikibot/xmlreader.py b/pywikibot/xmlreader.py
index fbef835..69a5a11 100644
--- a/pywikibot/xmlreader.py
+++ b/pywikibot/xmlreader.py
@@ -19,7 +19,7 @@
import re
from dataclasses import dataclass
-from typing import NamedTuple
+from typing import TYPE_CHECKING, NamedTuple
from xml.etree.ElementTree import Element
@@ -28,11 +28,13 @@
except ImportError:
from xml.etree.ElementTree import ParseError, iterparse
-from collections.abc import Callable, Iterator
-
from pywikibot.tools import open_archive
+if TYPE_CHECKING:
+ from collections.abc import Callable, Iterator
+
+
@dataclass
class XmlEntry:
diff --git a/scripts/add_text.py b/scripts/add_text.py
index add8687..6fe0889 100755
--- a/scripts/add_text.py
+++ b/scripts/add_text.py
@@ -69,14 +69,18 @@
from __future__ import annotations
import re
-from collections.abc import Sequence
from pathlib import Path
+from typing import TYPE_CHECKING
import pywikibot
from pywikibot import pagegenerators, textlib
from pywikibot.bot import AutomaticTWSummaryBot, ExistingPageBot
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+
DEFAULT_ARGS: dict[str, bool | str] = {
'text': '',
'textfile': '',
diff --git a/scripts/category.py b/scripts/category.py
index ac9d451..8ab7bdc 100755
--- a/scripts/category.py
+++ b/scripts/category.py
@@ -163,13 +163,12 @@
import os
import pickle
import re
-from collections.abc import Sequence
from contextlib import suppress
from dataclasses import dataclass, field
from itertools import chain
from operator import methodcaller
from textwrap import fill
-from typing import Union
+from typing import TYPE_CHECKING, Union
import pywikibot
from pywikibot import config, i18n, pagegenerators, textlib
@@ -192,6 +191,10 @@
from pywikibot.tools.itertools import intersect_generators
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+
# This is required for the text that is shown when you run this script
# with the parameter -help.
docuReplacements = {'¶ms;': pagegenerators.parameterHelp} # noqa: N816
diff --git a/scripts/checkimages.py b/scripts/checkimages.py
index c585210..5977188 100755
--- a/scripts/checkimages.py
+++ b/scripts/checkimages.py
@@ -84,8 +84,8 @@
import collections
import re
import time
-from collections.abc import Generator
from itertools import zip_longest
+from typing import TYPE_CHECKING
import pywikibot
from pywikibot import config, i18n
@@ -107,6 +107,10 @@
from pywikibot.site import Namespace
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
try:
from scripts.welcome import get_welcome_text
except ModuleNotFoundError:
diff --git a/scripts/harvest_template.py b/scripts/harvest_template.py
index b8a77e3..d099176 100755
--- a/scripts/harvest_template.py
+++ b/scripts/harvest_template.py
@@ -117,8 +117,7 @@
import re
import signal
import sys
-from collections.abc import Generator
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pywikibot
from pywikibot import WbTime, textlib
@@ -132,6 +131,10 @@
)
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
willstop = False
diff --git a/scripts/interwiki.py b/scripts/interwiki.py
index bc75034..090d1cd 100755
--- a/scripts/interwiki.py
+++ b/scripts/interwiki.py
@@ -359,10 +359,10 @@
import re
import sys
from collections import Counter, defaultdict
-from collections.abc import Iterable
from contextlib import suppress
from pathlib import Path
from textwrap import fill
+from typing import TYPE_CHECKING
import pywikibot
from pywikibot import (
@@ -401,6 +401,10 @@
from pywikibot.tools.collections import SizedKeyCollection
+if TYPE_CHECKING:
+ from collections.abc import Iterable
+
+
docuReplacements = {
'¶ms;': pagegenerators.parameterHelp
}
diff --git a/scripts/misspelling.py b/scripts/misspelling.py
index 999c141..d99d9ee 100755
--- a/scripts/misspelling.py
+++ b/scripts/misspelling.py
@@ -26,13 +26,17 @@
"""
from __future__ import annotations
-from collections.abc import Generator
from itertools import chain
+from typing import TYPE_CHECKING
import pywikibot
from pywikibot import i18n, pagegenerators
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
try:
from scripts.solve_disambiguation import (
DisambiguationRobot as BaseDisambigBot,
diff --git a/scripts/pagefromfile.py b/scripts/pagefromfile.py
index 472c484..ce7a28e 100755
--- a/scripts/pagefromfile.py
+++ b/scripts/pagefromfile.py
@@ -79,8 +79,8 @@
import os
import re
-from collections.abc import Generator
from pathlib import Path
+from typing import TYPE_CHECKING
import pywikibot
from pywikibot import config, i18n
@@ -89,6 +89,10 @@
from pywikibot.tools.collections import GeneratorWrapper
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
CTX_ATTR = '_content_ctx'
diff --git a/scripts/patrol.py b/scripts/patrol.py
index ced9a77..9939154 100755
--- a/scripts/patrol.py
+++ b/scripts/patrol.py
@@ -48,8 +48,8 @@
import time
from collections import defaultdict
-from collections.abc import Container
from contextlib import suppress
+from typing import TYPE_CHECKING
import mwparserfromhell
@@ -59,6 +59,10 @@
from pywikibot.site import Namespace
+if TYPE_CHECKING:
+ from collections.abc import Container
+
+
def verbose_output(string) -> None:
"""Verbose output."""
if pywikibot.config.verbose_output:
diff --git a/scripts/redirect.py b/scripts/redirect.py
index 4cf812e..507b4c0 100755
--- a/scripts/redirect.py
+++ b/scripts/redirect.py
@@ -80,11 +80,10 @@
from __future__ import annotations
import datetime
-from collections.abc import Generator
from contextlib import suppress
from itertools import islice
from textwrap import fill
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pywikibot
import pywikibot.data
@@ -106,6 +105,10 @@
from pywikibot.textlib import extract_templates_and_params_regex_simple
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
BROKEN_REDIRECT_TEMPLATE = 'Q11838699', 'Q4847311', 'Q21528265'
docuReplacements = {'¶ms;': pagegenerators.parameterHelp} # noqa: N816
diff --git a/scripts/revertbot.py b/scripts/revertbot.py
index d919f7a..e8abe4f 100755
--- a/scripts/revertbot.py
+++ b/scripts/revertbot.py
@@ -48,19 +48,23 @@
from __future__ import annotations
import abc
-from collections.abc import Mapping
from textwrap import fill
-from typing import Any
+from typing import TYPE_CHECKING, Any
import pywikibot
from pywikibot import i18n
from pywikibot.bot import OptionHandler
from pywikibot.date import format_date, formatYear
from pywikibot.exceptions import APIError, Error
-from pywikibot.page import Contribution
from pywikibot.tools import deprecated
+if TYPE_CHECKING:
+ from collections.abc import Mapping
+
+ from pywikibot.page import Contribution
+
+
class AbstractRevertBot(OptionHandler, abc.ABC):
"""Abstract RevertBot class.
diff --git a/scripts/solve_disambiguation.py b/scripts/solve_disambiguation.py
index f484a8b..685b4ba 100755
--- a/scripts/solve_disambiguation.py
+++ b/scripts/solve_disambiguation.py
@@ -80,10 +80,10 @@
from __future__ import annotations
import re
-from collections.abc import Generator
from contextlib import suppress
from itertools import chain, islice
from pathlib import Path
+from typing import TYPE_CHECKING
import pywikibot
from pywikibot import config, i18n, pagegenerators
@@ -108,6 +108,10 @@
from pywikibot.tools.formatter import SequenceOutputter
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
# Disambiguation Needed template
dn_template = {
'ar': '{{بحاجة لتوضيح}}',
diff --git a/scripts/templatecount.py b/scripts/templatecount.py
index 34973c1..26721ce 100755
--- a/scripts/templatecount.py
+++ b/scripts/templatecount.py
@@ -38,11 +38,15 @@
"""
from __future__ import annotations
-from collections.abc import Generator
+from typing import TYPE_CHECKING
import pywikibot
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
class TemplateCountRobot:
"""Template count bot."""
diff --git a/scripts/welcome.py b/scripts/welcome.py
index 52efe16..601ad93 100755
--- a/scripts/welcome.py
+++ b/scripts/welcome.py
@@ -182,12 +182,12 @@
import pickle
import re
import time
-from collections.abc import Generator
from contextlib import suppress
from datetime import timedelta
from enum import Enum
from random import choice
from textwrap import fill
+from typing import TYPE_CHECKING
import pywikibot
from pywikibot import config, i18n
@@ -201,6 +201,10 @@
from pywikibot.tools import cached
+if TYPE_CHECKING:
+ from collections.abc import Generator
+
+
locale.setlocale(locale.LC_ALL, '')
# Script uses the method i18n.translate() to find the right
diff --git a/tests/hooks/copyright_fixer.py b/tests/hooks/copyright_fixer.py
index 02c4444..043fa6d 100755
--- a/tests/hooks/copyright_fixer.py
+++ b/tests/hooks/copyright_fixer.py
@@ -13,9 +13,13 @@
import re
import subprocess
import sys
-from collections.abc import Sequence
from datetime import date
from pathlib import Path
+from typing import TYPE_CHECKING
+
+
+if TYPE_CHECKING:
+ from collections.abc import Sequence
PATTERN = re.compile(
diff --git a/tests/script_tests.py b/tests/script_tests.py
index edd27e3..7e514e3 100755
--- a/tests/script_tests.py
+++ b/tests/script_tests.py
@@ -9,9 +9,9 @@
import sys
import unittest
-from collections.abc import Iterator
from contextlib import suppress
from pathlib import Path
+from typing import TYPE_CHECKING
from pywikibot.bot import global_args as pwb_args
from pywikibot.tools import has_module
@@ -20,6 +20,10 @@
from tests.utils import execute_pwb
+if TYPE_CHECKING:
+ from collections.abc import Iterator
+
+
scripts_path = join_root_path('scripts')
# login script should be the first to test
diff --git a/tests/utils.py b/tests/utils.py
index 09bf200..0337c85 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -12,12 +12,11 @@
import tempfile
import unittest
import warnings
-from collections.abc import Sequence
from contextlib import contextmanager, suppress
from pathlib import Path
from platform import python_implementation
from subprocess import PIPE, Popen, TimeoutExpired
-from typing import NoReturn, TypedDict
+from typing import TYPE_CHECKING, NoReturn, TypedDict
import pywikibot
from pywikibot import config
@@ -30,6 +29,10 @@
from tests import _pwb_py
+if TYPE_CHECKING:
+ from collections.abc import Sequence
+
+
OSWIN32 = (sys.platform == 'win32')
--
To view, visit
https://gerrit.wikimedia.org/r/c/pywikibot/core/+/1361157?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.wikimedia.org/r/settings?usp=email
Gerrit-MessageType: merged
Gerrit-Project: pywikibot/core
Gerrit-Branch: master
Gerrit-Change-Id: Ie8dd6f071f2b06c983765dc3c183782461d6d803
Gerrit-Change-Number: 1361157
Gerrit-PatchSet: 4
Gerrit-Owner: Xqt <[email protected]>
Gerrit-Reviewer: Mahveotm <[email protected]>
Gerrit-Reviewer: jenkins-bot
_______________________________________________
Pywikibot-commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]