Skip to content

Commit

Permalink
Drop Python 3.10 (ipython#14589)
Browse files Browse the repository at this point in the history
  • Loading branch information
Carreau authored Dec 10, 2024
2 parents 92b295a + d0dd9b5 commit f32e1b2
Show file tree
Hide file tree
Showing 16 changed files with 40 additions and 108 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/downstream.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.10"]
python-version: ["3.13"]
include:
- os: macos-13
python-version: "3.10"
python-version: "3.13"

steps:
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/nightly-wheel-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: "3.10"
python-version: "3.13"
cache: pip
cache-dependency-path: |
pyproject.toml
Expand Down
25 changes: 11 additions & 14 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,10 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu-latest, windows-latest]
python-version: ["3.10", "3.11", "3.12","3.13"]
python-version: ["3.11", "3.12","3.13"]
deps: [test_extra]
# Test all on ubuntu, test ends on macos
include:
- os: macos-latest
python-version: "3.10"
deps: test_extra
- os: macos-latest
python-version: "3.11"
deps: test_extra
Expand All @@ -40,15 +37,15 @@ jobs:
python-version: "3.13"
deps: test
# Installing optional dependencies stuff takes ages on PyPy
- os: ubuntu-latest
python-version: "pypy-3.10"
deps: test
- os: windows-latest
python-version: "pypy-3.10"
deps: test
- os: macos-latest
python-version: "pypy-3.10"
deps: test
# - os: ubuntu-latest
# python-version: "pypy-3.11"
# deps: test
# - os: windows-latest
# python-version: "pypy-3.11"
# deps: test
# - os: macos-latest
# python-version: "pypy-3.11"
# deps: test
# Temporary CI run to use entry point compatible code in matplotlib-inline.
- os: ubuntu-latest
python-version: "3.12"
Expand Down Expand Up @@ -88,7 +85,7 @@ jobs:
if: runner.os != 'Windows' # setup.py does not support sdist on Windows
run: check-manifest

- name: Install entry point compatible code (TEMPORARY)
- name: Install entry point compatible code (TEMPORARY, April 2024)
if: matrix.want-latest-entry-point-code
run: |
python -m pip list
Expand Down
3 changes: 2 additions & 1 deletion IPython/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@
#-----------------------------------------------------------------------------

# Don't forget to also update setup.py when this changes!
if sys.version_info < (3, 10):
if sys.version_info < (3, 11):
raise ImportError(
"""
IPython 8.31+ supports Python 3.11 and above, following SPEC0
IPython 8.19+ supports Python 3.10 and above, following SPEC0.
IPython 8.13+ supports Python 3.9 and above, following NEP 29.
IPython 8.0-8.12 supports Python 3.8 and above, following NEP 29.
Expand Down
27 changes: 8 additions & 19 deletions IPython/core/completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,14 @@

import __main__

from typing import cast

if sys.version_info < (3, 12):
from typing_extensions import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard
else:
from typing import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard


# skip module docstests
__skip_doctest__ = True

Expand All @@ -257,25 +265,6 @@
JEDI_INSTALLED = False


if TYPE_CHECKING or GENERATING_DOCUMENTATION and sys.version_info >= (3, 11):
from typing import cast
from typing_extensions import TypedDict, NotRequired, Protocol, TypeAlias, TypeGuard
else:
from typing import Generic

def cast(type_, obj):
"""Workaround for `TypeError: MatcherAPIv2() takes no arguments`"""
return obj

# do not require on runtime
NotRequired = Tuple # requires Python >=3.11
TypedDict = Dict # by extension of `NotRequired` requires 3.11 too
Protocol = object # requires Python >=3.8
TypeAlias = Any # requires Python >=3.10
TypeGuard = Generic # requires Python >=3.10
if GENERATING_DOCUMENTATION:
from typing import TypedDict

# -----------------------------------------------------------------------------
# Globals
#-----------------------------------------------------------------------------
Expand Down
5 changes: 1 addition & 4 deletions IPython/core/guarded_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,7 @@
from IPython.utils.decorators import undoc


if sys.version_info < (3, 11):
from typing_extensions import Self, LiteralString
else:
from typing import Self, LiteralString
from typing import Self, LiteralString

if sys.version_info < (3, 12):
from typing_extensions import TypeAliasType
Expand Down
2 changes: 0 additions & 2 deletions IPython/core/interactiveshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,6 @@ def sphinxify_docstring(docstring):
except ImportError:
sphinxify = None

if sys.version_info[:2] < (3, 11):
from exceptiongroup import BaseExceptionGroup

class ProvisionalWarning(DeprecationWarning):
"""
Expand Down
8 changes: 2 additions & 6 deletions IPython/core/tests/test_exceptiongroup_tb.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ def _exceptiongroup_common(
native: bool,
) -> None:
pre_raise = "exceptiongroup." if not native else ""
pre_catch = pre_raise if sys.version_info < (3, 11) else ""
filestr = f"""
{"import exceptiongroup" if not native else ""}
import pytest
Expand Down Expand Up @@ -42,7 +41,7 @@ def inner(inner_chain):
def outer(outer_chain, inner_chain):
try:
inner(inner_chain)
except {pre_catch}BaseExceptionGroup as e:
except BaseExceptionGroup as e:
if outer_chain == "none":
raise
if outer_chain == "from":
Expand All @@ -68,7 +67,7 @@ def outer(outer_chain, inner_chain):

match_lines += [
" + Exception Group Traceback (most recent call last):",
f" | {pre_catch}BaseExceptionGroup: Oops (2 sub-exceptions)",
" | BaseExceptionGroup: Oops (2 sub-exceptions)",
" | ValueError: From f()",
" | BaseException: From g()",
]
Expand Down Expand Up @@ -96,9 +95,6 @@ def outer(outer_chain, inner_chain):
assert False, f"{expected} not found in cap.stderr"


@pytest.mark.skipif(
sys.version_info < (3, 11), reason="Native ExceptionGroup not implemented"
)
@pytest.mark.parametrize("outer_chain", ["none", "from", "another"])
@pytest.mark.parametrize("inner_chain", ["none", "from", "another"])
def test_native_exceptiongroup(outer_chain, inner_chain) -> None:
Expand Down
5 changes: 1 addition & 4 deletions IPython/core/tests/test_guarded_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
import pytest


if sys.version_info < (3, 11):
from typing_extensions import Self, LiteralString
else:
from typing import Self, LiteralString
from typing import Self, LiteralString

if sys.version_info < (3, 12):
from typing_extensions import TypeAliasType
Expand Down
6 changes: 0 additions & 6 deletions IPython/core/tests/test_inputsplitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,6 @@ def test_unicode(self):
self.isp.push(u'\xc3\xa9')
self.isp.push(u"u'\xc3\xa9'")

@pytest.mark.xfail(
reason="Bug in python 3.9.8 – bpo 45738",
condition=sys.version_info in [(3, 11, 0, "alpha", 2)],
raises=SystemError,
strict=True,
)
def test_line_continuation(self):
""" Test issue #2108."""
isp = self.isp
Expand Down
18 changes: 1 addition & 17 deletions IPython/core/tests/test_inputtransformer2.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,17 +314,7 @@ def __init__(self, s):
pytest.param("\\\r\n", "incomplete", 0),
pytest.param("a = '''\n hi", "incomplete", 3),
pytest.param("def a():\n x=1\n global x", "invalid", None),
pytest.param(
"a \\ ",
"invalid",
None,
marks=pytest.mark.xfail(
reason="Bug in python 3.9.8 – bpo 45738",
condition=sys.version_info in [(3, 11, 0, "alpha", 2)],
raises=SystemError,
strict=True,
),
), # Nothing allowed after backslash,
pytest.param("a \\ ", "invalid", None), # Nothing allowed after backslash,
pytest.param("1\\\n+2", "complete", None),
]

Expand All @@ -336,12 +326,6 @@ def test_check_complete_param(code, expected, number):


@pytest.mark.xfail(platform.python_implementation() == "PyPy", reason="fail on pypy")
@pytest.mark.xfail(
reason="Bug in python 3.9.8 – bpo 45738",
condition=sys.version_info in [(3, 11, 0, "alpha", 2)],
raises=SystemError,
strict=True,
)
def test_check_complete():
cc = ipt2.TransformerManager().check_complete

Expand Down
17 changes: 6 additions & 11 deletions IPython/core/tests/test_magic_arguments.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,9 @@ def foo(self, args):


def test_magic_arguments():
# “optional arguments” was replaced with “options” in argparse help
# https://docs.python.org/3/whatsnew/3.10.html#argparse
# https://bugs.python.org/issue9694
options = "optional arguments" if sys.version_info < (3, 10) else "options"

assert (
magic_foo1.__doc__
== f"::\n\n %foo1 [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n"
== f"::\n\n %foo1 [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\noptions:\n -f FOO, --foo FOO an argument\n"
)
assert getattr(magic_foo1, "argcmd_name", None) == None
assert real_name(magic_foo1) == "foo1"
Expand All @@ -98,7 +93,7 @@ def test_magic_arguments():

assert (
magic_foo3.__doc__
== f"::\n\n %foo3 [-f FOO] [-b BAR] [-z BAZ]\n\n{LEADING_SPACE}A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n\nGroup:\n -b BAR, --bar BAR a grouped argument\n\nSecond Group:\n -z BAZ, --baz BAZ another grouped argument\n"
== f"::\n\n %foo3 [-f FOO] [-b BAR] [-z BAZ]\n\n{LEADING_SPACE}A docstring.\n\noptions:\n -f FOO, --foo FOO an argument\n\nGroup:\n -b BAR, --bar BAR a grouped argument\n\nSecond Group:\n -z BAZ, --baz BAZ another grouped argument\n"
)
assert getattr(magic_foo3, "argcmd_name", None) == None
assert real_name(magic_foo3) == "foo3"
Expand All @@ -107,7 +102,7 @@ def test_magic_arguments():

assert (
magic_foo4.__doc__
== f"::\n\n %foo4 [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n"
== f"::\n\n %foo4 [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\noptions:\n -f FOO, --foo FOO an argument\n"
)
assert getattr(magic_foo4, "argcmd_name", None) == None
assert real_name(magic_foo4) == "foo4"
Expand All @@ -116,7 +111,7 @@ def test_magic_arguments():

assert (
magic_foo5.__doc__
== f"::\n\n %frobnicate [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n"
== f"::\n\n %frobnicate [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\noptions:\n -f FOO, --foo FOO an argument\n"
)
assert getattr(magic_foo5, "argcmd_name", None) == "frobnicate"
assert real_name(magic_foo5) == "frobnicate"
Expand All @@ -125,7 +120,7 @@ def test_magic_arguments():

assert (
magic_magic_foo.__doc__
== f"::\n\n %magic_foo [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n"
== f"::\n\n %magic_foo [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\noptions:\n -f FOO, --foo FOO an argument\n"
)
assert getattr(magic_magic_foo, "argcmd_name", None) == None
assert real_name(magic_magic_foo) == "magic_foo"
Expand All @@ -134,7 +129,7 @@ def test_magic_arguments():

assert (
foo.__doc__
== f"::\n\n %foo [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\n{options}:\n -f FOO, --foo FOO an argument\n"
== f"::\n\n %foo [-f FOO]\n\n{LEADING_SPACE}A docstring.\n\noptions:\n -f FOO, --foo FOO an argument\n"
)
assert getattr(foo, "argcmd_name", None) == None
assert real_name(foo) == "foo"
Expand Down
4 changes: 1 addition & 3 deletions IPython/lib/tests/test_pretty.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,7 @@ def test_pprint_heap_allocated_type():
Test that pprint works for heap allocated types.
"""
module_name = "xxlimited_35"
expected_output = (
"xxlimited.Null" if sys.version_info < (3, 10, 6) else "xxlimited_35.Null"
)
expected_output = "xxlimited_35.Null"
xxlimited = pytest.importorskip(module_name)
output = pretty.pretty(xxlimited.Null)
assert output == expected_output
Expand Down
5 changes: 1 addition & 4 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,7 @@
import sys, os
from pathlib import Path

if sys.version_info > (3, 11):
import tomllib
else:
import tomli as tomllib
import tomllib

with open("./sphinx.toml", "rb") as f:
config = tomllib.load(f)
Expand Down
5 changes: 1 addition & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ classifiers = [
"Programming Language :: Python :: 3 :: Only",
"Topic :: System :: Shells",
]
requires-python = ">=3.10"
requires-python = ">=3.11"
dependencies = [
'colorama; sys_platform == "win32"',
"decorator",
"exceptiongroup; python_version<'3.11'",
"jedi>=0.16",
"matplotlib-inline",
'pexpect>4.3; sys_platform != "win32" and sys_platform != "emscripten"',
Expand Down Expand Up @@ -71,8 +70,6 @@ doc = [
"sphinx-rtd-theme",
"sphinx>=1.3",
"sphinxcontrib-jquery",
"tomli ; python_version<'3.11'",
"typing_extensions",
]
kernel = [
"ipykernel",
Expand Down
12 changes: 2 additions & 10 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#
# This check is also made in IPython/__init__, don't forget to update both when
# changing Python version requirements.
if sys.version_info < (3, 10):
if sys.version_info < (3, 11):
pip_message = 'This may be due to an out of date pip. Make sure you have pip >= 9.0.1.'
try:
import pip
Expand All @@ -39,18 +39,10 @@


error = """
(information not available for more recent version of IPython)
IPython 8.19+ supports Python 3.10 and above, following SPEC0
IPython 8.13+ supports Python 3.9 and above, following NEP 29.
IPython 8.0-8.12 supports Python 3.8 and above, following NEP 29.
When using Python 2.7, please install IPython 5.x LTS Long Term Support version.
Python 3.3 and 3.4 were supported up to IPython 6.x.
Python 3.5 was supported with IPython 7.0 to 7.9.
Python 3.6 was supported with IPython up to 7.16.
Python 3.7 was still supported with the 7.x branch.
See IPython `README.rst` file for more information:
https://github.com/ipython/ipython/blob/main/README.rst
Python {py} detected.
{pip}
Expand Down

0 comments on commit f32e1b2

Please sign in to comment.