bpo-10049: Add a "no-op" (null) context manager to contextlib (GH-4464)

Adds a simpler and faster alternative to ExitStack for handling
single optional context managers without having to change the
lexical structure of your code.
diff --git a/Lib/contextlib.py b/Lib/contextlib.py
index 962ceda..c1f8a84 100644
--- a/Lib/contextlib.py
+++ b/Lib/contextlib.py
@@ -5,7 +5,7 @@
 from collections import deque
 from functools import wraps
 
-__all__ = ["asynccontextmanager", "contextmanager", "closing",
+__all__ = ["asynccontextmanager", "contextmanager", "closing", "nullcontext",
            "AbstractContextManager", "ContextDecorator", "ExitStack",
            "redirect_stdout", "redirect_stderr", "suppress"]
 
@@ -469,3 +469,24 @@
                 exc_details[1].__context__ = fixed_ctx
                 raise
         return received_exc and suppressed_exc
+
+
+class nullcontext(AbstractContextManager):
+    """Context manager that does no additional processing.
+
+    Used as a stand-in for a normal context manager, when a particular
+    block of code is only sometimes used with a normal context manager:
+
+    cm = optional_cm if condition else nullcontext()
+    with cm:
+        # Perform operation, using optional_cm if condition is True
+    """
+
+    def __init__(self, enter_result=None):
+        self.enter_result = enter_result
+
+    def __enter__(self):
+        return self.enter_result
+
+    def __exit__(self, *excinfo):
+        pass