From 00639fc954adfd94d74d39c451e3b5d54c53f2b4 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Fri, 18 Sep 2020 20:16:25 +0200 Subject: [PATCH 01/13] Reintroduced `types.EllipsisType` --- Lib/test/test_types.py | 4 ++++ Lib/types.py | 1 + 2 files changed, 5 insertions(+) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index f499fb9c8c51a4..829c03b883c598 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -713,6 +713,10 @@ def test_or_type_repr(self): assert repr(int | None) == "int | None" assert repr(int | typing.GenericAlias(list, int)) == "int | list[int]" + def test_ellipsis_type(self): + self.assertIsInstance(Ellipsis, types.EllipsisType) + + class MappingProxyTests(unittest.TestCase): mappingproxy = types.MappingProxyType diff --git a/Lib/types.py b/Lib/types.py index 9642e7212caac6..12d7d42ceec39d 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -296,5 +296,6 @@ def wrapped(*args, **kwargs): GenericAlias = type(list[int]) Union = type(int | str) +EllipsisType = type(Ellipsis) __all__ = [n for n in globals() if n[:1] != '_'] From 0a97a885178adaf79d93041aed5bbab3c9e7d264 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Fri, 18 Sep 2020 20:17:20 +0200 Subject: [PATCH 02/13] Replaced `type(...)` and `type(ellipsis)` with `types.EllipsisType` --- Lib/ast.py | 5 +++-- Lib/copy.py | 6 +++--- Lib/lib2to3/fixes/fix_types.py | 1 - Lib/pickle.py | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index d860917f4d03ae..bb346f5c76ce57 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -24,6 +24,7 @@ :copyright: Copyright 2008 by Armin Ronacher. :license: Python License. """ +import types import sys from _ast import * from contextlib import contextmanager, nullcontext @@ -572,7 +573,7 @@ def __new__(cls, *args, **kwargs): Str: (str,), Bytes: (bytes,), NameConstant: (type(None), bool), - Ellipsis: (type(...),), + Ellipsis: (types.EllipsisType,), } _const_types_not = { Num: (bool,), @@ -586,7 +587,7 @@ def __new__(cls, *args, **kwargs): complex: 'Num', str: 'Str', bytes: 'Bytes', - type(...): 'Ellipsis', + types.EllipsisType: 'Ellipsis', } class slice(AST): diff --git a/Lib/copy.py b/Lib/copy.py index dd41c54dffe1d7..687215fe59fec5 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -108,8 +108,8 @@ def _copy_immutable(x): return x for t in (type(None), int, float, bool, complex, str, tuple, bytes, frozenset, type, range, slice, property, - types.BuiltinFunctionType, type(Ellipsis), type(NotImplemented), - types.FunctionType, weakref.ref): + types.BuiltinFunctionType, types.EllipsisType, + type(NotImplemented), types.FunctionType, weakref.ref): d[t] = _copy_immutable t = getattr(types, "CodeType", None) if t is not None: @@ -182,7 +182,7 @@ def deepcopy(x, memo=None, _nil=[]): def _deepcopy_atomic(x, memo): return x d[type(None)] = _deepcopy_atomic -d[type(Ellipsis)] = _deepcopy_atomic +d[types.EllipsisType] = _deepcopy_atomic d[type(NotImplemented)] = _deepcopy_atomic d[int] = _deepcopy_atomic d[float] = _deepcopy_atomic diff --git a/Lib/lib2to3/fixes/fix_types.py b/Lib/lib2to3/fixes/fix_types.py index 67bf51f2f5b85a..a5e5742812536f 100644 --- a/Lib/lib2to3/fixes/fix_types.py +++ b/Lib/lib2to3/fixes/fix_types.py @@ -30,7 +30,6 @@ 'ComplexType' : 'complex', 'DictType': 'dict', 'DictionaryType' : 'dict', - 'EllipsisType' : 'type(Ellipsis)', #'FileType' : 'io.IOBase', 'FloatType': 'float', 'IntType': 'int', diff --git a/Lib/pickle.py b/Lib/pickle.py index cbac5f168b45eb..77ce4872967023 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -23,7 +23,7 @@ """ -from types import FunctionType +from types import FunctionType, EllipsisType from copyreg import dispatch_table from copyreg import _extension_registry, _inverted_registry, _extension_cache from itertools import islice @@ -1121,7 +1121,7 @@ def save_type(self, obj): return self.save_reduce(type, (None,), obj=obj) elif obj is type(NotImplemented): return self.save_reduce(type, (NotImplemented,), obj=obj) - elif obj is type(...): + elif obj is EllipsisType: return self.save_reduce(type, (...,), obj=obj) return self.save_global(obj) From 8aecfd52580453da2410f2c69d299a5d99016365 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Fri, 18 Sep 2020 20:31:20 +0200 Subject: [PATCH 03/13] Added `EllipsisType` to the documentation --- Doc/library/constants.rst | 3 ++- Doc/library/types.rst | 7 +++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index f17e1a37875168..9fd910d812b9a7 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -59,7 +59,8 @@ A small number of constants live in the built-in namespace. They are: .. index:: single: ...; ellipsis literal .. data:: Ellipsis - The same as the ellipsis literal "``...``". Special value used mostly in conjunction + The same as the ellipsis literal "``...``" and sole value of the type + :data:`types.EllipsisType`. Special value used mostly in conjunction with extended slicing syntax for user-defined container data types. diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 79acdf4499afd2..64d76317f2bf9c 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -236,6 +236,13 @@ Standard names are defined for the following types: Defaults to ``None``. Previously the attribute was optional. +.. data:: EllipsisType + + The type of :data:`Ellipsis`. + + .. versionadded:: 3.10 + + .. class:: TracebackType(tb_next, tb_frame, tb_lasti, tb_lineno) The type of traceback objects such as found in ``sys.exc_info()[2]``. From 4066b4bbbfb952950b4e4659ba3f47f479695570 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Sun, 20 Sep 2020 15:15:47 +0200 Subject: [PATCH 04/13] Added Misc/NEWS.d and whatsnew entries --- Doc/whatsnew/3.10.rst | 6 ++++++ .../next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst | 1 + 2 files changed, 7 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index ce888fec1d8c97..74fae2bd9a75ed 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -145,6 +145,12 @@ Add :data:`sys.orig_argv` attribute: the list of the original command line arguments passed to the Python executable. (Contributed by Victor Stinner in :issue:`23427`.) +types +----- + +Reintroduced the :data:`types.EllipsisType` class. +(Contributed by Bas van Beek in :issue:`41810`.) + unittest -------- diff --git a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst new file mode 100644 index 00000000000000..d04ff5a23a5355 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst @@ -0,0 +1 @@ +:data:`types.EllipsisType` has been reintroduced. From 307dcc1cc9f4f71dcd5d1f67012448e5e63a86c3 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Sun, 20 Sep 2020 15:20:34 +0200 Subject: [PATCH 05/13] Updated the acknowledgements --- Misc/ACKS | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/ACKS b/Misc/ACKS index d23797a2f55574..4023850e662dfd 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -134,6 +134,7 @@ Robin Becker Torsten Becker Bill Bedford MichaĆ Bednarski +Bas van Beek Ian Beer Stefan Behnel Reimer Behrends From 9fc1381b3e8ae8cb4fffb1e56df49ed899a64572 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Mon, 21 Sep 2020 20:32:12 +0200 Subject: [PATCH 06/13] Reintroduced `types.NoneType` and `types.NotImplementedType` --- Lib/test/test_types.py | 6 ++++++ Lib/types.py | 2 ++ 2 files changed, 8 insertions(+) diff --git a/Lib/test/test_types.py b/Lib/test/test_types.py index 829c03b883c598..52a59d54f044d9 100644 --- a/Lib/test/test_types.py +++ b/Lib/test/test_types.py @@ -716,6 +716,12 @@ def test_or_type_repr(self): def test_ellipsis_type(self): self.assertIsInstance(Ellipsis, types.EllipsisType) + def test_notimplemented_type(self): + self.assertIsInstance(NotImplemented, types.NotImplementedType) + + def test_none_type(self): + self.assertIsInstance(None, types.NoneType) + class MappingProxyTests(unittest.TestCase): mappingproxy = types.MappingProxyType diff --git a/Lib/types.py b/Lib/types.py index 12d7d42ceec39d..532f4806fc0226 100644 --- a/Lib/types.py +++ b/Lib/types.py @@ -297,5 +297,7 @@ def wrapped(*args, **kwargs): Union = type(int | str) EllipsisType = type(Ellipsis) +NoneType = type(None) +NotImplementedType = type(NotImplemented) __all__ = [n for n in globals() if n[:1] != '_'] From 2791a239bacfe1f16e9672ca063cdb1f29e9a147 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Mon, 21 Sep 2020 20:33:51 +0200 Subject: [PATCH 07/13] Replaced `type(NotImplemented)` and `type(None)` `type(NotImplemented)` and `type(None)` have, respectively, been replaced with `types.NotImplementedType` and `types.NoneType` --- Lib/ast.py | 4 ++-- Lib/copy.py | 8 ++++---- Lib/distutils/unixccompiler.py | 4 ++-- Lib/idlelib/run.py | 3 ++- Lib/imp.py | 2 +- Lib/inspect.py | 2 +- Lib/lib2to3/fixes/fix_types.py | 2 -- Lib/lib2to3/tests/test_fixers.py | 4 ---- Lib/pickle.py | 12 ++++++------ Lib/pickletools.py | 3 ++- Lib/pprint.py | 2 +- Lib/pydoc_data/topics.py | 2 +- Lib/random.py | 3 ++- Lib/runpy.py | 2 +- Lib/sqlite3/test/userfunctions.py | 9 +++++---- Lib/test/test_dataclasses.py | 5 +++-- Lib/test/test_descr.py | 22 +++++++++++----------- Lib/test/test_getargs2.py | 9 +++++---- Lib/test/test_nntplib.py | 3 ++- Lib/test/test_pwd.py | 3 ++- Lib/test/test_ssl.py | 3 ++- Lib/test/test_statistics.py | 3 ++- Lib/test/test_typing.py | 4 ++-- Lib/tkinter/__init__.py | 2 +- Lib/tkinter/ttk.py | 3 ++- Lib/typing.py | 16 ++++++++-------- Lib/unittest/test/testmock/testhelpers.py | 2 +- Lib/xmlrpc/client.py | 3 ++- 28 files changed, 73 insertions(+), 67 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index bb346f5c76ce57..ce1f4533f68e67 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -572,7 +572,7 @@ def __new__(cls, *args, **kwargs): Num: (int, float, complex), Str: (str,), Bytes: (bytes,), - NameConstant: (type(None), bool), + NameConstant: (types.NoneType, bool), Ellipsis: (types.EllipsisType,), } _const_types_not = { @@ -581,7 +581,7 @@ def __new__(cls, *args, **kwargs): _const_node_type_names = { bool: 'NameConstant', # should be before int - type(None): 'NameConstant', + types.NoneType: 'NameConstant', int: 'Num', float: 'Num', complex: 'Num', diff --git a/Lib/copy.py b/Lib/copy.py index 687215fe59fec5..245c55d7f16312 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -106,10 +106,10 @@ def copy(x): def _copy_immutable(x): return x -for t in (type(None), int, float, bool, complex, str, tuple, +for t in (types.NoneType, int, float, bool, complex, str, tuple, bytes, frozenset, type, range, slice, property, types.BuiltinFunctionType, types.EllipsisType, - type(NotImplemented), types.FunctionType, weakref.ref): + types.NotImplementedType, types.FunctionType, weakref.ref): d[t] = _copy_immutable t = getattr(types, "CodeType", None) if t is not None: @@ -181,9 +181,9 @@ def deepcopy(x, memo=None, _nil=[]): def _deepcopy_atomic(x, memo): return x -d[type(None)] = _deepcopy_atomic +d[types.NoneType] = _deepcopy_atomic d[types.EllipsisType] = _deepcopy_atomic -d[type(NotImplemented)] = _deepcopy_atomic +d[types.NotImplementedType] = _deepcopy_atomic d[int] = _deepcopy_atomic d[float] = _deepcopy_atomic d[bool] = _deepcopy_atomic diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py index 4d7a6de740ab3a..a97e9dfee40f17 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -13,7 +13,7 @@ * link shared library handled by 'cc -shared' """ -import os, sys, re +import os, sys, re, types from distutils import sysconfig from distutils.dep_util import newer @@ -157,7 +157,7 @@ def link(self, target_desc, objects, lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) - if not isinstance(output_dir, (str, type(None))): + if not isinstance(output_dir, (str, types.NoneType)): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 1e84ecc6584ef1..963fdcf1afa47f 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -15,6 +15,7 @@ import _thread as thread import threading import warnings +import types from idlelib import autocomplete # AutoComplete, fetch_encodings from idlelib import calltip # Calltip @@ -558,7 +559,7 @@ def runcode(self, code): except SystemExit as e: if e.args: # SystemExit called with an argument. ob = e.args[0] - if not isinstance(ob, (type(None), int)): + if not isinstance(ob, (types.NoneType, int)): print('SystemExit: ' + str(ob), file=sys.stderr) # Return to the interactive prompt. except: diff --git a/Lib/imp.py b/Lib/imp.py index 31f8c766381adc..32d175e20b7637 100644 --- a/Lib/imp.py +++ b/Lib/imp.py @@ -264,7 +264,7 @@ def find_module(name, path=None): """ if not isinstance(name, str): raise TypeError("'name' must be a str, not {}".format(type(name))) - elif not isinstance(path, (type(None), list)): + elif not isinstance(path, (types.NoneType, list)): # Backwards-compatibility raise RuntimeError("'path' must be None or a list, " "not {}".format(type(path))) diff --git a/Lib/inspect.py b/Lib/inspect.py index 887a3424057b6e..15a2759f388226 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -2034,7 +2034,7 @@ def wrap_value(s): except NameError: raise RuntimeError() - if isinstance(value, (str, int, float, bytes, bool, type(None))): + if isinstance(value, (str, int, float, bytes, bool, types.NoneType)): return ast.Constant(value) raise RuntimeError() diff --git a/Lib/lib2to3/fixes/fix_types.py b/Lib/lib2to3/fixes/fix_types.py index a5e5742812536f..a17c99e497d432 100644 --- a/Lib/lib2to3/fixes/fix_types.py +++ b/Lib/lib2to3/fixes/fix_types.py @@ -36,8 +36,6 @@ 'ListType': 'list', 'LongType': 'int', 'ObjectType' : 'object', - 'NoneType': 'type(None)', - 'NotImplementedType' : 'type(NotImplemented)', 'SliceType' : 'slice', 'StringType': 'bytes', # XXX ? 'StringTypes' : '(str,)', # XXX ? diff --git a/Lib/lib2to3/tests/test_fixers.py b/Lib/lib2to3/tests/test_fixers.py index 121ebe68e5402b..33ff1cc51a61a5 100644 --- a/Lib/lib2to3/tests/test_fixers.py +++ b/Lib/lib2to3/tests/test_fixers.py @@ -3276,10 +3276,6 @@ def test_basic_types_convert(self): a = """int""" self.check(b, a) - b = """types.NoneType""" - a = """type(None)""" - self.check(b, a) - b = "types.StringTypes" a = "(str,)" self.check(b, a) diff --git a/Lib/pickle.py b/Lib/pickle.py index 77ce4872967023..13c988d1320f4e 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -23,7 +23,7 @@ """ -from types import FunctionType, EllipsisType +import types from copyreg import dispatch_table from copyreg import _extension_registry, _inverted_registry, _extension_cache from itertools import islice @@ -737,7 +737,7 @@ def save_reduce(self, func, args, state=None, listitems=None, def save_none(self, obj): self.write(NONE) - dispatch[type(None)] = save_none + dispatch[types.NoneType] = save_none def save_bool(self, obj): if self.proto >= 2: @@ -1117,15 +1117,15 @@ def save_global(self, obj, name=None): self.memoize(obj) def save_type(self, obj): - if obj is type(None): + if obj is types.NoneType: return self.save_reduce(type, (None,), obj=obj) - elif obj is type(NotImplemented): + elif obj is types.NotImplementedType: return self.save_reduce(type, (NotImplemented,), obj=obj) - elif obj is EllipsisType: + elif obj is types.EllipsisType: return self.save_reduce(type, (...,), obj=obj) return self.save_global(obj) - dispatch[FunctionType] = save_global + dispatch[types.FunctionType] = save_global dispatch[type] = save_type diff --git a/Lib/pickletools.py b/Lib/pickletools.py index 95706e746c9870..ca681b0f03f5ad 100644 --- a/Lib/pickletools.py +++ b/Lib/pickletools.py @@ -15,6 +15,7 @@ import pickle import re import sys +import types __all__ = ['dis', 'genops', 'optimize'] @@ -1017,7 +1018,7 @@ def __repr__(self): pynone = StackObject( name="None", - obtype=type(None), + obtype=types.NoneType, doc="The Python None object.") pytuple = StackObject( diff --git a/Lib/pprint.py b/Lib/pprint.py index 213998e3491ef7..35fabe450dacbc 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -591,7 +591,7 @@ def _safe_repr(object, context, maxlevels, level, sort_dicts): return rep, (rep and not rep.startswith('<')), False _builtin_scalars = frozenset({str, bytes, bytearray, int, float, complex, - bool, type(None)}) + bool, _types.NoneType}) def _recursion(object): return ("<Recursion on %s with id=%s>" diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index 8aca5c0cb88e38..f4790eb4e27275 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1365,7 +1365,7 @@ 'explicitly return a\n' 'value. It supports no special operations. There is ' 'exactly one null\n' - 'object, named "None" (a built-in name). "type(None)()" ' + 'object, named "None" (a built-in name). "types.NoneType()" ' 'produces the\n' 'same singleton.\n' '\n' diff --git a/Lib/random.py b/Lib/random.py index 3ea369b81b3e50..e4a7597af64c00 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -55,6 +55,7 @@ from bisect import bisect as _bisect import os as _os import _random +import types try: # hashlib is pretty heavy to load, try lean internal module first @@ -154,7 +155,7 @@ def seed(self, a=None, version=2): a += _sha512(a).digest() a = int.from_bytes(a, 'big') - elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)): + elif not isinstance(a, (types.NoneType, int, float, str, bytes, bytearray)): _warn('Seeding based on hashing is deprecated\n' 'since Python 3.9 and will be removed in a subsequent ' 'version. The only \n' diff --git a/Lib/runpy.py b/Lib/runpy.py index 7e1e1ac5dde2df..c27c5bc9959857 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -261,7 +261,7 @@ def run_path(path_name, init_globals=None, run_name=None): if type(importer).__module__ == 'imp': if type(importer).__name__ == 'NullImporter': is_NullImporter = True - if isinstance(importer, type(None)) or is_NullImporter: + if isinstance(importer, types.NoneType) or is_NullImporter: # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files code, fname = _get_code_from_file(run_name, path_name) diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index c11c82e1275778..27b429ce84225f 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -21,6 +21,7 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. +import types import unittest import unittest.mock import sqlite3 as sqlite @@ -49,7 +50,7 @@ def func_isint(v): def func_isfloat(v): return type(v) is float def func_isnone(v): - return type(v) is type(None) + return type(v) is types.NoneType def func_isblob(v): return isinstance(v, (bytes, memoryview)) def func_islonglong(v): @@ -107,7 +108,7 @@ def __init__(self): self.val = None def step(self, whichType, val): - theType = {"str": str, "int": int, "float": float, "None": type(None), + theType = {"str": str, "int": int, "float": float, "None": types.NoneType, "blob": bytes} self.val = int(theType[whichType] is type(val)) @@ -119,7 +120,7 @@ def __init__(self): self.val = 0 def step(self, whichType, *vals): - theType = {"str": str, "int": int, "float": float, "None": type(None), + theType = {"str": str, "int": int, "float": float, "None": types.NoneType, "blob": bytes} for val in vals: self.val += int(theType[whichType] is type(val)) @@ -211,7 +212,7 @@ def CheckFuncReturnNull(self): cur = self.con.cursor() cur.execute("select returnnull()") val = cur.fetchone()[0] - self.assertEqual(type(val), type(None)) + self.assertEqual(type(val), types.NoneType) self.assertEqual(val, None) def CheckFuncReturnBlob(self): diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index b20103bdce51cb..8005f4f361c4b7 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -8,6 +8,7 @@ import inspect import builtins import unittest +import types from unittest.mock import Mock from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional from typing import get_type_hints @@ -2026,7 +2027,7 @@ class C: def test_docstring_one_field_with_default_none(self): @dataclass class C: - x: Union[int, type(None)] = None + x: Union[int, types.NoneType] = None self.assertDocStrEqual(C.__doc__, "C(x:Optional[int]=None)") @@ -2955,7 +2956,7 @@ def test_text_annotations(self): self.assertEqual( get_type_hints(dataclass_textanno.Bar.__init__), {'foo': dataclass_textanno.Foo, - 'return': type(None)}) + 'return': types.NoneType}) class TestMakeDataclass(unittest.TestCase): diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 307416c3300ae3..0d2e402f53ae77 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -3260,7 +3260,7 @@ class Int(int): __slots__ = [] cant(2, bool) o = object() cant(o, type(1)) - cant(o, type(None)) + cant(o, types.NoneType) del o class G(object): __slots__ = ["a", "b"] @@ -4000,35 +4000,35 @@ class D(C): def test_unsubclassable_types(self): with self.assertRaises(TypeError): - class X(type(None)): + class X(types.NoneType): pass with self.assertRaises(TypeError): - class X(object, type(None)): + class X(object, types.NoneType): pass with self.assertRaises(TypeError): - class X(type(None), object): + class X(types.NoneType, object): pass class O(object): pass with self.assertRaises(TypeError): - class X(O, type(None)): + class X(O, types.NoneType): pass with self.assertRaises(TypeError): - class X(type(None), O): + class X(types.NoneType, O): pass class X(object): pass with self.assertRaises(TypeError): - X.__bases__ = type(None), + X.__bases__ = types.NoneType, with self.assertRaises(TypeError): - X.__bases__ = object, type(None) + X.__bases__ = object, types.NoneType with self.assertRaises(TypeError): - X.__bases__ = type(None), object + X.__bases__ = types.NoneType, object with self.assertRaises(TypeError): - X.__bases__ = O, type(None) + X.__bases__ = O, types.NoneType with self.assertRaises(TypeError): - X.__bases__ = type(None), O + X.__bases__ = types.NoneType, O def test_mutable_bases_with_failing_mro(self): # Testing mutable bases with failing mro... diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_getargs2.py index 09560197913059..1803adc0b8ab8e 100644 --- a/Lib/test/test_getargs2.py +++ b/Lib/test/test_getargs2.py @@ -2,6 +2,7 @@ import math import string import sys +import types from test import support from test.support import import_helper # Skip this test if the _testcapi module isn't available. @@ -567,11 +568,11 @@ def test_args(self): ret = get_args() self.assertIn(ret, ((), None)) - self.assertIn(type(ret), (tuple, type(None))) + self.assertIn(type(ret), (tuple, types.NoneType)) ret = get_args(*()) self.assertIn(ret, ((), None)) - self.assertIn(type(ret), (tuple, type(None))) + self.assertIn(type(ret), (tuple, types.NoneType)) def test_tuple(self): from _testcapi import getargs_tuple @@ -605,11 +606,11 @@ def test_kwargs(self): ret = get_kwargs() self.assertIn(ret, ({}, None)) - self.assertIn(type(ret), (dict, type(None))) + self.assertIn(type(ret), (dict, types.NoneType)) ret = get_kwargs(**{}) self.assertIn(ret, ({}, None)) - self.assertIn(type(ret), (dict, type(None))) + self.assertIn(type(ret), (dict, types.NoneType)) def test_positional_args(self): # using all positional args diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index b11c19c84d3fb1..4a21e96033f032 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -9,6 +9,7 @@ import os.path import re import threading +import types from test import support from test.support import socket_helper @@ -126,7 +127,7 @@ def _check_art_dict(self, art_dict): "references", ":bytes", ":lines"} ) for v in art_dict.values(): - self.assertIsInstance(v, (str, type(None))) + self.assertIsInstance(v, (str, types.NoneType)) def test_xover(self): resp, count, first, last, name = self.server.group(self.GROUP_NAME) diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index f8f12571ca90e0..67602147660c56 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -1,5 +1,6 @@ import sys import unittest +import types from test.support import import_helper pwd = import_helper.import_module('pwd') @@ -21,7 +22,7 @@ def test_values(self): self.assertEqual(e[3], e.pw_gid) self.assertIsInstance(e.pw_gid, int) self.assertEqual(e[4], e.pw_gecos) - self.assertIn(type(e.pw_gecos), (str, type(None))) + self.assertIn(type(e.pw_gecos), (str, types.NoneType)) self.assertEqual(e[5], e.pw_dir) self.assertIsInstance(e.pw_dir, str) self.assertEqual(e[6], e.pw_shell) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 26eec969a82e0d..60f52c1a9308ca 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -25,6 +25,7 @@ import platform import sysconfig import functools +import types try: import ctypes except ImportError: @@ -971,7 +972,7 @@ def test_asn1object(self): self.assertIsInstance(obj.nid, int) self.assertIsInstance(obj.shortname, str) self.assertIsInstance(obj.longname, str) - self.assertIsInstance(obj.oid, (str, type(None))) + self.assertIsInstance(obj.oid, (str, types.NoneType)) val = ssl._ASN1Object.fromname('TLS Web Server Authentication') self.assertEqual(val, expected) diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index 997110732a1765..a6695f1318ce3f 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -14,6 +14,7 @@ import random import sys import unittest +import types from test import support from test.support import import_helper @@ -937,7 +938,7 @@ def test_float(self): self.check_type_coercions(float) def test_non_numeric_types(self): - for bad_type in (str, list, type(None), tuple, dict): + for bad_type in (str, list, types.NoneType, tuple, dict): for good_type in (int, float, Fraction, Decimal): self.assertCoerceRaises(good_type, bad_type) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 42aa430c5e107e..3465cf9fb0e4ce 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2845,7 +2845,7 @@ def test_get_type_hints_classes(self): self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) self.assertEqual(gth(ann_module.foo), {'x': int}) self.assertEqual(gth(NoneAndForward), - {'parent': NoneAndForward, 'meaning': type(None)}) + {'parent': NoneAndForward, 'meaning': types.NoneType}) self.assertEqual(gth(HasForeignBaseClass), {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, 'some_b': mod_generics_cache.B}) @@ -2885,7 +2885,7 @@ def testf(x, y): ... testf.__annotations__['x'] = 'int' self.assertEqual(gth(testf), {'x': int}) def testg(x: None): ... - self.assertEqual(gth(testg), {'x': type(None)}) + self.assertEqual(gth(testg), {'x': types.NoneType}) def test_get_type_hints_for_object_with_annotations(self): class A: ... diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 1067ab6a8b8a1d..0a5988dd61cecc 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -102,7 +102,7 @@ def _cnfmerge(cnfs): """Internal function.""" if isinstance(cnfs, dict): return cnfs - elif isinstance(cnfs, (type(None), str)): + elif isinstance(cnfs, (types.NoneType, str)): return cnfs else: cnf = {} diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index c7c71cd5a559cf..3b32b1b95994d4 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -25,6 +25,7 @@ # functions "tclobjs_to_py", "setup_master"] +import types import tkinter from tkinter import _flatten, _join, _stringify, _splitdict @@ -1085,7 +1086,7 @@ def configure(self, cnf=None, **kw): Setting a value for any of the "from", "from_" or "to" options generates a <<RangeChanged>> event.""" retval = Widget.configure(self, cnf, **kw) - if not isinstance(cnf, (type(None), str)): + if not isinstance(cnf, (types.NoneType, str)): kw.update(cnf) if any(['from' in kw, 'from_' in kw, 'to' in kw]): self.event_generate('<<RangeChanged>>') diff --git a/Lib/typing.py b/Lib/typing.py index 8c61bd8e084a85..356cab9cc3b0b8 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -121,7 +121,7 @@ def _type_check(arg, msg, is_argument=True): """Check that the argument is a type, and return it (internal helper). - As a special case, accept None and return type(None) instead. Also wrap strings + As a special case, accept None and return types.NoneType instead. Also wrap strings into ForwardRef instances. Consider several corner cases, for example plain special forms like Union are not valid, while Union[int, str] is OK, etc. The msg argument is a human-readable error message, e.g:: @@ -135,7 +135,7 @@ def _type_check(arg, msg, is_argument=True): invalid_generic_forms = invalid_generic_forms + (ClassVar, Final) if arg is None: - return type(None) + return types.NoneType if isinstance(arg, str): return ForwardRef(arg) if (isinstance(arg, _GenericAlias) and @@ -392,7 +392,7 @@ def Union(self, parameters): To define a union, use e.g. Union[int, str]. Details: - The arguments must be types and there must be at least one. - None as an argument is a special case and is replaced by - type(None). + types.NoneType. - Unions of unions are flattened, e.g.:: Union[Union[int, str], float] == Union[int, str, float] @@ -430,7 +430,7 @@ def Optional(self, parameters): Optional[X] is equivalent to Union[X, None]. """ arg = _type_check(parameters, f"{self} requires a single type.") - return Union[arg, type(None)] + return Union[arg, types.NoneType] @_SpecialForm def Literal(self, parameters): @@ -889,9 +889,9 @@ def __hash__(self): def __repr__(self): args = self.__args__ if len(args) == 2: - if args[0] is type(None): + if args[0] is types.NoneType: return f'typing.Optional[{_type_repr(args[1])}]' - elif args[1] is type(None): + elif args[1] is types.NoneType: return f'typing.Optional[{_type_repr(args[0])}]' return super().__repr__() @@ -1374,7 +1374,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): ann = base.__dict__.get('__annotations__', {}) for name, value in ann.items(): if value is None: - value = type(None) + value = types.NoneType if isinstance(value, str): value = ForwardRef(value, is_argument=False) value = _eval_type(value, base_globals, localns) @@ -1406,7 +1406,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): hints = dict(hints) for name, value in hints.items(): if value is None: - value = type(None) + value = types.NoneType if isinstance(value, str): value = ForwardRef(value) value = _eval_type(value, globalns, localns) diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 9e7ec5d62d5da2..10e7c35f0ae6ea 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -863,7 +863,7 @@ class Foo(object): mock = create_autospec(Foo) none = mock.bar - self.assertNotIsInstance(none, type(None)) + self.assertNotIsInstance(none, types.NoneType) none.foo() none.foo.assert_called_once_with() diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index d15d60d2937a82..575d67a0b3ff0f 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -138,6 +138,7 @@ from xml.parsers import expat import errno from io import BytesIO +import types try: import gzip except ImportError: @@ -533,7 +534,7 @@ def dump_nil (self, value, write): if not self.allow_none: raise TypeError("cannot marshal None unless allow_none is enabled") write("<value><nil/></value>") - dispatch[type(None)] = dump_nil + dispatch[types.NoneType] = dump_nil def dump_bool(self, value, write): write("<value><boolean>") From da1ab85ce2a913322f2ad30c3171ac7aecc70e37 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Mon, 21 Sep 2020 20:34:38 +0200 Subject: [PATCH 08/13] Added `types.NoneType` & `types.NotImplementedType` to whatsnew and the docs --- Doc/library/constants.rst | 5 +++-- Doc/library/types.rst | 14 ++++++++++++++ Doc/whatsnew/3.10.rst | 3 ++- .../2020-09-20-15-14-05.bpo-41810.7l8lyV.rst | 3 ++- 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index 9fd910d812b9a7..11bd0d2b4c89eb 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -19,14 +19,15 @@ A small number of constants live in the built-in namespace. They are: .. data:: None - The sole value of the type ``NoneType``. ``None`` is frequently used to + The sole value of the type :data:`types.NoneType`. ``None`` is frequently used to represent the absence of a value, as when default arguments are not passed to a function. Assignments to ``None`` are illegal and raise a :exc:`SyntaxError`. .. data:: NotImplemented - Special value which should be returned by the binary special methods + Sole value of the type :data:`types.NotImplementedType` and a + special value which should be returned by the binary special methods (e.g. :meth:`__eq__`, :meth:`__lt__`, :meth:`__add__`, :meth:`__rsub__`, etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods diff --git a/Doc/library/types.rst b/Doc/library/types.rst index 64d76317f2bf9c..25fa750f2ccacf 100644 --- a/Doc/library/types.rst +++ b/Doc/library/types.rst @@ -103,6 +103,13 @@ If you instantiate any of these types, note that signatures may vary between Pyt Standard names are defined for the following types: +.. data:: NoneType + + The type of :data:`None`. + + .. versionadded:: 3.10 + + .. data:: FunctionType LambdaType @@ -186,6 +193,13 @@ Standard names are defined for the following types: .. versionadded:: 3.7 +.. data:: NotImplementedType + + The type of :data:`NotImplemented`. + + .. versionadded:: 3.10 + + .. data:: MethodDescriptorType The type of methods of some built-in data types such as :meth:`str.join`. diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 74fae2bd9a75ed..a55fee2b238fd5 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -148,7 +148,8 @@ arguments passed to the Python executable. types ----- -Reintroduced the :data:`types.EllipsisType` class. +Reintroduced the :data:`types.EllipsisType`, :data:`types.NoneType` +and :data:`types.NotImplementedType` classes. (Contributed by Bas van Beek in :issue:`41810`.) unittest diff --git a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst index d04ff5a23a5355..a04f0f5a49a17b 100644 --- a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst +++ b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst @@ -1 +1,2 @@ -:data:`types.EllipsisType` has been reintroduced. +:data:`types.EllipsisType`, :data:`types.EllipsisType` and +:data:`types.NoneType` have been reintroduced. From f682623aa3001a4ac19e727c3103cdb0dce8672e Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Mon, 21 Sep 2020 22:28:58 +0200 Subject: [PATCH 09/13] Replaced a duplicate `EllipsisType` with `NotImplementedType` Addresses https://github.com/python/cpython/pull/22336#discussion_r492317442 --- .../NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst index a04f0f5a49a17b..38b35905f275b6 100644 --- a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst +++ b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst @@ -1,2 +1,3 @@ :data:`types.EllipsisType`, :data:`types.EllipsisType` and :data:`types.NoneType` have been reintroduced. +:data:`types.EllipsisType`, :data:`types.NotImplementedType` and From 370149882d2cea95f2fed7c732bcbb6ae343a3fe Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Mon, 21 Sep 2020 22:30:19 +0200 Subject: [PATCH 10/13] Provide motivation for the type reintroduction Addresses https://github.com/python/cpython/pull/22336#discussion_r492317123 --- Doc/whatsnew/3.10.rst | 3 ++- .../next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index a55fee2b238fd5..a5e28b3258fe7f 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -149,7 +149,8 @@ types ----- Reintroduced the :data:`types.EllipsisType`, :data:`types.NoneType` -and :data:`types.NotImplementedType` classes. +and :data:`types.NotImplementedType` classes, aforementioned types +now being useable as annotations. (Contributed by Bas van Beek in :issue:`41810`.) unittest diff --git a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst index 38b35905f275b6..c01e76285e5de7 100644 --- a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst +++ b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst @@ -1,3 +1,3 @@ -:data:`types.EllipsisType`, :data:`types.EllipsisType` and -:data:`types.NoneType` have been reintroduced. :data:`types.EllipsisType`, :data:`types.NotImplementedType` and +:data:`types.NoneType` have been reintroduced, aforementioned types +now being useable as annotations. From 33caa6fb32ec98766a9402670176ddde16d47738 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Mon, 21 Sep 2020 22:48:43 +0200 Subject: [PATCH 11/13] Explicitly mention static type checkers --- Doc/whatsnew/3.10.rst | 4 ++-- .../next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index a5e28b3258fe7f..f88281a934ca19 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -149,8 +149,8 @@ types ----- Reintroduced the :data:`types.EllipsisType`, :data:`types.NoneType` -and :data:`types.NotImplementedType` classes, aforementioned types -now being useable as annotations. +and :data:`types.NotImplementedType` classes, providing a new set +of types readily interpretable by type checkers. (Contributed by Bas van Beek in :issue:`41810`.) unittest diff --git a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst index c01e76285e5de7..515aea9e36ce95 100644 --- a/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst +++ b/Misc/NEWS.d/next/Library/2020-09-20-15-14-05.bpo-41810.7l8lyV.rst @@ -1,3 +1,3 @@ :data:`types.EllipsisType`, :data:`types.NotImplementedType` and -:data:`types.NoneType` have been reintroduced, aforementioned types -now being useable as annotations. +:data:`types.NoneType` have been reintroduced, providing a new set +of types readily interpretable by static type checkers. From 84ebe183e0c4ed9059e88fbede11092759f3eb66 Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Mon, 21 Sep 2020 23:40:24 +0200 Subject: [PATCH 12/13] Revert the `type(...)` to `types....` replacements Reverts https://github.com/python/cpython/pull/22336/commits/2791a239bacfe1f16e9672ca063cdb1f29e9a147 and https://github.com/python/cpython/pull/22336/commits/0a97a885178adaf79d93041aed5bbab3c9e7d264. Save this for a follow up. --- Lib/ast.py | 9 ++++----- Lib/copy.py | 12 ++++++------ Lib/distutils/unixccompiler.py | 4 ++-- Lib/idlelib/run.py | 3 +-- Lib/imp.py | 2 +- Lib/inspect.py | 2 +- Lib/lib2to3/fixes/fix_types.py | 3 +++ Lib/lib2to3/tests/test_fixers.py | 4 ++++ Lib/pickle.py | 12 ++++++------ Lib/pickletools.py | 3 +-- Lib/pprint.py | 2 +- Lib/pydoc_data/topics.py | 2 +- Lib/random.py | 3 +-- Lib/runpy.py | 2 +- Lib/sqlite3/test/userfunctions.py | 9 ++++----- Lib/test/test_dataclasses.py | 5 ++--- Lib/test/test_descr.py | 22 +++++++++++----------- Lib/test/test_getargs2.py | 9 ++++----- Lib/test/test_nntplib.py | 3 +-- Lib/test/test_pwd.py | 3 +-- Lib/test/test_ssl.py | 3 +-- Lib/test/test_statistics.py | 3 +-- Lib/test/test_typing.py | 4 ++-- Lib/tkinter/__init__.py | 2 +- Lib/tkinter/ttk.py | 3 +-- Lib/typing.py | 16 ++++++++-------- Lib/unittest/test/testmock/testhelpers.py | 2 +- Lib/xmlrpc/client.py | 3 +-- 28 files changed, 72 insertions(+), 78 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index ce1f4533f68e67..d860917f4d03ae 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -24,7 +24,6 @@ :copyright: Copyright 2008 by Armin Ronacher. :license: Python License. """ -import types import sys from _ast import * from contextlib import contextmanager, nullcontext @@ -572,8 +571,8 @@ def __new__(cls, *args, **kwargs): Num: (int, float, complex), Str: (str,), Bytes: (bytes,), - NameConstant: (types.NoneType, bool), - Ellipsis: (types.EllipsisType,), + NameConstant: (type(None), bool), + Ellipsis: (type(...),), } _const_types_not = { Num: (bool,), @@ -581,13 +580,13 @@ def __new__(cls, *args, **kwargs): _const_node_type_names = { bool: 'NameConstant', # should be before int - types.NoneType: 'NameConstant', + type(None): 'NameConstant', int: 'Num', float: 'Num', complex: 'Num', str: 'Str', bytes: 'Bytes', - types.EllipsisType: 'Ellipsis', + type(...): 'Ellipsis', } class slice(AST): diff --git a/Lib/copy.py b/Lib/copy.py index 245c55d7f16312..dd41c54dffe1d7 100644 --- a/Lib/copy.py +++ b/Lib/copy.py @@ -106,10 +106,10 @@ def copy(x): def _copy_immutable(x): return x -for t in (types.NoneType, int, float, bool, complex, str, tuple, +for t in (type(None), int, float, bool, complex, str, tuple, bytes, frozenset, type, range, slice, property, - types.BuiltinFunctionType, types.EllipsisType, - types.NotImplementedType, types.FunctionType, weakref.ref): + types.BuiltinFunctionType, type(Ellipsis), type(NotImplemented), + types.FunctionType, weakref.ref): d[t] = _copy_immutable t = getattr(types, "CodeType", None) if t is not None: @@ -181,9 +181,9 @@ def deepcopy(x, memo=None, _nil=[]): def _deepcopy_atomic(x, memo): return x -d[types.NoneType] = _deepcopy_atomic -d[types.EllipsisType] = _deepcopy_atomic -d[types.NotImplementedType] = _deepcopy_atomic +d[type(None)] = _deepcopy_atomic +d[type(Ellipsis)] = _deepcopy_atomic +d[type(NotImplemented)] = _deepcopy_atomic d[int] = _deepcopy_atomic d[float] = _deepcopy_atomic d[bool] = _deepcopy_atomic diff --git a/Lib/distutils/unixccompiler.py b/Lib/distutils/unixccompiler.py index a97e9dfee40f17..4d7a6de740ab3a 100644 --- a/Lib/distutils/unixccompiler.py +++ b/Lib/distutils/unixccompiler.py @@ -13,7 +13,7 @@ * link shared library handled by 'cc -shared' """ -import os, sys, re, types +import os, sys, re from distutils import sysconfig from distutils.dep_util import newer @@ -157,7 +157,7 @@ def link(self, target_desc, objects, lib_opts = gen_lib_options(self, library_dirs, runtime_library_dirs, libraries) - if not isinstance(output_dir, (str, types.NoneType)): + if not isinstance(output_dir, (str, type(None))): raise TypeError("'output_dir' must be a string or None") if output_dir is not None: output_filename = os.path.join(output_dir, output_filename) diff --git a/Lib/idlelib/run.py b/Lib/idlelib/run.py index 963fdcf1afa47f..1e84ecc6584ef1 100644 --- a/Lib/idlelib/run.py +++ b/Lib/idlelib/run.py @@ -15,7 +15,6 @@ import _thread as thread import threading import warnings -import types from idlelib import autocomplete # AutoComplete, fetch_encodings from idlelib import calltip # Calltip @@ -559,7 +558,7 @@ def runcode(self, code): except SystemExit as e: if e.args: # SystemExit called with an argument. ob = e.args[0] - if not isinstance(ob, (types.NoneType, int)): + if not isinstance(ob, (type(None), int)): print('SystemExit: ' + str(ob), file=sys.stderr) # Return to the interactive prompt. except: diff --git a/Lib/imp.py b/Lib/imp.py index 32d175e20b7637..31f8c766381adc 100644 --- a/Lib/imp.py +++ b/Lib/imp.py @@ -264,7 +264,7 @@ def find_module(name, path=None): """ if not isinstance(name, str): raise TypeError("'name' must be a str, not {}".format(type(name))) - elif not isinstance(path, (types.NoneType, list)): + elif not isinstance(path, (type(None), list)): # Backwards-compatibility raise RuntimeError("'path' must be None or a list, " "not {}".format(type(path))) diff --git a/Lib/inspect.py b/Lib/inspect.py index 15a2759f388226..887a3424057b6e 100644 --- a/Lib/inspect.py +++ b/Lib/inspect.py @@ -2034,7 +2034,7 @@ def wrap_value(s): except NameError: raise RuntimeError() - if isinstance(value, (str, int, float, bytes, bool, types.NoneType)): + if isinstance(value, (str, int, float, bytes, bool, type(None))): return ast.Constant(value) raise RuntimeError() diff --git a/Lib/lib2to3/fixes/fix_types.py b/Lib/lib2to3/fixes/fix_types.py index a17c99e497d432..67bf51f2f5b85a 100644 --- a/Lib/lib2to3/fixes/fix_types.py +++ b/Lib/lib2to3/fixes/fix_types.py @@ -30,12 +30,15 @@ 'ComplexType' : 'complex', 'DictType': 'dict', 'DictionaryType' : 'dict', + 'EllipsisType' : 'type(Ellipsis)', #'FileType' : 'io.IOBase', 'FloatType': 'float', 'IntType': 'int', 'ListType': 'list', 'LongType': 'int', 'ObjectType' : 'object', + 'NoneType': 'type(None)', + 'NotImplementedType' : 'type(NotImplemented)', 'SliceType' : 'slice', 'StringType': 'bytes', # XXX ? 'StringTypes' : '(str,)', # XXX ? diff --git a/Lib/lib2to3/tests/test_fixers.py b/Lib/lib2to3/tests/test_fixers.py index 33ff1cc51a61a5..121ebe68e5402b 100644 --- a/Lib/lib2to3/tests/test_fixers.py +++ b/Lib/lib2to3/tests/test_fixers.py @@ -3276,6 +3276,10 @@ def test_basic_types_convert(self): a = """int""" self.check(b, a) + b = """types.NoneType""" + a = """type(None)""" + self.check(b, a) + b = "types.StringTypes" a = "(str,)" self.check(b, a) diff --git a/Lib/pickle.py b/Lib/pickle.py index 13c988d1320f4e..cbac5f168b45eb 100644 --- a/Lib/pickle.py +++ b/Lib/pickle.py @@ -23,7 +23,7 @@ """ -import types +from types import FunctionType from copyreg import dispatch_table from copyreg import _extension_registry, _inverted_registry, _extension_cache from itertools import islice @@ -737,7 +737,7 @@ def save_reduce(self, func, args, state=None, listitems=None, def save_none(self, obj): self.write(NONE) - dispatch[types.NoneType] = save_none + dispatch[type(None)] = save_none def save_bool(self, obj): if self.proto >= 2: @@ -1117,15 +1117,15 @@ def save_global(self, obj, name=None): self.memoize(obj) def save_type(self, obj): - if obj is types.NoneType: + if obj is type(None): return self.save_reduce(type, (None,), obj=obj) - elif obj is types.NotImplementedType: + elif obj is type(NotImplemented): return self.save_reduce(type, (NotImplemented,), obj=obj) - elif obj is types.EllipsisType: + elif obj is type(...): return self.save_reduce(type, (...,), obj=obj) return self.save_global(obj) - dispatch[types.FunctionType] = save_global + dispatch[FunctionType] = save_global dispatch[type] = save_type diff --git a/Lib/pickletools.py b/Lib/pickletools.py index ca681b0f03f5ad..95706e746c9870 100644 --- a/Lib/pickletools.py +++ b/Lib/pickletools.py @@ -15,7 +15,6 @@ import pickle import re import sys -import types __all__ = ['dis', 'genops', 'optimize'] @@ -1018,7 +1017,7 @@ def __repr__(self): pynone = StackObject( name="None", - obtype=types.NoneType, + obtype=type(None), doc="The Python None object.") pytuple = StackObject( diff --git a/Lib/pprint.py b/Lib/pprint.py index 35fabe450dacbc..213998e3491ef7 100644 --- a/Lib/pprint.py +++ b/Lib/pprint.py @@ -591,7 +591,7 @@ def _safe_repr(object, context, maxlevels, level, sort_dicts): return rep, (rep and not rep.startswith('<')), False _builtin_scalars = frozenset({str, bytes, bytearray, int, float, complex, - bool, _types.NoneType}) + bool, type(None)}) def _recursion(object): return ("<Recursion on %s with id=%s>" diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index f4790eb4e27275..8aca5c0cb88e38 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1365,7 +1365,7 @@ 'explicitly return a\n' 'value. It supports no special operations. There is ' 'exactly one null\n' - 'object, named "None" (a built-in name). "types.NoneType()" ' + 'object, named "None" (a built-in name). "type(None)()" ' 'produces the\n' 'same singleton.\n' '\n' diff --git a/Lib/random.py b/Lib/random.py index e4a7597af64c00..3ea369b81b3e50 100644 --- a/Lib/random.py +++ b/Lib/random.py @@ -55,7 +55,6 @@ from bisect import bisect as _bisect import os as _os import _random -import types try: # hashlib is pretty heavy to load, try lean internal module first @@ -155,7 +154,7 @@ def seed(self, a=None, version=2): a += _sha512(a).digest() a = int.from_bytes(a, 'big') - elif not isinstance(a, (types.NoneType, int, float, str, bytes, bytearray)): + elif not isinstance(a, (type(None), int, float, str, bytes, bytearray)): _warn('Seeding based on hashing is deprecated\n' 'since Python 3.9 and will be removed in a subsequent ' 'version. The only \n' diff --git a/Lib/runpy.py b/Lib/runpy.py index c27c5bc9959857..7e1e1ac5dde2df 100644 --- a/Lib/runpy.py +++ b/Lib/runpy.py @@ -261,7 +261,7 @@ def run_path(path_name, init_globals=None, run_name=None): if type(importer).__module__ == 'imp': if type(importer).__name__ == 'NullImporter': is_NullImporter = True - if isinstance(importer, types.NoneType) or is_NullImporter: + if isinstance(importer, type(None)) or is_NullImporter: # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files code, fname = _get_code_from_file(run_name, path_name) diff --git a/Lib/sqlite3/test/userfunctions.py b/Lib/sqlite3/test/userfunctions.py index 27b429ce84225f..c11c82e1275778 100644 --- a/Lib/sqlite3/test/userfunctions.py +++ b/Lib/sqlite3/test/userfunctions.py @@ -21,7 +21,6 @@ # misrepresented as being the original software. # 3. This notice may not be removed or altered from any source distribution. -import types import unittest import unittest.mock import sqlite3 as sqlite @@ -50,7 +49,7 @@ def func_isint(v): def func_isfloat(v): return type(v) is float def func_isnone(v): - return type(v) is types.NoneType + return type(v) is type(None) def func_isblob(v): return isinstance(v, (bytes, memoryview)) def func_islonglong(v): @@ -108,7 +107,7 @@ def __init__(self): self.val = None def step(self, whichType, val): - theType = {"str": str, "int": int, "float": float, "None": types.NoneType, + theType = {"str": str, "int": int, "float": float, "None": type(None), "blob": bytes} self.val = int(theType[whichType] is type(val)) @@ -120,7 +119,7 @@ def __init__(self): self.val = 0 def step(self, whichType, *vals): - theType = {"str": str, "int": int, "float": float, "None": types.NoneType, + theType = {"str": str, "int": int, "float": float, "None": type(None), "blob": bytes} for val in vals: self.val += int(theType[whichType] is type(val)) @@ -212,7 +211,7 @@ def CheckFuncReturnNull(self): cur = self.con.cursor() cur.execute("select returnnull()") val = cur.fetchone()[0] - self.assertEqual(type(val), types.NoneType) + self.assertEqual(type(val), type(None)) self.assertEqual(val, None) def CheckFuncReturnBlob(self): diff --git a/Lib/test/test_dataclasses.py b/Lib/test/test_dataclasses.py index 8005f4f361c4b7..b20103bdce51cb 100644 --- a/Lib/test/test_dataclasses.py +++ b/Lib/test/test_dataclasses.py @@ -8,7 +8,6 @@ import inspect import builtins import unittest -import types from unittest.mock import Mock from typing import ClassVar, Any, List, Union, Tuple, Dict, Generic, TypeVar, Optional from typing import get_type_hints @@ -2027,7 +2026,7 @@ class C: def test_docstring_one_field_with_default_none(self): @dataclass class C: - x: Union[int, types.NoneType] = None + x: Union[int, type(None)] = None self.assertDocStrEqual(C.__doc__, "C(x:Optional[int]=None)") @@ -2956,7 +2955,7 @@ def test_text_annotations(self): self.assertEqual( get_type_hints(dataclass_textanno.Bar.__init__), {'foo': dataclass_textanno.Foo, - 'return': types.NoneType}) + 'return': type(None)}) class TestMakeDataclass(unittest.TestCase): diff --git a/Lib/test/test_descr.py b/Lib/test/test_descr.py index 0d2e402f53ae77..307416c3300ae3 100644 --- a/Lib/test/test_descr.py +++ b/Lib/test/test_descr.py @@ -3260,7 +3260,7 @@ class Int(int): __slots__ = [] cant(2, bool) o = object() cant(o, type(1)) - cant(o, types.NoneType) + cant(o, type(None)) del o class G(object): __slots__ = ["a", "b"] @@ -4000,35 +4000,35 @@ class D(C): def test_unsubclassable_types(self): with self.assertRaises(TypeError): - class X(types.NoneType): + class X(type(None)): pass with self.assertRaises(TypeError): - class X(object, types.NoneType): + class X(object, type(None)): pass with self.assertRaises(TypeError): - class X(types.NoneType, object): + class X(type(None), object): pass class O(object): pass with self.assertRaises(TypeError): - class X(O, types.NoneType): + class X(O, type(None)): pass with self.assertRaises(TypeError): - class X(types.NoneType, O): + class X(type(None), O): pass class X(object): pass with self.assertRaises(TypeError): - X.__bases__ = types.NoneType, + X.__bases__ = type(None), with self.assertRaises(TypeError): - X.__bases__ = object, types.NoneType + X.__bases__ = object, type(None) with self.assertRaises(TypeError): - X.__bases__ = types.NoneType, object + X.__bases__ = type(None), object with self.assertRaises(TypeError): - X.__bases__ = O, types.NoneType + X.__bases__ = O, type(None) with self.assertRaises(TypeError): - X.__bases__ = types.NoneType, O + X.__bases__ = type(None), O def test_mutable_bases_with_failing_mro(self): # Testing mutable bases with failing mro... diff --git a/Lib/test/test_getargs2.py b/Lib/test/test_getargs2.py index 1803adc0b8ab8e..09560197913059 100644 --- a/Lib/test/test_getargs2.py +++ b/Lib/test/test_getargs2.py @@ -2,7 +2,6 @@ import math import string import sys -import types from test import support from test.support import import_helper # Skip this test if the _testcapi module isn't available. @@ -568,11 +567,11 @@ def test_args(self): ret = get_args() self.assertIn(ret, ((), None)) - self.assertIn(type(ret), (tuple, types.NoneType)) + self.assertIn(type(ret), (tuple, type(None))) ret = get_args(*()) self.assertIn(ret, ((), None)) - self.assertIn(type(ret), (tuple, types.NoneType)) + self.assertIn(type(ret), (tuple, type(None))) def test_tuple(self): from _testcapi import getargs_tuple @@ -606,11 +605,11 @@ def test_kwargs(self): ret = get_kwargs() self.assertIn(ret, ({}, None)) - self.assertIn(type(ret), (dict, types.NoneType)) + self.assertIn(type(ret), (dict, type(None))) ret = get_kwargs(**{}) self.assertIn(ret, ({}, None)) - self.assertIn(type(ret), (dict, types.NoneType)) + self.assertIn(type(ret), (dict, type(None))) def test_positional_args(self): # using all positional args diff --git a/Lib/test/test_nntplib.py b/Lib/test/test_nntplib.py index 4a21e96033f032..b11c19c84d3fb1 100644 --- a/Lib/test/test_nntplib.py +++ b/Lib/test/test_nntplib.py @@ -9,7 +9,6 @@ import os.path import re import threading -import types from test import support from test.support import socket_helper @@ -127,7 +126,7 @@ def _check_art_dict(self, art_dict): "references", ":bytes", ":lines"} ) for v in art_dict.values(): - self.assertIsInstance(v, (str, types.NoneType)) + self.assertIsInstance(v, (str, type(None))) def test_xover(self): resp, count, first, last, name = self.server.group(self.GROUP_NAME) diff --git a/Lib/test/test_pwd.py b/Lib/test/test_pwd.py index 67602147660c56..f8f12571ca90e0 100644 --- a/Lib/test/test_pwd.py +++ b/Lib/test/test_pwd.py @@ -1,6 +1,5 @@ import sys import unittest -import types from test.support import import_helper pwd = import_helper.import_module('pwd') @@ -22,7 +21,7 @@ def test_values(self): self.assertEqual(e[3], e.pw_gid) self.assertIsInstance(e.pw_gid, int) self.assertEqual(e[4], e.pw_gecos) - self.assertIn(type(e.pw_gecos), (str, types.NoneType)) + self.assertIn(type(e.pw_gecos), (str, type(None))) self.assertEqual(e[5], e.pw_dir) self.assertIsInstance(e.pw_dir, str) self.assertEqual(e[6], e.pw_shell) diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index 60f52c1a9308ca..26eec969a82e0d 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -25,7 +25,6 @@ import platform import sysconfig import functools -import types try: import ctypes except ImportError: @@ -972,7 +971,7 @@ def test_asn1object(self): self.assertIsInstance(obj.nid, int) self.assertIsInstance(obj.shortname, str) self.assertIsInstance(obj.longname, str) - self.assertIsInstance(obj.oid, (str, types.NoneType)) + self.assertIsInstance(obj.oid, (str, type(None))) val = ssl._ASN1Object.fromname('TLS Web Server Authentication') self.assertEqual(val, expected) diff --git a/Lib/test/test_statistics.py b/Lib/test/test_statistics.py index a6695f1318ce3f..997110732a1765 100644 --- a/Lib/test/test_statistics.py +++ b/Lib/test/test_statistics.py @@ -14,7 +14,6 @@ import random import sys import unittest -import types from test import support from test.support import import_helper @@ -938,7 +937,7 @@ def test_float(self): self.check_type_coercions(float) def test_non_numeric_types(self): - for bad_type in (str, list, types.NoneType, tuple, dict): + for bad_type in (str, list, type(None), tuple, dict): for good_type in (int, float, Fraction, Decimal): self.assertCoerceRaises(good_type, bad_type) diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py index 3465cf9fb0e4ce..42aa430c5e107e 100644 --- a/Lib/test/test_typing.py +++ b/Lib/test/test_typing.py @@ -2845,7 +2845,7 @@ def test_get_type_hints_classes(self): self.assertEqual(gth(ann_module.S), {'x': str, 'y': str}) self.assertEqual(gth(ann_module.foo), {'x': int}) self.assertEqual(gth(NoneAndForward), - {'parent': NoneAndForward, 'meaning': types.NoneType}) + {'parent': NoneAndForward, 'meaning': type(None)}) self.assertEqual(gth(HasForeignBaseClass), {'some_xrepr': XRepr, 'other_a': mod_generics_cache.A, 'some_b': mod_generics_cache.B}) @@ -2885,7 +2885,7 @@ def testf(x, y): ... testf.__annotations__['x'] = 'int' self.assertEqual(gth(testf), {'x': int}) def testg(x: None): ... - self.assertEqual(gth(testg), {'x': types.NoneType}) + self.assertEqual(gth(testg), {'x': type(None)}) def test_get_type_hints_for_object_with_annotations(self): class A: ... diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 0a5988dd61cecc..1067ab6a8b8a1d 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -102,7 +102,7 @@ def _cnfmerge(cnfs): """Internal function.""" if isinstance(cnfs, dict): return cnfs - elif isinstance(cnfs, (types.NoneType, str)): + elif isinstance(cnfs, (type(None), str)): return cnfs else: cnf = {} diff --git a/Lib/tkinter/ttk.py b/Lib/tkinter/ttk.py index 3b32b1b95994d4..c7c71cd5a559cf 100644 --- a/Lib/tkinter/ttk.py +++ b/Lib/tkinter/ttk.py @@ -25,7 +25,6 @@ # functions "tclobjs_to_py", "setup_master"] -import types import tkinter from tkinter import _flatten, _join, _stringify, _splitdict @@ -1086,7 +1085,7 @@ def configure(self, cnf=None, **kw): Setting a value for any of the "from", "from_" or "to" options generates a <<RangeChanged>> event.""" retval = Widget.configure(self, cnf, **kw) - if not isinstance(cnf, (types.NoneType, str)): + if not isinstance(cnf, (type(None), str)): kw.update(cnf) if any(['from' in kw, 'from_' in kw, 'to' in kw]): self.event_generate('<<RangeChanged>>') diff --git a/Lib/typing.py b/Lib/typing.py index 356cab9cc3b0b8..8c61bd8e084a85 100644 --- a/Lib/typing.py +++ b/Lib/typing.py @@ -121,7 +121,7 @@ def _type_check(arg, msg, is_argument=True): """Check that the argument is a type, and return it (internal helper). - As a special case, accept None and return types.NoneType instead. Also wrap strings + As a special case, accept None and return type(None) instead. Also wrap strings into ForwardRef instances. Consider several corner cases, for example plain special forms like Union are not valid, while Union[int, str] is OK, etc. The msg argument is a human-readable error message, e.g:: @@ -135,7 +135,7 @@ def _type_check(arg, msg, is_argument=True): invalid_generic_forms = invalid_generic_forms + (ClassVar, Final) if arg is None: - return types.NoneType + return type(None) if isinstance(arg, str): return ForwardRef(arg) if (isinstance(arg, _GenericAlias) and @@ -392,7 +392,7 @@ def Union(self, parameters): To define a union, use e.g. Union[int, str]. Details: - The arguments must be types and there must be at least one. - None as an argument is a special case and is replaced by - types.NoneType. + type(None). - Unions of unions are flattened, e.g.:: Union[Union[int, str], float] == Union[int, str, float] @@ -430,7 +430,7 @@ def Optional(self, parameters): Optional[X] is equivalent to Union[X, None]. """ arg = _type_check(parameters, f"{self} requires a single type.") - return Union[arg, types.NoneType] + return Union[arg, type(None)] @_SpecialForm def Literal(self, parameters): @@ -889,9 +889,9 @@ def __hash__(self): def __repr__(self): args = self.__args__ if len(args) == 2: - if args[0] is types.NoneType: + if args[0] is type(None): return f'typing.Optional[{_type_repr(args[1])}]' - elif args[1] is types.NoneType: + elif args[1] is type(None): return f'typing.Optional[{_type_repr(args[0])}]' return super().__repr__() @@ -1374,7 +1374,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): ann = base.__dict__.get('__annotations__', {}) for name, value in ann.items(): if value is None: - value = types.NoneType + value = type(None) if isinstance(value, str): value = ForwardRef(value, is_argument=False) value = _eval_type(value, base_globals, localns) @@ -1406,7 +1406,7 @@ def get_type_hints(obj, globalns=None, localns=None, include_extras=False): hints = dict(hints) for name, value in hints.items(): if value is None: - value = types.NoneType + value = type(None) if isinstance(value, str): value = ForwardRef(value) value = _eval_type(value, globalns, localns) diff --git a/Lib/unittest/test/testmock/testhelpers.py b/Lib/unittest/test/testmock/testhelpers.py index 10e7c35f0ae6ea..9e7ec5d62d5da2 100644 --- a/Lib/unittest/test/testmock/testhelpers.py +++ b/Lib/unittest/test/testmock/testhelpers.py @@ -863,7 +863,7 @@ class Foo(object): mock = create_autospec(Foo) none = mock.bar - self.assertNotIsInstance(none, types.NoneType) + self.assertNotIsInstance(none, type(None)) none.foo() none.foo.assert_called_once_with() diff --git a/Lib/xmlrpc/client.py b/Lib/xmlrpc/client.py index 575d67a0b3ff0f..d15d60d2937a82 100644 --- a/Lib/xmlrpc/client.py +++ b/Lib/xmlrpc/client.py @@ -138,7 +138,6 @@ from xml.parsers import expat import errno from io import BytesIO -import types try: import gzip except ImportError: @@ -534,7 +533,7 @@ def dump_nil (self, value, write): if not self.allow_none: raise TypeError("cannot marshal None unless allow_none is enabled") write("<value><nil/></value>") - dispatch[types.NoneType] = dump_nil + dispatch[type(None)] = dump_nil def dump_bool(self, value, write): write("<value><boolean>") From 23ed559738432aae3e2cca47636c75f15abc341a Mon Sep 17 00:00:00 2001 From: Bas van Beek <b.f.van.beek@vu.nl> Date: Tue, 22 Sep 2020 16:28:25 +0200 Subject: [PATCH 13/13] Reworded parts of the `constants` documentation Addresses https://github.com/python/cpython/pull/22336#discussion_r492478512, https://github.com/python/cpython/pull/22336#discussion_r492479743 & https://github.com/python/cpython/pull/22336#discussion_r492480008 --- Doc/library/constants.rst | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/Doc/library/constants.rst b/Doc/library/constants.rst index 11bd0d2b4c89eb..38dd552a0363ac 100644 --- a/Doc/library/constants.rst +++ b/Doc/library/constants.rst @@ -19,20 +19,21 @@ A small number of constants live in the built-in namespace. They are: .. data:: None - The sole value of the type :data:`types.NoneType`. ``None`` is frequently used to - represent the absence of a value, as when default arguments are not passed to a - function. Assignments to ``None`` are illegal and raise a :exc:`SyntaxError`. + An object frequently used to represent the absence of a value, as when + default arguments are not passed to a function. Assignments to ``None`` + are illegal and raise a :exc:`SyntaxError`. + ``None`` is the sole instance of the :data:`NoneType` type. .. data:: NotImplemented - Sole value of the type :data:`types.NotImplementedType` and a - special value which should be returned by the binary special methods + A special value which should be returned by the binary special methods (e.g. :meth:`__eq__`, :meth:`__lt__`, :meth:`__add__`, :meth:`__rsub__`, etc.) to indicate that the operation is not implemented with respect to the other type; may be returned by the in-place binary special methods (e.g. :meth:`__imul__`, :meth:`__iand__`, etc.) for the same purpose. It should not be evaluated in a boolean context. + ``NotImplemented`` is the sole instance of the :data:`types.NotImplementedType` type. .. note:: @@ -60,9 +61,9 @@ A small number of constants live in the built-in namespace. They are: .. index:: single: ...; ellipsis literal .. data:: Ellipsis - The same as the ellipsis literal "``...``" and sole value of the type - :data:`types.EllipsisType`. Special value used mostly in conjunction + The same as the ellipsis literal "``...``". Special value used mostly in conjunction with extended slicing syntax for user-defined container data types. + ``Ellipsis`` is the sole instance of the :data:`types.EllipsisType` type. .. data:: __debug__