tarek / pep376

code for PEP 376

Clone this repository (size: 66.5 KB): HTTPS / SSH
$ hg clone http://bitbucket.org/tarek/pep376/
commit 18: 8c1102a08b66
parent 17: f6fede60a1e8
branch: default
changed API name (EggInfo -> Distribution) + better global APIs
ta...@MacZiade
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)

Up to file-list pkgutil.py:

@@ -141,9 +141,9 @@ def is_egg_info(path):
141
141
142
142
143
143
#
144
# EggInfo class (with DistributionMetadata in it)
144
# Distribution class (with DistributionMetadata in it)
145
145
#
146
class EggInfo(object):
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 "EggInfo('%s')" % self.name
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
# EggInfoDirectory represents a directory that contains egg-info files
246
# DistributionDirectory represents a directory that contains egg-info files
247
247
#
248
class EggInfoDirectory(object):
248
class DistributionDirectory(object):
249
249
250
250
    def __init__(self, path):
251
251
        self.path = path
252
        self._egg_infos = []
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._egg_infos.append(EggInfo(fullpath))
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._egg_infos)
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 = [egg_info for egg_info in self if egg_info.uses(path)]
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 EggInfoDirectories(object):
293
class DistributionDirectories(object):
294
294
295
295
    def __init__(self, use_cache=True):
296
296
        self._paths = []
297
        self._egg_info_dirs = []
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._egg_info_dirs)
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
            egg_info_dir = _CACHED_DIRS[path]
308
            dist_dir = _CACHED_DIRS[path]
309
309
        else:
310
            egg_info_dir = EggInfoDirectory(path)
310
            dist_dir = DistributionDirectory(path)
311
311
            if self.use_cache:
312
                _CACHED_DIRS[path] = egg_info_dir
312
                _CACHED_DIRS[path] = dist_dir
313
313
314
        self._egg_info_dirs.append(egg_info_dir)
314
        self._dist_dirs.append(dist_dir)
315
315
        self._paths.append(path)
316
316
317
317
    def clear(self):
318
        self._egg_info_dirs.clear()
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
        self._paths.remove(egg_info_dir.path)
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_egg_infos(self):
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_egg_info(self, project_name):
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
                    return egg_info
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 EggInfoDirectories instance
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_egg_info('mercurial', [SITE_PKG])
26
    project = get_distribution('mercurial')
24
27
    assert_equals(project.name, 'mercurial')
25
28
26
    project = get_egg_info('processing', [SITE_PKG])
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(egg_info.get_installed_files(local=True))
39
    files = list(dist.get_installed_files(local=True))
39
40
40
    site_packages = os.path.split(egg_info.info_path)[0]
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 = egg_info.get_egg_info_file('RECORD')
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(egg_info.get_egg_info_files()),
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 = EggInfoDirectory(SITE_PKG)
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