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__