commit | author | age
|
434c05
|
1 |
import os |
d9a76e
|
2 |
import pkg_resources |
423b85
|
3 |
import sys |
3c2ed7
|
4 |
import imp |
CM |
5 |
|
|
6 |
ignore_types = [ imp.C_EXTENSION, imp.C_BUILTIN ] |
|
7 |
init_names = [ '__init__%s' % x[0] for x in imp.get_suffixes() if |
|
8 |
x[0] and x[2] not in ignore_types ] |
434c05
|
9 |
|
d9a76e
|
10 |
def caller_path(path, level=2): |
434c05
|
11 |
if not os.path.isabs(path): |
d9a76e
|
12 |
module = caller_module(level+1) |
CM |
13 |
prefix = package_path(module) |
434c05
|
14 |
path = os.path.join(prefix, path) |
CM |
15 |
return path |
|
16 |
|
a56564
|
17 |
def caller_module(level=2, sys=sys): |
d9a76e
|
18 |
module_globals = sys._getframe(level).f_globals |
a56564
|
19 |
module_name = module_globals.get('__name__') or '__main__' |
d9a76e
|
20 |
module = sys.modules[module_name] |
CM |
21 |
return module |
434c05
|
22 |
|
6efd81
|
23 |
def package_name(pkg_or_module): |
CM |
24 |
""" If this function is passed a module, return the dotted Python |
|
25 |
package name of the package in which the module lives. If this |
|
26 |
function is passed a package, return the dotted Python package |
|
27 |
name of the package itself.""" |
601e03
|
28 |
if pkg_or_module is None: |
45d08c
|
29 |
return '__main__' |
6efd81
|
30 |
pkg_filename = pkg_or_module.__file__ |
CM |
31 |
pkg_name = pkg_or_module.__name__ |
|
32 |
splitted = os.path.split(pkg_filename) |
3c2ed7
|
33 |
if splitted[-1] in init_names: |
6efd81
|
34 |
# it's a package |
CM |
35 |
return pkg_name |
|
36 |
return pkg_name.rsplit('.', 1)[0] |
|
37 |
|
39480c
|
38 |
def package_of(pkg_or_module): |
CM |
39 |
""" Return the package of a module or return the package itself """ |
|
40 |
pkg_name = package_name(pkg_or_module) |
|
41 |
__import__(pkg_name) |
|
42 |
return sys.modules[pkg_name] |
|
43 |
|
5f4b80
|
44 |
def caller_package(level=2, caller_module=caller_module): |
CM |
45 |
# caller_module in arglist for tests |
|
46 |
module = caller_module(level+1) |
bfee0a
|
47 |
f = getattr(module, '__file__', '') |
CM |
48 |
if (('__init__.py' in f) or ('__init__$py' in f)): # empty at >>> |
5f4b80
|
49 |
# Module is a package |
CM |
50 |
return module |
|
51 |
# Go up one level to get package |
|
52 |
package_name = module.__name__.rsplit('.', 1)[0] |
|
53 |
return sys.modules[package_name] |
|
54 |
|
d9a76e
|
55 |
def package_path(package): |
CM |
56 |
# computing the abspath is actually kinda expensive so we memoize |
|
57 |
# the result |
cba2e1
|
58 |
prefix = getattr(package, '__abspath__', None) |
d9a76e
|
59 |
if prefix is None: |
CM |
60 |
prefix = pkg_resources.resource_filename(package.__name__, '') |
|
61 |
# pkg_resources doesn't care whether we feed it a package |
|
62 |
# name or a module name within the package, the result |
|
63 |
# will be the same: a directory name to the package itself |
|
64 |
try: |
cba2e1
|
65 |
package.__abspath__ = prefix |
d9a76e
|
66 |
except: |
CM |
67 |
# this is only an optimization, ignore any error |
|
68 |
pass |
|
69 |
return prefix |
600ea3
|
70 |
|