Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Python 3.13 #9852

Merged
merged 9 commits into from
Aug 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/primer-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
timeout-minutes: 5
strategy:
matrix:
python-version: [3.9, "3.10", "3.11", "3.12"]
python-version: [3.9, "3.10", "3.11", "3.12", "3.13-dev"]
outputs:
python-key: ${{ steps.generate-python-key.outputs.key }}
steps:
Expand Down Expand Up @@ -72,7 +72,7 @@ jobs:
needs: prepare-tests-linux
strategy:
matrix:
python-version: [3.9, "3.10", "3.11", "3.12"]
python-version: [3.9, "3.10", "3.11", "3.12", "3.13-dev"]
steps:
- name: Check out code from GitHub
uses: actions/checkout@v4.1.7
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.9, "3.10", "3.11", "3.12"]
python-version: [3.9, "3.10", "3.11", "3.12", "3.13-dev"]
outputs:
python-key: ${{ steps.generate-python-key.outputs.key }}
steps:
Expand Down Expand Up @@ -175,7 +175,7 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: [3.9, "3.10", "3.11", "3.12"]
python-version: [3.9, "3.10", "3.11", "3.12", "3.13-dev"]
steps:
- name: Set temp directory
run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV
Expand Down
1 change: 1 addition & 0 deletions .pyenchant_pylint_custom_dict.txt
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ paren
parens
passthru
pathlib
patternerror
positionals
png
pragma
Expand Down
3 changes: 3 additions & 0 deletions doc/whatsnew/fragments/9852.other
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Add support for Python 3.13.

Refs #9852
3 changes: 2 additions & 1 deletion pylint/checkers/refactoring/refactoring_checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
(
"_io.open", # regular 'open()' call
"pathlib.Path.open",
"pathlib._local.Path.open", # Python 3.13
"codecs.open",
"urllib.request.urlopen",
"tempfile.NamedTemporaryFile",
Expand Down Expand Up @@ -1691,7 +1692,7 @@ def _check_consider_using_with(self, node: nodes.Call) -> None:
return
inferred = utils.safe_infer(node.func)
if not inferred or not isinstance(
inferred, (nodes.FunctionDef, nodes.ClassDef, bases.UnboundMethod)
inferred, (nodes.FunctionDef, nodes.ClassDef, bases.BoundMethod)
):
return
could_be_used_in_with = (
Expand Down
7 changes: 4 additions & 3 deletions pylint/checkers/stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
ENV_GETTERS = ("os.getenv",)
SUBPROCESS_POPEN = "subprocess.Popen"
SUBPROCESS_RUN = "subprocess.run"
OPEN_MODULE = {"_io", "pathlib"}
OPEN_MODULE = {"_io", "pathlib", "pathlib._local"}
PATHLIB_MODULE = {"pathlib", "pathlib._local"}
DEBUG_BREAKPOINTS = ("builtins.breakpoint", "sys.breakpointhook", "pdb.set_trace")
LRU_CACHE = {
"functools.lru_cache", # Inferred for @lru_cache
Expand Down Expand Up @@ -784,7 +785,7 @@ def _check_open_call(
mode_arg = utils.get_argument_from_call(
node, position=1, keyword="mode"
)
elif open_module == "pathlib":
elif open_module in PATHLIB_MODULE:
mode_arg = utils.get_argument_from_call(
node, position=0, keyword="mode"
)
Expand Down Expand Up @@ -814,7 +815,7 @@ def _check_open_call(
):
confidence = HIGH
try:
if open_module == "pathlib":
if open_module in PATHLIB_MODULE:
if node.func.attrname == "read_text":
encoding_arg = utils.get_argument_from_call(
node, position=0, keyword="encoding"
Expand Down
5 changes: 4 additions & 1 deletion pylint/extensions/docparams.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,9 @@ def visit_raise(self, node: nodes.Raise) -> None:
for found_exc in found_excs_class_names:
if found_exc == expected.name:
break
if found_exc == "error" and expected.name == "PatternError":
# Python 3.13: re.error aliases re.PatternError
break
if any(found_exc == ancestor.name for ancestor in expected.ancestors()):
break
else:
Expand Down Expand Up @@ -653,7 +656,7 @@ def _add_raise_message(
"""Adds a message on :param:`node` for the missing exception type.

:param missing_exceptions: A list of missing exception types.
:param node: The node show the message on.
:param node: The node to show the message on.
"""
if node.is_abstract():
try:
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development :: Debuggers",
Expand All @@ -40,7 +41,7 @@ dependencies = [
# Also upgrade requirements_test_min.txt.
# Pinned to dev of second minor update to allow editable installs and fix primer issues,
# see https://github.com/pylint-dev/astroid/issues/1341
"astroid>=3.3.1,<=3.4.0-dev0",
"astroid>=3.3.2,<=3.4.0-dev0",
"isort>=4.2.5,<6,!=5.13.0",
"mccabe>=0.6,<0.8",
"tomli>=1.1.0;python_version<'3.11'",
Expand Down
2 changes: 1 addition & 1 deletion requirements_test_min.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.[testutils,spelling]
# astroid dependency is also defined in pyproject.toml
astroid==3.3.1 # Pinned to a specific version for tests
astroid==3.3.2 # Pinned to a specific version for tests
typing-extensions~=4.12
py~=1.11.0
pytest~=8.3
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[testoptions]
max_pyver=3.13
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,33 @@ def test_find_google_attr_raises_exact_exc(self):
"""This is a google docstring.

Raises:
re.error: Sometimes
calendar.IllegalMonthError: Sometimes
"""
import re
import calendar

raise re.error("hi")
raise calendar.IllegalMonthError(-1)


def test_find_google_attr_raises_substr_exc(self):
"""This is a google docstring.

Raises:
re.error: Sometimes
calendar.IllegalMonthError: Sometimes
"""
from re import error
from calendar import IllegalMonthError

raise error("hi")
raise IllegalMonthError(-1)


def test_find_valid_missing_google_attr_raises(self): # [missing-raises-doc]
"""This is a google docstring.

Raises:
re.anothererror: Sometimes
calendar.anothererror: Sometimes
"""
from re import error
from calendar import IllegalMonthError

raise error("hi")
raise IllegalMonthError(-1)


def test_find_invalid_missing_google_attr_raises(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
missing-raises-doc:6:0:6:35:test_find_missing_google_raises:"""RuntimeError"" not documented as being raised":HIGH
unreachable:13:4:13:25:test_find_missing_google_raises:Unreachable code:HIGH
missing-raises-doc:38:0:38:46:test_find_valid_missing_google_attr_raises:"""error"" not documented as being raised":HIGH
missing-raises-doc:38:0:38:46:test_find_valid_missing_google_attr_raises:"""IllegalMonthError"" not documented as being raised":HIGH
unreachable:83:4:83:25:test_find_all_google_raises:Unreachable code:HIGH
unreachable:94:4:94:25:test_find_multiple_google_raises:Unreachable code:HIGH
unreachable:95:4:95:30:test_find_multiple_google_raises:Unreachable code:HIGH
Expand Down
18 changes: 9 additions & 9 deletions tests/functional/ext/docparams/raise/missing_raises_doc_Numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,38 +87,38 @@ def test_find_numpy_attr_raises_exact_exc(self):

Raises
------
re.error
calendar.IllegalMonthError
Sometimes
"""
import re
import calendar

raise re.error("hi")
raise calendar.IllegalMonthError(-1)


def test_find_numpy_attr_raises_substr_exc(self):
"""This is a numpy docstring.

Raises
------
re.error
calendar.IllegalMonthError
Sometimes
"""
from re import error
from calendar import IllegalMonthError

raise error("hi")
raise IllegalMonthError(-1)


def test_find_valid_missing_numpy_attr_raises(self): # [missing-raises-doc]
"""This is a numpy docstring.

Raises
------
re.anothererror
calendar.anothererror
Sometimes
"""
from re import error
from calendar import IllegalMonthError

raise error("hi")
raise IllegalMonthError(-1)


def test_find_invalid_missing_numpy_attr_raises(self):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ unreachable:20:4:20:25:test_find_missing_numpy_raises:Unreachable code:HIGH
unreachable:34:4:34:25:test_find_all_numpy_raises:Unreachable code:HIGH
missing-raises-doc:37:0:37:35:test_find_rethrown_numpy_raises:"""RuntimeError"" not documented as being raised":HIGH
missing-raises-doc:53:0:53:44:test_find_rethrown_numpy_multiple_raises:"""RuntimeError, ValueError"" not documented as being raised":HIGH
missing-raises-doc:111:0:111:45:test_find_valid_missing_numpy_attr_raises:"""error"" not documented as being raised":HIGH
missing-raises-doc:111:0:111:45:test_find_valid_missing_numpy_attr_raises:"""IllegalMonthError"" not documented as being raised":HIGH
missing-raises-doc:146:4:146:11:Foo.foo:"""AttributeError"" not documented as being raised":HIGH
unreachable:158:8:158:17:Foo.foo:Unreachable code:HIGH
unreachable:182:8:182:17:Foo.foo:Unreachable code:HIGH
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,33 +123,33 @@ def test_find_sphinx_attr_raises_exact_exc(self):
def test_find_sphinx_attr_raises_substr_exc(self):
"""This is a sphinx docstring.

:raises re.error: Sometimes
:raises calendar.IllegalMonthError: Sometimes
"""
from re import error
from calendar import IllegalMonthError

raise error("hi")
raise IllegalMonthError(-1)


def test_find_valid_missing_sphinx_attr_raises(self): # [missing-raises-doc]
"""This is a sphinx docstring.

:raises re.anothererror: Sometimes
:raises calendar.anothererror: Sometimes
"""
from re import error
from calendar import IllegalMonthError

raise error("hi")
raise IllegalMonthError(-1)


def test_find_invalid_missing_sphinx_attr_raises(self):
"""This is a sphinx docstring.
pylint allows this to pass since the comparison between Raises and
raise are based on the class name, not the qualified name.

:raises bogusmodule.error: Sometimes
:raises bogusmodule.IllegalMonthError: Sometimes
"""
from re import error
from calendar import IllegalMonthError

raise error("hi")
raise IllegalMonthError(-1)


class Foo:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@ missing-raises-doc:90:0:90:55:test_find_missing_sphinx_raises_infer_from_instanc
unreachable:97:4:97:25:test_find_missing_sphinx_raises_infer_from_instance:Unreachable code:HIGH
missing-raises-doc:100:0:100:55:test_find_missing_sphinx_raises_infer_from_function:"""RuntimeError"" not documented as being raised":HIGH
unreachable:110:4:110:25:test_find_missing_sphinx_raises_infer_from_function:Unreachable code:HIGH
missing-raises-doc:133:0:133:46:test_find_valid_missing_sphinx_attr_raises:"""error"" not documented as being raised":HIGH
missing-raises-doc:133:0:133:46:test_find_valid_missing_sphinx_attr_raises:"""IllegalMonthError"" not documented as being raised":HIGH
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
var7: typing.Hashable # [consider-using-alias]
var8: typing.ContextManager[str] # [consider-using-alias]
var9: typing.Pattern[str] # [consider-using-alias]
var10: typing.re.Match[str] # [consider-using-alias]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It didn't seem worth it to extract this into its own test file that runs on 3.12 and below only. Let's conserve energy.

var11: list[int]
var12: collections.abc
var13: Awaitable[None]
Expand Down
23 changes: 11 additions & 12 deletions tests/functional/ext/typing/typing_consider_using_alias.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ consider-using-alias:27:6:27:21::'typing.Iterable' will be deprecated with PY39,
consider-using-alias:28:6:28:21::'typing.Hashable' will be deprecated with PY39, consider using 'collections.abc.Hashable' instead:INFERENCE
consider-using-alias:29:6:29:27::'typing.ContextManager' will be deprecated with PY39, consider using 'contextlib.AbstractContextManager' instead:INFERENCE
consider-using-alias:30:6:30:20::'typing.Pattern' will be deprecated with PY39, consider using 're.Pattern' instead:INFERENCE
consider-using-alias:31:7:31:22::'typing.Match' will be deprecated with PY39, consider using 're.Match' instead:INFERENCE
consider-using-alias:40:9:40:13::'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:42:7:42:11::'typing.Type' will be deprecated with PY39, consider using 'type' instead:INFERENCE
consider-using-alias:43:7:43:12::'typing.Tuple' will be deprecated with PY39, consider using 'tuple' instead:INFERENCE
consider-using-alias:44:7:44:15::'typing.Callable' will be deprecated with PY39, consider using 'collections.abc.Callable' instead:INFERENCE
consider-using-alias:50:74:50:78:func1:'typing.Dict' will be deprecated with PY39, consider using 'dict' instead:INFERENCE
consider-using-alias:50:16:50:20:func1:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:50:37:50:41:func1:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:50:93:50:105:func1:'typing.Tuple' will be deprecated with PY39, consider using 'tuple' instead:INFERENCE
consider-using-alias:66:12:66:16:CustomNamedTuple:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:71:12:71:16:CustomTypedDict2:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:75:12:75:16:CustomDataClass:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:39:9:39:13::'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:41:7:41:11::'typing.Type' will be deprecated with PY39, consider using 'type' instead:INFERENCE
consider-using-alias:42:7:42:12::'typing.Tuple' will be deprecated with PY39, consider using 'tuple' instead:INFERENCE
consider-using-alias:43:7:43:15::'typing.Callable' will be deprecated with PY39, consider using 'collections.abc.Callable' instead:INFERENCE
consider-using-alias:49:74:49:78:func1:'typing.Dict' will be deprecated with PY39, consider using 'dict' instead:INFERENCE
consider-using-alias:49:16:49:20:func1:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:49:37:49:41:func1:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:49:93:49:105:func1:'typing.Tuple' will be deprecated with PY39, consider using 'tuple' instead:INFERENCE
consider-using-alias:65:12:65:16:CustomNamedTuple:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:70:12:70:16:CustomTypedDict2:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:74:12:74:16:CustomDataClass:'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
var7: typing.Hashable # [consider-using-alias]
var8: typing.ContextManager[str] # [consider-using-alias]
var9: typing.Pattern[str] # [consider-using-alias]
var10: typing.re.Match[str] # [consider-using-alias]
var11: list[int]
var12: collections.abc
var13: Awaitable[None]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,14 @@ consider-using-alias:25:6:25:21::'typing.Iterable' will be deprecated with PY39,
consider-using-alias:26:6:26:21::'typing.Hashable' will be deprecated with PY39, consider using 'collections.abc.Hashable' instead:INFERENCE
consider-using-alias:27:6:27:27::'typing.ContextManager' will be deprecated with PY39, consider using 'contextlib.AbstractContextManager' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:28:6:28:20::'typing.Pattern' will be deprecated with PY39, consider using 're.Pattern' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:29:7:29:22::'typing.Match' will be deprecated with PY39, consider using 're.Match' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:38:9:38:13::'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:40:7:40:11::'typing.Type' will be deprecated with PY39, consider using 'type' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:41:7:41:12::'typing.Tuple' will be deprecated with PY39, consider using 'tuple' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:42:7:42:15::'typing.Callable' will be deprecated with PY39, consider using 'collections.abc.Callable' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:48:74:48:78:func1:'typing.Dict' will be deprecated with PY39, consider using 'dict' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:48:16:48:20:func1:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:48:37:48:41:func1:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:48:93:48:105:func1:'typing.Tuple' will be deprecated with PY39, consider using 'tuple' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:64:12:64:16:CustomNamedTuple:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:69:12:69:16:CustomTypedDict2:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:73:12:73:16:CustomDataClass:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:37:9:37:13::'typing.List' will be deprecated with PY39, consider using 'list' instead:INFERENCE
consider-using-alias:39:7:39:11::'typing.Type' will be deprecated with PY39, consider using 'type' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:40:7:40:12::'typing.Tuple' will be deprecated with PY39, consider using 'tuple' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:41:7:41:15::'typing.Callable' will be deprecated with PY39, consider using 'collections.abc.Callable' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:47:74:47:78:func1:'typing.Dict' will be deprecated with PY39, consider using 'dict' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:47:16:47:20:func1:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:47:37:47:41:func1:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:47:93:47:105:func1:'typing.Tuple' will be deprecated with PY39, consider using 'tuple' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:63:12:63:16:CustomNamedTuple:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:68:12:68:16:CustomTypedDict2:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
consider-using-alias:72:12:72:16:CustomDataClass:'typing.List' will be deprecated with PY39, consider using 'list' instead. Add 'from __future__ import annotations' as well:INFERENCE
1 change: 0 additions & 1 deletion tests/functional/ext/typing/typing_deprecated_alias.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
var7: typing.Hashable # [deprecated-typing-alias]
var8: typing.ContextManager[str] # [deprecated-typing-alias]
var9: typing.Pattern[str] # [deprecated-typing-alias]
var10: typing.re.Match[str] # [deprecated-typing-alias]
var11: list[int]
var12: collections.abc
var13: Awaitable[None]
Expand Down
Loading
Loading