Merge lp:~cjwatson/lazr.restful/mutator-replacement into lp:lazr.restful

Proposed by Colin Watson on 2018-09-28
Status: Needs review
Proposed branch: lp:~cjwatson/lazr.restful/mutator-replacement
Merge into: lp:lazr.restful
Diff against target: 156 lines (+40/-29)
3 files modified
src/lazr/restful/NEWS.txt (+9/-0)
src/lazr/restful/docs/webservice-declarations.txt (+14/-21)
src/lazr/restful/metazcml.py (+17/-8)
To merge this branch: bzr merge lp:~cjwatson/lazr.restful/mutator-replacement
Reviewer Review Type Date Requested Status
LAZR Developers 2018-09-28 Pending
Review via email: mp+355845@code.launchpad.net

Commit message

Remove limitation on immediately reinstating a mutator as a named operation.

Description of the change

This previously only worked if the registration code happened to encounter the replacing named operation before it encountered the replaced mutator, which ultimately depended on dict iteration order. I considered making it enforce the limitation consistently, but it was just as easy to remove the limitation.

To post a comment you must log in.

Unmerged revisions

220. By Colin Watson on 2018-09-28

Remove limitation on immediately reinstating a mutator as a named operation.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/lazr/restful/NEWS.txt'
2--- src/lazr/restful/NEWS.txt 2018-02-21 15:18:34 +0000
3+++ src/lazr/restful/NEWS.txt 2018-09-28 14:44:56 +0000
4@@ -2,6 +2,15 @@
5 NEWS for lazr.restful
6 =====================
7
8+0.20.2
9+======
10+
11+Remove limitation on immediately reinstating a named operation with the same
12+name as a mutator in the webservice version that gets rid of named
13+operations for mutator methods. (This was previously only unreliably
14+enforced in any case, as it depended on the order of methods returned by
15+zope.interface.Interface.namesAndDescriptions.)
16+
17 0.20.1 (2018-02-21)
18 ===================
19
20
21=== modified file 'src/lazr/restful/docs/webservice-declarations.txt'
22--- src/lazr/restful/docs/webservice-declarations.txt 2016-02-17 01:07:21 +0000
23+++ src/lazr/restful/docs/webservice-declarations.txt 2018-09-28 14:44:56 +0000
24@@ -2901,14 +2901,13 @@
25 >>> print entry.field
26 !foo!
27
28-You can't immediately reinstate a mutator operation as a named operation
29-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
30+You can immediately reinstate a mutator operation as a named operation
31+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
32
33-Here's one that shows a limitation of the software. This method
34-defines a mutator 'set_value' for version 1.0, which will be removed
35-in version 2.0. It *also* defines a named operation to be published
36-as 'set_value' in version 2.0, and a third operation to be published
37-as 'set_value' in version 3.0.
38+This method defines a mutator 'set_value' for version 1.0, which will be
39+removed in version 2.0. It *also* defines a named operation to be published
40+as 'set_value' in version 2.0, and a third operation to be published as
41+'set_value' in version 3.0.
42
43 >>> class IMutatorPlusNamedOperationEntry(Interface):
44 ... export_as_webservice_entry()
45@@ -2950,23 +2949,17 @@
46 >>> print operation_for(context, '1.0', 'set_value').__class__.__name__
47 POST_IMutatorPlusNamedOperationEntry_set_value_1_0
48
49-But the named operation that replaces the mutator in version 1.0 is
50-not accessible.
51-
52- >>> operation_for(context, '2.0', 'set_value')
53- Traceback (most recent call last):
54- ...
55- ComponentLookupError: ...
56-
57-The named operation of the same name defined in version 3.0 _is_
58-accessible.
59-
60+The named operations that replace the mutator in versions 2.0 and 3.0 are
61+also accessible.
62+
63+ >>> print operation_for(context, '2.0', 'set_value').__class__.__name__
64+ POST_IMutatorPlusNamedOperationEntry_set_value_2_0
65 >>> print operation_for(context, '3.0', 'set_value').__class__.__name__
66 POST_IMutatorPlusNamedOperationEntry_set_value_3_0
67
68-So, in the version that gets rid of named operations for mutator
69-methods, you can't define a named operation with the same name as one
70-of the outgoing mutator methods.
71+So, in the version that gets rid of named operations for mutator methods,
72+you can immediately define a named operation with the same name as one of
73+the outgoing mutator methods.
74
75 Removing mutator named operations altogether
76 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
77
78=== modified file 'src/lazr/restful/metazcml.py'
79--- src/lazr/restful/metazcml.py 2016-11-26 00:54:04 +0000
80+++ src/lazr/restful/metazcml.py 2018-09-28 14:44:56 +0000
81@@ -476,6 +476,8 @@
82 no_mutator_operations_after+1]
83 else:
84 block_mutator_operations_as_of_version = None
85+ registered_adapters = set()
86+ block_mutator_operations = set()
87
88 methods = interface.namesAndDescriptions(True)
89 for iface in REGISTERED_CONTRIBUTORS[interface]:
90@@ -522,7 +524,6 @@
91 # version.
92 previous_operation_name = None
93 previous_operation_provides = None
94- mutator_operation_needs_to_be_blocked = False
95 for version, tag in tag.stack:
96 if version is None:
97 this_version_index = 0
98@@ -592,7 +593,6 @@
99 # This will save us from having to do another
100 # de-registration later.
101 factory = _mask_adapter_registration
102- mutator_operation_needs_to_be_blocked = False
103 else:
104 factory = generate_operation_adapter(method, version)
105
106@@ -607,6 +607,9 @@
107 _mask_adapter_registration, interface, version,
108 previous_operation_provides, previous_operation_name,
109 context.info)
110+ registered_adapters.add(
111+ (previous_operation_name, version,
112+ previous_operation_provides))
113
114 # If the operation exists in this version (ie. its name is
115 # not None), register it using this version's name.
116@@ -614,6 +617,8 @@
117 register_adapter_for_version(
118 factory, interface, version, operation_provides,
119 operation_name, context.info)
120+ registered_adapters.add(
121+ (operation_name, version, operation_provides))
122 if (tag.get('is_mutator')
123 and block_mutator_operations_as_of_version != None):
124 defined_in = this_version_index
125@@ -625,21 +630,25 @@
126 # mutators stop being named operations, and
127 # the operation registration for this mutator
128 # will need to be blocked.
129- mutator_operation_needs_to_be_blocked = True
130+ block_mutator_operations.add(
131+ (operation_name,
132+ block_mutator_operations_as_of_version,
133+ operation_provides))
134 if repository is not None:
135 repository.append(VersionedObject(version, method))
136 previous_operation_name = operation_name
137 previous_operation_provides = operation_provides
138
139- if mutator_operation_needs_to_be_blocked:
140+ for operation_key in block_mutator_operations:
141+ if operation_key not in registered_adapters:
142+ operation_name, version, operation_provides = operation_key
143 # The operation was registered as a mutator, back in the
144 # days when mutator operations were also named operations,
145 # and it never got de-registered. De-register it now.
146 register_adapter_for_version(
147- _mask_adapter_registration, interface,
148- block_mutator_operations_as_of_version,
149- previous_operation_provides, previous_operation_name,
150- context.info)
151+ _mask_adapter_registration, interface, version,
152+ operation_provides, operation_name, context.info)
153+
154
155 def _mask_adapter_registration(*args):
156 """A factory function that stops an adapter lookup from succeeding.

Subscribers

People subscribed via source and target branches