Remove Python 2 support from some third-party distributions (#7466)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
Sebastian Rittau
2022-03-09 19:19:22 +01:00
committed by GitHub
parent 4e87b9058f
commit c3907ab26b
49 changed files with 10 additions and 557 deletions

View File

@@ -126,10 +126,6 @@ contains the following:
* `METADATA.toml`, describing the package. See below for details.
* Stubs (i.e. `*.pyi` files) for packages and modules that are shipped in the
source distribution.
* If the stubs are either Python 2-only, or if the Python 2 and Python 3 stubs
are separate, the Python 2 stubs are put in a `@python2` subdirectory.
Stubs outside `@python2` are always used with Python 3,
and also with Python 2 if `python2 = true` is set in `METADATA.toml` (see below).
* (Rarely) some docs specific to a given type stub package in `README` file.
When a third party stub is added or

View File

@@ -1,3 +1,2 @@
version = "2.49.*"
python2 = true
requires = ["types-six"]

View File

@@ -1,4 +1,2 @@
version = "3.3.*"
python2 = true
requires = ["types-enum34", "types-ipaddress"]
obsolete_since = "3.4.4"

View File

@@ -1,70 +0,0 @@
import sys
from _typeshed import Self
from abc import ABCMeta
from typing import Any, Iterator, Mapping, TypeVar, Union
_T = TypeVar("_T")
_S = TypeVar("_S", bound=type[Enum])
# Note: EnumMeta actually subclasses type directly, not ABCMeta.
# This is a temporary workaround to allow multiple creation of enums with builtins
# such as str as mixins, which due to the handling of ABCs of builtin types, cause
# spurious inconsistent metaclass structure. See #1595.
# Structurally: Iterable[T], Reversible[T], Container[T] where T is the enum itself
class EnumMeta(ABCMeta):
def __iter__(self: type[_T]) -> Iterator[_T]: ...
def __reversed__(self: type[_T]) -> Iterator[_T]: ...
def __contains__(self, member: object) -> bool: ...
def __getitem__(self: type[_T], name: str) -> _T: ...
@property
def __members__(self: type[_T]) -> Mapping[str, _T]: ...
def __len__(self) -> int: ...
class Enum(metaclass=EnumMeta):
name: str
value: Any
_name_: str
_value_: Any
_member_names_: list[str] # undocumented
_member_map_: dict[str, Enum] # undocumented
_value2member_map_: dict[int, Enum] # undocumented
if sys.version_info >= (3, 7):
_ignore_: Union[str, list[str]]
_order_: str
__order__: str
@classmethod
def _missing_(cls, value: object) -> Any: ...
@staticmethod
def _generate_next_value_(name: str, start: int, count: int, last_values: list[Any]) -> Any: ...
def __new__(cls: type[Self], value: object) -> Self: ...
def __dir__(self) -> list[str]: ...
def __format__(self, format_spec: str) -> str: ...
def __hash__(self) -> Any: ...
def __reduce_ex__(self, proto: object) -> Any: ...
class IntEnum(int, Enum):
value: int
def unique(enumeration: _S) -> _S: ...
_auto_null: Any
# subclassing IntFlag so it picks up all implemented base functions, best modeling behavior of enum.auto()
class auto(IntFlag):
value: Any
class Flag(Enum):
def __contains__(self: _T, other: _T) -> bool: ...
def __bool__(self) -> bool: ...
def __or__(self: Self, other: Self) -> Self: ...
def __and__(self: Self, other: Self) -> Self: ...
def __xor__(self: Self, other: Self) -> Self: ...
def __invert__(self: Self) -> Self: ...
class IntFlag(int, Flag):
def __or__(self: Self, other: Union[int, Self]) -> Self: ...
def __and__(self: Self, other: Union[int, Self]) -> Self: ...
def __xor__(self: Self, other: Union[int, Self]) -> Self: ...
__ror__ = __or__
__rand__ = __and__
__rxor__ = __xor__

View File

@@ -1,2 +0,0 @@
version = "1.1.*"
python2 = true

View File

@@ -1,149 +0,0 @@
from _typeshed import Self
from typing import Any, Container, Generic, Iterable, Iterator, Optional, SupportsInt, Text, TypeVar, overload
# Undocumented length constants
IPV4LENGTH: int
IPV6LENGTH: int
_A = TypeVar("_A", IPv4Address, IPv6Address)
_N = TypeVar("_N", IPv4Network, IPv6Network)
_T = TypeVar("_T")
def ip_address(address: object) -> Any: ... # morally Union[IPv4Address, IPv6Address]
def ip_network(address: object, strict: bool = ...) -> Any: ... # morally Union[IPv4Network, IPv6Network]
def ip_interface(address: object) -> Any: ... # morally Union[IPv4Interface, IPv6Interface]
class _IPAddressBase:
def __eq__(self, other: object) -> bool: ...
def __ge__(self: _T, other: _T) -> bool: ...
def __gt__(self: _T, other: _T) -> bool: ...
def __le__(self: _T, other: _T) -> bool: ...
def __lt__(self: _T, other: _T) -> bool: ...
def __ne__(self, other: object) -> bool: ...
@property
def compressed(self) -> Text: ...
@property
def exploded(self) -> Text: ...
@property
def reverse_pointer(self) -> Text: ...
@property
def version(self) -> int: ...
class _BaseAddress(_IPAddressBase, SupportsInt):
def __init__(self, address: object) -> None: ...
def __add__(self: Self, other: int) -> Self: ...
def __hash__(self) -> int: ...
def __int__(self) -> int: ...
def __sub__(self: Self, other: int) -> Self: ...
@property
def is_global(self) -> bool: ...
@property
def is_link_local(self) -> bool: ...
@property
def is_loopback(self) -> bool: ...
@property
def is_multicast(self) -> bool: ...
@property
def is_private(self) -> bool: ...
@property
def is_reserved(self) -> bool: ...
@property
def is_unspecified(self) -> bool: ...
@property
def max_prefixlen(self) -> int: ...
@property
def packed(self) -> bytes: ...
class _BaseNetwork(_IPAddressBase, Container[_A], Iterable[_A], Generic[_A]):
network_address: _A
netmask: _A
def __init__(self, address: object, strict: bool = ...) -> None: ...
def __contains__(self, other: Any) -> bool: ...
def __getitem__(self, n: int) -> _A: ...
def __iter__(self) -> Iterator[_A]: ...
def address_exclude(self: _T, other: _T) -> Iterator[_T]: ...
@property
def broadcast_address(self) -> _A: ...
def compare_networks(self: _T, other: _T) -> int: ...
def hosts(self) -> Iterator[_A]: ...
@property
def is_global(self) -> bool: ...
@property
def is_link_local(self) -> bool: ...
@property
def is_loopback(self) -> bool: ...
@property
def is_multicast(self) -> bool: ...
@property
def is_private(self) -> bool: ...
@property
def is_reserved(self) -> bool: ...
@property
def is_unspecified(self) -> bool: ...
@property
def max_prefixlen(self) -> int: ...
@property
def num_addresses(self) -> int: ...
def overlaps(self, other: _BaseNetwork[_A]) -> bool: ...
@property
def prefixlen(self) -> int: ...
def subnets(self: _T, prefixlen_diff: int = ..., new_prefix: Optional[int] = ...) -> Iterator[_T]: ...
def supernet(self: Self, prefixlen_diff: int = ..., new_prefix: Optional[int] = ...) -> Self: ...
@property
def with_hostmask(self) -> Text: ...
@property
def with_netmask(self) -> Text: ...
@property
def with_prefixlen(self) -> Text: ...
@property
def hostmask(self) -> _A: ...
class _BaseInterface(_BaseAddress, Generic[_A, _N]):
hostmask: _A
netmask: _A
network: _N
@property
def ip(self) -> _A: ...
@property
def with_hostmask(self) -> Text: ...
@property
def with_netmask(self) -> Text: ...
@property
def with_prefixlen(self) -> Text: ...
class IPv4Address(_BaseAddress): ...
class IPv4Network(_BaseNetwork[IPv4Address]): ...
class IPv4Interface(IPv4Address, _BaseInterface[IPv4Address, IPv4Network]): ...
class IPv6Address(_BaseAddress):
@property
def ipv4_mapped(self) -> Optional[IPv4Address]: ...
@property
def is_site_local(self) -> bool: ...
@property
def sixtofour(self) -> Optional[IPv4Address]: ...
@property
def teredo(self) -> Optional[tuple[IPv4Address, IPv4Address]]: ...
class IPv6Network(_BaseNetwork[IPv6Address]):
@property
def is_site_local(self) -> bool: ...
class IPv6Interface(IPv6Address, _BaseInterface[IPv6Address, IPv6Network]): ...
def v4_int_to_packed(address: int) -> bytes: ...
def v6_int_to_packed(address: int) -> bytes: ...
@overload
def summarize_address_range(first: IPv4Address, last: IPv4Address) -> Iterator[IPv4Network]: ...
@overload
def summarize_address_range(first: IPv6Address, last: IPv6Address) -> Iterator[IPv6Network]: ...
def collapse_addresses(addresses: Iterable[_N]) -> Iterator[_N]: ...
@overload
def get_mixed_type_key(obj: _A) -> tuple[int, _A]: ...
@overload
def get_mixed_type_key(obj: IPv4Network) -> tuple[int, IPv4Address, IPv4Address]: ...
@overload
def get_mixed_type_key(obj: IPv6Network) -> tuple[int, IPv6Address, IPv6Address]: ...
class AddressValueError(ValueError): ...
class NetmaskValueError(ValueError): ...

View File

@@ -1,2 +0,0 @@
version = "1.0.*"
python2 = true

View File

@@ -1,3 +1,2 @@
version = "2.8.*"
python2 = true
requires = ["types-cryptography"]

View File

@@ -1,3 +1,2 @@
version = "0.2.*"
python2 = true
requires = ["types-paramiko"]

View File

@@ -1,3 +1 @@
version = "7.0.*"
python2 = true
requires = ["types-enum34"]

View File

@@ -1,119 +0,0 @@
from __future__ import print_function
import types
import typing
import unittest
from __builtin__ import unichr as unichr
from functools import wraps as wraps
from StringIO import StringIO as StringIO
from typing import (
Any,
AnyStr,
Callable,
ItemsView,
Iterable,
KeysView,
Mapping,
NoReturn,
Pattern,
Text,
TypeVar,
ValuesView,
overload,
)
from typing_extensions import Literal
from . import moves
BytesIO = StringIO
_T = TypeVar("_T")
_K = TypeVar("_K")
_V = TypeVar("_V")
__author__: str
__version__: str
PY2: Literal[True]
PY3: Literal[False]
PY34: Literal[False]
string_types: tuple[type[str], type[unicode]]
integer_types: tuple[type[int], type[long]]
class_types: tuple[type[type[Any]], type[types.ClassType]]
text_type: type[unicode]
binary_type: type[str]
MAXSIZE: int
def advance_iterator(it: typing.Iterator[_T]) -> _T: ...
next = advance_iterator
def callable(obj: object) -> bool: ...
def get_unbound_function(unbound: types.MethodType) -> types.FunctionType: ...
def create_bound_method(func: types.FunctionType, obj: object) -> types.MethodType: ...
def create_unbound_method(func: types.FunctionType, cls: type | types.ClassType) -> types.MethodType: ...
class Iterator:
def next(self) -> Any: ...
def get_method_function(meth: types.MethodType) -> types.FunctionType: ...
def get_method_self(meth: types.MethodType) -> object | None: ...
def get_function_closure(fun: types.FunctionType) -> tuple[types._Cell, ...] | None: ...
def get_function_code(fun: types.FunctionType) -> types.CodeType: ...
def get_function_defaults(fun: types.FunctionType) -> tuple[Any, ...] | None: ...
def get_function_globals(fun: types.FunctionType) -> dict[str, Any]: ...
def iterkeys(d: Mapping[_K, _V]) -> typing.Iterator[_K]: ...
def itervalues(d: Mapping[_K, _V]) -> typing.Iterator[_V]: ...
def iteritems(d: Mapping[_K, _V]) -> typing.Iterator[tuple[_K, _V]]: ...
# def iterlists
def viewkeys(d: Mapping[_K, _V]) -> KeysView[_K]: ...
def viewvalues(d: Mapping[_K, _V]) -> ValuesView[_V]: ...
def viewitems(d: Mapping[_K, _V]) -> ItemsView[_K, _V]: ...
def b(s: str) -> str: ...
def u(s: str) -> unicode: ...
int2byte = chr
def byte2int(bs: str) -> int: ...
def indexbytes(buf: str, i: int) -> int: ...
def iterbytes(buf: str) -> typing.Iterator[int]: ...
def assertCountEqual(self: unittest.TestCase, first: Iterable[_T], second: Iterable[_T], msg: str = ...) -> None: ...
@overload
def assertRaisesRegex(self: unittest.TestCase, msg: str = ...) -> Any: ...
@overload
def assertRaisesRegex(self: unittest.TestCase, callable_obj: Callable[..., Any], *args: Any, **kwargs: Any) -> Any: ...
def assertRegex(self: unittest.TestCase, text: AnyStr, expected_regex: AnyStr | Pattern[AnyStr], msg: str = ...) -> None: ...
def reraise(tp: type[BaseException] | None, value: BaseException | None, tb: types.TracebackType | None = ...) -> NoReturn: ...
def exec_(_code_: unicode | types.CodeType, _globs_: dict[str, Any] = ..., _locs_: dict[str, Any] = ...): ...
def raise_from(value: BaseException | type[BaseException], from_value: BaseException | None) -> NoReturn: ...
print_ = print
def with_metaclass(meta: type, *bases: type) -> type: ...
def add_metaclass(metaclass: type) -> Callable[[_T], _T]: ...
def ensure_binary(s: bytes | Text, encoding: str = ..., errors: str = ...) -> bytes: ...
def ensure_str(s: bytes | Text, encoding: str = ..., errors: str = ...) -> str: ...
def ensure_text(s: bytes | Text, encoding: str = ..., errors: str = ...) -> Text: ...
def python_2_unicode_compatible(klass: _T) -> _T: ...
class _LazyDescr(object):
name: str
def __init__(self, name: str) -> None: ...
def __get__(self, obj: object | None, type: type[Any] | None = ...) -> Any: ...
class MovedModule(_LazyDescr):
mod: str
def __init__(self, name: str, old: str, new: str | None = ...) -> None: ...
def __getattr__(self, attr: str) -> Any: ...
class MovedAttribute(_LazyDescr):
mod: str
attr: str
def __init__(self, name: str, old_mod: str, new_mod: str, old_attr: str | None = ..., new_attr: str | None = ...) -> None: ...
def add_move(move: MovedModule | MovedAttribute) -> None: ...
def remove_move(name: str) -> None: ...

View File

@@ -1 +0,0 @@
from BaseHTTPServer import *

View File

@@ -1 +0,0 @@
from CGIHTTPServer import *

View File

@@ -1 +0,0 @@
from SimpleHTTPServer import *

View File

@@ -1,78 +0,0 @@
# Stubs for six.moves
#
# Note: Commented out items means they weren't implemented at the time.
# Uncomment them when the modules have been added to the typeshed.
import __builtin__
import itertools
import os
import pipes
from __builtin__ import intern as intern, reduce as reduce, xrange as xrange
from cStringIO import StringIO as _cStringIO
from StringIO import StringIO as StringIO
from UserDict import UserDict as UserDict
from UserList import UserList as UserList
from UserString import UserString as UserString
# import Tkinter as tkinter
# import Dialog as tkinter_dialog
# import FileDialog as tkinter_filedialog
# import ScrolledText as tkinter_scrolledtext
# import SimpleDialog as tkinter_simpledialog
# import Tix as tkinter_tix
# import ttk as tkinter_ttk
# import Tkconstants as tkinter_constants
# import Tkdnd as tkinter_dnd
# import tkColorChooser as tkinter_colorchooser
# import tkCommonDialog as tkinter_commondialog
# import tkFileDialog as tkinter_tkfiledialog
# import tkFont as tkinter_font
# import tkMessageBox as tkinter_messagebox
# import tkSimpleDialog as tkinter_tksimpledialog
# import email.MIMEBase as email_mime_base
# import email.MIMEMultipart as email_mime_multipart
# import email.MIMENonMultipart as email_mime_nonmultipart
# import gdbm as dbm_gnu
from . import (
BaseHTTPServer,
CGIHTTPServer,
SimpleHTTPServer,
_dummy_thread,
_thread,
configparser,
copyreg as copyreg,
cPickle,
email_mime_text,
html_entities,
html_parser,
http_client,
http_cookiejar,
http_cookies,
queue,
reprlib,
socketserver,
urllib,
urllib_error,
urllib_parse,
urllib_robotparser,
xmlrpc_client,
)
# import SimpleXMLRPCServer as xmlrpc_server
builtins = __builtin__
input = __builtin__.raw_input
reload_module = __builtin__.reload
range = __builtin__.xrange
cStringIO = _cStringIO
filter = itertools.ifilter
filterfalse = itertools.ifilterfalse
map = itertools.imap
zip = itertools.izip
zip_longest = itertools.izip_longest
getcwdb = os.getcwd
getcwd = os.getcwdu
shlex_quote = pipes.quote

View File

@@ -1 +0,0 @@
from dummy_thread import *

View File

@@ -1 +0,0 @@
from thread import *

View File

@@ -1 +0,0 @@
from cPickle import *

View File

@@ -1 +0,0 @@
from collections import *

View File

@@ -1 +0,0 @@
from ConfigParser import *

View File

@@ -1 +0,0 @@
from copy_reg import *

View File

@@ -1 +0,0 @@
from email.mime.base import *

View File

@@ -1 +0,0 @@
from email.mime.multipart import *

View File

@@ -1 +0,0 @@
from email.mime.nonmultipart import *

View File

@@ -1 +0,0 @@
from email.MIMEText import *

View File

@@ -1 +0,0 @@
from htmlentitydefs import *

View File

@@ -1 +0,0 @@
from HTMLParser import *

View File

@@ -1 +0,0 @@
from httplib import *

View File

@@ -1 +0,0 @@
from cookielib import *

View File

@@ -1 +0,0 @@
from Cookie import *

View File

@@ -1 +0,0 @@
from Queue import *

View File

@@ -1 +0,0 @@
from repr import *

View File

@@ -1 +0,0 @@
from SocketServer import *

View File

@@ -1,5 +0,0 @@
import six.moves.urllib.error as error
import six.moves.urllib.parse as parse
import six.moves.urllib.request as request
import six.moves.urllib.response as response
import six.moves.urllib.robotparser as robotparser

View File

@@ -1,2 +0,0 @@
from urllib import ContentTooShortError as ContentTooShortError
from urllib2 import HTTPError as HTTPError, URLError as URLError

View File

@@ -1,29 +0,0 @@
from urllib import (
quote as quote,
quote_plus as quote_plus,
splitquery as splitquery,
splittag as splittag,
splituser as splituser,
unquote as unquote,
unquote_plus as unquote_plus,
urlencode as urlencode,
)
from urlparse import (
ParseResult as ParseResult,
SplitResult as SplitResult,
parse_qs as parse_qs,
parse_qsl as parse_qsl,
urldefrag as urldefrag,
urljoin as urljoin,
urlparse as urlparse,
urlsplit as urlsplit,
urlunparse as urlunparse,
urlunsplit as urlunsplit,
uses_fragment as uses_fragment,
uses_netloc as uses_netloc,
uses_params as uses_params,
uses_query as uses_query,
uses_relative as uses_relative,
)
unquote_to_bytes = unquote

View File

@@ -1,39 +0,0 @@
from urllib import (
FancyURLopener as FancyURLopener,
URLopener as URLopener,
getproxies as getproxies,
pathname2url as pathname2url,
proxy_bypass as proxy_bypass,
url2pathname as url2pathname,
urlcleanup as urlcleanup,
urlretrieve as urlretrieve,
)
from urllib2 import (
AbstractBasicAuthHandler as AbstractBasicAuthHandler,
AbstractDigestAuthHandler as AbstractDigestAuthHandler,
BaseHandler as BaseHandler,
CacheFTPHandler as CacheFTPHandler,
FileHandler as FileHandler,
FTPHandler as FTPHandler,
HTTPBasicAuthHandler as HTTPBasicAuthHandler,
HTTPCookieProcessor as HTTPCookieProcessor,
HTTPDefaultErrorHandler as HTTPDefaultErrorHandler,
HTTPDigestAuthHandler as HTTPDigestAuthHandler,
HTTPErrorProcessor as HTTPErrorProcessor,
HTTPHandler as HTTPHandler,
HTTPPasswordMgr as HTTPPasswordMgr,
HTTPPasswordMgrWithDefaultRealm as HTTPPasswordMgrWithDefaultRealm,
HTTPRedirectHandler as HTTPRedirectHandler,
HTTPSHandler as HTTPSHandler,
OpenerDirector as OpenerDirector,
ProxyBasicAuthHandler as ProxyBasicAuthHandler,
ProxyDigestAuthHandler as ProxyDigestAuthHandler,
ProxyHandler as ProxyHandler,
Request as Request,
UnknownHandler as UnknownHandler,
build_opener as build_opener,
install_opener as install_opener,
parse_http_list as parse_http_list,
parse_keqv_list as parse_keqv_list,
urlopen as urlopen,
)

View File

@@ -1 +0,0 @@
from urllib import addbase as addbase, addclosehook as addclosehook, addinfo as addinfo, addinfourl as addinfourl

View File

@@ -1 +0,0 @@
from robotparser import RobotFileParser as RobotFileParser

View File

@@ -1 +0,0 @@
from .urllib.error import *

View File

@@ -1 +0,0 @@
from .urllib.parse import *

View File

@@ -1 +0,0 @@
from .urllib.request import *

View File

@@ -1 +0,0 @@
from .urllib.response import *

View File

@@ -1 +0,0 @@
from robotparser import *

View File

@@ -1 +0,0 @@
from xmlrpclib import *

View File

@@ -1,2 +1 @@
version = "1.16.*"
python2 = true

View File

@@ -68,17 +68,9 @@ def check_stubs():
else:
assert name.isidentifier(), f"Bad file name '{entry}' in stubs"
else:
if entry in ("@python2", "@tests"):
if entry == "@tests":
continue
assert_stubs_only(os.path.join("stubs", distribution, entry))
if os.path.isdir(os.path.join("stubs", distribution, "@python2")):
for entry in os.listdir(os.path.join("stubs", distribution, "@python2")):
if os.path.isfile(os.path.join("stubs", distribution, "@python2", entry)):
name, ext = os.path.splitext(entry)
assert name.isidentifier(), f"Bad file name '{entry}' in stubs"
assert ext == ".pyi", f"Unexpected file {entry} in @python2 stubs"
else:
assert_stubs_only(os.path.join("stubs", distribution, "@python2", entry))
def check_same_files():

View File

@@ -46,11 +46,13 @@ def check_new_syntax(tree: ast.AST, path: Path) -> list[str]:
class ObjectClassdefFinder(ast.NodeVisitor):
def visit_ClassDef(self, node: ast.ClassDef) -> None:
if any(isinstance(base, ast.Name) and base.id == "object" for base in node.bases):
errors.append(
f"{path}:{node.lineno}: Do not inherit from `object` explicitly, "
f"as all classes implicitly inherit from `object` in Python 3"
)
# Temporarily disable this check for two ex-Python 2 stubs.
if "paramiko" not in str(path) and "cryptography" not in str(path):
if any(isinstance(base, ast.Name) and base.id == "object" for base in node.bases):
errors.append(
f"{path}:{node.lineno}: Do not inherit from `object` explicitly, "
f"as all classes implicitly inherit from `object` in Python 3"
)
self.generic_visit(node)
class IfFinder(ast.NodeVisitor):

View File

@@ -101,7 +101,7 @@ def is_supported(distribution, major):
data = dict(tomli.loads(f.read()))
if major == 2:
# Python 2 is not supported by default.
return bool(data.get("python2", False)) or (dist_path / "@python2").exists()
return bool(data.get("python2", False))
# Python 3 is supported by default.
return has_py3_stubs(dist_path)
@@ -246,13 +246,8 @@ def add_third_party_files(
for dependency in dependencies:
add_third_party_files(dependency, major, files, args, configurations, seen_dists)
if major == 2 and os.path.isdir(os.path.join("stubs", distribution, "@python2")):
root = os.path.join("stubs", distribution, "@python2")
else:
root = os.path.join("stubs", distribution)
root = os.path.join("stubs", distribution)
for name in os.listdir(root):
if name == "@python2":
continue
mod, _ = os.path.splitext(name)
if mod.startswith("."):
continue