https://github.com/boostorg/python/pull/482 From: Eisuke Kawashima Date: Mon, 31 Mar 2025 19:49:28 +0900 Subject: [PATCH] fix(test.pickle): fix for change in the return value of object.__reduce__() https://docs.python.org/3.11/library/pickle.html#object.__reduce__ fix #461 --- test/pickle1.py | 26 ++++++++++++++++++++++++-- test/pickle4.py | 26 ++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/libs/python/test/pickle1.py b/libs/python/test/pickle1.py index b8f4efd9b0..0df59a4b3a 100644 --- a/libs/python/test/pickle1.py +++ b/libs/python/test/pickle1.py @@ -9,8 +9,10 @@ 1 >>> pickle1_ext.world.__name__ 'world' - >>> pickle1_ext.world('Hello').__reduce__() + >>> pickle1_ext.world('Hello').__reduce__() # doctest: +PY310 (, ('Hello',)) + >>> pickle1_ext.world('Hello').__reduce__() # doctest: +PY311 + (, ('Hello',), None) >>> wd = pickle1_ext.world('California') >>> pstr = pickle.dumps(wd) >>> wl = pickle.loads(pstr) @@ -31,7 +33,27 @@ def run(args = None): if args is not None: sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) + + # > https://docs.python.org/3.11/library/pickle.html#object.__reduce__ + # object.__reduce__() returns + # - python 3.10 or prior: a 2-element tuple + # - python 3.11 or later: a 3-element tuple (object's state added) + PY310 = doctest.register_optionflag("PY310") + PY311 = doctest.register_optionflag("PY311") + + class ConditionalChecker(doctest.OutputChecker): + def check_output(self, want, got, optionflags): + if (optionflags & PY311) and (sys.version_info[:2] < (3, 11)): + return True + if (optionflags & PY310) and (sys.version_info[:2] >= (3, 11)): + return True + return doctest.OutputChecker.check_output(self, want, got, optionflags) + + runner = doctest.DocTestRunner(ConditionalChecker()) + for test in doctest.DocTestFinder().find(sys.modules.get(__name__)): + runner.run(test) + + return doctest.TestResults(runner.failures, runner.tries) if __name__ == '__main__': print("running...") diff --git a/libs/python/test/pickle4.py b/libs/python/test/pickle4.py index be813bbb13..3cf4d7241f 100644 --- a/libs/python/test/pickle4.py +++ b/libs/python/test/pickle4.py @@ -12,8 +12,10 @@ 1 >>> pickle4_ext.world.__name__ 'world' - >>> pickle4_ext.world('Hello').__reduce__() + >>> pickle4_ext.world('Hello').__reduce__() # doctest: +PY310 (, ('Hello',)) + >>> pickle4_ext.world('Hello').__reduce__() # doctest: +PY311 + (, ('Hello',), None) >>> wd = pickle4_ext.world('California') >>> pstr = pickle.dumps(wd) >>> wl = pickle.loads(pstr) @@ -29,7 +31,27 @@ def run(args = None): if args is not None: sys.argv = args - return doctest.testmod(sys.modules.get(__name__)) + + # > https://docs.python.org/3.11/library/pickle.html#object.__reduce__ + # object.__reduce__() returns + # - python 3.10 or prior: a 2-element tuple + # - python 3.11 or later: a 3-element tuple (object's state added) + PY310 = doctest.register_optionflag("PY310") + PY311 = doctest.register_optionflag("PY311") + + class ConditionalChecker(doctest.OutputChecker): + def check_output(self, want, got, optionflags): + if (optionflags & PY311) and (sys.version_info[:2] < (3, 11)): + return True + if (optionflags & PY310) and (sys.version_info[:2] >= (3, 11)): + return True + return doctest.OutputChecker.check_output(self, want, got, optionflags) + + runner = doctest.DocTestRunner(ConditionalChecker()) + for test in doctest.DocTestFinder().find(sys.modules.get(__name__)): + runner.run(test) + + return doctest.TestResults(runner.failures, runner.tries) if __name__ == '__main__': print("running...")