Merge lp:~pieter-equinox/reahl/reahl-declarative into lp:~iv/reahl/reahl-declarative
- reahl-declarative
- Merge into reahl-declarative
Status: | Merged |
---|---|
Merged at revision: | 80 |
Proposed branch: | lp:~pieter-equinox/reahl/reahl-declarative |
Merge into: | lp:~iv/reahl/reahl-declarative |
Diff against target: |
582 lines (+172/-192) 9 files modified
reahl-bzrsupport/reahl/bzrsupport.py (+1/-1) reahl-dev/reahl_dev.egg-info/SOURCES.txt (+0/-1) reahl-dev/reahl_dev.egg-info/entry_points.txt (+55/-55) reahl-stubble/ideas/stubble.py (+1/-2) reahl-stubble/reahl/stubble/intercept.py (+1/-1) reahl-stubble/reahl/stubble/stub.py (+5/-2) reahl-stubble/reahl/stubble_dev/BasicStubRequirementsTests.py (+101/-126) reahl-tofu/reahl/tofu/fixture.py (+4/-4) reahl-webdev/reahl/webdev/tools.py (+4/-0) |
To merge this branch: | bzr merge lp:~pieter-equinox/reahl/reahl-declarative |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Iwan Vosloo | Approve | ||
Review via email: mp+230770@code.launchpad.net |
Commit message
Description of the change
Nop
Iwan Vosloo (iv) : | # |
- 74. By Pieter Nagel
-
Add PyCharm project files and adapt .bzrignore to ignore user preferences
- 75. By Pieter Nagel
-
Need to decode shell output in bzrsupport for Python3
- 76. By Pieter Nagel
-
Temporary hacks to work around issues
- 77. By Pieter Nagel
-
Hold off on adding PyCharm config to project, for now
- 78. By Pieter Nagel
-
Merged
- 79. By Pieter Nagel
-
Ignore .idea again
- 80. By Pieter Nagel
-
Workaround for new.instancemethod not existing on Py3. Root problem is that MarkingDecorator tries to be both a decorator and a descriptor and does all kinds of mucking with the object model that is not needed.
- 81. By Pieter Nagel
-
Cleaner replacement for new.instancemethod in tofu and stubble
- 82. By Pieter Nagel
-
Fix one MethodType instantiation in stubble
- 83. By Pieter Nagel
-
Stubble: deahl with types/classes printing themselves differently under Py3 vs Py2
- 84. By Pieter Nagel
-
SystemOutStub: sys.stdout is open in text mode
Pieter Nagel (pieter-equinox) wrote : | # |
Tofu passes all tests in Python 3. One can now just run "reahl unit" under Python 3.
Stubble is faring better but there are still 6 failures.
Iwan Vosloo (iv) : | # |
Preview Diff
1 | === modified file 'reahl-bzrsupport/reahl/bzrsupport.py' |
2 | --- reahl-bzrsupport/reahl/bzrsupport.py 2014-07-06 10:25:15 +0000 |
3 | +++ reahl-bzrsupport/reahl/bzrsupport.py 2014-08-16 12:12:26 +0000 |
4 | @@ -130,7 +130,7 @@ |
5 | out.seek(0) |
6 | err.seek(0) |
7 | if not err.read(): |
8 | - files = out.read().split('\n') |
9 | + files = out.read().decode().split('\n') |
10 | return files |
11 | except Exception as ex: |
12 | logging.error('Error trying to execute "bzr %s": %s' % (bzr_args, ex)) |
13 | |
14 | === modified file 'reahl-dev/reahl_dev.egg-info/SOURCES.txt' |
15 | --- reahl-dev/reahl_dev.egg-info/SOURCES.txt 2014-08-14 16:12:02 +0000 |
16 | +++ reahl-dev/reahl_dev.egg-info/SOURCES.txt 2014-08-16 12:12:26 +0000 |
17 | @@ -3,7 +3,6 @@ |
18 | COPYING |
19 | LICENSE |
20 | reahl |
21 | -setup.py |
22 | reahl/__init__.py |
23 | reahl/dev/__init__.py |
24 | reahl/dev/devdomain.py |
25 | |
26 | === modified file 'reahl-dev/reahl_dev.egg-info/entry_points.txt' |
27 | --- reahl-dev/reahl_dev.egg-info/entry_points.txt 2014-08-14 16:12:02 +0000 |
28 | +++ reahl-dev/reahl_dev.egg-info/entry_points.txt 2014-08-16 12:12:26 +0000 |
29 | @@ -1,68 +1,68 @@ |
30 | +[reahl.eggs] |
31 | +Egg = reahl.component.eggs:ReahlEgg |
32 | + |
33 | +[reahl.dev.commands] |
34 | +ListSelections = reahl.dev.devshell:ListSelections |
35 | +Shell = reahl.dev.devshell:Shell |
36 | +Select = reahl.dev.devshell:Select |
37 | +Upload = reahl.dev.devshell:Upload |
38 | +ServeSMTP = reahl.dev.mailtest:ServeSMTP |
39 | +Info = reahl.dev.devshell:Info |
40 | +AddLocale = reahl.dev.devshell:AddLocale |
41 | +DeleteSelection = reahl.dev.devshell:DeleteSelection |
42 | +Setup = reahl.dev.devshell:Setup |
43 | +Read = reahl.dev.devshell:Read |
44 | +UpdateAptRepository = reahl.dev.devshell:UpdateAptRepository |
45 | +SubstVars = reahl.dev.devshell:SubstVars |
46 | +MergeTranslations = reahl.dev.devshell:MergeTranslations |
47 | +MarkReleased = reahl.dev.devshell:MarkReleased |
48 | +CompileTranslations = reahl.dev.devshell:CompileTranslations |
49 | +Save = reahl.dev.devshell:Save |
50 | +ClearSelection = reahl.dev.devshell:ClearSelection |
51 | +DebInstall = reahl.dev.devshell:DebInstall |
52 | +ExplainLegend = reahl.dev.devshell:ExplainLegend |
53 | +ExtractMessages = reahl.dev.devshell:ExtractMessages |
54 | +ListMissingDependencies = reahl.dev.devshell:ListMissingDependencies |
55 | +List = reahl.dev.devshell:List |
56 | +Debianise = reahl.dev.devshell:Debianise |
57 | +Build = reahl.dev.devshell:Build |
58 | +Refresh = reahl.dev.devshell:Refresh |
59 | + |
60 | [reahl.dev.xmlclasses] |
61 | -NamespaceList = reahl.dev.devdomain:NamespaceList |
62 | -DebianPackage = reahl.dev.devdomain:DebianPackage |
63 | -ScriptExport = reahl.dev.devdomain:ScriptExport |
64 | -BzrSourceControl = reahl.dev.devdomain:BzrSourceControl |
65 | -ExtraPath = reahl.dev.devdomain:ExtraPath |
66 | -ThirdpartyDependency = reahl.dev.devdomain:ThirdpartyDependency |
67 | -EntryPointExport = reahl.dev.devdomain:EntryPointExport |
68 | -MigrationList = reahl.dev.devdomain:MigrationList |
69 | +PersistedClassesList = reahl.dev.devdomain:PersistedClassesList |
70 | +ExtrasList = reahl.dev.devdomain:ExtrasList |
71 | +AttachmentList = reahl.dev.devdomain:AttachmentList |
72 | NamespaceEntry = reahl.dev.devdomain:NamespaceEntry |
73 | +HardcodedMetadata = reahl.dev.devdomain:HardcodedMetadata |
74 | FileList = reahl.dev.devdomain:FileList |
75 | -MetaInfo = reahl.dev.devdomain:MetaInfo |
76 | -DebianPackageSet = reahl.dev.devdomain:DebianPackageSet |
77 | -ExcludedPackage = reahl.dev.devdomain:ExcludedPackage |
78 | -OrderedPersistedClass = reahl.dev.devdomain:OrderedPersistedClass |
79 | -TranslationPackage = reahl.dev.devdomain:TranslationPackage |
80 | -PersistedClassesList = reahl.dev.devdomain:PersistedClassesList |
81 | -PackageIndex = reahl.dev.devdomain:PackageIndex |
82 | +ChickenProject = reahl.dev.devdomain:ChickenProject |
83 | +PythonSourcePackage = reahl.dev.devdomain:PythonSourcePackage |
84 | +EggProject = reahl.dev.devdomain:EggProject |
85 | SshRepository = reahl.dev.devdomain:SshRepository |
86 | -AttachmentList = reahl.dev.devdomain:AttachmentList |
87 | Project = reahl.dev.devdomain:Project |
88 | -Dependency = reahl.dev.devdomain:Dependency |
89 | +ScriptExport = reahl.dev.devdomain:ScriptExport |
90 | +OrderedPersistedClass = reahl.dev.devdomain:OrderedPersistedClass |
91 | +ConfigurationSpec = reahl.dev.devdomain:ConfigurationSpec |
92 | +MetaInfo = reahl.dev.devdomain:MetaInfo |
93 | CommandAlias = reahl.dev.devdomain:CommandAlias |
94 | -ConfigurationSpec = reahl.dev.devdomain:ConfigurationSpec |
95 | -ExtrasList = reahl.dev.devdomain:ExtrasList |
96 | -EggProject = reahl.dev.devdomain:EggProject |
97 | +ShippedFile = reahl.dev.devdomain:ShippedFile |
98 | +EntryPointExport = reahl.dev.devdomain:EntryPointExport |
99 | ProjectTag = reahl.dev.devdomain:ProjectTag |
100 | -HardcodedMetadata = reahl.dev.devdomain:HardcodedMetadata |
101 | -ShippedFile = reahl.dev.devdomain:ShippedFile |
102 | +ExtraPath = reahl.dev.devdomain:ExtraPath |
103 | +ScheduledJobSpec = reahl.dev.devdomain:ScheduledJobSpec |
104 | +DebianPackageSet = reahl.dev.devdomain:DebianPackageSet |
105 | +TranslationPackage = reahl.dev.devdomain:TranslationPackage |
106 | XMLDependencyList = reahl.dev.devdomain:XMLDependencyList |
107 | -ChickenProject = reahl.dev.devdomain:ChickenProject |
108 | +NamespaceList = reahl.dev.devdomain:NamespaceList |
109 | +ExcludedPackage = reahl.dev.devdomain:ExcludedPackage |
110 | +BzrSourceControl = reahl.dev.devdomain:BzrSourceControl |
111 | +DebianPackage = reahl.dev.devdomain:DebianPackage |
112 | +ThirdpartyDependency = reahl.dev.devdomain:ThirdpartyDependency |
113 | +MigrationList = reahl.dev.devdomain:MigrationList |
114 | DebianPackageMetadata = reahl.dev.devdomain:DebianPackageMetadata |
115 | -ScheduledJobSpec = reahl.dev.devdomain:ScheduledJobSpec |
116 | -PythonSourcePackage = reahl.dev.devdomain:PythonSourcePackage |
117 | +PackageIndex = reahl.dev.devdomain:PackageIndex |
118 | +Dependency = reahl.dev.devdomain:Dependency |
119 | |
120 | [console_scripts] |
121 | reahl = reahl.dev.devshell:WorkspaceCommandline.execute_one |
122 | |
123 | -[reahl.eggs] |
124 | -Egg = reahl.component.eggs:ReahlEgg |
125 | - |
126 | -[reahl.dev.commands] |
127 | -DebInstall = reahl.dev.devshell:DebInstall |
128 | -MergeTranslations = reahl.dev.devshell:MergeTranslations |
129 | -AddLocale = reahl.dev.devshell:AddLocale |
130 | -SubstVars = reahl.dev.devshell:SubstVars |
131 | -Build = reahl.dev.devshell:Build |
132 | -Save = reahl.dev.devshell:Save |
133 | -Debianise = reahl.dev.devshell:Debianise |
134 | -Shell = reahl.dev.devshell:Shell |
135 | -Read = reahl.dev.devshell:Read |
136 | -UpdateAptRepository = reahl.dev.devshell:UpdateAptRepository |
137 | -ListSelections = reahl.dev.devshell:ListSelections |
138 | -Info = reahl.dev.devshell:Info |
139 | -ClearSelection = reahl.dev.devshell:ClearSelection |
140 | -Setup = reahl.dev.devshell:Setup |
141 | -List = reahl.dev.devshell:List |
142 | -Upload = reahl.dev.devshell:Upload |
143 | -Refresh = reahl.dev.devshell:Refresh |
144 | -ExplainLegend = reahl.dev.devshell:ExplainLegend |
145 | -MarkReleased = reahl.dev.devshell:MarkReleased |
146 | -ExtractMessages = reahl.dev.devshell:ExtractMessages |
147 | -ListMissingDependencies = reahl.dev.devshell:ListMissingDependencies |
148 | -ServeSMTP = reahl.dev.mailtest:ServeSMTP |
149 | -DeleteSelection = reahl.dev.devshell:DeleteSelection |
150 | -CompileTranslations = reahl.dev.devshell:CompileTranslations |
151 | -Select = reahl.dev.devshell:Select |
152 | - |
153 | |
154 | === modified file 'reahl-stubble/ideas/stubble.py' |
155 | --- reahl-stubble/ideas/stubble.py 2014-07-05 10:41:49 +0000 |
156 | +++ reahl-stubble/ideas/stubble.py 2014-08-16 12:12:26 +0000 |
157 | @@ -17,7 +17,6 @@ |
158 | from __future__ import unicode_literals |
159 | from __future__ import print_function |
160 | import six |
161 | -import new |
162 | import types |
163 | import inspect |
164 | from functools import reduce |
165 | @@ -68,7 +67,7 @@ |
166 | stub_args = inspect.getargspec(self.stub) |
167 | assert real_args == stub_args, 'argument specification mismatch' |
168 | |
169 | - return new.instancemethod(self.stub, instance, owner) |
170 | + return types.MethodType(self.stub, instance) |
171 | |
172 | def __set__(self, instance, value): |
173 | assert None, 'cannot set stub methods' |
174 | |
175 | === modified file 'reahl-stubble/reahl/stubble/intercept.py' |
176 | --- reahl-stubble/reahl/stubble/intercept.py 2014-08-14 08:49:20 +0000 |
177 | +++ reahl-stubble/reahl/stubble/intercept.py 2014-08-16 12:12:26 +0000 |
178 | @@ -53,7 +53,7 @@ |
179 | sys.stdout = self.original_stdout |
180 | |
181 | def capture_console_screenshot(self, filename): |
182 | - with io.open(filename, 'wb') as output_file: |
183 | + with io.open(filename, 'w') as output_file: |
184 | output_file.write(self.captured_output) |
185 | |
186 | |
187 | |
188 | === modified file 'reahl-stubble/reahl/stubble/stub.py' |
189 | --- reahl-stubble/reahl/stubble/stub.py 2014-07-06 10:25:15 +0000 |
190 | +++ reahl-stubble/reahl/stubble/stub.py 2014-08-16 12:12:26 +0000 |
191 | @@ -21,7 +21,7 @@ |
192 | import os.path |
193 | import pkg_resources |
194 | import inspect |
195 | -import new |
196 | +import types |
197 | |
198 | import collections |
199 | from functools import reduce |
200 | @@ -209,7 +209,10 @@ |
201 | if inspect.ismethoddescriptor(self.value) or inspect.isdatadescriptor(self.value): |
202 | return self.value.__get__(instance, owner) |
203 | if inspect.isfunction(self.value): |
204 | - return new.instancemethod(self.value, instance, owner) |
205 | + if instance is None: |
206 | + return self |
207 | + else: |
208 | + return types.MethodType(self.value, instance) |
209 | else: |
210 | return self.value |
211 | |
212 | |
213 | === modified file 'reahl-stubble/reahl/stubble_dev/BasicStubRequirementsTests.py' |
214 | --- reahl-stubble/reahl/stubble_dev/BasicStubRequirementsTests.py 2014-07-06 10:25:15 +0000 |
215 | +++ reahl-stubble/reahl/stubble_dev/BasicStubRequirementsTests.py 2014-08-16 12:12:26 +0000 |
216 | @@ -16,9 +16,8 @@ |
217 | |
218 | from __future__ import unicode_literals |
219 | from __future__ import print_function |
220 | -import six |
221 | |
222 | -from nose.tools import istest, assert_raises, assert_true, assert_equals |
223 | +from nose.tools import istest, assert_raises, assert_raises_regexp, assert_true |
224 | |
225 | from reahl.stubble import stubclass, exempt, EmptyStub |
226 | |
227 | @@ -50,148 +49,123 @@ |
228 | @istest |
229 | def test_method_attribute_mismatch(self): |
230 | """a method in the stub which is an attribute in the stubbed is not allowed""" |
231 | - def declare_class(): |
232 | + #normal case |
233 | + with assert_raises_regexp( |
234 | + AssertionError, |
235 | + "^attribute mismatch: <class '.*\.Stub'>\.<(unbound method|function) .*Stub\.attr.*> is not compatible with the original type <(type|class) 'int'> on <class '.*Stubbed'>"): |
236 | @stubclass(self.stubbed) |
237 | class Stub(object): |
238 | - def attr(self): pass |
239 | - |
240 | - #normal case |
241 | - with assert_raises(AssertionError) as context: |
242 | - declare_class() |
243 | - assert_equals( six.text_type(context.exception), '''attribute mismatch: <class 'reahl.stubble_dev.BasicStubRequirementsTests.Stub'>.<unbound method Stub.attr> is not compatible with the original type <type 'int'> on <class 'reahl.stubble_dev.BasicStubRequirementsTests.Stubbed'>''' ) |
244 | + def attr(self): |
245 | + pass |
246 | |
247 | @istest |
248 | def test_method_signature_mismatch(self): |
249 | """a method signature mismatch between the stub and the stubbed is not allowed""" |
250 | - def declare_class(): |
251 | + #normal case |
252 | + with assert_raises_regexp( |
253 | + AssertionError, |
254 | + '^signature mismatch:.*Stub.method.*\(self, b, akwarg=None, \*args, \*\*kwargs\) does not match .*Stubbed.method.*\(self, a, b, akwarg=None, \*args, \*\*kwargs\)$'): |
255 | @stubclass(self.stubbed) |
256 | class Stub(object): |
257 | - def method(self, b, akwarg=None, *args, **kwargs): pass |
258 | + def method(self, b, akwarg=None, *args, **kwargs): |
259 | + pass |
260 | |
261 | - #normal case |
262 | - with assert_raises(AssertionError) as context: |
263 | - declare_class() |
264 | - |
265 | - assert_equals( six.text_type(context.exception), '''signature mismatch: <unbound method Stub.method>(self, b, akwarg=None, *args, **kwargs) does not match <unbound method Stubbed.method>(self, a, b, akwarg=None, *args, **kwargs)''' ) |
266 | |
267 | @istest |
268 | def test_property_method_missing_on_orig(self): |
269 | """a property on the stub is not allowed if the stubbed class does not have property or an attribute""" |
270 | - def declare_class(): |
271 | + #case where the property does ont exist on the stubbed class |
272 | + with assert_raises(AssertionError): |
273 | @stubclass(self.stubbed) |
274 | class Stub(object): |
275 | @property |
276 | def non_existing_property(self): |
277 | return 2 |
278 | |
279 | - #case where the property does ont exist on the stubbed class |
280 | - assert_raises(AssertionError, declare_class) |
281 | - |
282 | @istest |
283 | def test_property_method_masks_method_on_orig(self): |
284 | """a property on the stub is not allowed if the stubbed class has a method with the same name""" |
285 | - def declare_class(): |
286 | + #case where the property does ont exist on the stubbed class |
287 | + with assert_raises(AssertionError): |
288 | @stubclass(self.stubbed) |
289 | class Stub(object): |
290 | @property |
291 | def method(self): |
292 | return 2 |
293 | |
294 | - #case where the property does ont exist on the stubbed class |
295 | - assert_raises(AssertionError, declare_class) |
296 | - |
297 | @istest |
298 | def test_property_method_for_attribute_on_orig(self): |
299 | """a property on the stub is allowed if the stubbed class has a property or an attribute of the same name""" |
300 | #case where the stubbed class has an attribute for the property |
301 | - def declare_class(): |
302 | - @stubclass(self.stubbed) |
303 | - class Stub(object): |
304 | - @property |
305 | - def attr(self): |
306 | - return 2 |
307 | - |
308 | - declare_class() |
309 | + @stubclass(self.stubbed) |
310 | + class Stub(object): |
311 | + @property |
312 | + def attr(self): |
313 | + return 2 |
314 | |
315 | #case where the stubbed class has a matching property |
316 | - def declare_class(): |
317 | - @stubclass(self.stubbed) |
318 | - class Stub(object): |
319 | - @property |
320 | - def my_existing_property(self): |
321 | - return 2 |
322 | - |
323 | - declare_class() |
324 | + @stubclass(self.stubbed) |
325 | + class Stub(object): |
326 | + @property |
327 | + def my_existing_property(self): |
328 | + return 2 |
329 | |
330 | @istest |
331 | def test_attribute_not_present_mismatch(self): |
332 | """an attribute in the stub which is not in the stubbed is not allowed""" |
333 | - def declare_class(): |
334 | + #normal case |
335 | + with assert_raises(AssertionError): |
336 | @stubclass(self.stubbed, True) |
337 | class Stub(object): |
338 | i_am_not = 1 |
339 | |
340 | - #normal case |
341 | - assert_raises(AssertionError, declare_class) |
342 | - |
343 | @istest |
344 | def test_method_name_mismatch(self): |
345 | """a method in the stub which has no counterpart in the stubbed is not allowed""" |
346 | - def declare_class(): |
347 | + #normal case |
348 | + with assert_raises(AssertionError): |
349 | @stubclass(self.stubbed) |
350 | class Stub(object): |
351 | - def method1(self, a, b): pass |
352 | - |
353 | - #normal case |
354 | - assert_raises(AssertionError, declare_class) |
355 | + def method1(self, a, b): |
356 | + pass |
357 | |
358 | @istest |
359 | def test_normal_method(self): |
360 | """a method in the stub which accurately describes one in the stubbed is allowed""" |
361 | - def declare_class(): |
362 | - @stubclass(self.stubbed) |
363 | - class Stub(object): |
364 | - def method(self, a, b, akwarg=None, *args, **kwargs): pass |
365 | - |
366 | #normal case |
367 | - declare_class() |
368 | + @stubclass(self.stubbed) |
369 | + class Stub(object): |
370 | + def method(self, a, b, akwarg=None, *args, **kwargs): |
371 | + pass |
372 | + |
373 | |
374 | @istest |
375 | def test_normal_attribute(self): |
376 | """an attribute in the stub which is also present in the stubbed is allowed""" |
377 | |
378 | #normal case |
379 | - def declare_class(): |
380 | - @stubclass(self.stubbed, True) |
381 | - class Stub(object): |
382 | - attr = 1 |
383 | - |
384 | - declare_class() |
385 | + @stubclass(self.stubbed, True) |
386 | + class Stub(object): |
387 | + attr = 1 |
388 | |
389 | #case where we're not checking for attributes |
390 | - def declare_class(): |
391 | - @stubclass(self.stubbed) |
392 | - class Stub(object): |
393 | - i_am_not = 1 |
394 | - |
395 | - declare_class() |
396 | + @stubclass(self.stubbed) |
397 | + class Stub(object): |
398 | + i_am_not = 1 |
399 | |
400 | #----------------------------------------[ exempt members ] |
401 | @istest |
402 | def test_exempt_attribute(self): |
403 | """an attribute or property marked exempt does not raise an error""" |
404 | - def declare_class(): |
405 | - @stubclass(self.stubbed, True) |
406 | - class Stub(object): |
407 | - attr = 1 |
408 | - attr = exempt(attr) |
409 | - @exempt |
410 | - @property |
411 | - def prop(self): pass |
412 | - return Stub |
413 | - |
414 | + @stubclass(self.stubbed, True) |
415 | #normal case |
416 | - Stub = declare_class() |
417 | + class Stub(object): |
418 | + attr = 1 |
419 | + attr = exempt(attr) |
420 | + @exempt |
421 | + @property |
422 | + def prop(self): |
423 | + pass |
424 | |
425 | # the property returns the correct value |
426 | assert Stub().prop is None |
427 | @@ -199,59 +173,60 @@ |
428 | @istest |
429 | def test_exempt_method(self): |
430 | """any methods marked as exempt does not raise an error""" |
431 | - def declare_class(): |
432 | - @stubclass(self.stubbed) |
433 | - class Stub(object): |
434 | - @exempt |
435 | - def local_method(self): pass |
436 | - |
437 | - @exempt |
438 | - def method(): pass |
439 | - |
440 | - @exempt |
441 | - @classmethod |
442 | - def local_class_method(cls): pass |
443 | - |
444 | - @exempt |
445 | - @classmethod |
446 | - def a_class_method(cls): pass |
447 | - return Stub |
448 | - |
449 | #normal case |
450 | - _class = declare_class() |
451 | - _class.local_class_method() |
452 | - _class.a_class_method() |
453 | + @stubclass(self.stubbed) |
454 | + class Stub(object): |
455 | + @exempt |
456 | + def local_method(self): |
457 | + pass |
458 | + |
459 | + @exempt |
460 | + def method(): |
461 | + pass |
462 | + |
463 | + @exempt |
464 | + @classmethod |
465 | + def local_class_method(cls): |
466 | + pass |
467 | + |
468 | + @exempt |
469 | + @classmethod |
470 | + def a_class_method(cls): |
471 | + pass |
472 | + |
473 | + Stub.local_class_method() |
474 | + Stub.a_class_method() |
475 | |
476 | @istest |
477 | def test_exempt_inherited_method(self): |
478 | """any methods marked as exempt does not raise an error, even if they are inherited by the stub""" |
479 | - def declare_class(): |
480 | - @stubclass(self.stubbed) |
481 | - class Stub(object): |
482 | - @exempt |
483 | - def local_method(self): pass |
484 | - |
485 | - @exempt |
486 | - def method(): pass |
487 | - |
488 | - @exempt |
489 | - @classmethod |
490 | - def local_class_method(cls): pass |
491 | - |
492 | - @exempt |
493 | - @classmethod |
494 | - def a_class_method(cls): pass |
495 | - |
496 | - |
497 | - @stubclass(self.stubbed) |
498 | - class InheritingStub(Stub): |
499 | - pass |
500 | - |
501 | - return InheritingStub |
502 | - |
503 | #normal case |
504 | - _class = declare_class() |
505 | - _class.local_class_method() |
506 | - _class.a_class_method() |
507 | + @stubclass(self.stubbed) |
508 | + class Stub(object): |
509 | + @exempt |
510 | + def local_method(self): |
511 | + pass |
512 | + |
513 | + @exempt |
514 | + def method(self): |
515 | + pass |
516 | + |
517 | + @exempt |
518 | + @classmethod |
519 | + def local_class_method(cls): |
520 | + pass |
521 | + |
522 | + @exempt |
523 | + @classmethod |
524 | + def a_class_method(cls): |
525 | + pass |
526 | + |
527 | + |
528 | + @stubclass(self.stubbed) |
529 | + class InheritingStub(Stub): |
530 | + pass |
531 | + |
532 | + InheritingStub.local_class_method() |
533 | + InheritingStub.a_class_method() |
534 | |
535 | |
536 | |
537 | === modified file 'reahl-tofu/reahl/tofu/fixture.py' |
538 | --- reahl-tofu/reahl/tofu/fixture.py 2014-07-06 10:25:15 +0000 |
539 | +++ reahl-tofu/reahl/tofu/fixture.py 2014-08-16 12:12:26 +0000 |
540 | @@ -19,7 +19,7 @@ |
541 | from __future__ import print_function |
542 | import six |
543 | import sys |
544 | -import new |
545 | +import types |
546 | |
547 | #--------------------------------------------------[ MarkingDecorator ] |
548 | class MarkingDecorator(object): |
549 | @@ -35,10 +35,10 @@ |
550 | |
551 | def __get__(self, instance, owner): |
552 | self.bind_class(owner) |
553 | - if not instance: |
554 | + if instance is None: |
555 | return self |
556 | -# return functools.wraps(self.function)(new.instancemethod(self.function, instance, owner)) |
557 | - return new.instancemethod(self.function, instance, owner) |
558 | + else: |
559 | + return types.MethodType(self.function, instance) |
560 | |
561 | @property |
562 | def name(self): |
563 | |
564 | === modified file 'reahl-webdev/reahl/webdev/tools.py' |
565 | --- reahl-webdev/reahl/webdev/tools.py 2014-08-14 08:49:20 +0000 |
566 | +++ reahl-webdev/reahl/webdev/tools.py 2014-08-16 12:12:26 +0000 |
567 | @@ -20,6 +20,7 @@ |
568 | |
569 | import six |
570 | import io |
571 | +import time |
572 | import contextlib |
573 | from six.moves.urllib import parse as urllib_parse |
574 | import logging |
575 | @@ -79,6 +80,9 @@ |
576 | def lxml_html(self): |
577 | if self.raw_html: |
578 | return html.fromstring(self.raw_html) |
579 | + time.sleep(0.5) #xxxxx |
580 | + if self.raw_html: |
581 | + return html.fromstring(self.raw_html) |
582 | return None |
583 | |
584 |
(this was a test merge request)