mirror of
https://github.com/RustPython/RustPython.git
synced 2026-10-28 10:44:36 +08:00
Update uuid from 3.13.5 (#5901)
* Update uuid from 3.13.5 * Mark failing test
This commit is contained in:
1 parent
0a59c1cad3
commit
94a55eb479
2 files changed
+194
-39
No files matched your search
Vendored
+114
-9
@@ -4,6 +4,7 @@ from test.support import import_helper
|
||||
import builtins
|
||||
import contextlib
|
||||
import copy
|
||||
import enum
|
||||
import io
|
||||
import os
|
||||
import pickle
|
||||
@@ -18,7 +19,7 @@ def importable(name):
|
||||
try:
|
||||
__import__(name)
|
||||
return True
|
||||
except:
|
||||
except ModuleNotFoundError:
|
||||
return False
|
||||
|
||||
|
||||
@@ -31,6 +32,15 @@ def mock_get_command_stdout(data):
|
||||
class BaseTestUUID:
|
||||
uuid = None
|
||||
|
||||
# TODO: RUSTPYTHON
|
||||
@unittest.expectedFailure
|
||||
def test_safe_uuid_enum(self):
|
||||
class CheckedSafeUUID(enum.Enum):
|
||||
safe = 0
|
||||
unsafe = -1
|
||||
unknown = None
|
||||
enum._test_simple_enum(CheckedSafeUUID, py_uuid.SafeUUID)
|
||||
|
||||
def test_UUID(self):
|
||||
equal = self.assertEqual
|
||||
ascending = []
|
||||
@@ -522,7 +532,14 @@ class BaseTestUUID:
|
||||
@support.requires_mac_ver(10, 5)
|
||||
@unittest.skipUnless(os.name == 'posix', 'POSIX-only test')
|
||||
def test_uuid1_safe(self):
|
||||
if not self.uuid._has_uuid_generate_time_safe:
|
||||
try:
|
||||
import _uuid
|
||||
except ImportError:
|
||||
has_uuid_generate_time_safe = False
|
||||
else:
|
||||
has_uuid_generate_time_safe = _uuid.has_uuid_generate_time_safe
|
||||
|
||||
if not has_uuid_generate_time_safe or not self.uuid._generate_time_safe:
|
||||
self.skipTest('requires uuid_generate_time_safe(3)')
|
||||
|
||||
u = self.uuid.uuid1()
|
||||
@@ -538,7 +555,6 @@ class BaseTestUUID:
|
||||
"""
|
||||
if os.name != 'posix':
|
||||
self.skipTest('POSIX-only test')
|
||||
self.uuid._load_system_functions()
|
||||
f = self.uuid._generate_time_safe
|
||||
if f is None:
|
||||
self.skipTest('need uuid._generate_time_safe')
|
||||
@@ -573,8 +589,7 @@ class BaseTestUUID:
|
||||
self.assertEqual(u.is_safe, self.uuid.SafeUUID.unknown)
|
||||
|
||||
def test_uuid1_time(self):
|
||||
with mock.patch.object(self.uuid, '_has_uuid_generate_time_safe', False), \
|
||||
mock.patch.object(self.uuid, '_generate_time_safe', None), \
|
||||
with mock.patch.object(self.uuid, '_generate_time_safe', None), \
|
||||
mock.patch.object(self.uuid, '_last_timestamp', None), \
|
||||
mock.patch.object(self.uuid, 'getnode', return_value=93328246233727), \
|
||||
mock.patch('time.time_ns', return_value=1545052026752910643), \
|
||||
@@ -582,8 +597,7 @@ class BaseTestUUID:
|
||||
u = self.uuid.uuid1()
|
||||
self.assertEqual(u, self.uuid.UUID('a7a55b92-01fc-11e9-94c5-54e1acf6da7f'))
|
||||
|
||||
with mock.patch.object(self.uuid, '_has_uuid_generate_time_safe', False), \
|
||||
mock.patch.object(self.uuid, '_generate_time_safe', None), \
|
||||
with mock.patch.object(self.uuid, '_generate_time_safe', None), \
|
||||
mock.patch.object(self.uuid, '_last_timestamp', None), \
|
||||
mock.patch('time.time_ns', return_value=1545052026752910643):
|
||||
u = self.uuid.uuid1(node=93328246233727, clock_seq=5317)
|
||||
@@ -592,7 +606,22 @@ class BaseTestUUID:
|
||||
def test_uuid3(self):
|
||||
equal = self.assertEqual
|
||||
|
||||
# Test some known version-3 UUIDs.
|
||||
# Test some known version-3 UUIDs with name passed as a byte object
|
||||
for u, v in [(self.uuid.uuid3(self.uuid.NAMESPACE_DNS, b'python.org'),
|
||||
'6fa459ea-ee8a-3ca4-894e-db77e160355e'),
|
||||
(self.uuid.uuid3(self.uuid.NAMESPACE_URL, b'http://python.org/'),
|
||||
'9fe8e8c4-aaa8-32a9-a55c-4535a88b748d'),
|
||||
(self.uuid.uuid3(self.uuid.NAMESPACE_OID, b'1.3.6.1'),
|
||||
'dd1a1cef-13d5-368a-ad82-eca71acd4cd1'),
|
||||
(self.uuid.uuid3(self.uuid.NAMESPACE_X500, b'c=ca'),
|
||||
'658d3002-db6b-3040-a1d1-8ddd7d189a4d'),
|
||||
]:
|
||||
equal(u.variant, self.uuid.RFC_4122)
|
||||
equal(u.version, 3)
|
||||
equal(u, self.uuid.UUID(v))
|
||||
equal(str(u), v)
|
||||
|
||||
# Test some known version-3 UUIDs with name passed as a string
|
||||
for u, v in [(self.uuid.uuid3(self.uuid.NAMESPACE_DNS, 'python.org'),
|
||||
'6fa459ea-ee8a-3ca4-894e-db77e160355e'),
|
||||
(self.uuid.uuid3(self.uuid.NAMESPACE_URL, 'http://python.org/'),
|
||||
@@ -624,7 +653,22 @@ class BaseTestUUID:
|
||||
def test_uuid5(self):
|
||||
equal = self.assertEqual
|
||||
|
||||
# Test some known version-5 UUIDs.
|
||||
# Test some known version-5 UUIDs with names given as byte objects
|
||||
for u, v in [(self.uuid.uuid5(self.uuid.NAMESPACE_DNS, b'python.org'),
|
||||
'886313e1-3b8a-5372-9b90-0c9aee199e5d'),
|
||||
(self.uuid.uuid5(self.uuid.NAMESPACE_URL, b'http://python.org/'),
|
||||
'4c565f0d-3f5a-5890-b41b-20cf47701c5e'),
|
||||
(self.uuid.uuid5(self.uuid.NAMESPACE_OID, b'1.3.6.1'),
|
||||
'1447fa61-5277-5fef-a9b3-fbc6e44f4af3'),
|
||||
(self.uuid.uuid5(self.uuid.NAMESPACE_X500, b'c=ca'),
|
||||
'cc957dd1-a972-5349-98cd-874190002798'),
|
||||
]:
|
||||
equal(u.variant, self.uuid.RFC_4122)
|
||||
equal(u.version, 5)
|
||||
equal(u, self.uuid.UUID(v))
|
||||
equal(str(u), v)
|
||||
|
||||
# Test some known version-5 UUIDs with names given as strings
|
||||
for u, v in [(self.uuid.uuid5(self.uuid.NAMESPACE_DNS, 'python.org'),
|
||||
'886313e1-3b8a-5372-9b90-0c9aee199e5d'),
|
||||
(self.uuid.uuid5(self.uuid.NAMESPACE_URL, 'http://python.org/'),
|
||||
@@ -667,6 +711,67 @@ class BaseTestUUID:
|
||||
weak = weakref.ref(strong)
|
||||
self.assertIs(strong, weak())
|
||||
|
||||
@mock.patch.object(sys, "argv", ["", "-u", "uuid3", "-n", "@dns"])
|
||||
@mock.patch('sys.stderr', new_callable=io.StringIO)
|
||||
def test_cli_namespace_required_for_uuid3(self, mock_err):
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
self.uuid.main()
|
||||
|
||||
# Check that exception code is the same as argparse.ArgumentParser.error
|
||||
self.assertEqual(cm.exception.code, 2)
|
||||
self.assertIn("error: Incorrect number of arguments", mock_err.getvalue())
|
||||
|
||||
@mock.patch.object(sys, "argv", ["", "-u", "uuid3", "-N", "python.org"])
|
||||
@mock.patch('sys.stderr', new_callable=io.StringIO)
|
||||
def test_cli_name_required_for_uuid3(self, mock_err):
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
self.uuid.main()
|
||||
# Check that exception code is the same as argparse.ArgumentParser.error
|
||||
self.assertEqual(cm.exception.code, 2)
|
||||
self.assertIn("error: Incorrect number of arguments", mock_err.getvalue())
|
||||
|
||||
@mock.patch.object(sys, "argv", [""])
|
||||
def test_cli_uuid4_outputted_with_no_args(self):
|
||||
stdout = io.StringIO()
|
||||
with contextlib.redirect_stdout(stdout):
|
||||
self.uuid.main()
|
||||
|
||||
output = stdout.getvalue().strip()
|
||||
uuid_output = self.uuid.UUID(output)
|
||||
|
||||
# Output uuid should be in the format of uuid4
|
||||
self.assertEqual(output, str(uuid_output))
|
||||
self.assertEqual(uuid_output.version, 4)
|
||||
|
||||
@mock.patch.object(sys, "argv",
|
||||
["", "-u", "uuid3", "-n", "@dns", "-N", "python.org"])
|
||||
def test_cli_uuid3_ouputted_with_valid_namespace_and_name(self):
|
||||
stdout = io.StringIO()
|
||||
with contextlib.redirect_stdout(stdout):
|
||||
self.uuid.main()
|
||||
|
||||
output = stdout.getvalue().strip()
|
||||
uuid_output = self.uuid.UUID(output)
|
||||
|
||||
# Output should be in the form of uuid5
|
||||
self.assertEqual(output, str(uuid_output))
|
||||
self.assertEqual(uuid_output.version, 3)
|
||||
|
||||
@mock.patch.object(sys, "argv",
|
||||
["", "-u", "uuid5", "-n", "@dns", "-N", "python.org"])
|
||||
def test_cli_uuid5_ouputted_with_valid_namespace_and_name(self):
|
||||
stdout = io.StringIO()
|
||||
with contextlib.redirect_stdout(stdout):
|
||||
self.uuid.main()
|
||||
|
||||
output = stdout.getvalue().strip()
|
||||
uuid_output = self.uuid.UUID(output)
|
||||
|
||||
# Output should be in the form of uuid5
|
||||
self.assertEqual(output, str(uuid_output))
|
||||
self.assertEqual(uuid_output.version, 5)
|
||||
|
||||
|
||||
class TestUUIDWithoutExtModule(BaseTestUUID, unittest.TestCase):
|
||||
uuid = py_uuid
|
||||
|
||||
|
||||
Vendored
+80
-30
@@ -47,21 +47,22 @@ Typical usage:
|
||||
import os
|
||||
import sys
|
||||
|
||||
from enum import Enum
|
||||
from enum import Enum, _simple_enum
|
||||
|
||||
|
||||
__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
|
||||
|
||||
# The recognized platforms - known behaviors
|
||||
if sys.platform in ('win32', 'darwin'):
|
||||
_AIX = _LINUX = False
|
||||
elif sys.platform in ('emscripten', 'wasi'): # XXX: RUSTPYTHON; patched to support those platforms
|
||||
if sys.platform in {'win32', 'darwin', 'emscripten', 'wasi'}:
|
||||
_AIX = _LINUX = False
|
||||
elif sys.platform == 'linux':
|
||||
_LINUX = True
|
||||
_AIX = False
|
||||
else:
|
||||
import platform
|
||||
_platform_system = platform.system()
|
||||
_AIX = _platform_system == 'AIX'
|
||||
_LINUX = _platform_system == 'Linux'
|
||||
_LINUX = _platform_system in ('Linux', 'Android')
|
||||
|
||||
_MAC_DELIM = b':'
|
||||
_MAC_OMITS_LEADING_ZEROES = False
|
||||
@@ -77,7 +78,8 @@ int_ = int # The built-in int type
|
||||
bytes_ = bytes # The built-in bytes type
|
||||
|
||||
|
||||
class SafeUUID(Enum):
|
||||
@_simple_enum(Enum)
|
||||
class SafeUUID:
|
||||
safe = 0
|
||||
unsafe = -1
|
||||
unknown = None
|
||||
@@ -187,7 +189,7 @@ class UUID:
|
||||
if len(bytes) != 16:
|
||||
raise ValueError('bytes is not a 16-char string')
|
||||
assert isinstance(bytes, bytes_), repr(bytes)
|
||||
int = int_.from_bytes(bytes, byteorder='big')
|
||||
int = int_.from_bytes(bytes) # big endian
|
||||
if fields is not None:
|
||||
if len(fields) != 6:
|
||||
raise ValueError('fields is not a 6-tuple')
|
||||
@@ -285,7 +287,7 @@ class UUID:
|
||||
|
||||
@property
|
||||
def bytes(self):
|
||||
return self.int.to_bytes(16, 'big')
|
||||
return self.int.to_bytes(16) # big endian
|
||||
|
||||
@property
|
||||
def bytes_le(self):
|
||||
@@ -372,7 +374,12 @@ def _get_command_stdout(command, *args):
|
||||
# for are actually localized, but in theory some system could do so.)
|
||||
env = dict(os.environ)
|
||||
env['LC_ALL'] = 'C'
|
||||
proc = subprocess.Popen((executable,) + args,
|
||||
# Empty strings will be quoted by popen so we should just ommit it
|
||||
if args != ('',):
|
||||
command = (executable, *args)
|
||||
else:
|
||||
command = (executable,)
|
||||
proc = subprocess.Popen(command,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.DEVNULL,
|
||||
env=env)
|
||||
@@ -397,7 +404,7 @@ def _get_command_stdout(command, *args):
|
||||
# over locally administered ones since the former are globally unique, but
|
||||
# we'll return the first of the latter found if that's all the machine has.
|
||||
#
|
||||
# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local
|
||||
# See https://en.wikipedia.org/wiki/MAC_address#Universal_vs._local_(U/L_bit)
|
||||
|
||||
def _is_universal(mac):
|
||||
return not (mac & (1 << 41))
|
||||
@@ -512,7 +519,7 @@ def _ifconfig_getnode():
|
||||
mac = _find_mac_near_keyword('ifconfig', args, keywords, lambda i: i+1)
|
||||
if mac:
|
||||
return mac
|
||||
return None
|
||||
return None
|
||||
|
||||
def _ip_getnode():
|
||||
"""Get the hardware address on Unix by running ip."""
|
||||
@@ -525,6 +532,8 @@ def _ip_getnode():
|
||||
def _arp_getnode():
|
||||
"""Get the hardware address on Unix by running arp."""
|
||||
import os, socket
|
||||
if not hasattr(socket, "gethostbyname"):
|
||||
return None
|
||||
try:
|
||||
ip_addr = socket.gethostbyname(socket.gethostname())
|
||||
except OSError:
|
||||
@@ -558,32 +567,16 @@ def _netstat_getnode():
|
||||
# This works on AIX and might work on Tru64 UNIX.
|
||||
return _find_mac_under_heading('netstat', '-ian', b'Address')
|
||||
|
||||
def _ipconfig_getnode():
|
||||
"""[DEPRECATED] Get the hardware address on Windows."""
|
||||
# bpo-40501: UuidCreateSequential() is now the only supported approach
|
||||
return _windll_getnode()
|
||||
|
||||
def _netbios_getnode():
|
||||
"""[DEPRECATED] Get the hardware address on Windows."""
|
||||
# bpo-40501: UuidCreateSequential() is now the only supported approach
|
||||
return _windll_getnode()
|
||||
|
||||
|
||||
# Import optional C extension at toplevel, to help disabling it when testing
|
||||
try:
|
||||
import _uuid
|
||||
_generate_time_safe = getattr(_uuid, "generate_time_safe", None)
|
||||
_UuidCreate = getattr(_uuid, "UuidCreate", None)
|
||||
_has_uuid_generate_time_safe = _uuid.has_uuid_generate_time_safe
|
||||
except ImportError:
|
||||
_uuid = None
|
||||
_generate_time_safe = None
|
||||
_UuidCreate = None
|
||||
_has_uuid_generate_time_safe = None
|
||||
|
||||
|
||||
def _load_system_functions():
|
||||
"""[DEPRECATED] Platform-specific functions loaded at import time"""
|
||||
|
||||
|
||||
def _unix_getnode():
|
||||
@@ -609,7 +602,7 @@ def _random_getnode():
|
||||
# significant bit of the first octet". This works out to be the 41st bit
|
||||
# counting from 1 being the least significant bit, or 1<<40.
|
||||
#
|
||||
# See https://en.wikipedia.org/wiki/MAC_address#Unicast_vs._multicast
|
||||
# See https://en.wikipedia.org/w/index.php?title=MAC_address&oldid=1128764812#Universal_vs._local_(U/L_bit)
|
||||
import random
|
||||
return random.getrandbits(48) | (1 << 40)
|
||||
|
||||
@@ -705,9 +698,11 @@ def uuid1(node=None, clock_seq=None):
|
||||
|
||||
def uuid3(namespace, name):
|
||||
"""Generate a UUID from the MD5 hash of a namespace UUID and a name."""
|
||||
if isinstance(name, str):
|
||||
name = bytes(name, "utf-8")
|
||||
from hashlib import md5
|
||||
digest = md5(
|
||||
namespace.bytes + bytes(name, "utf-8"),
|
||||
namespace.bytes + name,
|
||||
usedforsecurity=False
|
||||
).digest()
|
||||
return UUID(bytes=digest[:16], version=3)
|
||||
@@ -718,13 +713,68 @@ def uuid4():
|
||||
|
||||
def uuid5(namespace, name):
|
||||
"""Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
|
||||
if isinstance(name, str):
|
||||
name = bytes(name, "utf-8")
|
||||
from hashlib import sha1
|
||||
hash = sha1(namespace.bytes + bytes(name, "utf-8")).digest()
|
||||
hash = sha1(namespace.bytes + name).digest()
|
||||
return UUID(bytes=hash[:16], version=5)
|
||||
|
||||
|
||||
def main():
|
||||
"""Run the uuid command line interface."""
|
||||
uuid_funcs = {
|
||||
"uuid1": uuid1,
|
||||
"uuid3": uuid3,
|
||||
"uuid4": uuid4,
|
||||
"uuid5": uuid5
|
||||
}
|
||||
uuid_namespace_funcs = ("uuid3", "uuid5")
|
||||
namespaces = {
|
||||
"@dns": NAMESPACE_DNS,
|
||||
"@url": NAMESPACE_URL,
|
||||
"@oid": NAMESPACE_OID,
|
||||
"@x500": NAMESPACE_X500
|
||||
}
|
||||
|
||||
import argparse
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Generates a uuid using the selected uuid function.")
|
||||
parser.add_argument("-u", "--uuid", choices=uuid_funcs.keys(), default="uuid4",
|
||||
help="The function to use to generate the uuid. "
|
||||
"By default uuid4 function is used.")
|
||||
parser.add_argument("-n", "--namespace",
|
||||
help="The namespace is a UUID, or '@ns' where 'ns' is a "
|
||||
"well-known predefined UUID addressed by namespace name. "
|
||||
"Such as @dns, @url, @oid, and @x500. "
|
||||
"Only required for uuid3/uuid5 functions.")
|
||||
parser.add_argument("-N", "--name",
|
||||
help="The name used as part of generating the uuid. "
|
||||
"Only required for uuid3/uuid5 functions.")
|
||||
|
||||
args = parser.parse_args()
|
||||
uuid_func = uuid_funcs[args.uuid]
|
||||
namespace = args.namespace
|
||||
name = args.name
|
||||
|
||||
if args.uuid in uuid_namespace_funcs:
|
||||
if not namespace or not name:
|
||||
parser.error(
|
||||
"Incorrect number of arguments. "
|
||||
f"{args.uuid} requires a namespace and a name. "
|
||||
"Run 'python -m uuid -h' for more information."
|
||||
)
|
||||
namespace = namespaces[namespace] if namespace in namespaces else UUID(namespace)
|
||||
print(uuid_func(namespace, name))
|
||||
else:
|
||||
print(uuid_func())
|
||||
|
||||
|
||||
# The following standard UUIDs are for use with uuid3() or uuid5().
|
||||
|
||||
NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
|
||||
NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
|
||||
NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
|
||||
NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user