gh-148740: Fix uuid CLI with custom UUIDs for UUIDv3/v5 namespaces (#148741)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Jansen Price
2026-04-29 08:44:22 -05:00
committed by GitHub
parent 16f292ef4e
commit f1588d460d
3 changed files with 79 additions and 17 deletions
+69 -15
View File
@@ -1182,6 +1182,47 @@ class CommandLineTestCases:
self.assertEqual(cm.exception.code, 2)
self.assertIn("error: Incorrect number of arguments", mock_err.getvalue())
@mock.patch.object(sys, "argv",
["", "-u", "uuid3", "-n", "@dns", "-N", "python.org"])
def test_cli_uuid3_outputted_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 uuid3
self.assertEqual(output, str(uuid_output))
self.assertEqual(uuid_output.version, 3)
@mock.patch.object(sys, "argv",
["", "-u", "uuid3", "-n",
"0d6a16cc-34a7-47d8-b660-214d0ae184d2",
"-N", "some.user"])
def test_cli_uuid3_outputted_with_custom_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 uuid3
self.assertEqual(output, str(uuid_output))
self.assertEqual(uuid_output.version, 3)
@mock.patch.object(sys, "argv",
["", "-u", "uuid3", "-n", "any UUID", "-N", "python.org"])
@mock.patch('sys.stderr', new_callable=io.StringIO)
def test_cli_uuid3_with_invalid_namespace(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: badly formed hexadecimal UUID string",
mock_err.getvalue())
@mock.patch.object(sys, "argv", [""])
def test_cli_uuid4_outputted_with_no_args(self):
stdout = io.StringIO()
@@ -1209,23 +1250,9 @@ class CommandLineTestCases:
uuid_output = self.uuid.UUID(o)
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):
def test_cli_uuid5_outputted_with_valid_namespace_and_name(self):
stdout = io.StringIO()
with contextlib.redirect_stdout(stdout):
self.uuid.main()
@@ -1237,6 +1264,33 @@ class CommandLineTestCases:
self.assertEqual(output, str(uuid_output))
self.assertEqual(uuid_output.version, 5)
@mock.patch.object(sys, "argv",
["", "-u", "uuid5", "-n",
"0d6a16cc-34a7-47d8-b660-214d0ae184d2",
"-N", "some.user"])
def test_cli_uuid5_ouputted_with_custom_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)
@mock.patch.object(sys, "argv",
["", "-u", "uuid5", "-n", "any UUID", "-N", "python.org"])
@mock.patch('sys.stderr', new_callable=io.StringIO)
def test_cli_uuid5_with_invalid_namespace(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: badly formed hexadecimal UUID string",
mock_err.getvalue())
@mock.patch.object(sys, "argv", ["", "-u", "uuid6"])
def test_cli_uuid6(self):
self.do_test_standalone_uuid(6)
+8 -2
View File
@@ -962,7 +962,7 @@ def main():
default="uuid4",
help="function to generate the UUID")
parser.add_argument("-n", "--namespace",
choices=["any UUID", *namespaces.keys()],
metavar=f"{{any UUID,{','.join(namespaces)}}}",
help="uuid3/uuid5 only: "
"a UUID, or a well-known predefined UUID addressed "
"by namespace name")
@@ -984,7 +984,13 @@ def main():
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)
if namespace in namespaces:
namespace = namespaces[namespace]
else:
try:
namespace = UUID(namespace)
except ValueError as exc:
parser.error(f"{exc}: {args.namespace!r}")
for _ in range(args.count):
print(uuid_func(namespace, name))
else:
@@ -0,0 +1,2 @@
Fix usage for :mod:`uuid` command-line interface to support a custom namespace be
provided for uuid3 and uuid5.