(root)/
Python-3.11.7/
Lib/
test/
test_print.py
       1  import unittest
       2  import sys
       3  from io import StringIO
       4  
       5  from test import support
       6  
       7  NotDefined = object()
       8  
       9  # A dispatch table all 8 combinations of providing
      10  # sep, end, and file.
      11  # I use this machinery so that I'm not just passing default
      12  # values to print, I'm either passing or not passing in the
      13  # arguments.
      14  dispatch = {
      15      (False, False, False):
      16          lambda args, sep, end, file: print(*args),
      17      (False, False, True):
      18          lambda args, sep, end, file: print(file=file, *args),
      19      (False, True,  False):
      20          lambda args, sep, end, file: print(end=end, *args),
      21      (False, True,  True):
      22          lambda args, sep, end, file: print(end=end, file=file, *args),
      23      (True,  False, False):
      24          lambda args, sep, end, file: print(sep=sep, *args),
      25      (True,  False, True):
      26          lambda args, sep, end, file: print(sep=sep, file=file, *args),
      27      (True,  True,  False):
      28          lambda args, sep, end, file: print(sep=sep, end=end, *args),
      29      (True,  True,  True):
      30          lambda args, sep, end, file: print(sep=sep, end=end, file=file, *args),
      31  }
      32  
      33  
      34  # Class used to test __str__ and print
      35  class ESC[4;38;5;81mClassWith__str__:
      36      def __init__(self, x):
      37          self.x = x
      38  
      39      def __str__(self):
      40          return self.x
      41  
      42  
      43  class ESC[4;38;5;81mTestPrint(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
      44      """Test correct operation of the print function."""
      45  
      46      def check(self, expected, args,
      47                sep=NotDefined, end=NotDefined, file=NotDefined):
      48          # Capture sys.stdout in a StringIO.  Call print with args,
      49          # and with sep, end, and file, if they're defined.  Result
      50          # must match expected.
      51  
      52          # Look up the actual function to call, based on if sep, end,
      53          # and file are defined.
      54          fn = dispatch[(sep is not NotDefined,
      55                         end is not NotDefined,
      56                         file is not NotDefined)]
      57  
      58          with support.captured_stdout() as t:
      59              fn(args, sep, end, file)
      60  
      61          self.assertEqual(t.getvalue(), expected)
      62  
      63      def test_print(self):
      64          def x(expected, args, sep=NotDefined, end=NotDefined):
      65              # Run the test 2 ways: not using file, and using
      66              # file directed to a StringIO.
      67  
      68              self.check(expected, args, sep=sep, end=end)
      69  
      70              # When writing to a file, stdout is expected to be empty
      71              o = StringIO()
      72              self.check('', args, sep=sep, end=end, file=o)
      73  
      74              # And o will contain the expected output
      75              self.assertEqual(o.getvalue(), expected)
      76  
      77          x('\n', ())
      78          x('a\n', ('a',))
      79          x('None\n', (None,))
      80          x('1 2\n', (1, 2))
      81          x('1   2\n', (1, ' ', 2))
      82          x('1*2\n', (1, 2), sep='*')
      83          x('1 s', (1, 's'), end='')
      84          x('a\nb\n', ('a', 'b'), sep='\n')
      85          x('1.01', (1.0, 1), sep='', end='')
      86          x('1*a*1.3+', (1, 'a', 1.3), sep='*', end='+')
      87          x('a\n\nb\n', ('a\n', 'b'), sep='\n')
      88          x('\0+ +\0\n', ('\0', ' ', '\0'), sep='+')
      89  
      90          x('a\n b\n', ('a\n', 'b'))
      91          x('a\n b\n', ('a\n', 'b'), sep=None)
      92          x('a\n b\n', ('a\n', 'b'), end=None)
      93          x('a\n b\n', ('a\n', 'b'), sep=None, end=None)
      94  
      95          x('*\n', (ClassWith__str__('*'),))
      96          x('abc 1\n', (ClassWith__str__('abc'), 1))
      97  
      98          # errors
      99          self.assertRaises(TypeError, print, '', sep=3)
     100          self.assertRaises(TypeError, print, '', end=3)
     101          self.assertRaises(AttributeError, print, '', file='')
     102  
     103      def test_print_flush(self):
     104          # operation of the flush flag
     105          class ESC[4;38;5;81mfilelike:
     106              def __init__(self):
     107                  self.written = ''
     108                  self.flushed = 0
     109  
     110              def write(self, str):
     111                  self.written += str
     112  
     113              def flush(self):
     114                  self.flushed += 1
     115  
     116          f = filelike()
     117          print(1, file=f, end='', flush=True)
     118          print(2, file=f, end='', flush=True)
     119          print(3, file=f, flush=False)
     120          self.assertEqual(f.written, '123\n')
     121          self.assertEqual(f.flushed, 2)
     122  
     123          # ensure exceptions from flush are passed through
     124          class ESC[4;38;5;81mnoflush:
     125              def write(self, str):
     126                  pass
     127  
     128              def flush(self):
     129                  raise RuntimeError
     130          self.assertRaises(RuntimeError, print, 1, file=noflush(), flush=True)
     131  
     132  
     133  class ESC[4;38;5;81mTestPy2MigrationHint(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     134      """Test that correct hint is produced analogous to Python3 syntax,
     135      if print statement is executed as in Python 2.
     136      """
     137  
     138      def test_normal_string(self):
     139          python2_print_str = 'print "Hello World"'
     140          with self.assertRaises(SyntaxError) as context:
     141              exec(python2_print_str)
     142  
     143          self.assertIn("Missing parentheses in call to 'print'. Did you mean print(...)",
     144                  str(context.exception))
     145  
     146      def test_string_with_soft_space(self):
     147          python2_print_str = 'print "Hello World",'
     148          with self.assertRaises(SyntaxError) as context:
     149              exec(python2_print_str)
     150  
     151          self.assertIn("Missing parentheses in call to 'print'. Did you mean print(...)",
     152                  str(context.exception))
     153  
     154      def test_string_with_excessive_whitespace(self):
     155          python2_print_str = 'print  "Hello World", '
     156          with self.assertRaises(SyntaxError) as context:
     157              exec(python2_print_str)
     158  
     159          self.assertIn("Missing parentheses in call to 'print'. Did you mean print(...)",
     160                  str(context.exception))
     161  
     162      def test_string_with_leading_whitespace(self):
     163          python2_print_str = '''if 1:
     164              print "Hello World"
     165          '''
     166          with self.assertRaises(SyntaxError) as context:
     167              exec(python2_print_str)
     168  
     169          self.assertIn("Missing parentheses in call to 'print'. Did you mean print(...)",
     170                  str(context.exception))
     171  
     172      # bpo-32685: Suggestions for print statement should be proper when
     173      # it is in the same line as the header of a compound statement
     174      # and/or followed by a semicolon
     175      def test_string_with_semicolon(self):
     176          python2_print_str = 'print p;'
     177          with self.assertRaises(SyntaxError) as context:
     178              exec(python2_print_str)
     179  
     180          self.assertIn("Missing parentheses in call to 'print'. Did you mean print(...)",
     181                  str(context.exception))
     182  
     183      def test_string_in_loop_on_same_line(self):
     184          python2_print_str = 'for i in s: print i'
     185          with self.assertRaises(SyntaxError) as context:
     186              exec(python2_print_str)
     187  
     188          self.assertIn("Missing parentheses in call to 'print'. Did you mean print(...)",
     189                  str(context.exception))
     190  
     191      def test_stream_redirection_hint_for_py2_migration(self):
     192          # Test correct hint produced for Py2 redirection syntax
     193          with self.assertRaises(TypeError) as context:
     194              print >> sys.stderr, "message"
     195          self.assertIn('Did you mean "print(<message>, '
     196                  'file=<output_stream>)"?', str(context.exception))
     197  
     198          # Test correct hint is produced in the case where RHS implements
     199          # __rrshift__ but returns NotImplemented
     200          with self.assertRaises(TypeError) as context:
     201              print >> 42
     202          self.assertIn('Did you mean "print(<message>, '
     203                  'file=<output_stream>)"?', str(context.exception))
     204  
     205          # Test stream redirection hint is specific to print
     206          with self.assertRaises(TypeError) as context:
     207              max >> sys.stderr
     208          self.assertNotIn('Did you mean ', str(context.exception))
     209  
     210          # Test stream redirection hint is specific to rshift
     211          with self.assertRaises(TypeError) as context:
     212              print << sys.stderr
     213          self.assertNotIn('Did you mean', str(context.exception))
     214  
     215          # Ensure right operand implementing rrshift still works
     216          class ESC[4;38;5;81mOverrideRRShift:
     217              def __rrshift__(self, lhs):
     218                  return 42 # Force result independent of LHS
     219  
     220          self.assertEqual(print >> OverrideRRShift(), 42)
     221  
     222  
     223  
     224  if __name__ == "__main__":
     225      unittest.main()