Skip to content

Commit 4e1948a

Browse files
Add Python 3.15 path HTTP and importlib updates (#15737)
1 parent 7ab8c37 commit 4e1948a

11 files changed

Lines changed: 309 additions & 174 deletions

File tree

stdlib/@tests/stubtest_allowlists/py315.txt

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -77,39 +77,16 @@ enum.__all__
7777
enum.auto.__init__
7878
enum.auto.value
7979
functools.partialmethod.__new__
80-
genericpath.ALL_BUT_LAST
81-
genericpath.__all__
82-
genericpath.commonprefix
83-
genericpath.getatime
84-
genericpath.getctime
85-
genericpath.getmtime
86-
genericpath.getsize
87-
genericpath.samefile
88-
genericpath.samestat
8980
http.HTTPMethod.description
90-
http.client.HTTPConnection.__init__
91-
http.client.HTTPSConnection.__init__
92-
http.server.CGIHTTPRequestHandler
93-
http.server.SimpleHTTPRequestHandler.__init__
94-
http.server.SimpleHTTPRequestHandler.default_content_type
95-
http.server.__all__
9681
importlib._abc.Loader.load_module
9782
importlib._bootstrap_external.NamespacePath
9883
importlib.abc.InspectLoader.source_to_code
9984
importlib.abc.MetaPathFinder.discover
10085
importlib.abc.PathEntryFinder.discover
101-
importlib.metadata.DeprecatedNonAbstract
102-
importlib.metadata.Distribution
103-
importlib.metadata.MetadataNotFound
104-
importlib.metadata.PathDistribution
105-
importlib.metadata.__all__
10686
importlib.resources._common.files
10787
importlib.resources._common.package_to_anchor
10888
importlib.resources.abc.Traversable.open
109-
importlib.resources.abc.Traversable.read_text
11089
inspect._ParameterKind.description
111-
inspect.getdoc
112-
inspect.getfullargspec
11390
io.Reader.__class_getitem__
11491
io.Reader.read
11592
io.Writer.__class_getitem__
@@ -134,24 +111,6 @@ multiprocessing.managers._BaseSetProxy.clear
134111
multiprocessing.managers._BaseSetProxy.copy
135112
multiprocessing.managers._BaseSetProxy.pop
136113
multiprocessing.process.BaseProcess.__init__
137-
ntpath.ALL_BUT_LAST
138-
ntpath.__all__
139-
ntpath.realpath
140-
os.path.ALL_BUT_LAST
141-
os.path.__all__
142-
pathlib.PurePath.__vfspath__
143-
pathlib.PurePath.is_reserved
144-
posixpath.ALL_BUT_LAST
145-
posixpath.__all__
146-
posixpath.basename
147-
posixpath.dirname
148-
posixpath.isabs
149-
posixpath.normcase
150-
posixpath.realpath
151-
posixpath.split
152-
posixpath.splitdrive
153-
posixpath.splitext
154-
posixpath.splitroot
155114
sre_compile
156115
sre_constants
157116
sre_parse
@@ -184,7 +143,6 @@ typing._SpecialForm.__mro_entries__
184143
typing_extensions.__all__
185144
typing_extensions.Protocol
186145
xml.etree.ElementTree.__all__
187-
zipimport.zipimporter.load_module
188146

189147
# =============================================================
190148
# Allowlist entries that cannot or should not be fixed; >=3.15

stdlib/genericpath.pyi

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import sys
33
from _typeshed import BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath, SupportsRichComparisonT
44
from collections.abc import Sequence
55
from typing import Literal, NewType, overload
6-
from typing_extensions import LiteralString
6+
from typing_extensions import LiteralString, deprecated
77

88
__all__ = [
99
"commonprefix",
@@ -23,22 +23,42 @@ if sys.version_info >= (3, 12):
2323
__all__ += ["islink"]
2424
if sys.version_info >= (3, 13):
2525
__all__ += ["isjunction", "isdevdrive", "lexists"]
26+
if sys.version_info >= (3, 15):
27+
__all__ += ["ALL_BUT_LAST"]
2628

2729
# All overloads can return empty string. Ideally, Literal[""] would be a valid
2830
# Iterable[T], so that list[T] | Literal[""] could be used as a return
2931
# type. But because this only works when T is str, we need Sequence[T] instead.
30-
@overload
31-
def commonprefix(m: Sequence[LiteralString]) -> LiteralString: ...
32-
@overload
33-
def commonprefix(m: Sequence[StrPath]) -> str: ...
34-
@overload
35-
def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ...
36-
@overload
37-
def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ...
38-
@overload
39-
def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ...
32+
if sys.version_info >= (3, 15):
33+
@overload
34+
@deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.")
35+
def commonprefix(m: Sequence[LiteralString], /) -> LiteralString: ...
36+
@overload
37+
@deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.")
38+
def commonprefix(m: Sequence[StrPath], /) -> str: ...
39+
@overload
40+
@deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.")
41+
def commonprefix(m: Sequence[BytesPath], /) -> bytes | Literal[""]: ...
42+
@overload
43+
@deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.")
44+
def commonprefix(m: Sequence[list[SupportsRichComparisonT]], /) -> Sequence[SupportsRichComparisonT]: ...
45+
@overload
46+
@deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.")
47+
def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]], /) -> Sequence[SupportsRichComparisonT]: ...
48+
49+
else:
50+
@overload
51+
def commonprefix(m: Sequence[LiteralString]) -> LiteralString: ...
52+
@overload
53+
def commonprefix(m: Sequence[StrPath]) -> str: ...
54+
@overload
55+
def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ...
56+
@overload
57+
def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ...
58+
@overload
59+
def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ...
60+
4061
def exists(path: FileDescriptorOrPath) -> bool: ...
41-
def getsize(filename: FileDescriptorOrPath) -> int: ...
4262
def isfile(path: FileDescriptorOrPath) -> bool: ...
4363
def isdir(s: FileDescriptorOrPath) -> bool: ...
4464

@@ -47,12 +67,23 @@ if sys.version_info >= (3, 12):
4767

4868
# These return float if os.stat_float_times() == True,
4969
# but int is a subclass of float.
50-
def getatime(filename: FileDescriptorOrPath) -> float: ...
51-
def getmtime(filename: FileDescriptorOrPath) -> float: ...
52-
def getctime(filename: FileDescriptorOrPath) -> float: ...
53-
def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath) -> bool: ...
5470
def sameopenfile(fp1: int, fp2: int) -> bool: ...
55-
def samestat(s1: os.stat_result, s2: os.stat_result) -> bool: ...
71+
72+
if sys.version_info >= (3, 15):
73+
def getsize(filename: FileDescriptorOrPath, /) -> int: ...
74+
def getatime(filename: FileDescriptorOrPath, /) -> float: ...
75+
def getmtime(filename: FileDescriptorOrPath, /) -> float: ...
76+
def getctime(filename: FileDescriptorOrPath, /) -> float: ...
77+
def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath, /) -> bool: ...
78+
def samestat(s1: os.stat_result, s2: os.stat_result, /) -> bool: ...
79+
80+
else:
81+
def getsize(filename: FileDescriptorOrPath) -> int: ...
82+
def getatime(filename: FileDescriptorOrPath) -> float: ...
83+
def getmtime(filename: FileDescriptorOrPath) -> float: ...
84+
def getctime(filename: FileDescriptorOrPath) -> float: ...
85+
def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath) -> bool: ...
86+
def samestat(s1: os.stat_result, s2: os.stat_result) -> bool: ...
5687

5788
if sys.version_info >= (3, 13):
5889
def isjunction(path: StrOrBytesPath) -> bool: ...
@@ -62,3 +93,7 @@ if sys.version_info >= (3, 13):
6293
# Added in Python 3.9.23, 3.10.18, 3.11.13, 3.12.11, 3.13.4
6394
_AllowMissingType = NewType("_AllowMissingType", object)
6495
ALLOW_MISSING: _AllowMissingType
96+
97+
if sys.version_info >= (3, 15):
98+
_AllButLastType = NewType("_AllButLastType", object)
99+
ALL_BUT_LAST: _AllButLastType

stdlib/http/client.pyi

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -178,14 +178,27 @@ class HTTPConnection:
178178
host: str
179179
port: int
180180
sock: socket | MaybeNone # can be `None` if `.connect()` was not called
181-
def __init__(
182-
self,
183-
host: str,
184-
port: int | None = None,
185-
timeout: float | None = ...,
186-
source_address: tuple[str, int] | None = None,
187-
blocksize: int = 8192,
188-
) -> None: ...
181+
if sys.version_info >= (3, 15):
182+
def __init__(
183+
self,
184+
host: str,
185+
port: int | None = None,
186+
timeout: float | None = ...,
187+
source_address: tuple[str, int] | None = None,
188+
blocksize: int = 8192,
189+
*,
190+
max_response_headers: int | None = None,
191+
) -> None: ...
192+
else:
193+
def __init__(
194+
self,
195+
host: str,
196+
port: int | None = None,
197+
timeout: float | None = ...,
198+
source_address: tuple[str, int] | None = None,
199+
blocksize: int = 8192,
200+
) -> None: ...
201+
189202
def request(
190203
self,
191204
method: str,
@@ -211,7 +224,19 @@ class HTTPConnection:
211224
class HTTPSConnection(HTTPConnection):
212225
# Can be `None` if `.connect()` was not called:
213226
sock: ssl.SSLSocket | MaybeNone
214-
if sys.version_info >= (3, 12):
227+
if sys.version_info >= (3, 15):
228+
def __init__(
229+
self,
230+
host: str,
231+
port: int | None = None,
232+
*,
233+
timeout: float | None = ...,
234+
source_address: tuple[str, int] | None = None,
235+
context: ssl.SSLContext | None = None,
236+
blocksize: int = 8192,
237+
max_response_headers: int | None = None,
238+
) -> None: ...
239+
elif sys.version_info >= (3, 12):
215240
def __init__(
216241
self,
217242
host: str,

stdlib/http/server.pyi

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,11 @@ from ssl import Purpose, SSLContext
1010
from typing import Any, AnyStr, BinaryIO, ClassVar, Protocol, type_check_only
1111
from typing_extensions import Self, deprecated
1212

13+
__all__ = ["HTTPServer", "ThreadingHTTPServer", "BaseHTTPRequestHandler", "SimpleHTTPRequestHandler"]
14+
if sys.version_info < (3, 15):
15+
__all__ += ["CGIHTTPRequestHandler"]
1316
if sys.version_info >= (3, 14):
14-
__all__ = [
15-
"HTTPServer",
16-
"ThreadingHTTPServer",
17-
"HTTPSServer",
18-
"ThreadingHTTPSServer",
19-
"BaseHTTPRequestHandler",
20-
"SimpleHTTPRequestHandler",
21-
"CGIHTTPRequestHandler",
22-
]
23-
else:
24-
__all__ = ["HTTPServer", "ThreadingHTTPServer", "BaseHTTPRequestHandler", "SimpleHTTPRequestHandler", "CGIHTTPRequestHandler"]
17+
__all__ = ["HTTPSServer", "ThreadingHTTPSServer"]
2518

2619
class HTTPServer(socketserver.TCPServer):
2720
server_name: str
@@ -77,6 +70,8 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler):
7770
protocol_version: str
7871
MessageClass: type
7972
responses: Mapping[int, tuple[str, str]]
73+
if sys.version_info >= (3, 15):
74+
default_content_type: str
8075
default_request_version: str # undocumented
8176
weekdayname: ClassVar[Sequence[str]] # undocumented
8277
monthname: ClassVar[Sequence[str | None]] # undocumented
@@ -102,14 +97,26 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
10297
if sys.version_info >= (3, 12):
10398
index_pages: ClassVar[tuple[str, ...]]
10499
directory: str
105-
def __init__(
106-
self,
107-
request: socketserver._RequestType,
108-
client_address: _socket._RetAddress,
109-
server: socketserver.BaseServer,
110-
*,
111-
directory: StrPath | None = None,
112-
) -> None: ...
100+
if sys.version_info >= (3, 15):
101+
def __init__(
102+
self,
103+
request: socketserver._RequestType,
104+
client_address: _socket._RetAddress,
105+
server: socketserver.BaseServer,
106+
*,
107+
directory: StrPath | None = None,
108+
extra_response_headers: Mapping[str, str] | None = None,
109+
) -> None: ...
110+
else:
111+
def __init__(
112+
self,
113+
request: socketserver._RequestType,
114+
client_address: _socket._RetAddress,
115+
server: socketserver.BaseServer,
116+
*,
117+
directory: StrPath | None = None,
118+
) -> None: ...
119+
113120
def do_GET(self) -> None: ...
114121
def do_HEAD(self) -> None: ...
115122
def send_head(self) -> io.BytesIO | BinaryIO | None: ... # undocumented
@@ -119,12 +126,14 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
119126
def guess_type(self, path: StrPath) -> str: ... # undocumented
120127

121128
def executable(path: StrPath) -> bool: ... # undocumented
122-
@deprecated("Deprecated since Python 3.13; will be removed in Python 3.15.")
123-
class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
124-
cgi_directories: list[str]
125-
have_fork: bool # undocumented
126-
def do_POST(self) -> None: ...
127-
def is_cgi(self) -> bool: ... # undocumented
128-
def is_executable(self, path: StrPath) -> bool: ... # undocumented
129-
def is_python(self, path: StrPath) -> bool: ... # undocumented
130-
def run_cgi(self) -> None: ... # undocumented
129+
130+
if sys.version_info < (3, 15):
131+
@deprecated("Deprecated since Python 3.13; will be removed in Python 3.15.")
132+
class CGIHTTPRequestHandler(SimpleHTTPRequestHandler):
133+
cgi_directories: list[str]
134+
have_fork: bool # undocumented
135+
def do_POST(self) -> None: ...
136+
def is_cgi(self) -> bool: ... # undocumented
137+
def is_executable(self, path: StrPath) -> bool: ... # undocumented
138+
def is_python(self, path: StrPath) -> bool: ... # undocumented
139+
def run_cgi(self) -> None: ... # undocumented

stdlib/importlib/metadata/__init__.pyi

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ __all__ = [
3131
"version",
3232
]
3333

34+
if sys.version_info >= (3, 15):
35+
__all__ += ["PackagePath", "MetadataNotFound", "SimplePath"]
36+
3437
_SimplePath: TypeAlias = SimplePath
3538

3639
def packages_distributions() -> Mapping[str, list[str]]: ...
@@ -39,6 +42,9 @@ class PackageNotFoundError(ModuleNotFoundError):
3942
@property
4043
def name(self) -> str: ... # type: ignore[override]
4144

45+
if sys.version_info >= (3, 15):
46+
class MetadataNotFound(FileNotFoundError): ...
47+
4248
if sys.version_info >= (3, 13):
4349
_EntryPointBase = object
4450
elif sys.version_info >= (3, 11):
@@ -203,7 +209,9 @@ class FileHash:
203209
value: str
204210
def __init__(self, spec: str) -> None: ...
205211

206-
if sys.version_info >= (3, 12):
212+
if sys.version_info >= (3, 15):
213+
_distribution_parent = abc.ABC
214+
elif sys.version_info >= (3, 12):
207215
class DeprecatedNonAbstract: ...
208216
_distribution_parent = DeprecatedNonAbstract
209217
else:

stdlib/importlib/resources/abc.pyi

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,12 @@ if sys.version_info >= (3, 11):
4444
def __truediv__(self, child: StrPath, /) -> Traversable: ...
4545
@abstractmethod
4646
def read_bytes(self) -> bytes: ...
47-
@abstractmethod
48-
def read_text(self, encoding: str | None = None) -> str: ...
47+
if sys.version_info >= (3, 15):
48+
@abstractmethod
49+
def read_text(self, encoding: str | None = None, errors: str | None = None) -> str: ...
50+
else:
51+
@abstractmethod
52+
def read_text(self, encoding: str | None = None) -> str: ...
4953

5054
class TraversableResources(ResourceReader):
5155
@abstractmethod

stdlib/inspect.pyi

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,13 @@ def getblock(lines: list[str]) -> list[str]: ...
306306
def getblock(lines: tuple[str, ...]) -> tuple[str, ...]: ...
307307
@overload
308308
def getblock(lines: Sequence[str]) -> Sequence[str]: ...
309-
def getdoc(object: object) -> str | None: ...
309+
310+
if sys.version_info >= (3, 15):
311+
def getdoc(object: object, *, inherit_class_doc: bool = True, fallback_to_class_doc: bool = True) -> str | None: ...
312+
313+
else:
314+
def getdoc(object: object) -> str | None: ...
315+
310316
def getcomments(object: object) -> str | None: ...
311317
def getfile(object: _SourceObjectType) -> str: ...
312318
def getmodule(object: object, _filename: str | None = None) -> ModuleType | None: ...
@@ -505,7 +511,11 @@ class FullArgSpec(NamedTuple):
505511
kwonlydefaults: dict[str, Any] | None
506512
annotations: dict[str, Any]
507513

508-
def getfullargspec(func: object) -> FullArgSpec: ...
514+
if sys.version_info >= (3, 15):
515+
def getfullargspec(func: object, *, annotation_format: Format = Format.VALUE) -> FullArgSpec: ... # noqa: Y011
516+
517+
else:
518+
def getfullargspec(func: object) -> FullArgSpec: ...
509519

510520
class ArgInfo(NamedTuple):
511521
args: list[str]

0 commit comments

Comments
 (0)