bpo-29783: Replace codecs.open() with io.open() (#599)

diff --git a/Doc/tools/extensions/pyspecific.py b/Doc/tools/extensions/pyspecific.py
index 1b91259..461e7a2 100644
--- a/Doc/tools/extensions/pyspecific.py
+++ b/Doc/tools/extensions/pyspecific.py
@@ -10,7 +10,7 @@
 """
 
 import re
-import codecs
+import io
 from os import path
 from time import asctime
 from pprint import pformat
@@ -254,11 +254,8 @@
         fpath = path.join(source_dir, fname)
         self.state.document.settings.record_dependencies.add(fpath)
         try:
-            fp = codecs.open(fpath, encoding='utf-8')
-            try:
+            with io.open(fpath, encoding='utf-8') as fp:
                 content = fp.read()
-            finally:
-                fp.close()
         except Exception:
             text = 'The NEWS file is not available.'
             node = nodes.strong(text, text)
diff --git a/Lib/codecs.py b/Lib/codecs.py
index 39ec845..44618cb 100644
--- a/Lib/codecs.py
+++ b/Lib/codecs.py
@@ -5,9 +5,10 @@
 
 (c) Copyright CNRI, All Rights Reserved. NO WARRANTY.
 
-"""#"
+"""
 
-import builtins, sys
+import builtins
+import sys
 
 ### Registry and builtin stateless codec functions
 
@@ -739,7 +740,7 @@
         """
         return getattr(self.stream, name)
 
-    # these are needed to make "with codecs.open(...)" work properly
+    # these are needed to make "with StreamReaderWriter(...)" work properly
 
     def __enter__(self):
         return self
diff --git a/Lib/lib2to3/pgen2/driver.py b/Lib/lib2to3/pgen2/driver.py
index a27b9cb..e5e4824 100644
--- a/Lib/lib2to3/pgen2/driver.py
+++ b/Lib/lib2to3/pgen2/driver.py
@@ -94,11 +94,8 @@
 
     def parse_file(self, filename, encoding=None, debug=False):
         """Parse a file and return the syntax tree."""
-        stream = codecs.open(filename, "r", encoding)
-        try:
+        with io.open(filename, "r", encoding=encoding) as stream:
             return self.parse_stream(stream, debug)
-        finally:
-            stream.close()
 
     def parse_string(self, text, debug=False):
         """Parse a string and return the syntax tree."""
diff --git a/Lib/lib2to3/refactor.py b/Lib/lib2to3/refactor.py
index 70b2a00..db2e38d 100644
--- a/Lib/lib2to3/refactor.py
+++ b/Lib/lib2to3/refactor.py
@@ -12,12 +12,12 @@
 
 
 # Python imports
+import io
 import os
 import sys
 import logging
 import operator
 import collections
-import io
 from itertools import chain
 
 # Local imports
@@ -107,22 +107,6 @@
 def _identity(obj):
     return obj
 
-if sys.version_info < (3, 0):
-    import codecs
-    _open_with_encoding = codecs.open
-    # codecs.open doesn't translate newlines sadly.
-    def _from_system_newlines(input):
-        return input.replace("\r\n", "\n")
-    def _to_system_newlines(input):
-        if os.linesep != "\n":
-            return input.replace("\n", os.linesep)
-        else:
-            return input
-else:
-    _open_with_encoding = open
-    _from_system_newlines = _identity
-    _to_system_newlines = _identity
-
 
 def _detect_future_features(source):
     have_docstring = False
@@ -330,8 +314,8 @@
             encoding = tokenize.detect_encoding(f.readline)[0]
         finally:
             f.close()
-        with _open_with_encoding(filename, "r", encoding=encoding) as f:
-            return _from_system_newlines(f.read()), encoding
+        with io.open(filename, "r", encoding=encoding) as f:
+            return f.read(), encoding
 
     def refactor_file(self, filename, write=False, doctests_only=False):
         """Refactors a file."""
@@ -530,16 +514,16 @@
         set.
         """
         try:
-            f = _open_with_encoding(filename, "w", encoding=encoding)
+            fp = io.open(filename, "w", encoding=encoding)
         except OSError as err:
             self.log_error("Can't create %s: %s", filename, err)
             return
-        try:
-            f.write(_to_system_newlines(new_text))
-        except OSError as err:
-            self.log_error("Can't write %s: %s", filename, err)
-        finally:
-            f.close()
+
+        with fp:
+            try:
+                fp.write(new_text)
+            except OSError as err:
+                self.log_error("Can't write %s: %s", filename, err)
         self.log_debug("Wrote changes to %s", filename)
         self.wrote = True
 
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index a5c4a8e..9c27f64 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -4598,7 +4598,7 @@
     def _test_module_encoding(self, path):
         path, _ = os.path.splitext(path)
         path += ".py"
-        with codecs.open(path, 'r', 'utf-8') as f:
+        with open(path, 'r', encoding='utf-8') as f:
             f.read()
 
     def test_argparse_module_encoding(self):