/
importing.py
161 lines (133 loc) · 5.17 KB
/
importing.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
import importlib
import sys
import site
from os import path
def prependsitedir(projdir, *args):
"""
like sys.addsitedir() but gives the added directory preference
over system directories. The paths will be normalized for dots and
slash direction before being added to the path.
projdir: the path you want to add to sys.path. If its a
a file, the parent directory will be added
*args: additional directories relative to the projdir to add
to sys.path.
"""
# let the user be lazy and send a file, we will convert to parent directory
# of file
if path.isfile(projdir):
projdir = path.dirname(projdir)
projdir = path.abspath(projdir)
# any args are considered paths that need to be joined to the
# projdir to get to the correct directory.
libpaths = []
for lpath in args:
libpaths.append(path.join(projdir, path.normpath(lpath)))
# add the path to sys.path with preference over everything that currently
# exists in sys.path
syspath_orig = set(sys.path)
site.addsitedir(projdir)
for lpath in libpaths:
site.addsitedir(lpath)
syspath_after = set(sys.path)
new_paths = list(syspath_after.difference(syspath_orig))
sys.path = new_paths + sys.path
def setup_virtual_env(pysmvt_libs_module, lib_path, *args):
# load the system library that corresponds with the version requested
libs_mod = __import__(pysmvt_libs_module)
prependsitedir(libs_mod.__file__)
# load the local 'libs' directory
prependsitedir(lib_path, *args)
def import_split(import_name):
""" takes a dotted string path and returns the components:
import_split('path') == 'path', None, None
import_split('path.part.object') == 'path.part', 'object', None
import_split('path.part:object') == 'path.part', 'object', None
import_split('path.part:object.attribute')
== 'path.part', 'object', 'attribute'
"""
obj = None
attr = None
if ':' in import_name:
module, obj = import_name.split(':', 1)
if '.' in obj:
obj, attr = obj.rsplit('.', 1)
elif '.' in import_name:
module, obj = import_name.rsplit('.', 1)
else:
module = import_name
return module, obj, attr
def find_path_package(thepath):
"""
Takes a file system path and returns the module object of the python
package the said path belongs to. If the said path can not be
determined, it returns None.
"""
pname = find_path_package_name(thepath)
if not pname:
return None
fromlist = ''
return __import__(pname, globals(), locals(), [fromlist])
_py_suffixes = importlib.machinery.all_suffixes()
def find_path_package_name(thepath):
"""
Takes a file system path and returns the name of the python package
the said path belongs to. If the said path can not be determined, it
returns None.
"""
module_found = False
last_module_found = None
continue_ = True
while continue_:
module_found = is_path_python_module(thepath)
next_path = path.dirname(thepath)
if next_path == thepath:
continue_ = False
if module_found:
init_names = ['__init__%s' % suffix.lower() for suffix in _py_suffixes]
if path.basename(thepath).lower() in init_names:
last_module_found = path.basename(path.dirname(thepath))
else:
last_module_found = path.basename(thepath)
if last_module_found and not module_found:
continue_ = False
thepath = next_path
return last_module_found
def is_path_python_module(thepath):
"""
Given a path, find out of the path is a python module or is inside
a python module.
"""
thepath = path.normpath(thepath)
if path.isfile(thepath):
base, ext = path.splitext(thepath)
if ext in _py_suffixes:
return True
return False
if path.isdir(thepath):
for suffix in _py_suffixes:
if path.isfile(path.join(thepath, '__init__%s' % suffix)):
return True
return False
# from werkzeug
def import_string(import_name, silent=False):
"""Imports an object based on a string. This is useful if you want to
use import paths as endpoints or something similar. An import path can
be specified either in dotted notation (``xml.sax.saxutils.escape``)
or with a colon as object delimiter (``xml.sax.saxutils:escape``).
If `silent` is True the return value will be `None` if the import fails.
:param import_name: the dotted name for the object to import.
:param silent: if set to `True` import errors are ignored and
`None` is returned instead.
:return: imported object
"""
try:
if ':' in import_name:
module, obj_name = import_name.split(':', 1)
elif '.' in import_name:
module, obj_name = import_name.rsplit('.', 1)
else:
return __import__(import_name)
return getattr(__import__(module, None, None, [obj_name]), obj_name)
except (ImportError, AttributeError):
if not silent:
raise