Merge ~cjwatson/launchpad:remove-enumcol into launchpad:master

Proposed by Colin Watson
Status: Merged
Approved by: Colin Watson
Approved revision: 0c5e3b3ea2b9fb1f224945fa95079185cc8ce618
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: ~cjwatson/launchpad:remove-enumcol
Merge into: launchpad:master
Diff against target: 192 lines (+40/-50)
2 files modified
lib/lp/services/database/doc/enumcol.txt (+31/-22)
lib/lp/services/database/enumcol.py (+9/-28)
Reviewer Review Type Date Requested Status
Ioana Lasc (community) Approve
Review via email: mp+412134@code.launchpad.net

Commit message

Remove now-unused EnumCol

Description of the change

All call sites now use the Storm-style `DBEnum` instead.

In the process of updating tests for this, I noticed that DBEnum only checks the type of the `enum` parameter when the property is used (thus constructing the associated variable), rather than when the property is constructed; and it also failed to actually do the type check in practice due to a Python 3 porting bug. This seems inconvenient, so I moved the type check earlier and fixed it for Python 3.

To post a comment you must log in.
Revision history for this message
Ioana Lasc (ilasc) wrote :

looks good and nice catch on the type check!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/lib/lp/services/database/doc/enumcol.txt b/lib/lp/services/database/doc/enumcol.txt
2index ac5ad80..4685182 100644
3--- a/lib/lp/services/database/doc/enumcol.txt
4+++ b/lib/lp/services/database/doc/enumcol.txt
5@@ -1,9 +1,8 @@
6-An example of EnumCol with EnumeratedTypes
7-==========================================
8+An example of DBEnum with EnumeratedTypes
9+=========================================
10
11-EnumCol is a type of column that is used in SQLBase classes where the
12-database representation is an integer and the code uses an enumerated
13-type.
14+DBEnum is a type of column that is used in Storm classes where the database
15+representation is an integer and the code uses an enumerated type.
16
17 Firstly we need an example table.
18
19@@ -20,10 +19,10 @@ Firstly we need an example table.
20 >>> import transaction
21 >>> transaction.commit()
22
23-The enumerated type that is used with the EnumCol must be a
24+The enumerated type that is used with the DBEnum must be a
25 DBEnumeratedType, with items that are instances of DBItem.
26
27-Attempting to use a normal enumerated type for an enumcol will
28+Attempting to use a normal enumerated type for a DBEnum will
29 result in an error.
30
31 >>> from lazr.enum import EnumeratedType, Item, use_template
32@@ -32,11 +31,15 @@ result in an error.
33 ... ONE = Item("One")
34 ... TWO = Item("Two")
35
36+ >>> from storm.locals import Int
37 >>> from lp.services.database.constants import DEFAULT
38- >>> from lp.services.database.enumcol import EnumCol
39- >>> from lp.services.database.sqlbase import SQLBase
40- >>> class BadFooTest(SQLBase):
41- ... foo = EnumCol(enum=PlainFooType, default=DEFAULT)
42+ >>> from lp.services.database.enumcol import DBEnum
43+ >>> from lp.services.database.interfaces import IStore
44+ >>> from lp.services.database.stormbase import StormBase
45+ >>> class BadFooTest(StormBase):
46+ ... __storm_table__ = "footest"
47+ ... id = Int(primary=True)
48+ ... foo = DBEnum(enum=PlainFooType, default=DEFAULT)
49 Traceback (most recent call last):
50 ...
51 TypeError: <EnumeratedType 'PlainFooType'> must be a
52@@ -59,12 +62,15 @@ result in an error.
53
54 The database implementation class then refers to the enumerated type.
55
56- >>> class FooTest(SQLBase):
57- ... foo = EnumCol(enum=FooType, default=DEFAULT)
58+ >>> class FooTest(StormBase):
59+ ... __storm_table__ = "footest"
60+ ... id = Int(primary=True)
61+ ... foo = DBEnum(enum=FooType, default=DEFAULT)
62
63 Create a row in the table.
64
65- >>> t = FooTest()
66+ >>> store = IStore(FooTest)
67+ >>> t = store.add(FooTest())
68
69 The value of the foo column has been set to the default defined in the
70 database, because we didn't specify one in the constructor.
71@@ -72,7 +78,7 @@ database, because we didn't specify one in the constructor.
72 >>> t.foo == FooType.ONE
73 True
74
75-You cannot use integers or strings as EnumCol values:
76+You cannot use integers or strings as DBEnum values:
77
78 >>> t.foo = 2
79 Traceback (most recent call last):
80@@ -130,24 +136,27 @@ schemas into one table. This works if you tell the column about both enums:
81
82 Redefine the table with awareness of BarType:
83
84- >>> class FooTest(SQLBase):
85- ... foo = EnumCol(schema=[FooType, BarType], default=DEFAULT)
86+ >>> class FooTest(StormBase):
87+ ... __storm_table__ = "footest"
88+ ... id = Int(primary=True)
89+ ... foo = DBEnum(enum=[FooType, BarType], default=DEFAULT)
90
91 We can assign items from either schema to the table;
92
93- >>> t = FooTest()
94+ >>> t = store.add(FooTest())
95 >>> t.foo = FooType.ONE
96+ >>> store.flush()
97 >>> t_id = t.id
98- >>> b = FooTest()
99+ >>> b = store.add(FooTest())
100 >>> b.foo = BarType.THREE
101+ >>> store.flush()
102 >>> b_id = b.id
103
104 And reading back from the database correctly finds things from the schemas in
105 the order given.
106
107- >>> from storm.store import AutoReload
108- >>> b.foo = AutoReload
109- >>> t.foo = AutoReload
110+ >>> store.autoreload(b)
111+ >>> store.autoreload(t)
112 >>> b.foo == BarType.THREE
113 True
114 >>> t.foo == FooType.ONE
115diff --git a/lib/lp/services/database/enumcol.py b/lib/lp/services/database/enumcol.py
116index cf4867c..3da2741 100644
117--- a/lib/lp/services/database/enumcol.py
118+++ b/lib/lp/services/database/enumcol.py
119@@ -1,13 +1,10 @@
120 # Copyright 2009-2021 Canonical Ltd. This software is licensed under the
121 # GNU Affero General Public License version 3 (see the file LICENSE).
122
123-import warnings
124-
125 from lazr.enum import (
126 DBEnumeratedType,
127 DBItem,
128 )
129-from storm import sqlobject
130 from storm.properties import SimpleProperty
131 from storm.variables import Variable
132 from zope.security.proxy import isinstance as zope_isinstance
133@@ -15,7 +12,6 @@ from zope.security.proxy import isinstance as zope_isinstance
134
135 __all__ = [
136 'DBEnum',
137- 'EnumCol',
138 ]
139
140
141@@ -27,7 +23,8 @@ def check_enum_type(enum):
142
143 def check_type(enum):
144 if type(enum) in (list, tuple):
145- map(check_enum_type, enum)
146+ for element in enum:
147+ check_enum_type(element)
148 else:
149 check_enum_type(enum)
150
151@@ -37,12 +34,8 @@ class DBEnumVariable(Variable):
152 __slots__ = ("_enum",)
153
154 def __init__(self, *args, **kwargs):
155- enum = kwargs.pop("enum")
156- if type(enum) not in (list, tuple):
157- enum = (enum,)
158- self._enum = enum
159- check_type(self._enum)
160- super(DBEnumVariable, self).__init__(*args, **kwargs)
161+ self._enum = kwargs.pop("enum")
162+ super().__init__(*args, **kwargs)
163
164 def parse_set(self, value, from_db):
165 if from_db:
166@@ -71,21 +64,9 @@ class DBEnumVariable(Variable):
167 class DBEnum(SimpleProperty):
168 variable_class = DBEnumVariable
169
170-
171-class EnumCol(sqlobject.PropertyAdapter, DBEnum):
172- def __init__(self, **kw):
173- # We want to end up using only the Storm style, not a mix of
174- # SQLObject and Storm.
175- warnings.warn(
176- "The SQLObject property EnumCol is deprecated; use the Storm "
177- "property DBEnum instead.",
178- DeprecationWarning, stacklevel=2)
179- try:
180- enum = kw.pop('enum')
181- except KeyError:
182- enum = kw.pop('schema')
183+ def __init__(self, *args, **kwargs):
184+ enum = kwargs.pop("enum")
185+ if type(enum) not in (list, tuple):
186+ enum = (enum,)
187 check_type(enum)
188- self._kwargs = {
189- 'enum': enum,
190- }
191- super().__init__(**kw)
192+ super().__init__(enum=enum, *args, **kwargs)

Subscribers

People subscribed via source and target branches

to status/vote changes: