diff options
author | Jason R. Coombs <jaraco@jaraco.com> | 2021-01-16 14:45:30 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-01-16 14:45:30 -0500 |
commit | 799722cb0ddb90752cde7798cab543f30623ebf2 (patch) | |
tree | 1a2b77e6a085b87be3cc8ebda21f9bdd90c41d35 | |
parent | bpo-42931: randbytes missing from random.__all__ (GH-24219) (GH-24225) (diff) | |
download | cpython-799722cb0ddb90752cde7798cab543f30623ebf2.tar.gz cpython-799722cb0ddb90752cde7798cab543f30623ebf2.tar.bz2 cpython-799722cb0ddb90752cde7798cab543f30623ebf2.zip |
[3.9] bpo-42163, bpo-42189, bpo-42659: Support uname_tuple._replace (for all but processor) (GH-23010) (#24232)
* Add test capturing missed expectation with uname_result._replace.
* bpo-42163: Override uname_result._make to allow uname_result._replace to work (for everything but 'processor'.
* Replace hard-coded length with one derived from the definition.
* Add test capturing missed expectation with copy/deepcopy on namedtuple (bpo-42189).
* bpo-42189: Exclude processor parameter when constructing uname_result.
* In _make, rely on __new__ to strip processor.
* Add blurb.
* iter is not necessary here.
* Rely on num_fields in __new__
* Add test for slices on uname
* Add test for copy and pickle.
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
* import pickle
* Fix equality test after pickling.
* Simply rely on __reduce__ for pickling.
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
(cherry picked from commit a6fd0f414c0cb4cd5cc20eb2df3340b31c6f7743)
Co-authored-by: Jason R. Coombs <jaraco@jaraco.com>
-rwxr-xr-x | Lib/platform.py | 17 | ||||
-rw-r--r-- | Lib/test/test_platform.py | 34 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2020-10-29-09-22-56.bpo-42163.O4VcCY.rst | 1 |
3 files changed, 50 insertions, 2 deletions
diff --git a/Lib/platform.py b/Lib/platform.py index e9f50ab622d..6258827d0e4 100755 --- a/Lib/platform.py +++ b/Lib/platform.py @@ -782,7 +782,7 @@ class uname_result( ): """ A uname_result that's largely compatible with a - simple namedtuple except that 'platform' is + simple namedtuple except that 'processor' is resolved late and cached to avoid calling "uname" except when needed. """ @@ -797,12 +797,25 @@ class uname_result( (self.processor,) ) + @classmethod + def _make(cls, iterable): + # override factory to affect length check + num_fields = len(cls._fields) + result = cls.__new__(cls, *iterable) + if len(result) != num_fields + 1: + msg = f'Expected {num_fields} arguments, got {len(result)}' + raise TypeError(msg) + return result + def __getitem__(self, key): - return tuple(iter(self))[key] + return tuple(self)[key] def __len__(self): return len(tuple(iter(self))) + def __reduce__(self): + return uname_result, tuple(self)[:len(self._fields)] + _uname_cache = None diff --git a/Lib/test/test_platform.py b/Lib/test/test_platform.py index a3b06feb655..9f04c79e09b 100644 --- a/Lib/test/test_platform.py +++ b/Lib/test/test_platform.py @@ -1,4 +1,6 @@ import os +import copy +import pickle import platform import subprocess import sys @@ -175,6 +177,38 @@ class PlatformTest(unittest.TestCase): ) self.assertEqual(tuple(res), expected) + def test_uname_replace(self): + res = platform.uname() + new = res._replace( + system='system', node='node', release='release', + version='version', machine='machine') + self.assertEqual(new.system, 'system') + self.assertEqual(new.node, 'node') + self.assertEqual(new.release, 'release') + self.assertEqual(new.version, 'version') + self.assertEqual(new.machine, 'machine') + # processor cannot be replaced + self.assertEqual(new.processor, res.processor) + + def test_uname_copy(self): + uname = platform.uname() + self.assertEqual(copy.copy(uname), uname) + self.assertEqual(copy.deepcopy(uname), uname) + + def test_uname_pickle(self): + orig = platform.uname() + for proto in range(pickle.HIGHEST_PROTOCOL + 1): + with self.subTest(protocol=proto): + pickled = pickle.dumps(orig, proto) + restored = pickle.loads(pickled) + self.assertEqual(restored, orig) + + def test_uname_slices(self): + res = platform.uname() + expected = tuple(res) + self.assertEqual(res[:], expected) + self.assertEqual(res[:5], expected[:5]) + @unittest.skipIf(sys.platform in ['win32', 'OpenVMS'], "uname -p not used") def test_uname_processor(self): """ diff --git a/Misc/NEWS.d/next/Library/2020-10-29-09-22-56.bpo-42163.O4VcCY.rst b/Misc/NEWS.d/next/Library/2020-10-29-09-22-56.bpo-42163.O4VcCY.rst new file mode 100644 index 00000000000..0c357eb4ac1 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-10-29-09-22-56.bpo-42163.O4VcCY.rst @@ -0,0 +1 @@ +Restore compatibility for ``uname_result`` around deepcopy and _replace. |