Skip to content

Commit

Permalink
Drop support for Python 3.7 (#267)
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexWaygood authored Jul 6, 2023
1 parent b518f6a commit 8860c6a
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 416 deletions.
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ jobs:
# For available versions, see:
# https://raw.githubusercontent.com/actions/python-versions/main/versions-manifest.json
python-version:
- "3.7"
- "3.7.1"
- "3.8"
- "3.8.0"
- "3.9"
Expand All @@ -53,7 +51,6 @@ jobs:
- "3.11"
- "3.11.0"
- "3.12"
- "pypy3.7"
- "pypy3.8"
- "pypy3.9"
- "pypy3.10"
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
# Release 4.8.0 (???)

- Drop support for Python 3.7 (including PyPy-3.7). Patch by Alex Waygood.

# Release 4.7.1 (July 2, 2023)

- Fix support for `TypedDict`, `NamedTuple` and `is_protocol` on PyPy-3.7 and
Expand Down
2 changes: 0 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ standard library, so that users can experiment with them before they are added t
standard library. Such features should already be specified in a PEP or merged into
CPython's `main` branch.

`typing_extensions` supports Python versions 3.7 and up.

# Versioning scheme

Starting with version 4.0.0, `typing_extensions` uses
Expand Down
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ Therefore, it's safe to depend
on `typing_extensions` like this: `typing_extensions >=x.y, <(x+1)`,
where `x.y` is the first version that includes all features you need.

`typing_extensions` supports Python versions 3.7 and higher.

## Included items

See [the documentation](https://typing-extensions.readthedocs.io/en/latest/#) for a
Expand Down
2 changes: 1 addition & 1 deletion doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ Example usage::
Python version support
----------------------

``typing_extensions`` currently supports Python versions 3.7 and higher. In the future,
``typing_extensions`` currently supports Python versions 3.8 and higher. In the future,
support for older Python versions will be dropped some time after that version
reaches end of life.

Expand Down
5 changes: 2 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ build-backend = "flit_core.buildapi"
[project]
name = "typing_extensions"
version = "4.7.1"
description = "Backported and Experimental Type Hints for Python 3.7+"
description = "Backported and Experimental Type Hints for Python 3.8+"
readme = "README.md"
requires-python = ">=3.7"
requires-python = ">=3.8"
license = { file = "LICENSE" }
keywords = [
"annotations",
Expand All @@ -34,7 +34,6 @@ classifiers = [
"Operating System :: OS Independent",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
Expand Down
72 changes: 10 additions & 62 deletions src/test_typing_extensions.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@

# Flags used to mark tests that only apply after a specific
# version of the typing module.
TYPING_3_8_0 = sys.version_info[:3] >= (3, 8, 0)
TYPING_3_9_0 = sys.version_info[:3] >= (3, 9, 0)
TYPING_3_10_0 = sys.version_info[:3] >= (3, 10, 0)

Expand All @@ -52,10 +51,6 @@
# 3.12 changes the representation of Unpack[] (PEP 692)
TYPING_3_12_0 = sys.version_info[:3] >= (3, 12, 0)

only_with_typing_Protocol = skipUnless(
hasattr(typing, "Protocol"), "Only relevant when typing.Protocol exists"
)

# https://github.com/python/cpython/pull/27017 was backported into some 3.9 and 3.10
# versions, but not all
HAS_FORWARD_MODULE = "module" in inspect.signature(typing._type_check).parameters
Expand Down Expand Up @@ -246,13 +241,7 @@ def some(arg: NoReturn) -> NoReturn: ...
def some_str(arg: 'NoReturn') -> 'typing.NoReturn': ...

expected = {'arg': NoReturn, 'return': NoReturn}
targets = [some]

# On 3.7.0 and 3.7.1, https://github.com/python/cpython/pull/10772
# wasn't applied yet and NoReturn fails _type_check.
if not ((3, 7, 0) <= sys.version_info < (3, 7, 2)):
targets.append(some_str)
for target in targets:
for target in some, some_str:
with self.subTest(target=target):
self.assertEqual(gth(target), expected)

Expand Down Expand Up @@ -595,15 +584,11 @@ def test_basics(self):
Final[int][str]

def test_repr(self):
if hasattr(typing, 'Final') and sys.version_info[:2] >= (3, 7):
mod_name = 'typing'
else:
mod_name = 'typing_extensions'
self.assertEqual(repr(Final), mod_name + '.Final')
self.assertEqual(repr(Final), 'typing.Final')
cv = Final[int]
self.assertEqual(repr(cv), mod_name + '.Final[int]')
self.assertEqual(repr(cv), 'typing.Final[int]')
cv = Final[Employee]
self.assertEqual(repr(cv), mod_name + f'.Final[{__name__}.Employee]')
self.assertEqual(repr(cv), f'typing.Final[{__name__}.Employee]')

def test_cannot_subclass(self):
with self.assertRaises(TypeError):
Expand Down Expand Up @@ -1771,7 +1756,6 @@ class E(C, BP): pass
self.assertNotIsInstance(D(), E)
self.assertNotIsInstance(E(), D)

@only_with_typing_Protocol
def test_runtimecheckable_on_typing_dot_Protocol(self):
@runtime_checkable
class Foo(typing.Protocol):
Expand All @@ -1784,7 +1768,6 @@ def __init__(self):
self.assertIsInstance(Bar(), Foo)
self.assertNotIsInstance(object(), Foo)

@only_with_typing_Protocol
def test_typing_dot_runtimecheckable_on_Protocol(self):
@typing.runtime_checkable
class Foo(Protocol):
Expand All @@ -1797,7 +1780,6 @@ def __init__(self):
self.assertIsInstance(Bar(), Foo)
self.assertNotIsInstance(object(), Foo)

@only_with_typing_Protocol
def test_typing_Protocol_and_extensions_Protocol_can_mix(self):
class TypingProto(typing.Protocol):
x: int
Expand Down Expand Up @@ -3173,7 +3155,6 @@ def c(self) -> int: return 5
with self.assertRaisesRegex(TypeError, "not a Protocol"):
get_protocol_members(ConcreteInherit())

@only_with_typing_Protocol
def test_get_protocol_members_typing(self):
with self.assertRaisesRegex(TypeError, "not a Protocol"):
get_protocol_members(typing.Protocol)
Expand Down Expand Up @@ -3222,7 +3203,6 @@ def test_is_protocol(self):
# Protocol is not itself a protocol
self.assertFalse(is_protocol(Protocol))

@only_with_typing_Protocol
def test_is_protocol_with_typing(self):
self.assertFalse(is_protocol(typing.Protocol))

Expand Down Expand Up @@ -3681,7 +3661,6 @@ class NewGeneric[T](TypedDict):
if hasattr(typing, "TypedDict"):
self.assertIs(is_typeddict(typing.TypedDict), False)

@skipUnless(TYPING_3_8_0, "Python 3.8+ required")
def test_is_typeddict_against_typeddict_from_typing(self):
Point = typing.TypedDict('Point', {'x': int, 'y': int})

Expand Down Expand Up @@ -3844,7 +3823,7 @@ class WithImplicitAny(B):
def test_non_generic_subscript(self):
# For backward compatibility, subscription works
# on arbitrary TypedDict types.
# (But we don't attempt to backport this misfeature onto 3.7 and 3.8.)
# (But we don't attempt to backport this misfeature onto 3.8.)
class TD(TypedDict):
a: T
A = TD[int]
Expand Down Expand Up @@ -4034,17 +4013,8 @@ class C:
classvar: Annotated[ClassVar[int], "a decoration"] = 4
const: Annotated[Final[int], "Const"] = 4

if sys.version_info[:2] >= (3, 7):
self.assertEqual(get_type_hints(C, globals())["classvar"], ClassVar[int])
self.assertEqual(get_type_hints(C, globals())["const"], Final[int])
else:
self.assertEqual(
get_type_hints(C, globals())["classvar"],
Annotated[ClassVar[int], "a decoration"]
)
self.assertEqual(
get_type_hints(C, globals())["const"], Annotated[Final[int], "Const"]
)
self.assertEqual(get_type_hints(C, globals())["classvar"], ClassVar[int])
self.assertEqual(get_type_hints(C, globals())["const"], Final[int])

def test_cannot_subclass(self):
with self.assertRaisesRegex(TypeError, "Cannot subclass .*Annotated"):
Expand Down Expand Up @@ -5069,11 +5039,8 @@ def test_typing_extensions_defers_when_possible(self):
'dataclass_transform',
'overload',
'ParamSpec',
'Text',
'TypeVar',
'TypeVarTuple',
'TYPE_CHECKING',
'Final',
'get_type_hints',
}
if sys.version_info < (3, 10):
Expand Down Expand Up @@ -5189,13 +5156,6 @@ class NonDefaultAfterDefault(NamedTuple):
x: int = 3
y: int

@skipUnless(
(
TYPING_3_8_0
or hasattr(CoolEmployeeWithDefault, '_field_defaults')
),
'"_field_defaults" attribute was added in a micro version of 3.7'
)
def test_field_defaults(self):
self.assertEqual(CoolEmployeeWithDefault._field_defaults, dict(cool=0))

Expand Down Expand Up @@ -5296,7 +5256,7 @@ class Group(NamedTuple):
self.assertEqual(a, (1, [2]))

@skipIf(TYPING_3_9_0, "Test isn't relevant to 3.9+")
def test_non_generic_subscript_error_message_py38_minus(self):
def test_non_generic_subscript_error_message_py38(self):
class Group(NamedTuple):
key: T
group: List[T]
Expand Down Expand Up @@ -5389,10 +5349,7 @@ class CNT(NamedTuple):
self.assertEqual(struct._fields, ())
self.assertEqual(struct.__annotations__, {})
self.assertIsInstance(struct(), struct)
# Attribute was added in a micro version of 3.7
# and is tested more fully elsewhere
if hasattr(struct, "_field_defaults"):
self.assertEqual(struct._field_defaults, {})
self.assertEqual(struct._field_defaults, {})

def test_namedtuple_errors(self):
with self.assertRaises(TypeError):
Expand Down Expand Up @@ -5429,15 +5386,6 @@ def test_copy_and_pickle(self):
def test_docstring(self):
self.assertIsInstance(NamedTuple.__doc__, str)

@skipUnless(TYPING_3_8_0, "NamedTuple had a bad signature on <=3.7")
def test_signature_is_same_as_typing_NamedTuple(self):
self.assertEqual(inspect.signature(NamedTuple), inspect.signature(typing.NamedTuple))

@skipIf(TYPING_3_8_0, "tests are only relevant to <=3.7")
def test_signature_on_37(self):
self.assertIsInstance(inspect.signature(NamedTuple), inspect.Signature)
self.assertFalse(hasattr(NamedTuple, "__text_signature__"))

@skipUnless(TYPING_3_9_0, "NamedTuple was a class on 3.8 and lower")
def test_same_as_typing_NamedTuple_39_plus(self):
self.assertEqual(
Expand Down Expand Up @@ -5592,7 +5540,7 @@ def test_bound_errors(self):
r"Bound must be a type\. Got \(1, 2\)\."):
TypeVar('X', bound=(1, 2))

# Technically we could run it on later versions of 3.7 and 3.8,
# Technically we could run it on later versions of 3.8,
# but that's not worth the effort.
@skipUnless(TYPING_3_9_0, "Fix was not backported")
def test_missing__name__(self):
Expand Down
Loading

0 comments on commit 8860c6a

Please sign in to comment.