(root)/
Python-3.11.7/
Lib/
test/
test_marshal.py
       1  from test import support
       2  from test.support import os_helper, requires_debug_ranges
       3  from test.support.script_helper import assert_python_ok
       4  import array
       5  import io
       6  import marshal
       7  import sys
       8  import unittest
       9  import os
      10  import types
      11  import textwrap
      12  
      13  try:
      14      import _testcapi
      15  except ImportError:
      16      _testcapi = None
      17  
      18  class ESC[4;38;5;81mHelperMixin:
      19      def helper(self, sample, *extra):
      20          new = marshal.loads(marshal.dumps(sample, *extra))
      21          self.assertEqual(sample, new)
      22          try:
      23              with open(os_helper.TESTFN, "wb") as f:
      24                  marshal.dump(sample, f, *extra)
      25              with open(os_helper.TESTFN, "rb") as f:
      26                  new = marshal.load(f)
      27              self.assertEqual(sample, new)
      28          finally:
      29              os_helper.unlink(os_helper.TESTFN)
      30  
      31  class ESC[4;38;5;81mIntTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase, ESC[4;38;5;149mHelperMixin):
      32      def test_ints(self):
      33          # Test a range of Python ints larger than the machine word size.
      34          n = sys.maxsize ** 2
      35          while n:
      36              for expected in (-n, n):
      37                  self.helper(expected)
      38              n = n >> 1
      39  
      40      def test_int64(self):
      41          # Simulate int marshaling with TYPE_INT64.
      42          maxint64 = (1 << 63) - 1
      43          minint64 = -maxint64-1
      44          for base in maxint64, minint64, -maxint64, -(minint64 >> 1):
      45              while base:
      46                  s = b'I' + int.to_bytes(base, 8, 'little', signed=True)
      47                  got = marshal.loads(s)
      48                  self.assertEqual(base, got)
      49                  if base == -1:  # a fixed-point for shifting right 1
      50                      base = 0
      51                  else:
      52                      base >>= 1
      53  
      54          got = marshal.loads(b'I\xfe\xdc\xba\x98\x76\x54\x32\x10')
      55          self.assertEqual(got, 0x1032547698badcfe)
      56          got = marshal.loads(b'I\x01\x23\x45\x67\x89\xab\xcd\xef')
      57          self.assertEqual(got, -0x1032547698badcff)
      58          got = marshal.loads(b'I\x08\x19\x2a\x3b\x4c\x5d\x6e\x7f')
      59          self.assertEqual(got, 0x7f6e5d4c3b2a1908)
      60          got = marshal.loads(b'I\xf7\xe6\xd5\xc4\xb3\xa2\x91\x80')
      61          self.assertEqual(got, -0x7f6e5d4c3b2a1909)
      62  
      63      def test_bool(self):
      64          for b in (True, False):
      65              self.helper(b)
      66  
      67  class ESC[4;38;5;81mFloatTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase, ESC[4;38;5;149mHelperMixin):
      68      def test_floats(self):
      69          # Test a few floats
      70          small = 1e-25
      71          n = sys.maxsize * 3.7e250
      72          while n > small:
      73              for expected in (-n, n):
      74                  self.helper(float(expected))
      75              n /= 123.4567
      76  
      77          f = 0.0
      78          s = marshal.dumps(f, 2)
      79          got = marshal.loads(s)
      80          self.assertEqual(f, got)
      81          # and with version <= 1 (floats marshalled differently then)
      82          s = marshal.dumps(f, 1)
      83          got = marshal.loads(s)
      84          self.assertEqual(f, got)
      85  
      86          n = sys.maxsize * 3.7e-250
      87          while n < small:
      88              for expected in (-n, n):
      89                  f = float(expected)
      90                  self.helper(f)
      91                  self.helper(f, 1)
      92              n *= 123.4567
      93  
      94  class ESC[4;38;5;81mStringTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase, ESC[4;38;5;149mHelperMixin):
      95      def test_unicode(self):
      96          for s in ["", "Andr\xe8 Previn", "abc", " "*10000]:
      97              self.helper(marshal.loads(marshal.dumps(s)))
      98  
      99      def test_string(self):
     100          for s in ["", "Andr\xe8 Previn", "abc", " "*10000]:
     101              self.helper(s)
     102  
     103      def test_bytes(self):
     104          for s in [b"", b"Andr\xe8 Previn", b"abc", b" "*10000]:
     105              self.helper(s)
     106  
     107  class ESC[4;38;5;81mExceptionTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     108      def test_exceptions(self):
     109          new = marshal.loads(marshal.dumps(StopIteration))
     110          self.assertEqual(StopIteration, new)
     111  
     112  class ESC[4;38;5;81mCodeTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     113      def test_code(self):
     114          co = ExceptionTestCase.test_exceptions.__code__
     115          new = marshal.loads(marshal.dumps(co))
     116          self.assertEqual(co, new)
     117  
     118      def test_many_codeobjects(self):
     119          # Issue2957: bad recursion count on code objects
     120          count = 5000    # more than MAX_MARSHAL_STACK_DEPTH
     121          codes = (ExceptionTestCase.test_exceptions.__code__,) * count
     122          marshal.loads(marshal.dumps(codes))
     123  
     124      def test_different_filenames(self):
     125          co1 = compile("x", "f1", "exec")
     126          co2 = compile("y", "f2", "exec")
     127          co1, co2 = marshal.loads(marshal.dumps((co1, co2)))
     128          self.assertEqual(co1.co_filename, "f1")
     129          self.assertEqual(co2.co_filename, "f2")
     130  
     131      @requires_debug_ranges()
     132      def test_minimal_linetable_with_no_debug_ranges(self):
     133          # Make sure when demarshalling objects with `-X no_debug_ranges`
     134          # that the columns are None.
     135          co = ExceptionTestCase.test_exceptions.__code__
     136          code = textwrap.dedent("""
     137          import sys
     138          import marshal
     139          with open(sys.argv[1], 'rb') as f:
     140              co = marshal.load(f)
     141              positions = list(co.co_positions())
     142              assert positions[0][2] is None
     143              assert positions[0][3] is None
     144          """)
     145  
     146          try:
     147              with open(os_helper.TESTFN, 'wb') as f:
     148                  marshal.dump(co, f)
     149  
     150              assert_python_ok('-X', 'no_debug_ranges',
     151                               '-c', code, os_helper.TESTFN)
     152          finally:
     153              os_helper.unlink(os_helper.TESTFN)
     154  
     155      @support.cpython_only
     156      def test_same_filename_used(self):
     157          s = """def f(): pass\ndef g(): pass"""
     158          co = compile(s, "myfile", "exec")
     159          co = marshal.loads(marshal.dumps(co))
     160          for obj in co.co_consts:
     161              if isinstance(obj, types.CodeType):
     162                  self.assertIs(co.co_filename, obj.co_filename)
     163  
     164  class ESC[4;38;5;81mContainerTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase, ESC[4;38;5;149mHelperMixin):
     165      d = {'astring': 'foo@bar.baz.spam',
     166           'afloat': 7283.43,
     167           'anint': 2**20,
     168           'ashortlong': 2,
     169           'alist': ['.zyx.41'],
     170           'atuple': ('.zyx.41',)*10,
     171           'aboolean': False,
     172           'aunicode': "Andr\xe8 Previn"
     173           }
     174  
     175      def test_dict(self):
     176          self.helper(self.d)
     177  
     178      def test_list(self):
     179          self.helper(list(self.d.items()))
     180  
     181      def test_tuple(self):
     182          self.helper(tuple(self.d.keys()))
     183  
     184      def test_sets(self):
     185          for constructor in (set, frozenset):
     186              self.helper(constructor(self.d.keys()))
     187  
     188  
     189  class ESC[4;38;5;81mBufferTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase, ESC[4;38;5;149mHelperMixin):
     190  
     191      def test_bytearray(self):
     192          b = bytearray(b"abc")
     193          self.helper(b)
     194          new = marshal.loads(marshal.dumps(b))
     195          self.assertEqual(type(new), bytes)
     196  
     197      def test_memoryview(self):
     198          b = memoryview(b"abc")
     199          self.helper(b)
     200          new = marshal.loads(marshal.dumps(b))
     201          self.assertEqual(type(new), bytes)
     202  
     203      def test_array(self):
     204          a = array.array('B', b"abc")
     205          new = marshal.loads(marshal.dumps(a))
     206          self.assertEqual(new, b"abc")
     207  
     208  
     209  class ESC[4;38;5;81mBugsTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     210      def test_bug_5888452(self):
     211          # Simple-minded check for SF 588452: Debug build crashes
     212          marshal.dumps([128] * 1000)
     213  
     214      def test_patch_873224(self):
     215          self.assertRaises(Exception, marshal.loads, b'0')
     216          self.assertRaises(Exception, marshal.loads, b'f')
     217          self.assertRaises(Exception, marshal.loads, marshal.dumps(2**65)[:-1])
     218  
     219      def test_version_argument(self):
     220          # Python 2.4.0 crashes for any call to marshal.dumps(x, y)
     221          self.assertEqual(marshal.loads(marshal.dumps(5, 0)), 5)
     222          self.assertEqual(marshal.loads(marshal.dumps(5, 1)), 5)
     223  
     224      def test_fuzz(self):
     225          # simple test that it's at least not *totally* trivial to
     226          # crash from bad marshal data
     227          for i in range(256):
     228              c = bytes([i])
     229              try:
     230                  marshal.loads(c)
     231              except Exception:
     232                  pass
     233  
     234      def test_loads_recursion(self):
     235          def run_tests(N, check):
     236              # (((...None...),),)
     237              check(b')\x01' * N + b'N')
     238              check(b'(\x01\x00\x00\x00' * N + b'N')
     239              # [[[...None...]]]
     240              check(b'[\x01\x00\x00\x00' * N + b'N')
     241              # {None: {None: {None: ...None...}}}
     242              check(b'{N' * N + b'N' + b'0' * N)
     243              # frozenset([frozenset([frozenset([...None...])])])
     244              check(b'>\x01\x00\x00\x00' * N + b'N')
     245          # Check that the generated marshal data is valid and marshal.loads()
     246          # works for moderately deep nesting
     247          run_tests(100, marshal.loads)
     248          # Very deeply nested structure shouldn't blow the stack
     249          def check(s):
     250              self.assertRaises(ValueError, marshal.loads, s)
     251          run_tests(2**20, check)
     252  
     253      def test_recursion_limit(self):
     254          # Create a deeply nested structure.
     255          head = last = []
     256          # The max stack depth should match the value in Python/marshal.c.
     257          # BUG: https://bugs.python.org/issue33720
     258          # Windows always limits the maximum depth on release and debug builds
     259          #if os.name == 'nt' and hasattr(sys, 'gettotalrefcount'):
     260          if os.name == 'nt':
     261              MAX_MARSHAL_STACK_DEPTH = 1000
     262          elif sys.platform == 'wasi':
     263              MAX_MARSHAL_STACK_DEPTH = 1500
     264          else:
     265              MAX_MARSHAL_STACK_DEPTH = 2000
     266          for i in range(MAX_MARSHAL_STACK_DEPTH - 2):
     267              last.append([0])
     268              last = last[-1]
     269  
     270          # Verify we don't blow out the stack with dumps/load.
     271          data = marshal.dumps(head)
     272          new_head = marshal.loads(data)
     273          # Don't use == to compare objects, it can exceed the recursion limit.
     274          self.assertEqual(len(new_head), len(head))
     275          self.assertEqual(len(new_head[0]), len(head[0]))
     276          self.assertEqual(len(new_head[-1]), len(head[-1]))
     277  
     278          last.append([0])
     279          self.assertRaises(ValueError, marshal.dumps, head)
     280  
     281      def test_exact_type_match(self):
     282          # Former bug:
     283          #   >>> class Int(int): pass
     284          #   >>> type(loads(dumps(Int())))
     285          #   <type 'int'>
     286          for typ in (int, float, complex, tuple, list, dict, set, frozenset):
     287              # Note: str subclasses are not tested because they get handled
     288              # by marshal's routines for objects supporting the buffer API.
     289              subtyp = type('subtyp', (typ,), {})
     290              self.assertRaises(ValueError, marshal.dumps, subtyp())
     291  
     292      # Issue #1792 introduced a change in how marshal increases the size of its
     293      # internal buffer; this test ensures that the new code is exercised.
     294      def test_large_marshal(self):
     295          size = int(1e6)
     296          testString = 'abc' * size
     297          marshal.dumps(testString)
     298  
     299      def test_invalid_longs(self):
     300          # Issue #7019: marshal.loads shouldn't produce unnormalized PyLongs
     301          invalid_string = b'l\x02\x00\x00\x00\x00\x00\x00\x00'
     302          self.assertRaises(ValueError, marshal.loads, invalid_string)
     303  
     304      def test_multiple_dumps_and_loads(self):
     305          # Issue 12291: marshal.load() should be callable multiple times
     306          # with interleaved data written by non-marshal code
     307          # Adapted from a patch by Engelbert Gruber.
     308          data = (1, 'abc', b'def', 1.0, (2, 'a', ['b', b'c']))
     309          for interleaved in (b'', b'0123'):
     310              ilen = len(interleaved)
     311              positions = []
     312              try:
     313                  with open(os_helper.TESTFN, 'wb') as f:
     314                      for d in data:
     315                          marshal.dump(d, f)
     316                          if ilen:
     317                              f.write(interleaved)
     318                          positions.append(f.tell())
     319                  with open(os_helper.TESTFN, 'rb') as f:
     320                      for i, d in enumerate(data):
     321                          self.assertEqual(d, marshal.load(f))
     322                          if ilen:
     323                              f.read(ilen)
     324                          self.assertEqual(positions[i], f.tell())
     325              finally:
     326                  os_helper.unlink(os_helper.TESTFN)
     327  
     328      def test_loads_reject_unicode_strings(self):
     329          # Issue #14177: marshal.loads() should not accept unicode strings
     330          unicode_string = 'T'
     331          self.assertRaises(TypeError, marshal.loads, unicode_string)
     332  
     333      def test_bad_reader(self):
     334          class ESC[4;38;5;81mBadReader(ESC[4;38;5;149mioESC[4;38;5;149m.ESC[4;38;5;149mBytesIO):
     335              def readinto(self, buf):
     336                  n = super().readinto(buf)
     337                  if n is not None and n > 4:
     338                      n += 10**6
     339                  return n
     340          for value in (1.0, 1j, b'0123456789', '0123456789'):
     341              self.assertRaises(ValueError, marshal.load,
     342                                BadReader(marshal.dumps(value)))
     343  
     344      def test_eof(self):
     345          data = marshal.dumps(("hello", "dolly", None))
     346          for i in range(len(data)):
     347              self.assertRaises(EOFError, marshal.loads, data[0: i])
     348  
     349      def test_deterministic_sets(self):
     350          # bpo-37596: To support reproducible builds, sets and frozensets need to
     351          # have their elements serialized in a consistent order (even when they
     352          # have been scrambled by hash randomization):
     353          for kind in ("set", "frozenset"):
     354              for elements in (
     355                  "float('nan'), b'a', b'b', b'c', 'x', 'y', 'z'",
     356                  # Also test for bad interactions with backreferencing:
     357                  "('Spam', 0), ('Spam', 1), ('Spam', 2), ('Spam', 3), ('Spam', 4), ('Spam', 5)",
     358              ):
     359                  s = f"{kind}([{elements}])"
     360                  with self.subTest(s):
     361                      # First, make sure that our test case still has different
     362                      # orders under hash seeds 0 and 1. If this check fails, we
     363                      # need to update this test with different elements. Skip
     364                      # this part if we are configured to use any other hash
     365                      # algorithm (for example, using Py_HASH_EXTERNAL):
     366                      if sys.hash_info.algorithm in {"fnv", "siphash24"}:
     367                          args = ["-c", f"print({s})"]
     368                          _, repr_0, _ = assert_python_ok(*args, PYTHONHASHSEED="0")
     369                          _, repr_1, _ = assert_python_ok(*args, PYTHONHASHSEED="1")
     370                          self.assertNotEqual(repr_0, repr_1)
     371                      # Then, perform the actual test:
     372                      args = ["-c", f"import marshal; print(marshal.dumps({s}))"]
     373                      _, dump_0, _ = assert_python_ok(*args, PYTHONHASHSEED="0")
     374                      _, dump_1, _ = assert_python_ok(*args, PYTHONHASHSEED="1")
     375                      self.assertEqual(dump_0, dump_1)
     376  
     377  LARGE_SIZE = 2**31
     378  pointer_size = 8 if sys.maxsize > 0xFFFFFFFF else 4
     379  
     380  class ESC[4;38;5;81mNullWriter:
     381      def write(self, s):
     382          pass
     383  
     384  @unittest.skipIf(LARGE_SIZE > sys.maxsize, "test cannot run on 32-bit systems")
     385  class ESC[4;38;5;81mLargeValuesTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     386      def check_unmarshallable(self, data):
     387          self.assertRaises(ValueError, marshal.dump, data, NullWriter())
     388  
     389      @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False)
     390      def test_bytes(self, size):
     391          self.check_unmarshallable(b'x' * size)
     392  
     393      @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False)
     394      def test_str(self, size):
     395          self.check_unmarshallable('x' * size)
     396  
     397      @support.bigmemtest(size=LARGE_SIZE, memuse=pointer_size + 1, dry_run=False)
     398      def test_tuple(self, size):
     399          self.check_unmarshallable((None,) * size)
     400  
     401      @support.bigmemtest(size=LARGE_SIZE, memuse=pointer_size + 1, dry_run=False)
     402      def test_list(self, size):
     403          self.check_unmarshallable([None] * size)
     404  
     405      @support.bigmemtest(size=LARGE_SIZE,
     406              memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
     407              dry_run=False)
     408      def test_set(self, size):
     409          self.check_unmarshallable(set(range(size)))
     410  
     411      @support.bigmemtest(size=LARGE_SIZE,
     412              memuse=pointer_size*12 + sys.getsizeof(LARGE_SIZE-1),
     413              dry_run=False)
     414      def test_frozenset(self, size):
     415          self.check_unmarshallable(frozenset(range(size)))
     416  
     417      @support.bigmemtest(size=LARGE_SIZE, memuse=2, dry_run=False)
     418      def test_bytearray(self, size):
     419          self.check_unmarshallable(bytearray(size))
     420  
     421  def CollectObjectIDs(ids, obj):
     422      """Collect object ids seen in a structure"""
     423      if id(obj) in ids:
     424          return
     425      ids.add(id(obj))
     426      if isinstance(obj, (list, tuple, set, frozenset)):
     427          for e in obj:
     428              CollectObjectIDs(ids, e)
     429      elif isinstance(obj, dict):
     430          for k, v in obj.items():
     431              CollectObjectIDs(ids, k)
     432              CollectObjectIDs(ids, v)
     433      return len(ids)
     434  
     435  class ESC[4;38;5;81mInstancingTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase, ESC[4;38;5;149mHelperMixin):
     436      keys = (123, 1.2345, 'abc', (123, 'abc'), frozenset({123, 'abc'}))
     437  
     438      def helper3(self, rsample, recursive=False, simple=False):
     439          #we have two instances
     440          sample = (rsample, rsample)
     441  
     442          n0 = CollectObjectIDs(set(), sample)
     443  
     444          for v in range(3, marshal.version + 1):
     445              s3 = marshal.dumps(sample, v)
     446              n3 = CollectObjectIDs(set(), marshal.loads(s3))
     447  
     448              #same number of instances generated
     449              self.assertEqual(n3, n0)
     450  
     451          if not recursive:
     452              #can compare with version 2
     453              s2 = marshal.dumps(sample, 2)
     454              n2 = CollectObjectIDs(set(), marshal.loads(s2))
     455              #old format generated more instances
     456              self.assertGreater(n2, n0)
     457  
     458              #if complex objects are in there, old format is larger
     459              if not simple:
     460                  self.assertGreater(len(s2), len(s3))
     461              else:
     462                  self.assertGreaterEqual(len(s2), len(s3))
     463  
     464      def testInt(self):
     465          intobj = 123321
     466          self.helper(intobj)
     467          self.helper3(intobj, simple=True)
     468  
     469      def testFloat(self):
     470          floatobj = 1.2345
     471          self.helper(floatobj)
     472          self.helper3(floatobj)
     473  
     474      def testStr(self):
     475          strobj = "abcde"*3
     476          self.helper(strobj)
     477          self.helper3(strobj)
     478  
     479      def testBytes(self):
     480          bytesobj = b"abcde"*3
     481          self.helper(bytesobj)
     482          self.helper3(bytesobj)
     483  
     484      def testList(self):
     485          for obj in self.keys:
     486              listobj = [obj, obj]
     487              self.helper(listobj)
     488              self.helper3(listobj)
     489  
     490      def testTuple(self):
     491          for obj in self.keys:
     492              tupleobj = (obj, obj)
     493              self.helper(tupleobj)
     494              self.helper3(tupleobj)
     495  
     496      def testSet(self):
     497          for obj in self.keys:
     498              setobj = {(obj, 1), (obj, 2)}
     499              self.helper(setobj)
     500              self.helper3(setobj)
     501  
     502      def testFrozenSet(self):
     503          for obj in self.keys:
     504              frozensetobj = frozenset({(obj, 1), (obj, 2)})
     505              self.helper(frozensetobj)
     506              self.helper3(frozensetobj)
     507  
     508      def testDict(self):
     509          for obj in self.keys:
     510              dictobj = {"hello": obj, "goodbye": obj, obj: "hello"}
     511              self.helper(dictobj)
     512              self.helper3(dictobj)
     513  
     514      def testModule(self):
     515          with open(__file__, "rb") as f:
     516              code = f.read()
     517          if __file__.endswith(".py"):
     518              code = compile(code, __file__, "exec")
     519          self.helper(code)
     520          self.helper3(code)
     521  
     522      def testRecursion(self):
     523          obj = 1.2345
     524          d = {"hello": obj, "goodbye": obj, obj: "hello"}
     525          d["self"] = d
     526          self.helper3(d, recursive=True)
     527          l = [obj, obj]
     528          l.append(l)
     529          self.helper3(l, recursive=True)
     530  
     531  class ESC[4;38;5;81mCompatibilityTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase):
     532      def _test(self, version):
     533          with open(__file__, "rb") as f:
     534              code = f.read()
     535          if __file__.endswith(".py"):
     536              code = compile(code, __file__, "exec")
     537          data = marshal.dumps(code, version)
     538          marshal.loads(data)
     539  
     540      def test0To3(self):
     541          self._test(0)
     542  
     543      def test1To3(self):
     544          self._test(1)
     545  
     546      def test2To3(self):
     547          self._test(2)
     548  
     549      def test3To3(self):
     550          self._test(3)
     551  
     552  class ESC[4;38;5;81mInterningTestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase, ESC[4;38;5;149mHelperMixin):
     553      strobj = "this is an interned string"
     554      strobj = sys.intern(strobj)
     555  
     556      def testIntern(self):
     557          s = marshal.loads(marshal.dumps(self.strobj))
     558          self.assertEqual(s, self.strobj)
     559          self.assertEqual(id(s), id(self.strobj))
     560          s2 = sys.intern(s)
     561          self.assertEqual(id(s2), id(s))
     562  
     563      def testNoIntern(self):
     564          s = marshal.loads(marshal.dumps(self.strobj, 2))
     565          self.assertEqual(s, self.strobj)
     566          self.assertNotEqual(id(s), id(self.strobj))
     567          s2 = sys.intern(s)
     568          self.assertNotEqual(id(s2), id(s))
     569  
     570  @support.cpython_only
     571  @unittest.skipUnless(_testcapi, 'requires _testcapi')
     572  class ESC[4;38;5;81mCAPI_TestCase(ESC[4;38;5;149munittestESC[4;38;5;149m.ESC[4;38;5;149mTestCase, ESC[4;38;5;149mHelperMixin):
     573  
     574      def test_write_long_to_file(self):
     575          for v in range(marshal.version + 1):
     576              _testcapi.pymarshal_write_long_to_file(0x12345678, os_helper.TESTFN, v)
     577              with open(os_helper.TESTFN, 'rb') as f:
     578                  data = f.read()
     579              os_helper.unlink(os_helper.TESTFN)
     580              self.assertEqual(data, b'\x78\x56\x34\x12')
     581  
     582      def test_write_object_to_file(self):
     583          obj = ('\u20ac', b'abc', 123, 45.6, 7+8j, 'long line '*1000)
     584          for v in range(marshal.version + 1):
     585              _testcapi.pymarshal_write_object_to_file(obj, os_helper.TESTFN, v)
     586              with open(os_helper.TESTFN, 'rb') as f:
     587                  data = f.read()
     588              os_helper.unlink(os_helper.TESTFN)
     589              self.assertEqual(marshal.loads(data), obj)
     590  
     591      def test_read_short_from_file(self):
     592          with open(os_helper.TESTFN, 'wb') as f:
     593              f.write(b'\x34\x12xxxx')
     594          r, p = _testcapi.pymarshal_read_short_from_file(os_helper.TESTFN)
     595          os_helper.unlink(os_helper.TESTFN)
     596          self.assertEqual(r, 0x1234)
     597          self.assertEqual(p, 2)
     598  
     599          with open(os_helper.TESTFN, 'wb') as f:
     600              f.write(b'\x12')
     601          with self.assertRaises(EOFError):
     602              _testcapi.pymarshal_read_short_from_file(os_helper.TESTFN)
     603          os_helper.unlink(os_helper.TESTFN)
     604  
     605      def test_read_long_from_file(self):
     606          with open(os_helper.TESTFN, 'wb') as f:
     607              f.write(b'\x78\x56\x34\x12xxxx')
     608          r, p = _testcapi.pymarshal_read_long_from_file(os_helper.TESTFN)
     609          os_helper.unlink(os_helper.TESTFN)
     610          self.assertEqual(r, 0x12345678)
     611          self.assertEqual(p, 4)
     612  
     613          with open(os_helper.TESTFN, 'wb') as f:
     614              f.write(b'\x56\x34\x12')
     615          with self.assertRaises(EOFError):
     616              _testcapi.pymarshal_read_long_from_file(os_helper.TESTFN)
     617          os_helper.unlink(os_helper.TESTFN)
     618  
     619      def test_read_last_object_from_file(self):
     620          obj = ('\u20ac', b'abc', 123, 45.6, 7+8j)
     621          for v in range(marshal.version + 1):
     622              data = marshal.dumps(obj, v)
     623              with open(os_helper.TESTFN, 'wb') as f:
     624                  f.write(data + b'xxxx')
     625              r, p = _testcapi.pymarshal_read_last_object_from_file(os_helper.TESTFN)
     626              os_helper.unlink(os_helper.TESTFN)
     627              self.assertEqual(r, obj)
     628  
     629              with open(os_helper.TESTFN, 'wb') as f:
     630                  f.write(data[:1])
     631              with self.assertRaises(EOFError):
     632                  _testcapi.pymarshal_read_last_object_from_file(os_helper.TESTFN)
     633              os_helper.unlink(os_helper.TESTFN)
     634  
     635      def test_read_object_from_file(self):
     636          obj = ('\u20ac', b'abc', 123, 45.6, 7+8j)
     637          for v in range(marshal.version + 1):
     638              data = marshal.dumps(obj, v)
     639              with open(os_helper.TESTFN, 'wb') as f:
     640                  f.write(data + b'xxxx')
     641              r, p = _testcapi.pymarshal_read_object_from_file(os_helper.TESTFN)
     642              os_helper.unlink(os_helper.TESTFN)
     643              self.assertEqual(r, obj)
     644              self.assertEqual(p, len(data))
     645  
     646              with open(os_helper.TESTFN, 'wb') as f:
     647                  f.write(data[:1])
     648              with self.assertRaises(EOFError):
     649                  _testcapi.pymarshal_read_object_from_file(os_helper.TESTFN)
     650              os_helper.unlink(os_helper.TESTFN)
     651  
     652  
     653  if __name__ == "__main__":
     654      unittest.main()