Merge lp:~pieter-equinox/reahl/reahl-declarative into lp:~iv/reahl/reahl-declarative

Proposed by Pieter Nagel
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
Reviewer Review Type Date Requested Status
Iwan Vosloo Approve
Review via email: mp+230770@code.launchpad.net

Description of the change

Nop

To post a comment you must log in.
Revision history for this message
Iwan Vosloo (iv) wrote :

(this was a test merge request)

review: Disapprove
Revision history for this message
Iwan Vosloo (iv) :
review: Needs Resubmitting
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

Revision history for this message
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.

Revision history for this message
Iwan Vosloo (iv) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
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

Subscribers

People subscribed via source and target branches

to all changes: