Merge lp:~barry/autopilot/lp1488175 into lp:autopilot

Proposed by Barry Warsaw
Status: Needs review
Proposed branch: lp:~barry/autopilot/lp1488175
Merge into: lp:autopilot
Diff against target: 912 lines (+242/-119) (has conflicts)
23 files modified
autopilot/introspection/_xpathselect.py (+4/-7)
autopilot/process/_bamf.py (+4/-2)
autopilot/run.py (+8/-8)
autopilot/testcase.py (+2/-2)
autopilot/tests/functional/test_ap_apps.py (+2/-1)
autopilot/tests/functional/test_autopilot_functional.py (+4/-2)
autopilot/tests/functional/test_dbus_query.py (+8/-10)
autopilot/tests/functional/test_input_stack.py (+9/-1)
autopilot/tests/unit/test_application_launcher.py (+11/-10)
autopilot/tests/unit/test_input.py (+4/-1)
autopilot/tests/unit/test_introspection_dbus.py (+4/-1)
autopilot/tests/unit/test_introspection_xpathselect.py (+33/-19)
autopilot/tests/unit/test_pick_backend.py (+20/-17)
autopilot/tests/unit/test_platform.py (+2/-1)
autopilot/tests/unit/test_process.py (+2/-2)
autopilot/tests/unit/test_stagnate_state.py (+6/-3)
autopilot/tests/unit/test_test_loader.py (+4/-3)
autopilot/tests/unit/test_testcase.py (+5/-4)
autopilot/tests/unit/test_types.py (+17/-8)
autopilot/vis/dbus_search.py (+10/-6)
debian/changelog (+73/-5)
docs/otto.py (+1/-4)
setup.py (+9/-2)
Text conflict in autopilot/tests/functional/test_input_stack.py
Text conflict in setup.py
To merge this branch: bzr merge lp:~barry/autopilot/lp1488175
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Autopilot Hackers Pending
Review via email: mp+268967@code.launchpad.net

Description of the change

My take on fixing the flake8 failures.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:519
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https://code.launchpad.net/~barry/autopilot/lp1488175/+merge/268967/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/autopilot-ci/1133/
Executed test runs:
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-wily-amd64-ci/63/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-wily-armhf-ci/62/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-wily-i386-ci/63/console

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/autopilot-ci/1133/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Max Brustkern (nuclearbob) wrote :

I have a couple of questions, but other than the merge conflicts, most of it looks great.

Revision history for this message
Barry Warsaw (barry) wrote :
Download full text (3.2 KiB)

On Aug 27, 2015, at 08:22 PM, Max Brustkern wrote:

>> @@ -39,8 +40,7 @@
>> """Must return a backend when called with a single backend."""
>> class Backend(object):
>> pass
>> - _create_backend = lambda: Backend()
>> - backend = _pick_backend(dict(foo=_create_backend), '')
>> + backend = _pick_backend(dict(foo=Backend), '')
>
>I'm not quite a clever in python as everyone else here, so I just want to
>make sure that Backend is wanted here and not Backend() This seems to apply
>to most of the tests around this, so I imagine they'd be breaking if it were
>incorrect, I just like to be sure it's intentional.

It is!

lambdas are defined here:

https://docs.python.org/3/reference/expressions.html#lambda

The example given provides a great way to think about them.

    lambda args: expression

is equivalent to

    def <lambda>(args):
        return expression

where the function is anonymous, i.e. it performs no name binding in the
current namespace. When you assign the `lambda: Backend()` to
_create_backend, it's the assignment that does the name binding to the
function object, so its exactly equivalent to:

    def _create_backend():
        return Backend()

Note too that when _pick_backend() is called, the code is passing in a
dictionary that maps the `foo` key to the *function object* created by the
lambda; specifically, the calling of the lambda-created function object is
deferred. It's exactly equivalent to just setting `foo` to the Backend
function object without calling it.

So in this case, the lambda is really just creating an unnecessary extra level
of call.

That's not quite the case where some of the lambdas take an argument, but you
can see how the translation to explicit function definitions should generally
go.

One thing to keep in mind about my translations. To be accurate, the
lambda-to-def conversion should return the value of the last expression, but I
don't do this in all cases because the tests appear to only care that an
exception is raised. Thus, the return values are mostly ignored. But for
correctness, you could return the values out of the locally defined
functions.

BTW, this equivalence is the reason why lambda are generally frowned upon.
They're almost never needed, and the savings in lines of code are usually not
worth the cost in readability or comprehension. It was probably the fans of
functional programming that tipped the balance against just removing them from
Python 3. ;)

>> === modified file 'setup.py'
>> --- setup.py 2015-08-19 00:25:00 +0000
>> +++ setup.py 2015-08-24 19:50:50 +0000
>> @@ -20,9 +20,16 @@
>> from setuptools import find_packages, setup, Extension
>>
>> import sys
>> +
>> +from setuptools import find_packages, setup, Extension
>
>It surprises me that these are needed and haven't been included
>previously. Was there something causing static analysis to not pick this up
>before?

Oh, that's weird. I don't remember adding that. Maybe it's a merge snafu?

P.S. you can play with this to see the equivalence in action:

def runme(func):
    print(func())

def hey():
    return 'hey'

yo = lambda: hey()

def sup():
    return hey()

run...

Read more...

Revision history for this message
Max Brustkern (nuclearbob) wrote :

> On Aug 27, 2015, at 08:22 PM, Max Brustkern wrote:
>
> >> @@ -39,8 +40,7 @@
> >> """Must return a backend when called with a single backend."""
> >> class Backend(object):
> >> pass
> >> - _create_backend = lambda: Backend()
> >> - backend = _pick_backend(dict(foo=_create_backend), '')
> >> + backend = _pick_backend(dict(foo=Backend), '')
> >
> >I'm not quite a clever in python as everyone else here, so I just want to
> >make sure that Backend is wanted here and not Backend() This seems to apply
> >to most of the tests around this, so I imagine they'd be breaking if it were
> >incorrect, I just like to be sure it's intentional.
>
> It is!
>
> lambdas are defined here:
>
> https://docs.python.org/3/reference/expressions.html#lambda
>
> The example given provides a great way to think about them.
>
> lambda args: expression
>
> is equivalent to
>
> def <lambda>(args):
> return expression
>
> where the function is anonymous, i.e. it performs no name binding in the
> current namespace. When you assign the `lambda: Backend()` to
> _create_backend, it's the assignment that does the name binding to the
> function object, so its exactly equivalent to:
>
> def _create_backend():
> return Backend()
>
> Note too that when _pick_backend() is called, the code is passing in a
> dictionary that maps the `foo` key to the *function object* created by the
> lambda; specifically, the calling of the lambda-created function object is
> deferred. It's exactly equivalent to just setting `foo` to the Backend
> function object without calling it.

Yeah, that's what was confusing me. I saw:
_create_backend = lambda: Backend()
and assumed that would return Backend() (the return value of that, i.e. an instance of the class) and not Backend (the class itself) The rest of the lambda syntax made sense to me, I just tripped over some parentheses here, since we're setting foo=Backend and not foo=Backend() like I would have expected from the lambda. Exciting stuff!

Unmerged revisions

519. By Barry Warsaw

A few more flake8 fixes.

518. By Barry Warsaw

Mass fix for LP: #1488175

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'autopilot/introspection/_xpathselect.py'
2--- autopilot/introspection/_xpathselect.py 2014-05-23 13:26:00 +0000
3+++ autopilot/introspection/_xpathselect.py 2015-08-24 19:50:50 +0000
4@@ -102,10 +102,7 @@
5 raise TypeError(
6 "'operation' parameter must be bytes, not '%s'"
7 % type(operation).__name__)
8- if (
9- parent
10- and parent.needs_client_side_filtering()
11- ):
12+ if parent and parent.needs_client_side_filtering():
13 raise InvalidXPathQuery(
14 "Cannot create a new query from a parent that requires "
15 "client-side filter processing."
16@@ -137,9 +134,9 @@
17 k: v for k, v in filters.items() if k not in self._server_filters
18 }
19 if (
20- operation == Query.Operation.DESCENDANT
21- and query == Query.WILDCARD
22- and not self._server_filters
23+ operation == Query.Operation.DESCENDANT and
24+ query == Query.WILDCARD and
25+ not self._server_filters
26 ):
27 raise InvalidXPathQuery(
28 "Must provide at least one server-side filter when searching "
29
30=== modified file 'autopilot/process/_bamf.py'
31--- autopilot/process/_bamf.py 2014-07-23 03:37:24 +0000
32+++ autopilot/process/_bamf.py 2015-08-24 19:50:50 +0000
33@@ -167,8 +167,10 @@
34 try:
35 new_windows = []
36 [new_windows.extend(a.get_windows()) for a in apps]
37- filter_fn = lambda w: w.x_id not in [
38- c.x_id for c in existing_windows]
39+
40+ def filter_fn(w):
41+ return w.x_id not in [c.x_id for c in existing_windows]
42+
43 new_wins = list(filter(filter_fn, new_windows))
44 if new_wins:
45 assert len(new_wins) == 1
46
47=== modified file 'autopilot/run.py'
48--- autopilot/run.py 2015-08-19 00:25:00 +0000
49+++ autopilot/run.py 2015-08-24 19:50:50 +0000
50@@ -355,8 +355,8 @@
51
52 def _is_testing_autopilot_module(test_names):
53 return (
54- os.path.basename(sys.argv[0]) == 'autopilot'
55- and any(t.startswith('autopilot') for t in test_names)
56+ os.path.basename(sys.argv[0]) == 'autopilot' and
57+ any(t.startswith('autopilot') for t in test_names)
58 )
59
60
61@@ -712,23 +712,23 @@
62 )
63
64 if self.args.run_order:
65- test_list_fn = lambda: iterate_tests(test_suite)
66+ test_list = list(iterate_tests(test_suite))
67 else:
68- test_list_fn = lambda: sorted(iterate_tests(test_suite), key=id)
69+ test_list = list(sorted(iterate_tests(test_suite), key=id))
70
71 # only show test suites, not test cases. TODO: Check if this is still
72 # a requirement.
73 if self.args.suites:
74 suite_names = ["%s.%s" % (t.__module__, t.__class__.__name__)
75- for t in test_list_fn()]
76+ for t in test_list]
77 unique_suite_names = list(OrderedDict.fromkeys(suite_names).keys())
78 num_tests = len(unique_suite_names)
79 total_title = "suites"
80 print(" %s" % ("\n ".join(unique_suite_names)))
81 else:
82- for test in test_list_fn():
83- has_scenarios = (hasattr(test, "scenarios")
84- and type(test.scenarios) is list)
85+ for test in test_list:
86+ has_scenarios = (hasattr(test, "scenarios") and
87+ type(test.scenarios) is list)
88 if has_scenarios:
89 num_tests += len(test.scenarios)
90 print(" *%d %s" % (len(test.scenarios), test.id()))
91
92=== modified file 'autopilot/testcase.py'
93--- autopilot/testcase.py 2015-08-19 03:34:47 +0000
94+++ autopilot/testcase.py 2015-08-24 19:50:50 +0000
95@@ -547,6 +547,6 @@
96
97 def _considered_failing_test(failure_class_type):
98 return (
99- not issubclass(failure_class_type, SkipTest)
100- and not issubclass(failure_class_type, _ExpectedFailure)
101+ not issubclass(failure_class_type, SkipTest) and
102+ not issubclass(failure_class_type, _ExpectedFailure)
103 )
104
105=== modified file 'autopilot/tests/functional/test_ap_apps.py'
106--- autopilot/tests/functional/test_ap_apps.py 2015-01-26 01:59:18 +0000
107+++ autopilot/tests/functional/test_ap_apps.py 2015-08-24 19:50:50 +0000
108@@ -31,6 +31,7 @@
109 Raises,
110 raises,
111 )
112+from functools import partial
113 from textwrap import dedent
114
115 from fixtures import EnvironmentVariable
116@@ -348,7 +349,7 @@
117 time.sleep(1)
118 os.abort()
119 """))
120- launch_fn = lambda: self.launch_test_application(path, app_type='qt')
121+ launch_fn = partial(self.launch_test_application, path, app_type='qt')
122 self.assertThat(launch_fn, raises(ProcessSearchError))
123
124 @skipIf(model() != "Desktop", "Only suitable on Desktop (Qt4)")
125
126=== modified file 'autopilot/tests/functional/test_autopilot_functional.py'
127--- autopilot/tests/functional/test_autopilot_functional.py 2015-05-01 02:29:02 +0000
128+++ autopilot/tests/functional/test_autopilot_functional.py 2015-08-24 19:50:50 +0000
129@@ -528,8 +528,10 @@
130 with TempDir() as tmp_dir_fixture:
131 dir_pattern = os.path.join(tmp_dir_fixture.path, 'rMD-session*')
132 original_session_dirs = set(glob.glob(dir_pattern))
133- get_new_sessions = lambda: \
134- set(glob.glob(dir_pattern)) - original_session_dirs
135+
136+ def get_new_sessions():
137+ return set(glob.glob(dir_pattern)) - original_session_dirs
138+
139 mock_test_case = Mock()
140 mock_test_case.shortDescription.return_value = "Dummy_Description"
141 logger = RMDVideoLogFixture(tmp_dir_fixture.path, mock_test_case)
142
143=== modified file 'autopilot/tests/functional/test_dbus_query.py'
144--- autopilot/tests/functional/test_dbus_query.py 2015-06-09 15:35:08 +0000
145+++ autopilot/tests/functional/test_dbus_query.py 2015-08-24 19:50:50 +0000
146@@ -22,6 +22,7 @@
147 import os
148 import subprocess
149 import signal
150+from functools import partial
151 from timeit import default_timer
152 from tempfile import mktemp
153 from testtools import skipIf
154@@ -140,12 +141,11 @@
155
156 def test_select_single_no_name_no_parameter_raises_exception(self):
157 app = self.start_fully_featured_app()
158- fn = lambda: app.select_single()
159- self.assertThat(fn, raises(ValueError))
160+ self.assertThat(app.select_single, raises(ValueError))
161
162 def test_select_single_no_match_raises_exception(self):
163 app = self.start_fully_featured_app()
164- match_fn = lambda: app.select_single("QMadeupType")
165+ match_fn = partial(app.select_single, "QMadeupType")
166 self.assertThat(match_fn, raises(StateNotFoundError('QMadeupType')))
167
168 def test_exception_raised_when_operating_on_dead_app(self):
169@@ -174,7 +174,7 @@
170
171 def test_select_single_parameters_no_match_raises_exception(self):
172 app = self.start_fully_featured_app()
173- match_fn = lambda: app.select_single(title="Non-existant object")
174+ match_fn = partial(app.select_single, title="Non-existant object")
175 self.assertThat(
176 match_fn,
177 raises(StateNotFoundError('*', title="Non-existant object"))
178@@ -182,13 +182,12 @@
179
180 def test_select_single_returning_multiple_raises(self):
181 app = self.start_fully_featured_app()
182- fn = lambda: app.select_single('QMenu')
183+ fn = partial(app.select_single, 'QMenu')
184 self.assertThat(fn, raises(ValueError))
185
186 def test_select_many_no_name_no_parameter_raises_exception(self):
187 app = self.start_fully_featured_app()
188- fn = lambda: app.select_single()
189- self.assertThat(fn, raises(ValueError))
190+ self.assertThat(app.select_single, raises(ValueError))
191
192 def test_select_many_only_using_parameters(self):
193 app = self.start_fully_featured_app()
194@@ -211,7 +210,7 @@
195 def test_wait_select_single_fails_slowly(self):
196 app = self.start_fully_featured_app()
197 start_time = default_timer()
198- fn = lambda: app.wait_select_single('QMadeupType')
199+ fn = partial(app.wait_select_single, 'QMadeupType')
200 self.assertThat(fn, raises(StateNotFoundError('QMadeupType')))
201 end_time = default_timer()
202 self.assertThat(abs(end_time - start_time), GreaterThan(9))
203@@ -234,8 +233,7 @@
204 dbus_pid = int(results[1].split("=")[1])
205 dbus_address = results[0].split("=", 1)[1]
206
207- kill_dbus = lambda pid: os.killpg(pid, signal.SIGTERM)
208- self.addCleanup(kill_dbus, dbus_pid)
209+ self.addCleanup(os.killpg, dbus_pid, signal.SIGTERM)
210
211 return dbus_address
212
213
214=== modified file 'autopilot/tests/functional/test_input_stack.py'
215--- autopilot/tests/functional/test_input_stack.py 2015-08-19 00:25:00 +0000
216+++ autopilot/tests/functional/test_input_stack.py 2015-08-24 19:50:50 +0000
217@@ -190,11 +190,17 @@
218 from autopilot.input import _uinput
219 return _uinput.Keyboard._device._pressed_keys_ecodes
220 else:
221+<<<<<<< TREE
222 self.fail(
223 "Don't know how to get pressed keys list for {}".format(
224 self.backend
225 )
226 )
227+=======
228+ self.fail("Don't know how to get pressed keys list for backend " +
229+ self.backend
230+ )
231+>>>>>>> MERGE-SOURCE
232
233
234 @skipIf(platform.model() != "Desktop", "Only suitable on Desktop (WinMocker)")
235@@ -468,7 +474,9 @@
236
237 app = self.start_qml_script(test_qml)
238 pinch_widget = app.select_single("QQuickRectangle")
239- widget_bg_colour = lambda: pinch_widget.color
240+
241+ def widget_bg_colour():
242+ return pinch_widget.color
243
244 self.assertThat(widget_bg_colour, Eventually(Equals(start_green_bg)))
245
246
247=== modified file 'autopilot/tests/unit/test_application_launcher.py'
248--- autopilot/tests/unit/test_application_launcher.py 2014-07-22 02:30:19 +0000
249+++ autopilot/tests/unit/test_application_launcher.py 2015-08-24 19:50:50 +0000
250@@ -586,9 +586,9 @@
251 )
252
253 def test_check_error_raises_RuntimeError_on_timeout(self):
254- fn = lambda: UpstartApplicationLauncher._check_status_error(
255- UpstartApplicationLauncher.Timeout
256- )
257+ def fn():
258+ UpstartApplicationLauncher._check_status_error(
259+ UpstartApplicationLauncher.Timeout)
260 self.assertThat(
261 fn,
262 raises(
263@@ -599,9 +599,9 @@
264 )
265
266 def test_check_error_raises_RuntimeError_on_failure(self):
267- fn = lambda: UpstartApplicationLauncher._check_status_error(
268- UpstartApplicationLauncher.Failed
269- )
270+ def fn():
271+ UpstartApplicationLauncher._check_status_error(
272+ UpstartApplicationLauncher.Failed)
273 self.assertThat(
274 fn,
275 raises(
276@@ -612,10 +612,11 @@
277 )
278
279 def test_check_error_raises_RuntimeError_with_extra_message(self):
280- fn = lambda: UpstartApplicationLauncher._check_status_error(
281- UpstartApplicationLauncher.Failed,
282- "extra message"
283- )
284+ def fn():
285+ UpstartApplicationLauncher._check_status_error(
286+ UpstartApplicationLauncher.Failed,
287+ "extra message"
288+ )
289 self.assertThat(
290 fn,
291 raises(
292
293=== modified file 'autopilot/tests/unit/test_input.py'
294--- autopilot/tests/unit/test_input.py 2015-07-07 22:50:24 +0000
295+++ autopilot/tests/unit/test_input.py 2015-08-24 19:50:50 +0000
296@@ -57,7 +57,10 @@
297
298 def test_get_center_point_raises_ValueError_on_empty_object(self):
299 obj = make_fake_object()
300- fn = lambda: get_center_point(obj)
301+
302+ def fn():
303+ get_center_point(obj)
304+
305 expected_exception = ValueError(
306 "Object '%r' does not have any recognised position attributes" %
307 obj)
308
309=== modified file 'autopilot/tests/unit/test_introspection_dbus.py'
310--- autopilot/tests/unit/test_introspection_dbus.py 2015-05-20 20:13:30 +0000
311+++ autopilot/tests/unit/test_introspection_dbus.py 2015-08-24 19:50:50 +0000
312@@ -185,7 +185,10 @@
313
314 with patch.object(fake_object, 'get_children', return_value=[child]):
315 out = StringIO()
316- print_func = lambda: fake_object.print_tree(out)
317+
318+ def print_func():
319+ fake_object.print_tree(out)
320+
321 self.assertThat(print_func, Not(Raises(StateNotFoundError)))
322 self.assertEqual(out.getvalue(), dedent("""\
323 == /some/path ==
324
325=== modified file 'autopilot/tests/unit/test_introspection_xpathselect.py'
326--- autopilot/tests/unit/test_introspection_xpathselect.py 2014-05-23 13:30:10 +0000
327+++ autopilot/tests/unit/test_introspection_xpathselect.py 2015-08-24 19:50:50 +0000
328@@ -28,11 +28,12 @@
329 class XPathSelectQueryTests(TestCase):
330
331 def test_query_raises_TypeError_on_non_bytes_query(self):
332- fn = lambda: xpathselect.Query(
333- None,
334- xpathselect.Query.Operation.CHILD,
335- 'asd'
336- )
337+ def fn():
338+ xpathselect.Query(
339+ None,
340+ xpathselect.Query.Operation.CHILD,
341+ 'asd'
342+ )
343 self.assertThat(
344 fn,
345 raises(
346@@ -151,7 +152,10 @@
347 def test_deriving_from_client_side_filtered_query_raises_ValueError(self):
348 q = xpathselect.Query.root("Foo") \
349 .select_descendant("Baz", dict(name="\u2026"))
350- fn = lambda: q.select_child("Foo")
351+
352+ def fn():
353+ q.select_child("Foo")
354+
355 self.assertThat(
356 fn,
357 raises(InvalidXPathQuery(
358@@ -161,7 +165,8 @@
359 )
360
361 def test_init_raises_TypeError_on_invalid_operation_type(self):
362- fn = lambda: xpathselect.Query(None, '/', b'sdf')
363+ def fn():
364+ xpathselect.Query(None, '/', b'sdf')
365 self.assertThat(
366 fn,
367 raises(TypeError(
368@@ -171,14 +176,16 @@
369 )
370
371 def test_init_raises_ValueError_on_invalid_operation(self):
372- fn = lambda: xpathselect.Query(None, b'foo', b'sdf')
373+ def fn():
374+ xpathselect.Query(None, b'foo', b'sdf')
375 self.assertThat(
376 fn,
377 raises(InvalidXPathQuery("Invalid operation 'foo'."))
378 )
379
380 def test_init_raises_ValueError_on_invalid_descendant_search(self):
381- fn = lambda: xpathselect.Query(None, b'//', b'*')
382+ def fn():
383+ xpathselect.Query(None, b'//', b'*')
384 self.assertThat(
385 fn,
386 raises(InvalidXPathQuery(
387@@ -188,7 +195,8 @@
388 )
389
390 def test_new_from_path_and_id_raises_TypeError_on_unicode_path(self):
391- fn = lambda: xpathselect.Query.new_from_path_and_id('bad_path', 42)
392+ def fn():
393+ xpathselect.Query.new_from_path_and_id('bad_path', 42)
394 self.assertThat(
395 fn,
396 raises(TypeError(
397@@ -197,14 +205,16 @@
398 )
399
400 def test_new_from_path_and_id_raises_ValueError_on_invalid_path(self):
401- fn = lambda: xpathselect.Query.new_from_path_and_id(b'bad_path', 42)
402+ def fn():
403+ xpathselect.Query.new_from_path_and_id(b'bad_path', 42)
404 self.assertThat(
405 fn,
406 raises(InvalidXPathQuery("Invalid path 'bad_path'."))
407 )
408
409 def test_new_from_path_and_id_raises_ValueError_on_invalid_path2(self):
410- fn = lambda: xpathselect.Query.new_from_path_and_id(b'/', 42)
411+ def fn():
412+ xpathselect.Query.new_from_path_and_id(b'/', 42)
413 self.assertThat(
414 fn,
415 raises(InvalidXPathQuery("Invalid path '/'."))
416@@ -238,7 +248,8 @@
417 self.assertEqual(b'/root/child[id=42]/..', q2.server_query_bytes())
418
419 def test_init_raises_ValueError_when_passing_filters_and_parent(self):
420- fn = lambda: xpathselect.Query(None, b'/', b'..', dict(foo=123))
421+ def fn():
422+ xpathselect.Query(None, b'/', b'..', dict(foo=123))
423 self.assertThat(
424 fn,
425 raises(InvalidXPathQuery(
426@@ -247,7 +258,8 @@
427 )
428
429 def test_init_raises_ValueError_when_passing_bad_op_and_parent(self):
430- fn = lambda: xpathselect.Query(None, b'//', b'..')
431+ def fn():
432+ xpathselect.Query(None, b'//', b'..')
433 self.assertThat(
434 fn,
435 raises(InvalidXPathQuery(
436@@ -260,7 +272,8 @@
437 self.assertEqual(b'/', q.server_query_bytes())
438
439 def test_cannot_select_child_on_pseudo_tree_root(self):
440- fn = lambda: xpathselect.Query.pseudo_tree_root().select_child('foo')
441+ def fn():
442+ xpathselect.Query.pseudo_tree_root().select_child('foo')
443 self.assertThat(
444 fn,
445 raises(InvalidXPathQuery(
446@@ -311,10 +324,11 @@
447 class ParameterFilterStringTests(TestWithScenarios, TestCase):
448
449 def test_raises_ValueError_on_unknown_type(self):
450- fn = lambda: xpathselect._get_filter_string_for_key_value_pair(
451- 'k',
452- object()
453- )
454+ def fn():
455+ xpathselect._get_filter_string_for_key_value_pair(
456+ 'k',
457+ object()
458+ )
459 self.assertThat(
460 fn,
461 raises(
462
463=== modified file 'autopilot/tests/unit/test_pick_backend.py'
464--- autopilot/tests/unit/test_pick_backend.py 2014-02-10 03:14:40 +0000
465+++ autopilot/tests/unit/test_pick_backend.py 2015-08-24 19:50:50 +0000
466@@ -31,7 +31,8 @@
467
468 def test_raises_runtime_error_on_empty_backends(self):
469 """Must raise a RuntimeError when we pass no backends."""
470- fn = lambda: _pick_backend({}, '')
471+ def fn():
472+ _pick_backend({}, '')
473 self.assertThat(
474 fn, raises(RuntimeError("Unable to instantiate any backends\n")))
475
476@@ -39,8 +40,7 @@
477 """Must return a backend when called with a single backend."""
478 class Backend(object):
479 pass
480- _create_backend = lambda: Backend()
481- backend = _pick_backend(dict(foo=_create_backend), '')
482+ backend = _pick_backend(dict(foo=Backend), '')
483 self.assertThat(backend, IsInstance(Backend))
484
485 def test_first_backend(self):
486@@ -51,8 +51,8 @@
487 class Backend2(object):
488 pass
489 backend_dict = OrderedDict()
490- backend_dict['be1'] = lambda: Backend1()
491- backend_dict['be2'] = lambda: Backend2()
492+ backend_dict['be1'] = Backend1
493+ backend_dict['be2'] = Backend2
494
495 backend = _pick_backend(backend_dict, '')
496 self.assertThat(backend, IsInstance(Backend1))
497@@ -66,8 +66,8 @@
498 class Backend2(object):
499 pass
500 backend_dict = OrderedDict()
501- backend_dict['be1'] = lambda: Backend1()
502- backend_dict['be2'] = lambda: Backend2()
503+ backend_dict['be1'] = Backend1
504+ backend_dict['be2'] = Backend2
505
506 backend = _pick_backend(backend_dict, 'be2')
507 self.assertThat(backend, IsInstance(Backend2))
508@@ -82,18 +82,20 @@
509 def __init__(self):
510 raise ValueError("Foo")
511 backend_dict = OrderedDict()
512- backend_dict['be1'] = lambda: Backend1()
513- backend_dict['be2'] = lambda: Backend2()
514+ backend_dict['be1'] = Backend1
515+ backend_dict['be2'] = Backend2
516
517- fn = lambda: _pick_backend(backend_dict, 'be2')
518+ def fn():
519+ _pick_backend(backend_dict, 'be2')
520 self.assertThat(fn, raises(BackendException))
521
522 def test_raises_RuntimeError_on_invalid_preferred_backend(self):
523 """Must raise RuntimeError when we pass a backend that's not there"""
524 class Backend(object):
525 pass
526- _create_backend = lambda: Backend()
527- fn = lambda: _pick_backend(dict(foo=_create_backend), 'bar')
528+
529+ def fn():
530+ return _pick_backend(dict(foo=Backend), 'bar')
531
532 self.assertThat(
533 fn,
534@@ -109,8 +111,8 @@
535 def __init__(self):
536 raise ValueError("Foo")
537 backend_dict = OrderedDict()
538- backend_dict['be1'] = lambda: Backend1()
539- backend_dict['be2'] = lambda: Backend2()
540+ backend_dict['be1'] = Backend1
541+ backend_dict['be2'] = Backend2
542
543 raised = False
544 try:
545@@ -128,10 +130,11 @@
546 def __init__(self):
547 raise ValueError("Foo")
548 backend_dict = OrderedDict()
549- backend_dict['be1'] = lambda: BadBackend()
550- backend_dict['be2'] = lambda: BadBackend()
551+ backend_dict['be1'] = BadBackend
552+ backend_dict['be2'] = BadBackend
553
554- fn = lambda: _pick_backend(backend_dict, '')
555+ def fn():
556+ return _pick_backend(backend_dict, '')
557 expected_exception = RuntimeError(dedent("""\
558 Unable to instantiate any backends
559 be1: ValueError('Foo',)
560
561=== modified file 'autopilot/tests/unit/test_platform.py'
562--- autopilot/tests/unit/test_platform.py 2014-07-23 03:37:24 +0000
563+++ autopilot/tests/unit/test_platform.py 2015-08-24 19:50:50 +0000
564@@ -68,7 +68,8 @@
565 class PlatformGetProcessNameTests(TestCase):
566
567 def test_returns_callable_value(self):
568- test_callable = lambda: "foo"
569+ def test_callable():
570+ return "foo"
571 self.assertEqual("foo", platform._get_process_name(test_callable))
572
573 def test_returns_string(self):
574
575=== modified file 'autopilot/tests/unit/test_process.py'
576--- autopilot/tests/unit/test_process.py 2014-05-20 08:53:21 +0000
577+++ autopilot/tests/unit/test_process.py 2015-08-24 19:50:50 +0000
578@@ -44,8 +44,8 @@
579 process.launch_uris_as_manager.called_once_with(
580 [],
581 None,
582- GLib.SpawnFlags.SEARCH_PATH
583- | GLib.SpawnFlags.STDOUT_TO_DEV_NULL,
584+ GLib.SpawnFlags.SEARCH_PATH |
585+ GLib.SpawnFlags.STDOUT_TO_DEV_NULL,
586 None,
587 None,
588 None,
589
590=== modified file 'autopilot/tests/unit/test_stagnate_state.py'
591--- autopilot/tests/unit/test_stagnate_state.py 2013-09-04 03:44:07 +0000
592+++ autopilot/tests/unit/test_stagnate_state.py 2015-08-24 19:50:50 +0000
593@@ -41,7 +41,8 @@
594 x, y = (1, 1)
595 state_check.check_state(x, y)
596
597- fn = lambda: state_check.check_state(x, y)
598+ def fn():
599+ state_check.check_state(x, y)
600 self.assertThat(
601 fn,
602 raises(
603@@ -52,7 +53,8 @@
604 )
605
606 def test_raises_exception_when_thresold_is_zero(self):
607- fn = lambda: StagnantStateDetector(threshold=0)
608+ def fn():
609+ StagnantStateDetector(threshold=0)
610 self.assertThat(
611 fn,
612 raises(ValueError("Threshold must be a positive integer."))
613@@ -64,5 +66,6 @@
614 no_hash = UnHashable()
615 state_check = StagnantStateDetector(threshold=5)
616
617- fn = lambda: state_check.check_state(no_hash)
618+ def fn():
619+ state_check.check_state(no_hash)
620 self.assertThat(fn, raises(TypeError("unhashable type: 'UnHashable'")))
621
622=== modified file 'autopilot/tests/unit/test_test_loader.py'
623--- autopilot/tests/unit/test_test_loader.py 2014-05-20 08:53:21 +0000
624+++ autopilot/tests/unit/test_test_loader.py 2015-08-24 19:50:50 +0000
625@@ -57,9 +57,10 @@
626 self.test_module_name = self._unique_module_name()
627
628 def _unique_module_name(self):
629- generator = lambda: ''.join(
630- random.choice(string.ascii_letters) for letter in range(8)
631- )
632+ def generator():
633+ return ''.join(
634+ random.choice(string.ascii_letters) for letter in range(8)
635+ )
636 name = generator()
637 while name in self._previous_module_names:
638 name = generator()
639
640=== modified file 'autopilot/tests/unit/test_testcase.py'
641--- autopilot/tests/unit/test_testcase.py 2014-07-29 01:47:19 +0000
642+++ autopilot/tests/unit/test_testcase.py 2015-08-24 19:50:50 +0000
643@@ -39,10 +39,11 @@
644
645 def test_snapshot_raises_AssertionError_with_new_apps_opened(self):
646 with sleep.mocked():
647- fn = lambda: _compare_system_with_process_snapshot(
648- lambda: ['foo'],
649- []
650- )
651+ def fn():
652+ return _compare_system_with_process_snapshot(
653+ lambda: ['foo'],
654+ []
655+ )
656 self.assertThat(fn, raises(AssertionError(
657 "The following apps were started during the test and "
658 "not closed: ['foo']"
659
660=== modified file 'autopilot/tests/unit/test_types.py'
661--- autopilot/tests/unit/test_types.py 2014-10-30 02:06:55 +0000
662+++ autopilot/tests/unit/test_types.py 2015-08-24 19:50:50 +0000
663@@ -677,7 +677,8 @@
664 ]
665 )
666
667- fn = lambda: create_value_instance(data, None, None)
668+ def fn():
669+ return create_value_instance(data, None, None)
670
671 self.assertThat(fn, raises(
672 ValueError("Rectangle must be constructed with 4 arguments, not 1")
673@@ -706,7 +707,8 @@
674 ]
675 )
676
677- fn = lambda: create_value_instance(data, None, None)
678+ def fn():
679+ return create_value_instance(data, None, None)
680
681 self.assertThat(fn, raises(
682 ValueError("Color must be constructed with 4 arguments, not 1")
683@@ -735,7 +737,8 @@
684 ]
685 )
686
687- fn = lambda: create_value_instance(data, None, None)
688+ def fn():
689+ create_value_instance(data, None, None)
690
691 self.assertThat(fn, raises(
692 ValueError("Point must be constructed with 2 arguments, not 3")
693@@ -762,7 +765,8 @@
694 ]
695 )
696
697- fn = lambda: create_value_instance(data, None, None)
698+ def fn():
699+ return create_value_instance(data, None, None)
700
701 self.assertThat(fn, raises(
702 ValueError("Size must be constructed with 2 arguments, not 1")
703@@ -790,7 +794,8 @@
704 ]
705 )
706
707- fn = lambda: create_value_instance(data, None, None)
708+ def fn():
709+ return create_value_instance(data, None, None)
710
711 self.assertThat(fn, raises(
712 ValueError("DateTime must be constructed with 1 arguments, not 3")
713@@ -821,7 +826,8 @@
714 ]
715 )
716
717- fn = lambda: create_value_instance(data, None, None)
718+ def fn():
719+ return create_value_instance(data, None, None)
720
721 self.assertThat(fn, raises(
722 ValueError("Time must be constructed with 4 arguments, not 3")
723@@ -852,7 +858,9 @@
724 dbus.Int32(0),
725 ]
726 )
727- fn = lambda: create_value_instance(data, None, None)
728+
729+ def fn():
730+ return create_value_instance(data, None, None)
731
732 self.assertThat(fn, raises(
733 ValueError("Cannot create attribute, no data supplied")
734@@ -881,7 +889,8 @@
735 ]
736 )
737
738- fn = lambda: create_value_instance(data, None, None)
739+ def fn():
740+ return create_value_instance(data, None, None)
741
742 self.assertThat(fn, raises(
743 ValueError("Point3D must be constructed with 3 arguments, not 2")
744
745=== modified file 'autopilot/vis/dbus_search.py'
746--- autopilot/vis/dbus_search.py 2014-04-10 21:39:39 +0000
747+++ autopilot/vis/dbus_search.py 2015-08-24 19:50:50 +0000
748@@ -43,12 +43,16 @@
749 constructed from the provided bus, connection and object name.
750
751 """
752- handler = lambda xml: self._xml_processor(
753- conn_name,
754- obj_name,
755- xml
756- )
757- error_handler = lambda *args: _logger.error("Error occured: %r" % args)
758+ def handler(xml):
759+ return self._xml_processor(
760+ conn_name,
761+ obj_name,
762+ xml
763+ )
764+
765+ def error_handler(*args):
766+ return _logger.error("Error occured: %r" % args)
767+
768 obj = self._bus.get_object(conn_name, obj_name)
769
770 # avoid introspecting our own PID, as that locks up with libdbus
771
772=== modified file 'debian/changelog'
773--- debian/changelog 2015-05-08 04:45:01 +0000
774+++ debian/changelog 2015-08-24 19:50:50 +0000
775@@ -1,12 +1,80 @@
776-autopilot (1.5.0) UNRELEASED; urgency=medium
777-
778+autopilot (1.5.1+15.10.20150723-0ubuntu1) wily; urgency=medium
779+
780+ [ Christopher Lee ]
781+ * Bug fixes including updated dependencies.
782+
783+ [ Ken VanDine ]
784+ * Bug fixes including updated dependencies.
785+
786+ -- CI Train Bot <ci-train-bot@canonical.com> Thu, 23 Jul 2015 14:39:21 +0000
787+
788+autopilot (1.5.1+15.10.20150716-0ubuntu1) wily; urgency=medium
789+
790+ [ Christopher Lee ]
791+ * Add window manager support for autopilot sandbox run, fixes LP:1379508
792+ * Add fixture that forces a gsetting for unity8 so that OSK is shown even
793+ when a UInput keyboard is present.
794+ * Fix unit test failures on Wily
795+
796+ -- CI Train Bot <ci-train-bot@canonical.com> Thu, 16 Jul 2015 04:38:49 +0000
797+
798+autopilot (1.5.1+15.04.20150708-0ubuntu1) vivid; urgency=medium
799+
800+ [ Christopher Lee ]
801+ * Create correct touch device at creation to stop unity8 erroneously
802+ changing to windowed mode. (Fixes lp:1471598).
803+
804+ -- CI Train Bot <ci-train-bot@canonical.com> Wed, 08 Jul 2015 03:44:43 +0000
805+
806+autopilot (1.5.1+15.04.20150522-0ubuntu1) vivid; urgency=medium
807+
808+ [ CI Train Bot ]
809+ * New rebuild forced.
810+
811+ [ Christopher Lee, Federico Gimenez, Leo Arias, Richard Huddie, Vincent Ladeuil ]
812+ * Bug fixes for logging (debug level now -vv) and application of CPO
813+ bases for proxy objects. (LP: #1425721, #1376996, #1420949)
814+
815+ -- CI Train Bot <ci-train-bot@canonical.com> Fri, 22 May 2015 16:54:03 +0000
816+
817+autopilot (1.5.0+15.04.20150408-0ubuntu1) vivid; urgency=medium
818+
819+ [ Albert Astals Cid ]
820+ * Bug fixes related to improving automated runs.
821+
822+ [ Christopher Lee ]
823+ * Bug fixes related to improving automated runs.
824+
825+ -- CI Train Bot <ci-train-bot@canonical.com> Wed, 08 Apr 2015 15:07:28 +0000
826+
827+autopilot (1.5.0+15.04.20150323-0ubuntu1) vivid; urgency=medium
828+
829+ [ CI Train Bot ]
830+ * New rebuild forced.
831+
832+ [ Christopher Lee ]
833+ * Bugfix for Touch pointer pressed. Packaging req. due to python3-xlib
834+ bug.
835+
836+ [ Leo Arias ]
837+ * Bugfix for Touch pointer pressed. Packaging req. due to python3-xlib
838+ bug.
839+
840+ -- CI Train Bot <ci-train-bot@canonical.com> Mon, 23 Mar 2015 09:34:31 +0000
841+
842+autopilot (1.5.0+15.04.20150226.1-0ubuntu1) vivid; urgency=medium
843+
844+ [ Christopher Lee ]
845 * Fix for desktop file name change (lp:1411096)
846 Fix for config value containing '=' char (lp:1408317)
847 Fix for skipped tests not appearing in log (lp:1414632)
848 Add json docs build (for web publish) (lp:1409778)
849 Documentation improvements for API, Tutorial, FAQ, and Guidelines
850
851- -- Christopher Lee <chris.lee@canonical.com> Fri, 27 Feb 2015 10:16:42 +1300
852+ [ CI Train Bot ]
853+ * New rebuild forced.
854+
855+ -- CI Train Bot <ci-train-bot@canonical.com> Thu, 26 Feb 2015 22:47:35 +0000
856
857 autopilot (1.5.0+15.04.20141031-0ubuntu1) vivid; urgency=low
858
859@@ -131,7 +199,7 @@
860 * Remove python2 packages and dependencies, as they're now handled by the
861 autopilot-legacy source package. (lp: #1308661)
862 * Autopilot vis tool can now search the introspection tree. (lp: #1097392)
863- * Autopilot vis tool can now draw a transparent overlay over the selected
864+ * Autopilot vis tool can now draw a transparent overlay over the selected
865 widget.
866 * Autopilot vis tool now shows the root of the introspection tree (lp: #1298600)
867 * Autopilot vis tool can now be launched from the unity dash.
868@@ -265,7 +333,7 @@
869
870 autopilot (1.4+14.04.20140310.1-0ubuntu1) trusty; urgency=low
871
872- *
873+ *
874
875 -- Ubuntu daily release <ps-jenkins@lists.canonical.com> Mon, 10 Mar 2014 19:39:00 +0000
876
877
878=== modified file 'docs/otto.py'
879--- docs/otto.py 2013-07-25 05:47:36 +0000
880+++ docs/otto.py 2015-08-24 19:50:50 +0000
881@@ -59,9 +59,6 @@
882 image_container.children.append(nodes.image(uri='/images/otto-64.png'))
883 image_container['classes'] = ['otto-image-container']
884 outer_container = nodes.container()
885- outer_container.children.extend(
886- [image_container]
887- + ad
888- )
889+ outer_container.children.extend([image_container] + ad)
890 outer_container['classes'] = ['otto-says-container']
891 return [outer_container]
892
893=== modified file 'setup.py'
894--- setup.py 2015-08-19 00:25:00 +0000
895+++ setup.py 2015-08-24 19:50:50 +0000
896@@ -20,9 +20,16 @@
897 from setuptools import find_packages, setup, Extension
898
899 import sys
900+
901+from setuptools import find_packages, setup, Extension
902+
903+
904 assert sys.version_info >= (3,), 'Python 3 is required'
905-
906-
907+<<<<<<< TREE
908+
909+
910+=======
911+>>>>>>> MERGE-SOURCE
912 VERSION = '1.5.0'
913
914

Subscribers

People subscribed via source and target branches