| commit 18: | 8c1102a08b66 |
| parent 17: | f6fede60a1e8 |
| branch: | default |
changed API name (EggInfo -> Distribution) + better global APIs
9 months ago
Changed (Δ118 bytes):
raw changeset »
pkgutil.py (44 lines added, 47 lines removed)
test_pkgutil.py (24 lines added, 24 lines removed)
| … | … | @@ -141,9 +141,9 @@ def is_egg_info(path): |
141 |
141 |
|
142 |
142 |
|
143 |
143 |
# |
144 |
# |
|
144 |
# Distribution class (with DistributionMetadata in it) |
|
145 |
145 |
# |
146 |
class |
|
146 |
class Distribution(object): |
|
147 |
147 |
|
148 |
148 |
def __init__(self, path): |
149 |
149 |
self.info_path = path |
| … | … | @@ -155,10 +155,10 @@ class EggInfo(object): |
155 |
155 |
self._files = None |
156 |
156 |
|
157 |
157 |
def __str__(self): |
158 |
return " |
|
158 |
return "Distribution('%s')" % self.name |
|
159 |
159 |
|
160 |
160 |
def _load_record(self): |
161 |
"""Loads the RECORD file |
|
161 |
"""Loads the RECORD file.""" |
|
162 |
162 |
if self._files is None: |
163 |
163 |
self._files = self._read_record() |
164 |
164 |
|
| … | … | @@ -243,38 +243,38 @@ class EggInfo(object): |
243 |
243 |
return open(local_path, binary and 'rb' or 'r') |
244 |
244 |
|
245 |
245 |
# |
246 |
# |
|
246 |
# DistributionDirectory represents a directory that contains egg-info files |
|
247 |
247 |
# |
248 |
class |
|
248 |
class DistributionDirectory(object): |
|
249 |
249 |
|
250 |
250 |
def __init__(self, path): |
251 |
251 |
self.path = path |
252 |
self._ |
|
252 |
self._dists = [] |
|
253 |
253 |
# filling the list once (see if it's the best way) |
254 |
254 |
# to minimize I/O |
255 |
255 |
for element in os.listdir(self.path): |
256 |
256 |
fullpath = join(self.path, element) |
257 |
257 |
if is_egg_info(fullpath): |
258 |
self._ |
|
258 |
self._dists.append(Distribution(fullpath)) |
|
259 |
259 |
|
260 |
260 |
# |
261 |
261 |
# container APIs |
262 |
262 |
# |
263 |
263 |
def __iter__(self): |
264 |
return iter(self._ |
|
264 |
return iter(self._dists) |
|
265 |
265 |
|
266 |
266 |
# |
267 |
267 |
# public APIs |
268 |
268 |
# |
269 |
269 |
def file_users(self, path): |
270 |
"""Returns EggInfo instances for the projects that uses `path`.""" |
|
271 |
for egg_info in self: |
|
272 |
if egg_info.uses(path): |
|
273 |
yield egg_info |
|
270 |
"""Returns Distribution instances for the projects that uses `path`.""" |
|
271 |
for dist in self: |
|
272 |
if dist.uses(path): |
|
273 |
yield dist |
|
274 |
274 |
|
275 |
275 |
def owner(self, path): |
276 |
276 |
"""Returns the owner of `path`.""" |
277 |
users = [ |
|
277 |
users = [dist for dist in self if dist.uses(path)] |
|
278 |
278 |
if len(users) == 1: |
279 |
279 |
return users[0] |
280 |
280 |
return None |
| … | … | @@ -290,37 +290,37 @@ def purge_cache(): |
290 |
290 |
_CACHED_DIRS.clear() |
291 |
291 |
|
292 |
292 |
|
293 |
class |
|
293 |
class DistributionDirectories(object): |
|
294 |
294 |
|
295 |
295 |
def __init__(self, use_cache=True): |
296 |
296 |
self._paths = [] |
297 |
self._ |
|
297 |
self._dist_dirs = [] |
|
298 |
298 |
self.use_cache = use_cache |
299 |
299 |
|
300 |
300 |
# |
301 |
301 |
# container APIs |
302 |
302 |
# |
303 |
303 |
def __iter__(self): |
304 |
return iter(self._ |
|
304 |
return iter(self._dist_dirs) |
|
305 |
305 |
|
306 |
306 |
def append(self, path): |
307 |
307 |
if self.use_cache and path in _CACHED_DIRS: |
308 |
|
|
308 |
dist_dir = _CACHED_DIRS[path] |
|
309 |
309 |
else: |
310 |
|
|
310 |
dist_dir = DistributionDirectory(path) |
|
311 |
311 |
if self.use_cache: |
312 |
_CACHED_DIRS[path] = |
|
312 |
_CACHED_DIRS[path] = dist_dir |
|
313 |
313 |
|
314 |
self._ |
|
314 |
self._dist_dirs.append(dist_dir) |
|
315 |
315 |
self._paths.append(path) |
316 |
316 |
|
317 |
317 |
def clear(self): |
318 |
self._ |
|
318 |
self._dist_dirs.clear() |
|
319 |
319 |
self._paths.clear() |
320 |
320 |
|
321 |
def remove(self, egg_info_dir): |
|
322 |
self._egg_info_dirs.remove(egg_info_dir) |
|
323 |
|
|
321 |
def remove(self, dist_dir): |
|
322 |
self._dist_dirs.remove(dist_dir) |
|
323 |
self._paths.remove(dist_dir.path) |
|
324 |
324 |
|
325 |
325 |
# |
326 |
326 |
# public APIs |
| … | … | @@ -336,20 +336,20 @@ class EggInfoDirectories(object): |
336 |
336 |
self.clear() |
337 |
337 |
self.load(paths) |
338 |
338 |
|
339 |
def get_ |
|
339 |
def get_distributions(self): |
|
340 |
340 |
for directory in self: |
341 |
for egg_info in directory: |
|
342 |
yield egg_info |
|
341 |
for dist in directory: |
|
342 |
yield dist |
|
343 |
343 |
|
344 |
def get_ |
|
344 |
def get_distribution(self, project_name): |
|
345 |
345 |
"""Returns an EggInfo instance for the given project name. |
346 |
346 |
|
347 |
347 |
If not found, returns None. |
348 |
348 |
""" |
349 |
349 |
for directory in self: |
350 |
for egg_info in directory: |
|
351 |
if egg_info.name == project_name: |
|
352 |
|
|
350 |
for dist in directory: |
|
351 |
if dist.name == project_name: |
|
352 |
return dist |
|
353 |
353 |
|
354 |
354 |
def get_file_users(self, path): |
355 |
355 |
"""Iterates over all projects to find out which project uses the file. |
| … | … | @@ -357,25 +357,22 @@ class EggInfoDirectories(object): |
357 |
357 |
Return EggInfo instances. |
358 |
358 |
""" |
359 |
359 |
for directory in self: |
360 |
for egg_info in directory.file_users(path): |
|
361 |
yield egg_info |
|
360 |
for dist in directory.file_users(path): |
|
361 |
yield dist |
|
362 |
362 |
|
363 |
363 |
# |
364 |
# high level APIs with a global |
|
364 |
# high level APIs with a global DistributionDirectories instance loaded |
|
365 |
# on sys.path |
|
365 |
366 |
# |
367 |
_dist_dirs = DistributionDirectories() |
|
368 |
_dist_dirs.load(sys.path) |
|
366 |
369 |
|
367 |
egg_infos = EggInfoDirectories() |
|
370 |
def get_distributions(): |
|
371 |
return _dist_dirs.get_distributions() |
|
368 |
372 |
|
369 |
def get_egg_infos(paths=sys.path): |
|
370 |
egg_infos.load(paths) |
|
371 |
return egg_infos.get_egg_infos() |
|
373 |
def get_distribution(project_name): |
|
374 |
return _dist_dirs.get_distribution(project_name) |
|
372 |
375 |
|
373 |
def get_egg_info(project_name, paths=sys.path): |
|
374 |
egg_infos.load(paths) |
|
375 |
return egg_infos.get_egg_info(project_name) |
|
376 |
def get_file_users(path): |
|
377 |
return _dist_dirs.get_file_users(path) |
|
376 |
378 |
|
377 |
def get_file_users(path, paths=sys.path): |
|
378 |
egg_infos.load(paths) |
|
379 |
return egg_infos.get_file_users(path) |
|
380 |
||
381 |
Up to file-list test_pkgutil.py:
1 |
1 |
from nose.tools import * |
2 |
import pkgutil |
|
2 |
3 |
from pkgutil import * |
3 |
4 |
import sys |
4 |
5 |
import os |
| … | … | @@ -8,69 +9,68 @@ SITE_PKG = os.path.join(os.path.dirname( |
8 |
9 |
def setup(): |
9 |
10 |
sys.old = sys.path |
10 |
11 |
sys.path = [SITE_PKG] |
12 |
pkgutil._dist_dirs = DistributionDirectories() |
|
13 |
pkgutil._dist_dirs.load([SITE_PKG]) |
|
11 |
14 |
|
12 |
15 |
def teardown(): |
13 |
16 |
sys.path = sys.old |
14 |
17 |
del sys.old |
15 |
18 |
|
16 |
def test_get_egg_infos(): |
|
17 |
projects = list(get_egg_infos([SITE_PKG])) |
|
19 |
def test_distributions(): |
|
20 |
projects = list(get_distributions()) |
|
18 |
21 |
assert_equals(len(projects), 2) |
19 |
22 |
|
20 |
def test_egg_info_directory(): |
|
21 |
assert_equals(get_egg_info('xxx', [SITE_PKG]), None) |
|
23 |
def test_distribution(): |
|
24 |
assert_equals(get_distribution('xxx'), None) |
|
22 |
25 |
|
23 |
project = get_ |
|
26 |
project = get_distribution('mercurial') |
|
24 |
27 |
assert_equals(project.name, 'mercurial') |
25 |
28 |
|
26 |
project = get_ |
|
29 |
project = get_distribution('processing') |
|
27 |
30 |
assert_equals(project.name, 'processing') |
28 |
31 |
|
29 |
def test_egg_info(): |
|
32 |
dist = get_distribution('mercurial') |
|
33 |
assert_equals(str(dist), "Distribution('mercurial')") |
|
30 |
34 |
|
31 |
egg_info = get_egg_info('mercurial', [SITE_PKG]) |
|
32 |
assert_equals(str(egg_info), "EggInfo('mercurial')") |
|
33 |
||
34 |
files = list(egg_info.get_installed_files()) |
|
35 |
files = list(dist.get_installed_files()) |
|
35 |
36 |
assert_equals(len(files), 4) |
36 |
37 |
assert_equals(files[0], ('mercurial/filelog.py', '98676876876876', '12')) |
37 |
38 |
|
38 |
files = list( |
|
39 |
files = list(dist.get_installed_files(local=True)) |
|
39 |
40 |
|
40 |
site_packages = os.path.split( |
|
41 |
site_packages = os.path.split(dist.info_path)[0] |
|
41 |
42 |
location = os.path.join(site_packages, 'mercurial', 'filelog.py') |
42 |
43 |
assert_equals(files[0], (location, '98676876876876', '12')) |
43 |
44 |
|
44 |
f = |
|
45 |
f = dist.get_egg_info_file('RECORD') |
|
45 |
46 |
record = os.path.join(SITE_PKG, 'mercurial-1.0.1.egg-info', 'RECORD') |
46 |
47 |
assert_equals(open(record).read(), f.read()) |
47 |
48 |
|
48 |
assert egg_info.uses('mercurial/filelog.py') |
|
49 |
assert not egg_info.uses('mercurial/filelog.sasasasa') |
|
49 |
assert dist.uses('mercurial/filelog.py') |
|
50 |
assert not dist.uses('mercurial/filelog.sasasasa') |
|
50 |
51 |
|
51 |
assert_equals(list( |
|
52 |
assert_equals(list(dist.get_egg_info_files()), |
|
52 |
53 |
['mercurial-1.0.1.egg-info/PKG_INFO', |
53 |
54 |
'mercurial-1.0.1.egg-info/RECORD']) |
54 |
55 |
|
55 |
||
56 |
assert_equals(list(egg_info.get_egg_info_files(local=True)), |
|
56 |
assert_equals(list(dist.get_egg_info_files(local=True)), |
|
57 |
57 |
[os.path.join(SITE_PKG, 'mercurial-1.0.1.egg-info/PKG_INFO'), |
58 |
58 |
os.path.join(SITE_PKG, 'mercurial-1.0.1.egg-info/RECORD')]) |
59 |
59 |
|
60 |
60 |
|
61 |
61 |
def test_directory(): |
62 |
dir = |
|
62 |
dir = DistributionDirectory(SITE_PKG) |
|
63 |
63 |
|
64 |
egg_info = dir.owner('mercurial/filelog.pyc') |
|
65 |
assert egg_info.name == 'mercurial' |
|
64 |
dist = dir.owner('mercurial/filelog.pyc') |
|
65 |
assert dist.name == 'mercurial' |
|
66 |
66 |
assert dir.owner('mercurial/filelog.py') is None |
67 |
67 |
|
68 |
68 |
def test_get_file_users(): |
69 |
||
70 |
users = list(get_file_users('mercurial/filelog.py', [SITE_PKG])) |
|
69 |
users = list(get_file_users('mercurial/filelog.py')) |
|
71 |
70 |
assert_equals(len(users), 2) |
72 |
71 |
|
73 |
72 |
def test_egg_info_dirname(): |
74 |
73 |
assert egg_info_dirname('zlib', '2.5.2') == 'zlib-2.5.2.egg-info' |
75 |
74 |
assert egg_info_dirname('python-ldap', '2.5'), 'python_ldap-2.5.egg-info' |
76 |
75 |
assert egg_info_dirname('python-ldap', '2.5 a---5'), 'python_ldap-2.5.a_5.egg-info' |
76 |
