From a6b31813f7906433d087a5d9a4b7b7843da4c24e Mon Sep 17 00:00:00 2001 From: Lance Edgar Date: Sun, 21 Dec 2025 01:17:56 -0600 Subject: [PATCH] fix: add `make_str_uuid()` to disambiguate what callers want first step on the way to fixing `make_uuid()` so it always returns a proper UUID instance --- docs/glossary.rst | 7 +++++ src/wuttjamaican/app.py | 63 ++++++++++++++++++++++++++-------------- src/wuttjamaican/util.py | 57 +++++++++++++++++++++++------------- tests/test_app.py | 9 ++++-- tests/test_util.py | 13 +++++++-- 5 files changed, 103 insertions(+), 46 deletions(-) diff --git a/docs/glossary.rst b/docs/glossary.rst index 0218540..47df4b0 100644 --- a/docs/glossary.rst +++ b/docs/glossary.rst @@ -321,6 +321,13 @@ Glossary the real workhorse; each can perform a different function with a custom arg set. See also :doc:`narr/cli/index`. + uuid + Universally-unique identifier. All built-in :term:`data models + ` have a UUID column for primary key. + + Call :meth:`~wuttjamaican.app.AppHandler.make_uuid()` to get a + new UUID. + virtual environment This term comes from the broader Python world and refers to an isolated way to install :term:`packages`. See also diff --git a/src/wuttjamaican/app.py b/src/wuttjamaican/app.py index 3b7ef86..9f4f41b 100644 --- a/src/wuttjamaican/app.py +++ b/src/wuttjamaican/app.py @@ -44,6 +44,7 @@ from wuttjamaican.util import ( make_full_name, make_utc, make_uuid, + make_str_uuid, make_true_uuid, progress_loop, resource_path, @@ -645,45 +646,63 @@ class AppHandler: # pylint: disable=too-many-public-methods """ return make_utc(dt=dt, tzinfo=tzinfo) + # TODO: deprecate / remove this eventually def make_true_uuid(self): """ - Generate a new UUID value. + Generate a new :term:`UUID `. - By default this simply calls - :func:`wuttjamaican.util.make_true_uuid()`. + This is a convenience around + :func:`~wuttjamaican.util.make_true_uuid()`. + + See also :meth:`make_uuid()`. :returns: :class:`python:uuid.UUID` instance - - .. warning:: - - For now, callers should use this method when they want a - proper UUID instance, whereas :meth:`make_uuid()` will - always return a string. - - However once all dependent logic has been refactored to - support proper UUID data type, then ``make_uuid()`` will - return those and this method will eventually be removed. """ return make_true_uuid() - def make_uuid(self): + # TODO: deprecate / remove this eventually + def make_str_uuid(self): """ - Generate a new UUID value. + Generate a new :term:`UUID ` string. - By default this simply calls - :func:`wuttjamaican.util.make_uuid()`. + This is a convenience around + :func:`~wuttjamaican.util.make_str_uuid()`. + + See also :meth:`make_uuid()`. :returns: UUID value as 32-character string. + """ + return make_str_uuid() + + # TODO: eventually refactor, to return true uuid + def make_uuid(self): + """ + Generate a new :term:`UUID ` (for now, as string). + + This is a convenience around + :func:`~wuttjamaican.util.make_uuid()`. + + :returns: UUID as 32-character hex string .. warning:: - For now, this method always returns a string. + **TEMPORARY BEHAVIOR** - However once all dependent logic has been refactored to - support proper UUID data type, then this method will return - those and the :meth:`make_true_uuid()` method will - eventually be removed. + For the moment, use of this method is discouraged. Instead + you should use :meth:`make_true_uuid()` or + :meth:`make_str_uuid()` to be explicit about the return + type you expect. + + *Eventually* (once it's clear most/all callers are using + the explicit methods) this will be refactored to return a + UUID instance. But for now this method returns a string. """ + warnings.warn( + "app.make_uuid() is temporarily deprecated, in favor of " + "explicit methods, app.make_true_uuid() and app.make_str_uuid()", + DeprecationWarning, + stacklevel=2, + ) return make_uuid() def progress_loop(self, *args, **kwargs): diff --git a/src/wuttjamaican/util.py b/src/wuttjamaican/util.py index f232767..a129887 100644 --- a/src/wuttjamaican/util.py +++ b/src/wuttjamaican/util.py @@ -29,6 +29,7 @@ import importlib import logging import os import shlex +import warnings from uuid_extensions import uuid7 @@ -325,43 +326,59 @@ def make_utc(dt=None, tzinfo=False): return dt.replace(tzinfo=datetime.timezone.utc) +# TODO: deprecate / remove this eventually def make_true_uuid(): """ - Generate a new v7 UUID value. + Generate a new v7 UUID. + + See also :func:`make_uuid()`. :returns: :class:`python:uuid.UUID` instance - - .. warning:: - - For now, callers should use this function when they want a - proper UUID instance, whereas :func:`make_uuid()` will always - return a string. - - However once all dependent logic has been refactored to support - proper UUID data type, then ``make_uuid()`` will return those - and this function will eventually be removed. """ return uuid7() -# TODO: deprecate this logic, and reclaim this name -# but using the above logic +# TODO: deprecate / remove this eventually +def make_str_uuid(): + """ + Generate a new v7 UUID value as string. + + See also :func:`make_uuid()`. + + :returns: UUID as 32-character hex string + """ + return make_true_uuid().hex + + +# TODO: eventually refactor, to return true uuid def make_uuid(): """ Generate a new v7 UUID value. - :returns: A 32-character hex string. + See also the app handler shortcut, + :meth:`~wuttjamaican.app.AppHandler.make_uuid()`. + + :returns: UUID as 32-character hex string .. warning:: - For now, this function always returns a string. + **TEMPORARY BEHAVIOR** - However once all dependent logic has been refactored to support - proper UUID data type, then this function will return those and - the :func:`make_true_uuid()` function will eventually be - removed. + For the moment, use of this function is discouraged. Instead you + should use :func:`make_true_uuid()` or :func:`make_str_uuid()` to + be explicit about the return type you expect. + + *Eventually* (once it's clear most/all callers are using the + explicit functions) this will be refactored to return a UUID + instance. But for now this function returns a string. """ - return make_true_uuid().hex + warnings.warn( + "util.make_uuid() is temporarily deprecated, in favor of " + "explicit functions, util.make_true_uuid() and util.make_str_uuid()", + DeprecationWarning, + stacklevel=2, + ) + return make_str_uuid() def parse_bool(value): diff --git a/tests/test_app.py b/tests/test_app.py index 7bdebf9..bf51576 100644 --- a/tests/test_app.py +++ b/tests/test_app.py @@ -510,14 +510,19 @@ app_title = WuttaTest self.assertIsInstance(dt, datetime.datetime) self.assertIsNone(dt.tzinfo) - def test_make_uuid(self): - uuid = self.app.make_uuid() + def test_make_str_uuid(self): + uuid = self.app.make_str_uuid() self.assertEqual(len(uuid), 32) def test_make_true_uuid(self): uuid = self.app.make_true_uuid() self.assertIsInstance(uuid, _uuid.UUID) + def test_make_uuid(self): + # TODO: temporary behavior + uuid = self.app.make_uuid() + self.assertEqual(len(uuid), 32) + def test_progress_loop(self): def act(obj, i): diff --git a/tests/test_util.py b/tests/test_util.py index 398a23e..31b0527 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -4,6 +4,7 @@ import datetime import sys from unittest import TestCase from unittest.mock import patch, MagicMock +from uuid import UUID import pytest @@ -332,9 +333,17 @@ class TestMakeUTC(TestCase): class TestMakeUUID(TestCase): - def test_basic(self): + def test_str_uuid(self): + uuid = mod.make_str_uuid() + self.assertIsInstance(uuid, str) + + def test_true_uuid(self): + uuid = mod.make_true_uuid() + self.assertIsInstance(uuid, UUID) + + def test_temporary_behavior(self): uuid = mod.make_uuid() - self.assertEqual(len(uuid), 32) + self.assertIsInstance(uuid, str) class TestParseBool(TestCase):