Deprecate current UUIDField behaviour

Change-Id: Ic7a62eec8f92de282fcf265d86f76d9c86dbc7fc
This commit is contained in:
Graham Hayes 2016-02-03 20:42:10 +00:00 committed by Dan Smith
parent 8e5a40a977
commit c6adc63632
2 changed files with 85 additions and 1 deletions

View File

@ -16,6 +16,8 @@ import abc
import datetime
from distutils import versionpredicate
import re
import uuid
import warnings
import copy
import iso8601
@ -306,7 +308,23 @@ class UUID(FieldType):
@staticmethod
def coerce(obj, attr, value):
# FIXME(danms): We should actually verify the UUIDness here
return str(value)
with warnings.catch_warnings():
warnings.simplefilter("once")
try:
uuid.UUID(str(value))
except Exception:
# This is to ensure no breaking behaviour for current
# users
warnings.warn("%s is an invalid UUID. Using UUIDFields "
"with invalid UUIDs is no longer "
"supported, and will be removed in a future "
"release. Please update your "
"code to input valid UUIDs or accept "
"ValueErrors for invalid UUIDs. See "
"http://docs.openstack.org/developer/oslo.versionedobjects/api/fields.html#oslo_versionedobjects.fields.UUIDField " # noqa
"for further details" % value, FutureWarning)
return str(value)
class MACAddress(FieldType):
@ -761,6 +779,35 @@ class StateMachine(EnumField):
class UUIDField(AutoTypedField):
"""UUID Field Type
.. warning::
This class does not actually validate UUIDs. This will happen in a
future major version of oslo.versionedobjects
To validate that you have valid UUIDs you need to do the following in
your own objects/fields.py
:Example:
.. code-block:: python
import oslo_versionedobjects.fields as ovo_fields
class UUID(ovo_fields.UUID):
def coerce(self, obj, attr, value):
uuid.UUID(value)
return str(value)
class UUIDField(ovo_fields.AutoTypedField):
AUTO_TYPE = UUID()
and then in your objects use
``<your_projects>.object.fields.UUIDField``.
This will become default behaviour in the future.
"""
AUTO_TYPE = UUID()

View File

@ -191,6 +191,43 @@ class TestMACAddress(TestField):
self.from_primitive_values = self.coerce_good_values[0:1]
class TestUUID(TestField):
def setUp(self):
super(TestUUID, self).setUp()
def test_validation_enabled(self):
self.field = fields.UUIDField()
self.coerce_good_values = [
('da66a411-af0e-4829-9b67-475017ddd152',
'da66a411-af0e-4829-9b67-475017ddd152'),
('da66a411af0e48299b67475017ddd152',
'da66a411af0e48299b67475017ddd152'),
('DA66A411-AF0E-4829-9B67-475017DDD152',
'DA66A411-AF0E-4829-9B67-475017DDD152'),
('DA66A411AF0E48299b67475017DDD152',
'DA66A411AF0E48299b67475017DDD152'),
# These values are included to ensure there is not change in
# behaviour - only when we can remove the old UUID behaviour can
# we add these to the "self.coerce_bad_values" list
('da66a411-af0e-4829-9b67',
'da66a411-af0e-4829-9b67'),
('da66a411-af0e-4829-9b67-475017ddd152548999',
'da66a411-af0e-4829-9b67-475017ddd152548999'),
('da66a411-af0e-4829-9b67-475017ddz152',
'da66a411-af0e-4829-9b67-475017ddz152'),
('fake_uuid', 'fake_uuid'),
('1', '1'),
(1, '1')
]
self.to_primitive_values = self.coerce_good_values[0:1]
self.from_primitive_values = self.coerce_good_values[0:1]
self.test_coerce_good_values()
self.test_from_primitive()
self.test_to_primitive()
class TestBaseEnum(TestField):
def setUp(self):
super(TestBaseEnum, self).setUp()