Merge lp:~dobey/dirspec/update-4-0 into lp:dirspec/stable-4-0

Proposed by dobey on 2012-07-18
Status: Merged
Approved by: dobey on 2012-07-19
Approved revision: no longer in the source branch.
Merged at revision: 7
Proposed branch: lp:~dobey/dirspec/update-4-0
Merge into: lp:dirspec/stable-4-0
Diff against target: 828 lines (+333/-129)
8 files modified
dirspec/basedir.py (+17/-13)
dirspec/tests/__init__.py (+25/-4)
dirspec/tests/test_basedir.py (+19/-31)
dirspec/tests/test_utils.py (+151/-44)
dirspec/utils.py (+95/-13)
run-tests (+20/-11)
run-tests.bat (+2/-10)
setup.py (+4/-3)
To merge this branch: bzr merge lp:~dobey/dirspec/update-4-0
Reviewer Review Type Date Requested Status
Mike McCracken (community) Approve on 2012-07-18
Brian Curtin (community) 2012-07-18 Approve on 2012-07-18
Review via email: mp+115597@code.launchpad.net

Commit Message

[Rodney Dawes]

    Port to Python 3
    Stop using twisted trial as the test runner and as the base test case
    Use setuptools test runner support to run the tests
    Use testtools.testcase as the base test case
    Fix the license header in run-tests to use LGPL-3 as it should have been
    Fix some pep8 errors

[Mike McCracken]

    Add a generic API for discovering paths to program executables
    Fix typo in windows path definition. (LP: #1026369)

To post a comment you must log in.
review: Approve
Mike McCracken (mikemc) :
review: Approve
Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (8.0 KiB)

The attempt to merge lp:~dobey/dirspec/update-4-0 into lp:dirspec/stable-4-0 failed. Below is the output from the failed tests.

running build
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/dirspec
copying dirspec/basedir.py -> build/lib.linux-x86_64-2.7/dirspec
copying dirspec/__init__.py -> build/lib.linux-x86_64-2.7/dirspec
copying dirspec/utils.py -> build/lib.linux-x86_64-2.7/dirspec
running test
running egg_info
creating dirspec.egg-info
writing dirspec.egg-info/PKG-INFO
writing top-level names to dirspec.egg-info/top_level.txt
writing dependency_links to dirspec.egg-info/dependency_links.txt
writing manifest file 'dirspec.egg-info/SOURCES.txt'
reading manifest file 'dirspec.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'dirspec.egg-info/SOURCES.txt'
running build_ext
running build
running build_py
creating build/lib
creating build/lib/dirspec
copying dirspec/basedir.py -> build/lib/dirspec
copying dirspec/__init__.py -> build/lib/dirspec
copying dirspec/utils.py -> build/lib/dirspec
running test
running egg_info
writing dirspec.egg-info/PKG-INFO
writing top-level names to dirspec.egg-info/top_level.txt
writing dependency_links to dirspec.egg-info/dependency_links.txt
reading manifest file 'dirspec.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'dirspec.egg-info/SOURCES.txt'
running build_ext

/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en-US.UTF-8)
+ python ./setup.py build test clean
test_darwin_pkgd (dirspec.tests.test_utils.DarwinPkgdTestCase)
dirspec.tests.test_utils.DarwinPkgdTestCase.test_darwin_pkgd ... ok
test_darwin_pkgd_raises_nopath (dirspec.tests.test_utils.DarwinPkgdTestCase)
dirspec.tests.test_utils.DarwinPkgdTestCase.test_darwin_pkgd_raises_nopath ... ok
test_darwin_pkgd_raises_on_no_appnames (dirspec.tests.test_utils.DarwinPkgdTestCase)
dirspec.tests.test_utils.DarwinPkgdTestCase.test_darwin_pkgd_raises_on_no_appnames ... ok
test_linux_no_src_relative_path (dirspec.tests.test_utils.PosixTestCase)
dirspec.tests.test_utils.PosixTestCase.test_linux_no_src_relative_path ... ok
test_linux_src_relative_path_exists (dirspec.tests.test_utils.PosixTestCase)
dirspec.tests.test_utils.PosixTestCase.test_linux_src_relative_path_exists ... ok
test_get_config_dirs (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_config_dirs ... ok
test_get_data_dirs (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_data_dirs ... ok
test_get_env_path_no_var (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_env_path_no_var ... skipped u'UnicodeEncodeError: bug #907053'
test_get_env_path_var (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_env_path_var ... skipped u'UnicodeEncodeError: bug #907053'
test_get_special_folders (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_special_folders ... skipped u'Win32...

Read more...

Ubuntu One Auto Pilot (otto-pilot) wrote :
Download full text (8.0 KiB)

The attempt to merge lp:~dobey/dirspec/update-4-0 into lp:dirspec/stable-4-0 failed. Below is the output from the failed tests.

running build
running build_py
creating build
creating build/lib.linux-x86_64-2.7
creating build/lib.linux-x86_64-2.7/dirspec
copying dirspec/basedir.py -> build/lib.linux-x86_64-2.7/dirspec
copying dirspec/__init__.py -> build/lib.linux-x86_64-2.7/dirspec
copying dirspec/utils.py -> build/lib.linux-x86_64-2.7/dirspec
running test
running egg_info
creating dirspec.egg-info
writing dirspec.egg-info/PKG-INFO
writing top-level names to dirspec.egg-info/top_level.txt
writing dependency_links to dirspec.egg-info/dependency_links.txt
writing manifest file 'dirspec.egg-info/SOURCES.txt'
reading manifest file 'dirspec.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'dirspec.egg-info/SOURCES.txt'
running build_ext
running build
running build_py
creating build/lib
creating build/lib/dirspec
copying dirspec/basedir.py -> build/lib/dirspec
copying dirspec/__init__.py -> build/lib/dirspec
copying dirspec/utils.py -> build/lib/dirspec
running test
running egg_info
writing dirspec.egg-info/PKG-INFO
writing top-level names to dirspec.egg-info/top_level.txt
writing dependency_links to dirspec.egg-info/dependency_links.txt
reading manifest file 'dirspec.egg-info/SOURCES.txt'
reading manifest template 'MANIFEST.in'
writing manifest file 'dirspec.egg-info/SOURCES.txt'
running build_ext

/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en-US.UTF-8)
+ python ./setup.py build test clean
test_darwin_pkgd (dirspec.tests.test_utils.DarwinPkgdTestCase)
dirspec.tests.test_utils.DarwinPkgdTestCase.test_darwin_pkgd ... ok
test_darwin_pkgd_raises_nopath (dirspec.tests.test_utils.DarwinPkgdTestCase)
dirspec.tests.test_utils.DarwinPkgdTestCase.test_darwin_pkgd_raises_nopath ... ok
test_darwin_pkgd_raises_on_no_appnames (dirspec.tests.test_utils.DarwinPkgdTestCase)
dirspec.tests.test_utils.DarwinPkgdTestCase.test_darwin_pkgd_raises_on_no_appnames ... ok
test_linux_no_src_relative_path (dirspec.tests.test_utils.PosixTestCase)
dirspec.tests.test_utils.PosixTestCase.test_linux_no_src_relative_path ... ok
test_linux_src_relative_path_exists (dirspec.tests.test_utils.PosixTestCase)
dirspec.tests.test_utils.PosixTestCase.test_linux_src_relative_path_exists ... ok
test_get_config_dirs (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_config_dirs ... ok
test_get_data_dirs (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_data_dirs ... ok
test_get_env_path_no_var (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_env_path_no_var ... skipped u'UnicodeEncodeError: bug #907053'
test_get_env_path_var (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_env_path_var ... skipped u'UnicodeEncodeError: bug #907053'
test_get_special_folders (dirspec.tests.test_utils.TestBaseDirectoryWindows)
dirspec.tests.test_utils.TestBaseDirectoryWindows.test_get_special_folders ... skipped u'Win32...

Read more...

lp:~dobey/dirspec/update-4-0 updated on 2012-07-19
7. By dobey on 2012-07-19

[Rodney Dawes]

    Port to Python 3
    Stop using twisted trial as the test runner and as the base test case
    Use setuptools test runner support to run the tests
    Use testtools.testcase as the base test case
    Fix the license header in run-tests to use LGPL-3 as it should have been
    Fix some pep8 errors

[Mike McCracken]

    Add a generic API for discovering paths to program executables
    Fix typo in windows path definition. (LP: #1026369)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'dirspec/basedir.py'
2--- dirspec/basedir.py 2011-12-19 18:11:14 +0000
3+++ dirspec/basedir.py 2012-07-19 13:43:42 +0000
4@@ -1,6 +1,6 @@
5 # -*- coding: utf-8 -*-
6 #
7-# Copyright 2011 Canonical Ltd.
8+# Copyright 2011-2012 Canonical Ltd.
9 #
10 # This program is free software: you can redistribute it and/or modify
11 # it under the terms of the GNU Lesser General Public License version 3
12@@ -15,6 +15,8 @@
13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 """XDG Base Directory paths."""
15
16+from __future__ import unicode_literals, print_function
17+
18 import os
19
20 from dirspec.utils import (default_cache_home,
21@@ -53,16 +55,18 @@
22 def get_xdg_config_dirs():
23 """Get the paths for the XDG config directories."""
24 result = [get_xdg_config_home()]
25- result.extend([x for x in get_env_path(
26- 'XDG_CONFIG_DIRS', default_config_path).split(os.pathsep)])
27+ result.extend([x.encode('utf-8') for x in get_env_path(
28+ 'XDG_CONFIG_DIRS',
29+ default_config_path).decode('utf-8').split(os.pathsep)])
30 return result
31
32
33 def get_xdg_data_dirs():
34 """Get the paths for the XDG data directories."""
35 result = [get_xdg_data_home()]
36- result.extend([x for x in get_env_path(
37- 'XDG_DATA_DIRS', default_data_path).split(os.pathsep)])
38+ result.extend([x.encode('utf-8') for x in get_env_path(
39+ 'XDG_DATA_DIRS',
40+ default_data_path).decode('utf-8').split(os.pathsep)])
41 return result
42
43
44@@ -77,7 +81,7 @@
45 resource = os.path.join(*resource)
46 assert not resource.startswith('/')
47 for config_dir in get_xdg_config_dirs():
48- path = os.path.join(config_dir, resource)
49+ path = os.path.join(config_dir, resource.encode('utf-8'))
50 # access the file system always with unicode
51 # to properly behave in some operating systems
52 if os.path.exists(unicode_path(path)):
53@@ -94,7 +98,7 @@
54 resource = os.path.join(*resource)
55 assert not resource.startswith('/')
56 for data_dir in get_xdg_data_dirs():
57- path = os.path.join(data_dir, resource)
58+ path = os.path.join(data_dir, resource.encode('utf-8'))
59 # access the file system always with unicode
60 # to properly behave in some operating systems
61 if os.path.exists(unicode_path(path)):
62@@ -120,11 +124,11 @@
63 """
64 resource = os.path.join(*resource)
65 assert not resource.startswith('/')
66- path = os.path.join(get_xdg_config_home(), resource)
67+ path = os.path.join(get_xdg_config_home(), resource.encode('utf-8'))
68 # access the file system always with unicode
69 # to properly behave in some operating systems
70 if not os.path.isdir(unicode_path(path)):
71- os.makedirs(unicode_path(path), 0700)
72+ os.makedirs(unicode_path(path), 0o700)
73 return path
74
75
76@@ -137,11 +141,11 @@
77 """
78 resource = os.path.join(*resource)
79 assert not resource.startswith('/')
80- path = os.path.join(get_xdg_data_home(), resource)
81+ path = os.path.join(get_xdg_data_home(), resource.encode('utf-8'))
82 # access the file system always with unicode
83 # to properly behave in some operating systems
84 if not os.path.isdir(unicode_path(path)):
85- os.makedirs(unicode_path(path), 0700)
86+ os.makedirs(unicode_path(path), 0o700)
87 return path
88
89
90@@ -150,6 +154,6 @@
91 xdg_config_home = get_xdg_config_home()
92 xdg_data_home = get_xdg_data_home()
93
94-xdg_config_dirs = filter(lambda x: x, get_xdg_config_dirs())
95-xdg_data_dirs = filter(lambda x: x, get_xdg_data_dirs())
96+xdg_config_dirs = [x for x in get_xdg_config_dirs() if x]
97+xdg_data_dirs = [x for x in get_xdg_data_dirs() if x]
98 # pylint: disable=C0103
99
100=== modified file 'dirspec/tests/__init__.py'
101--- dirspec/tests/__init__.py 2011-12-17 00:46:26 +0000
102+++ dirspec/tests/__init__.py 2012-07-19 13:43:42 +0000
103@@ -1,6 +1,6 @@
104 # -*- coding: utf-8 -*-
105 #
106-# Copyright 2011 Canonical Ltd.
107+# Copyright 2011-2012 Canonical Ltd.
108 #
109 # This program is free software: you can redistribute it and/or modify
110 # it under the terms of the GNU Lesser General Public License version 3
111@@ -15,7 +15,12 @@
112 # along with this program. If not, see <http://www.gnu.org/licenses/>.
113 """"dirspec tests."""
114
115-from twisted.trial.unittest import TestCase
116+from __future__ import unicode_literals, print_function
117+
118+import os
119+
120+from operator import setitem
121+from testtools.testcase import TestCase
122
123
124 class BaseTestCase(TestCase):
125@@ -23,8 +28,24 @@
126
127 def assert_utf8_bytes(self, value):
128 """Check that 'value' is a bytes sequence encoded with utf-8."""
129- self.assertIsInstance(value, str)
130+ self.assertIsInstance(value, bytes)
131 try:
132 value.decode('utf-8')
133- except UnicodeDecodeError:
134+ except UnicodeError:
135 self.fail('%r should be a utf8 encoded string.' % value)
136+
137+ def tweak_env(self, envvar, value):
138+ """Tweak the environment variable %var to %value.
139+
140+ Restore the old value when finished.
141+ """
142+ old_val = os.environ.get(envvar, None)
143+
144+ if old_val is None:
145+ self.addCleanup(os.environ.pop, envvar, None)
146+ else:
147+ self.addCleanup(setitem, os.environ, envvar, old_val)
148+ if value is None:
149+ os.environ.pop(envvar, None)
150+ else:
151+ os.environ[envvar] = value
152
153=== modified file 'dirspec/tests/test_basedir.py'
154--- dirspec/tests/test_basedir.py 2011-12-20 17:53:34 +0000
155+++ dirspec/tests/test_basedir.py 2012-07-19 13:43:42 +0000
156@@ -1,6 +1,6 @@
157 # -*- coding: utf-8 -*-
158 #
159-# Copyright 2011 Canonical Ltd.
160+# Copyright 2011-2012 Canonical Ltd.
161 #
162 # This program is free software: you can redistribute it and/or modify
163 # it under the terms of the GNU Lesser General Public License version 3
164@@ -15,37 +15,22 @@
165 # along with this program. If not, see <http://www.gnu.org/licenses/>.
166 """Tests for the base directory implementation."""
167
168+from __future__ import unicode_literals, print_function
169+
170 import os
171
172 from dirspec import basedir
173 from dirspec.tests import BaseTestCase
174-from operator import setitem
175
176
177 class BasedirTestCase(BaseTestCase):
178 """Tests for XDG Base Directory paths implementation."""
179
180- def tweak_env(self, envvar, value):
181- """Tweak the environment variable %var to %value.
182-
183- Restore the old value when finished.
184- """
185- old_val = os.environ.get(envvar, None)
186-
187- if old_val is None:
188- self.addCleanup(os.environ.pop, envvar, None)
189- else:
190- self.addCleanup(setitem, os.environ, envvar, old_val)
191- if value is None:
192- os.environ.pop(envvar, None)
193- else:
194- os.environ[envvar] = value
195-
196 def test_cache_home(self):
197 """Test that XDG_CACHE_HOME is handled correctly."""
198 self.tweak_env('XDG_CACHE_HOME', os.path.abspath(os.path.join(
199 os.getcwd(), '_trial_temp', 'cache')))
200- self.assertEqual(os.environ['XDG_CACHE_HOME'],
201+ self.assertEqual(os.environ['XDG_CACHE_HOME'].encode('utf-8'),
202 basedir.get_xdg_cache_home())
203
204 def test_config_dirs(self):
205@@ -53,14 +38,15 @@
206 self.tweak_env('XDG_CONFIG_HOME', os.path.abspath(os.path.join(
207 os.getcwd(), '_trial_temp', 'config')))
208 self.tweak_env('XDG_CONFIG_DIRS', os.pathsep.join(['etc']))
209- self.assertEqual([os.environ['XDG_CONFIG_HOME'], 'etc'],
210+ self.assertEqual([os.environ['XDG_CONFIG_HOME'].encode('utf-8'),
211+ b'etc'],
212 basedir.get_xdg_config_dirs())
213
214 def test_config_home(self):
215 """Test that XDG_CONFIG_DIRS is handled correctly."""
216 self.tweak_env('XDG_CONFIG_HOME', os.path.abspath(os.path.join(
217 os.getcwd(), '_trial_temp', 'config')))
218- self.assertEqual(os.environ['XDG_CONFIG_HOME'],
219+ self.assertEqual(os.environ['XDG_CONFIG_HOME'].encode('utf-8'),
220 basedir.get_xdg_config_home())
221
222 def test_data_dirs(self):
223@@ -68,20 +54,21 @@
224 self.tweak_env('XDG_DATA_HOME', os.path.abspath(os.path.join(
225 os.getcwd(), '_trial_temp', 'xdg_data')))
226 self.tweak_env('XDG_DATA_DIRS', os.pathsep.join(['foo', 'bar']))
227- self.assertEqual([os.environ['XDG_DATA_HOME'], 'foo', 'bar'],
228+ self.assertEqual([os.environ['XDG_DATA_HOME'].encode('utf-8'),
229+ b'foo', b'bar'],
230 basedir.get_xdg_data_dirs())
231
232 def test_data_home(self):
233 """Test that XDG_DATA_HOME is handled correctly."""
234 self.tweak_env('XDG_DATA_HOME', os.path.abspath(os.path.join(
235 os.getcwd(), '_trial_temp', 'xdg_data')))
236- self.assertEqual(os.environ['XDG_DATA_HOME'],
237+ self.assertEqual(os.environ['XDG_DATA_HOME'].encode('utf-8'),
238 basedir.get_xdg_data_home())
239
240 def test_default_cache_home(self):
241 """Ensure default values work correctly."""
242 self.tweak_env('XDG_CACHE_HOME', None)
243- expected = '/blah'
244+ expected = b'/blah'
245 self.patch(basedir, 'default_cache_home', expected)
246 self.assertFalse(os.environ.get('XDG_CACHE_HOME', False))
247 self.assertEqual(basedir.get_xdg_cache_home(), expected)
248@@ -90,17 +77,17 @@
249 """Ensure default values work correctly."""
250 self.tweak_env('XDG_CONFIG_DIRS', None)
251 self.tweak_env('XDG_CONFIG_HOME', None)
252- expected = '/blah'
253+ expected = b'/blah'
254 self.patch(basedir, 'default_config_home', expected)
255 self.patch(basedir, 'default_config_path', '')
256 self.assertFalse(os.environ.get('XDG_CONFIG_DIRS', False))
257 self.assertFalse(os.environ.get('XDG_CONFIG_HOME', False))
258- self.assertEqual(basedir.get_xdg_config_dirs(), [expected, ''])
259+ self.assertEqual(basedir.get_xdg_config_dirs(), [expected, b''])
260
261 def test_default_config_home(self):
262 """Ensure default values work correctly."""
263 self.tweak_env('XDG_CONFIG_HOME', None)
264- expected = '/blah'
265+ expected = b'/blah'
266 self.patch(basedir, 'default_config_home', expected)
267 self.assertFalse(os.environ.get('XDG_CONFIG_HOME', False))
268 self.assertEqual(basedir.get_xdg_config_home(), expected)
269@@ -109,17 +96,17 @@
270 """Ensure default values work correctly."""
271 self.tweak_env('XDG_DATA_DIRS', None)
272 self.tweak_env('XDG_DATA_HOME', None)
273- expected = '/blah'
274+ expected = b'/blah'
275 self.patch(basedir, 'default_data_home', expected)
276 self.patch(basedir, 'default_data_path', '')
277 self.assertFalse(os.environ.get('XDG_DATA_DIRS', False))
278 self.assertFalse(os.environ.get('XDG_DATA_HOME', False))
279- self.assertEqual(basedir.get_xdg_data_dirs(), [expected, ''])
280+ self.assertEqual(basedir.get_xdg_data_dirs(), [expected, b''])
281
282 def test_default_data_home(self):
283 """Ensure default values work correctly."""
284 self.tweak_env('XDG_DATA_HOME', None)
285- expected = '/blah'
286+ expected = b'/blah'
287 self.patch(basedir, 'default_data_home', expected)
288 self.assertFalse(os.environ.get('XDG_DATA_HOME', False))
289 self.assertEqual(basedir.get_xdg_data_home(), expected)
290@@ -160,4 +147,5 @@
291 self.tweak_env('XDG_CONFIG_HOME', 'config_home')
292 self.patch(os, "makedirs", lambda *args: None)
293 result = basedir.save_config_path("x")
294- self.assertEqual(result.split(os.sep)[-2:], ['config_home', 'x'])
295+ self.assertEqual(result.decode('utf-8').split(os.sep)[-2:],
296+ ['config_home', 'x'])
297
298=== modified file 'dirspec/tests/test_utils.py'
299--- dirspec/tests/test_utils.py 2011-12-20 20:14:09 +0000
300+++ dirspec/tests/test_utils.py 2012-07-19 13:43:42 +0000
301@@ -1,6 +1,6 @@
302 # -*- coding: utf-8 -*-
303 #
304-# Copyright 2011 Canonical Ltd.
305+# Copyright 2011-2012 Canonical Ltd.
306 #
307 # This program is free software: you can redistribute it and/or modify
308 # it under the terms of the GNU Lesser General Public License version 3
309@@ -14,12 +14,17 @@
310 # You should have received a copy of the GNU Lesser General Public License
311 # along with this program. If not, see <http://www.gnu.org/licenses/>.
312 """Tests for utilities for the base directory implementation."""
313+
314+from __future__ import unicode_literals, print_function
315+
316 import os
317 import sys
318
319-from dirspec import basedir
320-from dirspec.utils import get_env_path, get_special_folders, user_home
321+from dirspec import basedir, utils as dirutils
322+from dirspec.utils import (get_env_path, get_special_folders,
323+ user_home, get_program_path)
324 from dirspec.tests import BaseTestCase
325+from testtools.testcase import skip
326
327
328 class UtilsTestCase(BaseTestCase):
329@@ -46,9 +51,9 @@
330 def __init__(self):
331 """Set the proper mapping between CSIDL_ consts."""
332 self.values = {
333- 0: u'c:\\path\\to\\users\\home',
334- 1: u'c:\\path\\to\\users\\home\\appData\\local',
335- 2: u'c:\\programData',
336+ 0: 'c:\\path\\to\\users\\home',
337+ 1: 'c:\\path\\to\\users\\home\\appData\\local',
338+ 2: 'c:\\programData',
339 }
340
341 # pylint: disable=C0103
342@@ -63,6 +68,9 @@
343
344 def test_get_special_folders(self):
345 """Make sure we can import the platform module."""
346+ if sys.platform != 'win32':
347+ self.skipTest('Win32 is required for this test.')
348+
349 import win32com.shell
350 shell_module = FakeShellModule()
351 self.patch(win32com.shell, "shell", shell_module)
352@@ -73,51 +81,37 @@
353 self.assertTrue('AppData' in special_folders)
354 self.assertTrue('Common AppData' in special_folders)
355
356- self.assertTrue(special_folders['Personal'] == \
357+ self.assertEqual(
358+ special_folders['Personal'],
359 shell_module.values[FakeShellConModule.CSIDL_PROFILE])
360- self.assertTrue(special_folders['Local AppData'] == \
361+ self.assertEqual(
362+ special_folders['Local AppData'],
363 shell_module.values[FakeShellConModule.CSIDL_LOCAL_APPDATA])
364 self.assertTrue(special_folders['Local AppData'].startswith(
365- special_folders['AppData']))
366- self.assertTrue(special_folders['Common AppData'] == \
367+ special_folders['AppData']))
368+ self.assertEqual(
369+ special_folders['Common AppData'],
370 shell_module.values[FakeShellConModule.CSIDL_COMMON_APPDATA])
371
372 for val in special_folders.itervalues():
373 self.assertIsInstance(val, str)
374- val.decode('utf8')
375- # Should not raise exceptions
376-
377- if sys.platform != 'win32':
378- test_get_special_folders.skip = 'Only works on Win32'
379+ val.encode('utf-8')
380
381 def test_get_data_dirs(self):
382 """Check thet get_data_dirs uses pathsep correctly."""
383- bad_sep = filter(lambda x: x not in os.pathsep, ":;")
384+ bad_sep = str(filter(lambda x: x not in os.pathsep, ":;"))
385 dir_list = ["A", "B", bad_sep, "C"]
386- self.patch(os, "environ",
387- dict(XDG_DATA_DIRS=os.pathsep.join(
388- dir_list)))
389+ self.tweak_env('XDG_DATA_DIRS', os.pathsep.join(dir_list))
390 dirs = basedir.get_xdg_data_dirs()[1:]
391- self.assertEqual(dirs, dir_list)
392+ self.assertEqual(dirs, [x.encode('utf-8') for x in dir_list])
393
394 def test_get_config_dirs(self):
395 """Check thet get_data_dirs uses pathsep correctly."""
396- bad_sep = filter(lambda x: x not in os.pathsep, ":;")
397+ bad_sep = str(filter(lambda x: x not in os.pathsep, ":;"))
398 dir_list = ["A", "B", bad_sep, "C"]
399- self.patch(os, "environ",
400- dict(XDG_CONFIG_DIRS=os.pathsep.join(
401- dir_list)))
402+ self.tweak_env('XDG_CONFIG_DIRS', os.pathsep.join(dir_list))
403 dirs = basedir.get_xdg_config_dirs()[1:]
404- self.assertEqual(dirs, dir_list)
405-
406- def set_fake_environ(self, key, value):
407- """Set (and restore) a fake environ variable."""
408- if key in os.environ:
409- prev = os.environ[key]
410- self.addCleanup(os.environ.__setitem__, key, prev)
411- else:
412- self.addCleanup(os.environ.__delitem__, key)
413- os.environ[key] = value
414+ self.assertEqual(dirs, [x.encode('utf-8') for x in dir_list])
415
416 def unset_fake_environ(self, key):
417 """Unset (and restore) a fake environ variable."""
418@@ -126,24 +120,137 @@
419 self.addCleanup(os.environ.__setitem__, key, current_value)
420 del(os.environ[key])
421
422+ @skip('UnicodeEncodeError: bug #907053')
423 def test_get_env_path_var(self):
424 """Test that get_env_path transforms an env var."""
425- fake_path = u"C:\\Users\\Ñandú"
426- fake_env_var = "FAKE_ENV_VAR"
427+ fake_path = 'C:\\Users\\Ñandú'
428+ fake_env_var = 'FAKE_ENV_VAR'
429
430 mbcs_path = fake_path.encode(sys.getfilesystemencoding())
431- utf8_path = fake_path.encode("utf-8")
432-
433- self.set_fake_environ(fake_env_var, mbcs_path)
434- self.assertEqual(get_env_path(fake_env_var, "unexpected"), utf8_path)
435-
436+
437+ self.tweak_env(fake_env_var, str(mbcs_path))
438+ self.assertEqual(get_env_path(fake_env_var, "unexpected"), fake_path)
439+
440+ @skip('UnicodeEncodeError: bug #907053')
441 def test_get_env_path_no_var(self):
442 """Test that get_env_path returns the default when env var not set."""
443- fake_path = u"C:\\Users\\Ñandú"
444+ fake_path = "C:\\Users\\Ñandú"
445 fake_env_var = "fake_env_var"
446 default = fake_path.encode(sys.getfilesystemencoding())
447
448 self.unset_fake_environ(fake_env_var)
449 self.assertEqual(get_env_path(fake_env_var, default), default)
450- test_get_env_path_var.skip = 'UnicodeEncodeError: bug #907053'
451- test_get_env_path_no_var.skip = test_get_env_path_var.skip
452+
453+
454+class ProgramPathBaseTestCase(BaseTestCase):
455+ """Base class for testing the executable finder."""
456+
457+ def setUp(self):
458+ """Set up fake modules."""
459+ super(ProgramPathBaseTestCase, self).setUp()
460+ self.patch(os.path, "exists", lambda x: True)
461+
462+
463+class UnfrozenSrcTestCase(ProgramPathBaseTestCase):
464+ """Test non-linux path discovery."""
465+
466+ def setUp(self):
467+ super(UnfrozenSrcTestCase, self).setUp()
468+ self.patch(sys, "platform", "darwin")
469+
470+ def test_unfrozen_dev_toplevel(self):
471+ """Not frozen, return path to bin dir."""
472+ path = get_program_path("foo", fallback_dirs=['/path/to/bin'])
473+ self.assertEquals(path, os.path.join("/path/to/bin", "foo"))
474+
475+ def test_unfrozen_dev_toplevel_raises_nopath(self):
476+ """Not frozen, raise OSError when the path doesn't exist."""
477+ self.patch(os.path, "exists", lambda x: False)
478+ self.assertRaises(OSError, get_program_path, "foo")
479+
480+
481+class DarwinPkgdTestCase(ProgramPathBaseTestCase):
482+ """Test cmdline for running packaged on darwin."""
483+
484+ def setUp(self):
485+ """SetUp to mimic frozen darwin."""
486+ super(DarwinPkgdTestCase, self).setUp()
487+ self.patch(sys, "platform", "darwin")
488+ sys.frozen = True
489+
490+ self.darwin_app_names = {"foo": "Foo.app"}
491+
492+ def tearDown(self):
493+ """tearDown, Remove frozen attr"""
494+ del sys.frozen
495+ super(DarwinPkgdTestCase, self).tearDown()
496+
497+ def test_darwin_pkgd(self):
498+ """Return sub-app path on darwin when frozen."""
499+ path = get_program_path("foo", app_names=self.darwin_app_names)
500+ expectedpath = "%s%s" % (
501+ dirutils.__file__,
502+ os.path.sep + os.path.join('Contents', 'Resources', 'Foo.app',
503+ 'Contents', 'MacOS', 'foo'))
504+ self.assertEquals(path, expectedpath)
505+
506+ def test_darwin_pkgd_raises_on_no_appnames(self):
507+ """Raises TypeError when no app_names dict is in the kwargs."""
508+ self.assertRaises(TypeError, get_program_path, "foo")
509+
510+ def test_darwin_pkgd_raises_nopath(self):
511+ """Frozen, raise OSError when the path doesn't exist."""
512+ self.patch(os.path, "exists", lambda x: False)
513+ self.assertRaises(OSError, get_program_path, "foo",
514+ app_names=self.darwin_app_names)
515+
516+
517+class Win32PkgdTestCase(ProgramPathBaseTestCase):
518+ """Test cmdline for running packaged on windows."""
519+
520+ def setUp(self):
521+ """SetUp to mimic frozen windows."""
522+ super(Win32PkgdTestCase, self).setUp()
523+ self.patch(sys, "platform", "win32")
524+ sys.frozen = True
525+
526+ def tearDown(self):
527+ """tearDown, Remove frozen attr"""
528+ del sys.frozen
529+ super(Win32PkgdTestCase, self).tearDown()
530+
531+ def test_windows_pkgd(self):
532+ """Return sub-app path on windows when frozen."""
533+
534+ self.patch(sys, "executable", os.path.join("C:\\path", "to",
535+ "current.exe"))
536+ # patch abspath to let us run this tests on non-windows:
537+ self.patch(os.path, "abspath", lambda x: x)
538+ path = get_program_path("foo", None)
539+ expectedpath = os.path.join("C:\\path", "to", "foo.exe")
540+ self.assertEquals(path, expectedpath)
541+
542+ def test_windows_pkgd_raises_nopath(self):
543+ """Frozen, raise OSError when the path doesn't exist."""
544+ self.patch(os.path, "exists", lambda x: False)
545+ self.assertRaises(OSError, get_program_path, "foo")
546+
547+
548+class PosixTestCase(ProgramPathBaseTestCase):
549+ """Test cmdline for running on linux."""
550+
551+ def setUp(self):
552+ """SetUp to mimic linux2."""
553+ super(PosixTestCase, self).setUp()
554+ self.patch(sys, "platform", "linux2")
555+
556+ def test_linux_src_relative_path_exists(self):
557+ """linux, return source relative path if it exists."""
558+ path = get_program_path("foo", fallback_dirs=['/path/to/bin'])
559+ expectedpath = os.path.join("/path/to/bin", "foo")
560+ self.assertEquals(path, expectedpath)
561+
562+ def test_linux_no_src_relative_path(self):
563+ """raise if no src rel path."""
564+ self.patch(os.path, "exists", lambda x: False)
565+ self.assertRaises(OSError, get_program_path, "foo")
566
567=== modified file 'dirspec/utils.py'
568--- dirspec/utils.py 2011-12-17 00:46:26 +0000
569+++ dirspec/utils.py 2012-07-19 13:43:42 +0000
570@@ -1,6 +1,6 @@
571 # -*- coding: utf-8 -*-
572 #
573-# Copyright 2011 Canonical Ltd.
574+# Copyright 2011-2012 Canonical Ltd.
575 #
576 # This program is free software: you can redistribute it and/or modify
577 # it under the terms of the GNU Lesser General Public License version 3
578@@ -15,6 +15,9 @@
579 # along with this program. If not, see <http://www.gnu.org/licenses/>.
580 """Utilities for multiplatform support of XDG directory handling."""
581
582+from __future__ import unicode_literals, print_function
583+
584+import errno
585 import os
586 import sys
587
588@@ -25,24 +28,100 @@
589 'default_data_home',
590 'default_data_path',
591 'get_env_path',
592+ 'get_program_path',
593 'unicode_path',
594 ]
595
596
597+def _get_exe_path_frozen_win32(exe_name):
598+ """Get path to the helper .exe on packaged windows."""
599+ # all the .exes are in the same place on windows:
600+ cur_exec_path = os.path.abspath(sys.executable)
601+ exe_dir = os.path.dirname(cur_exec_path)
602+ return os.path.join(exe_dir, exe_name + ".exe")
603+
604+
605+def _get_exe_path_frozen_darwin(exe_name, app_names):
606+ """Get path to the sub-app executable on packaged darwin."""
607+
608+ sub_app_name = app_names[exe_name]
609+ main_app_dir = "".join(__file__.partition(".app")[:-1])
610+ main_app_resources_dir = os.path.join(main_app_dir,
611+ "Contents",
612+ "Resources")
613+ exe_bin = os.path.join(main_app_resources_dir,
614+ sub_app_name,
615+ "Contents", "MacOS",
616+ exe_name)
617+ return exe_bin
618+
619+
620+def get_program_path(program_name, *args, **kwargs):
621+ """Given a program name, returns the path to run that program.
622+
623+ Raises OSError if the program is not found.
624+
625+ :param program_name: The name of the program to find. For darwin and win32
626+ platforms, the behavior is changed slightly, when sys.frozen is set,
627+ to look in the packaged program locations for the program.
628+ :param search_dirs: A list of directories to look for the program in. This
629+ is only available as a keyword argument.
630+ :param app_names: A dict of program names mapped to sub-app names. Used
631+ for discovering paths in embedded .app bundles on the darwin platform.
632+ This is only available as a keyword argument.
633+ :return: The path to the discovered program.
634+ """
635+ search_dirs = kwargs.get('fallback_dirs', None)
636+ app_names = kwargs.get('app_names', None)
637+
638+ if getattr(sys, "frozen", None) is not None:
639+ if sys.platform == 'win32':
640+ program_path = _get_exe_path_frozen_win32(program_name)
641+ elif sys.platform == 'darwin':
642+ program_path = _get_exe_path_frozen_darwin(program_name,
643+ app_names)
644+ else:
645+ raise Exception("Unsupported platform for frozen execution: %r" %
646+ sys.platform)
647+ else:
648+ if search_dirs is not None:
649+ for dirname in search_dirs:
650+ program_path = os.path.join(dirname, program_name)
651+ if os.path.exists(program_path):
652+ return program_path
653+ else:
654+ # Check in normal system $PATH, if no fallback dirs specified
655+ from distutils.spawn import find_executable
656+ program_path = find_executable(program_name)
657+
658+ if program_path is None or not os.path.exists(program_path):
659+ raise OSError(errno.ENOENT,
660+ "Could not find executable %r" % program_name)
661+
662+ return program_path
663+
664+
665 def get_env_path(key, default):
666 """Get a UTF-8 encoded path from an environment variable."""
667 if key in os.environ:
668 # on windows, environment variables are mbcs bytes
669 # so we must turn them into utf-8 Syncdaemon paths
670- path = os.environ.get(key)
671- return path.decode(sys.getfilesystemencoding()).encode("utf-8")
672+ try:
673+ path = os.environb.get(key.encode('utf-8'))
674+ except AttributeError:
675+ path = os.environ[key]
676+ return path.decode(sys.getfilesystemencoding()).encode('utf-8')
677 else:
678+ if not isinstance(default, bytes):
679+ return default.encode('utf-8')
680 return default
681
682
683 def unicode_path(utf8path):
684 """Turn an utf8 path into a unicode path."""
685- return utf8path.decode("utf-8")
686+ if isinstance(utf8path, bytes):
687+ return utf8path.decode("utf-8")
688+ return utf8path
689
690
691 def get_special_folders():
692@@ -83,13 +162,16 @@
693 user_home = special_folders['Personal']
694 default_config_path = special_folders['Common AppData']
695 default_config_home = special_folders['Local AppData']
696- default_data_path = os.path.join(default_config_path, 'xdg')
697- default_data_home = os.path.join(default_config_home, 'xdg')
698- default_cache_home = os.path.join(default_data_home, 'cache')
699+ default_data_path = os.path.join(default_config_path, b'xdg')
700+ default_data_home = os.path.join(default_config_home, b'xdg')
701+ default_cache_home = os.path.join(default_data_home, b'cache')
702 else:
703- user_home = os.path.expanduser('~')
704- default_cache_home = os.path.join(user_home, '.cache')
705- default_config_path = '/etc/xdg'
706- default_config_home = os.path.join(user_home, '.config')
707- default_data_path = '/usr/local/share:/usr/share'
708- default_data_home = os.path.join(user_home, '.local', 'share')
709+ user_home = os.path.expanduser(b'~')
710+ default_cache_home = os.path.join(user_home,
711+ b'.cache')
712+ default_config_path = b'/etc/xdg'
713+ default_config_home = os.path.join(user_home,
714+ b'.config')
715+ default_data_path = b'/usr/local/share:/usr/share'
716+ default_data_home = os.path.join(user_home,
717+ b'.local', b'share')
718
719=== modified file 'run-tests'
720--- run-tests 2011-12-17 00:46:26 +0000
721+++ run-tests 2012-07-19 13:43:42 +0000
722@@ -1,23 +1,32 @@
723 #!/bin/bash
724 #
725-# Copyright 2010-2011 Canonical Ltd.
726+# Copyright 2010-2012 Canonical Ltd.
727 #
728-# This program is free software: you can redistribute it and/or modify it
729-# under the terms of the GNU Lesser General Public License version 3,
730+# This program is free software: you can redistribute it and/or modify
731+# it under the terms of the GNU Lesser General Public License version 3
732 # as published by the Free Software Foundation.
733 #
734-# This program is distributed in the hope that it will be useful, but
735-# WITHOUT ANY WARRANTY; without even the implied warranties of
736-# MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
737-# PURPOSE. See the GNU Affero General Public License for more details.
738+# This program is distributed in the hope that it will be useful,
739+# but WITHOUT ANY WARRANTY; without even the implied warranty of
740+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
741+# GNU Lesser General Public License for more details.
742 #
743-# You should have received a copy of the GNU Affero General Public License
744+# You should have received a copy of the GNU Lesser General Public License
745 # along with this program. If not, see <http://www.gnu.org/licenses/>.
746
747 set -e -x
748-trial dirspec
749+
750+# Run the tests
751+python ./setup.py build test clean
752+
753+# Only run the python3 tests if available
754+if [ -x "`which python3`" ]; then
755+ python3 ./setup.py build test clean
756+else
757+ echo "Python 3 not found. Not running Python 3 tests."
758+fi
759+
760+# Run the style checks
761 pyflakes dirspec setup.py
762 pep8 --repeat . setup.py
763-rm -rf _trial_temp
764-rm -f .coverage
765
766
767=== modified file 'run-tests.bat'
768--- run-tests.bat 2011-12-19 18:43:32 +0000
769+++ run-tests.bat 2012-07-19 13:43:42 +0000
770@@ -1,6 +1,4 @@
771-:: Author: Manuel de la Pena <manuel@canonical.com>
772-::
773-:: Copyright 2010-2011 Canonical Ltd.
774+:: Copyright 2010-2012 Canonical Ltd.
775 ::
776 :: This program is free software: you can redistribute it and/or modify it
777 :: under the terms of the GNU Lesser General Public License version 3,
778@@ -35,20 +33,14 @@
779 ECHO Please ensure you have python installed
780 GOTO :END
781
782-:: Using trial.py is different on Windows, so we need to set PYTHONPATH
783-SET PYTHONPATH=.
784-
785 :PYTHONPRESENT
786 ECHO Python found, executing the tests...
787 :: execute the tests with a number of ignored linux only modules
788-"%PYTHONEXECPATH%\python.exe" "%PYTHONEXECPATH%\Scripts\trial.py" dirspec
789+"%PYTHONEXECPATH%\python.exe" setup.py build test clean
790 "%PYTHONEXECPATH%\python.exe" "%PYTHONEXECPATH%\Scripts\pyflakes" dirspec
791 :: test for style if we can, if pep8 is not present, move to the end
792 IF EXIST "%PYTHONEXECPATH%Scripts\pep8.exe"
793 "%PYTHONEXECPATH%\Scripts\pep8.exe" --repeat dirspec
794 ELSE
795 ECHO Style checks were not done
796-:: Delete the temp folders
797-RMDIR /s /q _trial_temp
798-RMDIR /s /q .coverage
799 :END
800
801=== modified file 'setup.py'
802--- setup.py 2012-06-25 17:06:41 +0000
803+++ setup.py 2012-07-19 13:43:42 +0000
804@@ -1,7 +1,7 @@
805-#!/usr/bin/env python
806+#!/usr/bin/python
807 # -*- coding: utf-8 -*-
808 #
809-# Copyright 2011 Canonical Ltd.
810+# Copyright 2011-2012 Canonical Ltd.
811 #
812 # This program is free software: you can redistribute it and/or modify
813 # it under the terms of the GNU Lesser General Public License version 3
814@@ -15,7 +15,7 @@
815 # You should have received a copy of the GNU Lesser General Public License
816 # along with this program. If not, see <http://www.gnu.org/licenses/>.
817 """Setup and install dirspec."""
818-from distutils.core import setup
819+from setuptools import setup
820
821 setup(
822 name='dirspec',
823@@ -23,4 +23,5 @@
824 packages=['dirspec'],
825 description='XDG Base and User directories implementation',
826 url='https://launchpad.net/dirspec',
827+ test_suite='dirspec.tests',
828 )

Subscribers

People subscribed via source and target branches

to all changes: