python (3.11.7)
       1  # -*- coding: utf-8 -*-
       2  import codecs
       3  import io
       4  import logging
       5  import os
       6  import re
       7  import shutil
       8  import sys
       9  import tempfile
      10  import unittest
      11  
      12  from lib2to3 import main
      13  
      14  
      15  TEST_DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
      16  PY2_TEST_MODULE = os.path.join(TEST_DATA_DIR, "py2_test_grammar.py")
      17  
      18  
      19  class ESC[4;38;5;81mTestMain(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      20  
      21      def setUp(self):
      22          self.temp_dir = None  # tearDown() will rmtree this directory if set.
      23  
      24      def tearDown(self):
      25          # Clean up logging configuration down by main.
      26          del logging.root.handlers[:]
      27          if self.temp_dir:
      28              shutil.rmtree(self.temp_dir)
      29  
      30      def run_2to3_capture(self, args, in_capture, out_capture, err_capture):
      31          save_stdin = sys.stdin
      32          save_stdout = sys.stdout
      33          save_stderr = sys.stderr
      34          sys.stdin = in_capture
      35          sys.stdout = out_capture
      36          sys.stderr = err_capture
      37          try:
      38              return main.main("lib2to3.fixes", args)
      39          finally:
      40              sys.stdin = save_stdin
      41              sys.stdout = save_stdout
      42              sys.stderr = save_stderr
      43  
      44      def test_unencodable_diff(self):
      45          input_stream = io.StringIO("print 'nothing'\nprint u'über'\n")
      46          out = io.BytesIO()
      47          out_enc = codecs.getwriter("ascii")(out)
      48          err = io.StringIO()
      49          ret = self.run_2to3_capture(["-"], input_stream, out_enc, err)
      50          self.assertEqual(ret, 0)
      51          output = out.getvalue().decode("ascii")
      52          self.assertIn("-print 'nothing'", output)
      53          self.assertIn("WARNING: couldn't encode <stdin>'s diff for "
      54                        "your terminal", err.getvalue())
      55  
      56      def setup_test_source_trees(self):
      57          """Setup a test source tree and output destination tree."""
      58          self.temp_dir = tempfile.mkdtemp()  # tearDown() cleans this up.
      59          self.py2_src_dir = os.path.join(self.temp_dir, "python2_project")
      60          self.py3_dest_dir = os.path.join(self.temp_dir, "python3_project")
      61          os.mkdir(self.py2_src_dir)
      62          os.mkdir(self.py3_dest_dir)
      63          # Turn it into a package with a few files.
      64          self.setup_files = []
      65          open(os.path.join(self.py2_src_dir, "__init__.py"), "w").close()
      66          self.setup_files.append("__init__.py")
      67          shutil.copy(PY2_TEST_MODULE, self.py2_src_dir)
      68          self.setup_files.append(os.path.basename(PY2_TEST_MODULE))
      69          self.trivial_py2_file = os.path.join(self.py2_src_dir, "trivial.py")
      70          self.init_py2_file = os.path.join(self.py2_src_dir, "__init__.py")
      71          with open(self.trivial_py2_file, "w") as trivial:
      72              trivial.write("print 'I need a simple conversion.'")
      73          self.setup_files.append("trivial.py")
      74  
      75      def test_filename_changing_on_output_single_dir(self):
      76          """2to3 a single directory with a new output dir and suffix."""
      77          self.setup_test_source_trees()
      78          out = io.StringIO()
      79          err = io.StringIO()
      80          suffix = "TEST"
      81          ret = self.run_2to3_capture(
      82                  ["-n", "--add-suffix", suffix, "--write-unchanged-files",
      83                   "--no-diffs", "--output-dir",
      84                   self.py3_dest_dir, self.py2_src_dir],
      85                  io.StringIO(""), out, err)
      86          self.assertEqual(ret, 0)
      87          stderr = err.getvalue()
      88          self.assertIn(" implies -w.", stderr)
      89          self.assertIn(
      90                  "Output in %r will mirror the input directory %r layout" % (
      91                          self.py3_dest_dir, self.py2_src_dir), stderr)
      92          self.assertEqual(set(name+suffix for name in self.setup_files),
      93                           set(os.listdir(self.py3_dest_dir)))
      94          for name in self.setup_files:
      95              self.assertIn("Writing converted %s to %s" % (
      96                      os.path.join(self.py2_src_dir, name),
      97                      os.path.join(self.py3_dest_dir, name+suffix)), stderr)
      98          sep = re.escape(os.sep)
      99          self.assertRegex(
     100                  stderr, r"No changes to .*/__init__\.py".replace("/", sep))
     101          self.assertNotRegex(
     102                  stderr, r"No changes to .*/trivial\.py".replace("/", sep))
     103  
     104      def test_filename_changing_on_output_two_files(self):
     105          """2to3 two files in one directory with a new output dir."""
     106          self.setup_test_source_trees()
     107          err = io.StringIO()
     108          py2_files = [self.trivial_py2_file, self.init_py2_file]
     109          expected_files = set(os.path.basename(name) for name in py2_files)
     110          ret = self.run_2to3_capture(
     111                  ["-n", "-w", "--write-unchanged-files",
     112                   "--no-diffs", "--output-dir", self.py3_dest_dir] + py2_files,
     113                  io.StringIO(""), io.StringIO(), err)
     114          self.assertEqual(ret, 0)
     115          stderr = err.getvalue()
     116          self.assertIn(
     117                  "Output in %r will mirror the input directory %r layout" % (
     118                          self.py3_dest_dir, self.py2_src_dir), stderr)
     119          self.assertEqual(expected_files, set(os.listdir(self.py3_dest_dir)))
     120  
     121      def test_filename_changing_on_output_single_file(self):
     122          """2to3 a single file with a new output dir."""
     123          self.setup_test_source_trees()
     124          err = io.StringIO()
     125          ret = self.run_2to3_capture(
     126                  ["-n", "-w", "--no-diffs", "--output-dir", self.py3_dest_dir,
     127                   self.trivial_py2_file],
     128                  io.StringIO(""), io.StringIO(), err)
     129          self.assertEqual(ret, 0)
     130          stderr = err.getvalue()
     131          self.assertIn(
     132                  "Output in %r will mirror the input directory %r layout" % (
     133                          self.py3_dest_dir, self.py2_src_dir), stderr)
     134          self.assertEqual(set([os.path.basename(self.trivial_py2_file)]),
     135                           set(os.listdir(self.py3_dest_dir)))
     136  
     137  
     138  if __name__ == '__main__':
     139      unittest.main()