Add further types to `_INVALID_BUILTIN_CLASSES` (#13263)

This commit is contained in:
Adam Turner 2025-01-23 03:53:25 +00:00 committed by GitHub
parent 47bff3faea
commit ca2ab35d94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 116 additions and 3 deletions

View File

@ -3,12 +3,20 @@
from __future__ import annotations from __future__ import annotations
import contextvars import contextvars
import ctypes
import dataclasses import dataclasses
import io
import json
import lzma
import multiprocessing
import pathlib import pathlib
import pickle # NoQA: S403
import struct import struct
import sys import sys
import types import types
import typing import typing
import weakref
import zipfile
from collections.abc import Callable, Sequence from collections.abc import Callable, Sequence
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@ -45,6 +53,27 @@ _INVALID_BUILTIN_CLASSES: Final[Mapping[object, str]] = {
contextvars.Context: 'contextvars.Context', contextvars.Context: 'contextvars.Context',
contextvars.ContextVar: 'contextvars.ContextVar', contextvars.ContextVar: 'contextvars.ContextVar',
contextvars.Token: 'contextvars.Token', contextvars.Token: 'contextvars.Token',
# types in 'ctypes' with <type>.__module__ == '_ctypes':
ctypes.Array: 'ctypes.Array',
ctypes.Structure: 'ctypes.Structure',
ctypes.Union: 'ctypes.Union',
# types in 'io' with <type>.__module__ == '_io':
io.FileIO: 'io.FileIO',
io.BytesIO: 'io.BytesIO',
io.StringIO: 'io.StringIO',
io.BufferedReader: 'io.BufferedReader',
io.BufferedWriter: 'io.BufferedWriter',
io.BufferedRWPair: 'io.BufferedRWPair',
io.BufferedRandom: 'io.BufferedRandom',
io.TextIOWrapper: 'io.TextIOWrapper',
# types in 'json' with <type>.__module__ == 'json.{decoder,encoder}':
json.JSONDecoder: 'json.JSONDecoder',
json.JSONEncoder: 'json.JSONEncoder',
# types in 'lzma' with <type>.__module__ == '_lzma':
lzma.LZMACompressor: 'lzma.LZMACompressor',
lzma.LZMADecompressor: 'lzma.LZMADecompressor',
# types in 'multiprocessing' with <type>.__module__ == 'multiprocessing.context':
multiprocessing.Process: 'multiprocessing.Process',
# types in 'pathlib' with <type>.__module__ == 'pathlib._local': # types in 'pathlib' with <type>.__module__ == 'pathlib._local':
pathlib.Path: 'pathlib.Path', pathlib.Path: 'pathlib.Path',
pathlib.PosixPath: 'pathlib.PosixPath', pathlib.PosixPath: 'pathlib.PosixPath',
@ -52,6 +81,9 @@ _INVALID_BUILTIN_CLASSES: Final[Mapping[object, str]] = {
pathlib.PurePosixPath: 'pathlib.PurePosixPath', pathlib.PurePosixPath: 'pathlib.PurePosixPath',
pathlib.PureWindowsPath: 'pathlib.PureWindowsPath', pathlib.PureWindowsPath: 'pathlib.PureWindowsPath',
pathlib.WindowsPath: 'pathlib.WindowsPath', pathlib.WindowsPath: 'pathlib.WindowsPath',
# types in 'pickle' with <type>.__module__ == 'pickle':
pickle.Pickler: 'pickle.Pickler',
pickle.Unpickler: 'pickle.Unpickler',
# types in 'struct' with <type>.__module__ == '_struct': # types in 'struct' with <type>.__module__ == '_struct':
struct.Struct: 'struct.Struct', struct.Struct: 'struct.Struct',
# types in 'types' with <type>.__module__ == 'builtins': # types in 'types' with <type>.__module__ == 'builtins':
@ -78,6 +110,11 @@ _INVALID_BUILTIN_CLASSES: Final[Mapping[object, str]] = {
types.NotImplementedType: 'types.NotImplementedType', types.NotImplementedType: 'types.NotImplementedType',
types.TracebackType: 'types.TracebackType', types.TracebackType: 'types.TracebackType',
types.WrapperDescriptorType: 'types.WrapperDescriptorType', types.WrapperDescriptorType: 'types.WrapperDescriptorType',
# types in 'weakref' with <type>.__module__ == '_weakrefset':
weakref.WeakSet: 'weakref.WeakSet',
# types in 'zipfile' with <type>.__module__ == 'zipfile._path':
zipfile.Path: 'zipfile.Path',
zipfile.CompleteDirs: 'zipfile.CompleteDirs',
} }

View File

@ -2588,7 +2588,7 @@ def test_autodoc_TYPE_CHECKING(app):
'', '',
' .. py:attribute:: Foo.attr1', ' .. py:attribute:: Foo.attr1',
' :module: target.TYPE_CHECKING', ' :module: target.TYPE_CHECKING',
' :type: ~_io.StringIO', ' :type: ~io.StringIO',
'', '',
'', '',
'.. py:function:: spam(ham: ~collections.abc.Iterable[str]) -> tuple[~gettext.NullTranslations, bool]', '.. py:function:: spam(ham: ~collections.abc.Iterable[str]) -> tuple[~gettext.NullTranslations, bool]',

View File

@ -1356,7 +1356,7 @@ def test_autodoc_type_aliases(app):
' docstring', ' docstring',
'', '',
'', '',
'.. py:function:: read(r: ~_io.BytesIO) -> ~_io.StringIO', '.. py:function:: read(r: ~io.BytesIO) -> ~io.StringIO',
' :module: target.autodoc_type_aliases', ' :module: target.autodoc_type_aliases',
'', '',
' docstring', ' docstring',
@ -1429,7 +1429,7 @@ def test_autodoc_type_aliases(app):
' docstring', ' docstring',
'', '',
'', '',
'.. py:function:: read(r: ~_io.BytesIO) -> my.module.StringIO', '.. py:function:: read(r: ~io.BytesIO) -> my.module.StringIO',
' :module: target.autodoc_type_aliases', ' :module: target.autodoc_type_aliases',
'', '',
' docstring', ' docstring',

View File

@ -2,12 +2,27 @@
from __future__ import annotations from __future__ import annotations
import ctypes
import dataclasses import dataclasses
import sys import sys
import typing as t import typing as t
import zipfile
from collections import abc from collections import abc
from contextvars import Context, ContextVar, Token from contextvars import Context, ContextVar, Token
from enum import Enum from enum import Enum
from io import (
BufferedRandom,
BufferedReader,
BufferedRWPair,
BufferedWriter,
BytesIO,
FileIO,
StringIO,
TextIOWrapper,
)
from json import JSONDecoder, JSONEncoder
from lzma import LZMACompressor, LZMADecompressor
from multiprocessing import Process
from numbers import Integral from numbers import Integral
from pathlib import ( from pathlib import (
Path, Path,
@ -17,6 +32,7 @@ from pathlib import (
PureWindowsPath, PureWindowsPath,
WindowsPath, WindowsPath,
) )
from pickle import Pickler, Unpickler
from struct import Struct from struct import Struct
from types import ( from types import (
AsyncGeneratorType, AsyncGeneratorType,
@ -57,6 +73,7 @@ from typing import (
TypeVar, TypeVar,
Union, Union,
) )
from weakref import WeakSet
from sphinx.ext.autodoc import mock from sphinx.ext.autodoc import mock
from sphinx.util.typing import _INVALID_BUILTIN_CLASSES, restify, stringify_annotation from sphinx.util.typing import _INVALID_BUILTIN_CLASSES, restify, stringify_annotation
@ -129,6 +146,27 @@ def test_is_invalid_builtin_class():
Context, Context,
ContextVar, ContextVar,
Token, Token,
# ctypes
ctypes.Array,
ctypes.Structure,
ctypes.Union,
# io
FileIO,
BytesIO,
StringIO,
BufferedReader,
BufferedWriter,
BufferedRWPair,
BufferedRandom,
TextIOWrapper,
# json
JSONDecoder,
JSONEncoder,
# lzma
LZMACompressor,
LZMADecompressor,
# multiprocessing
Process,
# pathlib # pathlib
Path, Path,
PosixPath, PosixPath,
@ -136,6 +174,9 @@ def test_is_invalid_builtin_class():
PurePosixPath, PurePosixPath,
PureWindowsPath, PureWindowsPath,
WindowsPath, WindowsPath,
# pickle
Pickler,
Unpickler,
# struct # struct
Struct, Struct,
# types # types
@ -162,11 +203,37 @@ def test_is_invalid_builtin_class():
NotImplementedType, NotImplementedType,
TracebackType, TracebackType,
WrapperDescriptorType, WrapperDescriptorType,
# weakref
WeakSet,
# zipfile
zipfile.Path,
zipfile.CompleteDirs,
} }
# contextvars # contextvars
assert Context.__module__ == '_contextvars' assert Context.__module__ == '_contextvars'
assert ContextVar.__module__ == '_contextvars' assert ContextVar.__module__ == '_contextvars'
assert Token.__module__ == '_contextvars' assert Token.__module__ == '_contextvars'
# ctypes
assert ctypes.Array.__module__ == '_ctypes'
assert ctypes.Structure.__module__ == '_ctypes'
assert ctypes.Union.__module__ == '_ctypes'
# io
assert FileIO.__module__ == '_io'
assert BytesIO.__module__ == '_io'
assert StringIO.__module__ == '_io'
assert BufferedReader.__module__ == '_io'
assert BufferedWriter.__module__ == '_io'
assert BufferedRWPair.__module__ == '_io'
assert BufferedRandom.__module__ == '_io'
assert TextIOWrapper.__module__ == '_io'
# json
assert JSONDecoder.__module__ == 'json.decoder'
assert JSONEncoder.__module__ == 'json.encoder'
# lzma
assert LZMACompressor.__module__ == '_lzma'
assert LZMADecompressor.__module__ == '_lzma'
# multiprocessing
assert Process.__module__ == 'multiprocessing.context'
if sys.version_info[:2] >= (3, 13): if sys.version_info[:2] >= (3, 13):
# pathlib # pathlib
assert Path.__module__ == 'pathlib._local' assert Path.__module__ == 'pathlib._local'
@ -175,6 +242,9 @@ def test_is_invalid_builtin_class():
assert PurePosixPath.__module__ == 'pathlib._local' assert PurePosixPath.__module__ == 'pathlib._local'
assert PureWindowsPath.__module__ == 'pathlib._local' assert PureWindowsPath.__module__ == 'pathlib._local'
assert WindowsPath.__module__ == 'pathlib._local' assert WindowsPath.__module__ == 'pathlib._local'
# pickle
assert Pickler.__module__ == '_pickle'
assert Unpickler.__module__ == '_pickle'
# struct # struct
assert Struct.__module__ == '_struct' assert Struct.__module__ == '_struct'
# types # types
@ -201,6 +271,12 @@ def test_is_invalid_builtin_class():
assert NotImplementedType.__module__ == 'builtins' assert NotImplementedType.__module__ == 'builtins'
assert TracebackType.__module__ == 'builtins' assert TracebackType.__module__ == 'builtins'
assert WrapperDescriptorType.__module__ == 'builtins' assert WrapperDescriptorType.__module__ == 'builtins'
# weakref
assert WeakSet.__module__ == '_weakrefset'
if sys.version_info[:2] >= (3, 12):
# zipfile
assert zipfile.Path.__module__ == 'zipfile._path'
assert zipfile.CompleteDirs.__module__ == 'zipfile._path'
def test_restify_type_hints_containers(): def test_restify_type_hints_containers():