44import builtins
55import contextlib
66import copy
7+ import enum
78import io
89import os
910import pickle
@@ -18,7 +19,7 @@ def importable(name):
1819 try :
1920 __import__ (name )
2021 return True
21- except :
22+ except ModuleNotFoundError :
2223 return False
2324
2425
@@ -31,6 +32,15 @@ def get_command_stdout(command, args):
3132class BaseTestUUID :
3233 uuid = None
3334
35+ # TODO: RUSTPYTHON
36+ @unittest .expectedFailure
37+ def test_safe_uuid_enum (self ):
38+ class CheckedSafeUUID (enum .Enum ):
39+ safe = 0
40+ unsafe = - 1
41+ unknown = None
42+ enum ._test_simple_enum (CheckedSafeUUID , py_uuid .SafeUUID )
43+
3444 def test_UUID (self ):
3545 equal = self .assertEqual
3646 ascending = []
@@ -522,7 +532,14 @@ def test_uuid1(self):
522532 @support .requires_mac_ver (10 , 5 )
523533 @unittest .skipUnless (os .name == 'posix' , 'POSIX-only test' )
524534 def test_uuid1_safe (self ):
525- if not self .uuid ._has_uuid_generate_time_safe :
535+ try :
536+ import _uuid
537+ except ImportError :
538+ has_uuid_generate_time_safe = False
539+ else :
540+ has_uuid_generate_time_safe = _uuid .has_uuid_generate_time_safe
541+
542+ if not has_uuid_generate_time_safe or not self .uuid ._generate_time_safe :
526543 self .skipTest ('requires uuid_generate_time_safe(3)' )
527544
528545 u = self .uuid .uuid1 ()
@@ -538,7 +555,6 @@ def mock_generate_time_safe(self, safe_value):
538555 """
539556 if os .name != 'posix' :
540557 self .skipTest ('POSIX-only test' )
541- self .uuid ._load_system_functions ()
542558 f = self .uuid ._generate_time_safe
543559 if f is None :
544560 self .skipTest ('need uuid._generate_time_safe' )
@@ -573,17 +589,15 @@ def test_uuid1_bogus_return_value(self):
573589 self .assertEqual (u .is_safe , self .uuid .SafeUUID .unknown )
574590
575591 def test_uuid1_time (self ):
576- with mock .patch .object (self .uuid , '_has_uuid_generate_time_safe' , False ), \
577- mock .patch .object (self .uuid , '_generate_time_safe' , None ), \
592+ with mock .patch .object (self .uuid , '_generate_time_safe' , None ), \
578593 mock .patch .object (self .uuid , '_last_timestamp' , None ), \
579594 mock .patch .object (self .uuid , 'getnode' , return_value = 93328246233727 ), \
580595 mock .patch ('time.time_ns' , return_value = 1545052026752910643 ), \
581596 mock .patch ('random.getrandbits' , return_value = 5317 ): # guaranteed to be random
582597 u = self .uuid .uuid1 ()
583598 self .assertEqual (u , self .uuid .UUID ('a7a55b92-01fc-11e9-94c5-54e1acf6da7f' ))
584599
585- with mock .patch .object (self .uuid , '_has_uuid_generate_time_safe' , False ), \
586- mock .patch .object (self .uuid , '_generate_time_safe' , None ), \
600+ with mock .patch .object (self .uuid , '_generate_time_safe' , None ), \
587601 mock .patch .object (self .uuid , '_last_timestamp' , None ), \
588602 mock .patch ('time.time_ns' , return_value = 1545052026752910643 ):
589603 u = self .uuid .uuid1 (node = 93328246233727 , clock_seq = 5317 )
@@ -592,7 +606,22 @@ def test_uuid1_time(self):
592606 def test_uuid3 (self ):
593607 equal = self .assertEqual
594608
595- # Test some known version-3 UUIDs.
609+ # Test some known version-3 UUIDs with name passed as a byte object
610+ for u , v in [(self .uuid .uuid3 (self .uuid .NAMESPACE_DNS , b'python.org' ),
611+ '6fa459ea-ee8a-3ca4-894e-db77e160355e' ),
612+ (self .uuid .uuid3 (self .uuid .NAMESPACE_URL , b'http://python.org/' ),
613+ '9fe8e8c4-aaa8-32a9-a55c-4535a88b748d' ),
614+ (self .uuid .uuid3 (self .uuid .NAMESPACE_OID , b'1.3.6.1' ),
615+ 'dd1a1cef-13d5-368a-ad82-eca71acd4cd1' ),
616+ (self .uuid .uuid3 (self .uuid .NAMESPACE_X500 , b'c=ca' ),
617+ '658d3002-db6b-3040-a1d1-8ddd7d189a4d' ),
618+ ]:
619+ equal (u .variant , self .uuid .RFC_4122 )
620+ equal (u .version , 3 )
621+ equal (u , self .uuid .UUID (v ))
622+ equal (str (u ), v )
623+
624+ # Test some known version-3 UUIDs with name passed as a string
596625 for u , v in [(self .uuid .uuid3 (self .uuid .NAMESPACE_DNS , 'python.org' ),
597626 '6fa459ea-ee8a-3ca4-894e-db77e160355e' ),
598627 (self .uuid .uuid3 (self .uuid .NAMESPACE_URL , 'http://python.org/' ),
@@ -624,7 +653,22 @@ def test_uuid4(self):
624653 def test_uuid5 (self ):
625654 equal = self .assertEqual
626655
627- # Test some known version-5 UUIDs.
656+ # Test some known version-5 UUIDs with names given as byte objects
657+ for u , v in [(self .uuid .uuid5 (self .uuid .NAMESPACE_DNS , b'python.org' ),
658+ '886313e1-3b8a-5372-9b90-0c9aee199e5d' ),
659+ (self .uuid .uuid5 (self .uuid .NAMESPACE_URL , b'http://python.org/' ),
660+ '4c565f0d-3f5a-5890-b41b-20cf47701c5e' ),
661+ (self .uuid .uuid5 (self .uuid .NAMESPACE_OID , b'1.3.6.1' ),
662+ '1447fa61-5277-5fef-a9b3-fbc6e44f4af3' ),
663+ (self .uuid .uuid5 (self .uuid .NAMESPACE_X500 , b'c=ca' ),
664+ 'cc957dd1-a972-5349-98cd-874190002798' ),
665+ ]:
666+ equal (u .variant , self .uuid .RFC_4122 )
667+ equal (u .version , 5 )
668+ equal (u , self .uuid .UUID (v ))
669+ equal (str (u ), v )
670+
671+ # Test some known version-5 UUIDs with names given as strings
628672 for u , v in [(self .uuid .uuid5 (self .uuid .NAMESPACE_DNS , 'python.org' ),
629673 '886313e1-3b8a-5372-9b90-0c9aee199e5d' ),
630674 (self .uuid .uuid5 (self .uuid .NAMESPACE_URL , 'http://python.org/' ),
@@ -667,6 +711,67 @@ def test_uuid_weakref(self):
667711 weak = weakref .ref (strong )
668712 self .assertIs (strong , weak ())
669713
714+ @mock .patch .object (sys , "argv" , ["" , "-u" , "uuid3" , "-n" , "@dns" ])
715+ @mock .patch ('sys.stderr' , new_callable = io .StringIO )
716+ def test_cli_namespace_required_for_uuid3 (self , mock_err ):
717+ with self .assertRaises (SystemExit ) as cm :
718+ self .uuid .main ()
719+
720+ # Check that exception code is the same as argparse.ArgumentParser.error
721+ self .assertEqual (cm .exception .code , 2 )
722+ self .assertIn ("error: Incorrect number of arguments" , mock_err .getvalue ())
723+
724+ @mock .patch .object (sys , "argv" , ["" , "-u" , "uuid3" , "-N" , "python.org" ])
725+ @mock .patch ('sys.stderr' , new_callable = io .StringIO )
726+ def test_cli_name_required_for_uuid3 (self , mock_err ):
727+ with self .assertRaises (SystemExit ) as cm :
728+ self .uuid .main ()
729+ # Check that exception code is the same as argparse.ArgumentParser.error
730+ self .assertEqual (cm .exception .code , 2 )
731+ self .assertIn ("error: Incorrect number of arguments" , mock_err .getvalue ())
732+
733+ @mock .patch .object (sys , "argv" , ["" ])
734+ def test_cli_uuid4_outputted_with_no_args (self ):
735+ stdout = io .StringIO ()
736+ with contextlib .redirect_stdout (stdout ):
737+ self .uuid .main ()
738+
739+ output = stdout .getvalue ().strip ()
740+ uuid_output = self .uuid .UUID (output )
741+
742+ # Output uuid should be in the format of uuid4
743+ self .assertEqual (output , str (uuid_output ))
744+ self .assertEqual (uuid_output .version , 4 )
745+
746+ @mock .patch .object (sys , "argv" ,
747+ ["" , "-u" , "uuid3" , "-n" , "@dns" , "-N" , "python.org" ])
748+ def test_cli_uuid3_ouputted_with_valid_namespace_and_name (self ):
749+ stdout = io .StringIO ()
750+ with contextlib .redirect_stdout (stdout ):
751+ self .uuid .main ()
752+
753+ output = stdout .getvalue ().strip ()
754+ uuid_output = self .uuid .UUID (output )
755+
756+ # Output should be in the form of uuid5
757+ self .assertEqual (output , str (uuid_output ))
758+ self .assertEqual (uuid_output .version , 3 )
759+
760+ @mock .patch .object (sys , "argv" ,
761+ ["" , "-u" , "uuid5" , "-n" , "@dns" , "-N" , "python.org" ])
762+ def test_cli_uuid5_ouputted_with_valid_namespace_and_name (self ):
763+ stdout = io .StringIO ()
764+ with contextlib .redirect_stdout (stdout ):
765+ self .uuid .main ()
766+
767+ output = stdout .getvalue ().strip ()
768+ uuid_output = self .uuid .UUID (output )
769+
770+ # Output should be in the form of uuid5
771+ self .assertEqual (output , str (uuid_output ))
772+ self .assertEqual (uuid_output .version , 5 )
773+
774+
670775class TestUUIDWithoutExtModule (BaseTestUUID , unittest .TestCase ):
671776 uuid = py_uuid
672777
0 commit comments