Skip to content

Commit fbc695a

Browse files
committed
Add tests for pickle command-line interface
1 parent 55815a6 commit fbc695a

File tree

2 files changed

+65
-5
lines changed

2 files changed

+65
-5
lines changed

Lib/pickle.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1907,19 +1907,23 @@ def _loads(s, /, *, fix_imports=True, encoding="ASCII", errors="strict",
19071907
dump, dumps, load, loads = _dump, _dumps, _load, _loads
19081908

19091909

1910-
if __name__ == "__main__":
1910+
def _main(args=None):
19111911
import argparse
19121912
import pprint
19131913
parser = argparse.ArgumentParser(
19141914
description='display contents of the pickle files')
19151915
parser.add_argument(
19161916
'pickle_file',
19171917
nargs='+', help='the pickle file')
1918-
args = parser.parse_args()
1918+
args = parser.parse_args(args)
19191919
for fn in args.pickle_file:
19201920
if fn == '-':
19211921
obj = load(sys.stdin.buffer)
19221922
else:
19231923
with open(fn, 'rb') as f:
19241924
obj = load(f)
19251925
pprint.pprint(obj)
1926+
1927+
1928+
if __name__ == "__main__":
1929+
_main()

Lib/test/test_pickle.py

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
from _compat_pickle import (IMPORT_MAPPING, REVERSE_IMPORT_MAPPING,
22
NAME_MAPPING, REVERSE_NAME_MAPPING)
33
import builtins
4-
import pickle
5-
import io
64
import collections
5+
import contextlib
6+
import io
7+
import pickle
78
import struct
89
import sys
10+
import tempfile
911
import warnings
1012
import weakref
1113

1214
import doctest
1315
import unittest
16+
from io import StringIO
17+
from textwrap import dedent
1418
from test import support
15-
from test.support import import_helper
19+
from test.support import import_helper, os_helper
1620

1721
from test.pickletester import AbstractHookTests
1822
from test.pickletester import AbstractUnpickleTests
@@ -699,6 +703,58 @@ def test_multiprocessing_exceptions(self):
699703
('multiprocessing.context', name))
700704

701705

706+
class CommandLineTest(unittest.TestCase):
707+
def setUp(self):
708+
self.filename = tempfile.mktemp()
709+
self.addCleanup(os_helper.unlink, self.filename)
710+
711+
@staticmethod
712+
def text_normalize(string):
713+
"""Dedent *string* and strip it from its surrounding whitespaces.
714+
715+
This method is used by the other utility functions so that any
716+
string to write or to match against can be freely indented.
717+
"""
718+
return dedent(string).strip()
719+
720+
def set_pickle_data(self, data):
721+
with open(self.filename, 'wb') as f:
722+
pickle.dump(data, f)
723+
724+
def invoke_pickle(self, *flags):
725+
output = StringIO()
726+
with contextlib.redirect_stdout(output):
727+
pickle._main(args=[*flags, self.filename])
728+
return self.text_normalize(output.getvalue())
729+
730+
def test_invocation(self):
731+
# test 'python -m pickle pickle_file'
732+
data = {
733+
'a': [1, 2.0, 3+4j],
734+
'b': ('character string', b'byte string'),
735+
'c': {None, True, False}
736+
}
737+
expect = '''
738+
{'a': [1, 2.0, (3+4j)],
739+
'b': ('character string', b'byte string'),
740+
'c': {None, True, False}}
741+
'''
742+
self.set_pickle_data(data)
743+
744+
with self.subTest(data=data):
745+
res = self.invoke_pickle()
746+
expect = self.text_normalize(expect)
747+
self.assertListEqual(res.splitlines(), expect.splitlines())
748+
749+
def test_unknown_flag(self):
750+
data = 'some_text'
751+
self.set_pickle_data(data)
752+
with self.assertRaises(SystemExit):
753+
# suppress argparse error message
754+
with contextlib.redirect_stderr(StringIO()):
755+
_ = self.invoke_pickle('--unknown')
756+
757+
702758
def load_tests(loader, tests, pattern):
703759
tests.addTest(doctest.DocTestSuite(pickle))
704760
return tests

0 commit comments

Comments
 (0)