iris-pex-embedded-python 3.1.3__py3-none-any.whl → 3.1.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of iris-pex-embedded-python might be problematic. Click here for more details.
- intersystems_iris/_ConnectionInformation.py +22 -20
- intersystems_iris/dbapi/_DBAPI.py +6 -1
- intersystems_iris/dbapi/_ResultSetRow.py +26 -15
- intersystems_iris/dbapi/preparser/_PreParser.py +4 -1
- {iris_pex_embedded_python-3.1.3.dist-info → iris_pex_embedded_python-3.1.4.dist-info}/METADATA +1 -1
- {iris_pex_embedded_python-3.1.3.dist-info → iris_pex_embedded_python-3.1.4.dist-info}/RECORD +10 -16
- {iris_pex_embedded_python-3.1.3.dist-info → iris_pex_embedded_python-3.1.4.dist-info}/WHEEL +1 -1
- {iris_pex_embedded_python-3.1.3.dist-info → iris_pex_embedded_python-3.1.4.dist-info}/top_level.txt +0 -1
- iris/__init__.py +0 -60
- iris/__init__.pyi +0 -236
- iris/_cli.py +0 -38
- iris/iris_ipm.py +0 -40
- iris/iris_ipm.pyi +0 -17
- iris/iris_utils.py +0 -336
- {iris_pex_embedded_python-3.1.3.dist-info → iris_pex_embedded_python-3.1.4.dist-info}/LICENSE +0 -0
- {iris_pex_embedded_python-3.1.3.dist-info → iris_pex_embedded_python-3.1.4.dist-info}/entry_points.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import intersystems_iris._Constant
|
|
2
2
|
|
|
3
|
-
class _ConnectionInformation(object):
|
|
4
3
|
|
|
4
|
+
class _ConnectionInformation(object):
|
|
5
5
|
def __init__(self):
|
|
6
6
|
self.protocol_version = intersystems_iris._Constant._Constant.PROTOCOL_VERSION
|
|
7
7
|
self._is_unicode = True
|
|
@@ -20,9 +20,10 @@ class _ConnectionInformation(object):
|
|
|
20
20
|
def _parse_server_version(self, server_version):
|
|
21
21
|
split_1 = server_version.split("|")
|
|
22
22
|
self._server_version = split_1[0]
|
|
23
|
-
if len(split_1)>1:
|
|
23
|
+
if len(split_1) > 1:
|
|
24
|
+
self._iris_install_dir = split_1[1]
|
|
24
25
|
if self._server_version.find("Version") > 0:
|
|
25
|
-
version = server_version[server_version.find("Version")+8:]
|
|
26
|
+
version = server_version[server_version.find("Version") + 8 :]
|
|
26
27
|
self._server_version_major = version.split(".")[0]
|
|
27
28
|
self._server_version_minor = version.split(".")[1]
|
|
28
29
|
return
|
|
@@ -31,24 +32,25 @@ class _ConnectionInformation(object):
|
|
|
31
32
|
def _map_server_locale(locale):
|
|
32
33
|
# we need to map IRIS locale literals to Python locale literals
|
|
33
34
|
_locales = {
|
|
34
|
-
"LATIN1": "latin_1",
|
|
35
|
-
"LATIN2": "iso8859_2",
|
|
36
|
-
"LATINC": "iso8859_5",
|
|
37
|
-
"LATINA": "iso8859_6",
|
|
38
|
-
"LATING": "iso8859_7",
|
|
39
|
-
"LATINH": "iso8859_8",
|
|
40
|
-
"LATINT": "iso8859_11",
|
|
41
|
-
"LATIN9": "iso8859_15",
|
|
42
|
-
"CP1250": "cp1250",
|
|
43
|
-
"CP1251": "cp1251",
|
|
44
|
-
"CP1252": "cp1252",
|
|
45
|
-
"CP1253": "cp1253",
|
|
46
|
-
"CP1255": "cp1255",
|
|
47
|
-
"CP1256": "cp1256",
|
|
48
|
-
"CP1257": "cp1257",
|
|
49
|
-
"CP874": "cp874",
|
|
35
|
+
"LATIN1": "latin_1",
|
|
36
|
+
"LATIN2": "iso8859_2",
|
|
37
|
+
"LATINC": "iso8859_5",
|
|
38
|
+
"LATINA": "iso8859_6",
|
|
39
|
+
"LATING": "iso8859_7",
|
|
40
|
+
"LATINH": "iso8859_8",
|
|
41
|
+
"LATINT": "iso8859_11",
|
|
42
|
+
"LATIN9": "iso8859_15",
|
|
43
|
+
"CP1250": "cp1250",
|
|
44
|
+
"CP1251": "cp1251",
|
|
45
|
+
"CP1252": "cp1252",
|
|
46
|
+
"CP1253": "cp1253",
|
|
47
|
+
"CP1255": "cp1255",
|
|
48
|
+
"CP1256": "cp1256",
|
|
49
|
+
"CP1257": "cp1257",
|
|
50
|
+
"CP874": "cp874",
|
|
50
51
|
"UNICODE": "utf-8",
|
|
51
52
|
}
|
|
52
53
|
return _locales[locale.upper()] if locale.upper() in _locales else locale
|
|
53
54
|
|
|
54
|
-
|
|
55
|
+
def __repr__(self) -> str:
|
|
56
|
+
return f"<{self._server_version}>"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from typing import Union
|
|
1
2
|
import struct
|
|
2
3
|
import copy
|
|
3
4
|
import enum
|
|
@@ -25,6 +26,7 @@ from ._SQLType import SQLType
|
|
|
25
26
|
|
|
26
27
|
from .._IRISNative import connect as native_connect
|
|
27
28
|
from .._IRISEmbedded import _IRISEmbedded
|
|
29
|
+
from intersystems_iris._IRISConnection import _IRISConnection
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
def NotImplementedErrorDBAPI(msg=None):
|
|
@@ -42,7 +44,7 @@ def embedded_connect(*args, hostname=None, port=None, namespace=None, username=N
|
|
|
42
44
|
return connection
|
|
43
45
|
|
|
44
46
|
|
|
45
|
-
def connect(*args, embedded=False, hostname=None, port=None, namespace=None, username=None, password=None, **kw):
|
|
47
|
+
def connect(*args, embedded=False, hostname=None, port=None, namespace=None, username=None, password=None, **kw) -> Union[_IRISConnection, _IRISEmbedded]:
|
|
46
48
|
try:
|
|
47
49
|
if not embedded:
|
|
48
50
|
return native_connect(
|
|
@@ -1180,6 +1182,8 @@ class Cursor(_BaseCursor):
|
|
|
1180
1182
|
sets = self._parameter_sets or 1
|
|
1181
1183
|
self.params = list(self.params).copy()
|
|
1182
1184
|
param_types = [param.type for param in self._params._params_list]
|
|
1185
|
+
if not self.params:
|
|
1186
|
+
return
|
|
1183
1187
|
|
|
1184
1188
|
for i in range(sets):
|
|
1185
1189
|
params = self._params.collect(i)
|
|
@@ -2149,6 +2153,7 @@ class Cursor(_BaseCursor):
|
|
|
2149
2153
|
|
|
2150
2154
|
if retval is None:
|
|
2151
2155
|
return retval
|
|
2156
|
+
# print('retval', retval[:])
|
|
2152
2157
|
return retval.as_tuple()
|
|
2153
2158
|
# return tuple(retval[:])
|
|
2154
2159
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import uuid
|
|
2
|
-
from datetime import datetime, date, time
|
|
2
|
+
from datetime import datetime, date, time, timezone
|
|
3
3
|
from collections import namedtuple
|
|
4
4
|
from ._SQLType import SQLType
|
|
5
5
|
from .._DBList import _DBList
|
|
@@ -11,20 +11,26 @@ from ._Column import _Column
|
|
|
11
11
|
def from_timestamp_posix(posix):
|
|
12
12
|
time = int(posix)
|
|
13
13
|
if time > 0:
|
|
14
|
-
time ^= 0x1000000000000000
|
|
14
|
+
time ^= 0x1000000000000000
|
|
15
15
|
else:
|
|
16
|
-
time |= 0xF000000000000000
|
|
16
|
+
time |= 0xF000000000000000
|
|
17
17
|
|
|
18
18
|
time /= 1000000
|
|
19
19
|
|
|
20
|
-
value = datetime.
|
|
20
|
+
value = datetime.fromtimestamp(time, timezone.utc).replace(tzinfo=None)
|
|
21
21
|
return value
|
|
22
22
|
|
|
23
|
+
|
|
23
24
|
class _ResultSetRow:
|
|
24
25
|
_locale = "latin-1"
|
|
25
26
|
_connection = None
|
|
26
27
|
|
|
27
|
-
def __init__(
|
|
28
|
+
def __init__(
|
|
29
|
+
self,
|
|
30
|
+
connection,
|
|
31
|
+
columns=None,
|
|
32
|
+
rowcount=0,
|
|
33
|
+
):
|
|
28
34
|
self._connection = connection
|
|
29
35
|
# index from user-inputted columns to columns received from server
|
|
30
36
|
self.col_index = []
|
|
@@ -55,7 +61,7 @@ class _ResultSetRow:
|
|
|
55
61
|
self.colCount = len(columns) if columns != None else 0
|
|
56
62
|
|
|
57
63
|
# number of columns received from server, aka number of items per row
|
|
58
|
-
#self.colCount = rowcount
|
|
64
|
+
# self.colCount = rowcount
|
|
59
65
|
|
|
60
66
|
# list of _ListItems corresponding to the various entries in the row, plus the offset of next row's first _ListItem
|
|
61
67
|
self.rowItems = None
|
|
@@ -126,9 +132,9 @@ class _ResultSetRow:
|
|
|
126
132
|
|
|
127
133
|
def get(self):
|
|
128
134
|
return self[:]
|
|
129
|
-
|
|
135
|
+
|
|
130
136
|
def as_tuple(self):
|
|
131
|
-
row = namedtuple(
|
|
137
|
+
row = namedtuple("Row", [col.name for col in self._columns], rename=True)
|
|
132
138
|
values = self[:]
|
|
133
139
|
return row(*values)
|
|
134
140
|
|
|
@@ -164,15 +170,18 @@ class _ResultSetRow:
|
|
|
164
170
|
HOROLOG_ORDINAL = date(1840, 12, 31).toordinal()
|
|
165
171
|
if item:
|
|
166
172
|
item = date.fromordinal(HOROLOG_ORDINAL + item)
|
|
173
|
+
if ctype == SQLType.TIMESTAMP and item:
|
|
174
|
+
item = item + '.000' if '.' not in item else item
|
|
175
|
+
item = datetime.strptime(item, '%Y-%m-%d %H:%M:%S.%f')
|
|
167
176
|
if ctype == SQLType.TIME_HOROLOG:
|
|
168
177
|
if item:
|
|
169
178
|
item = time(item // 3600, item % 3600 // 60, item % 3600 % 60)
|
|
170
179
|
if ctype == SQLType.GUID:
|
|
171
180
|
item = uuid.UUID(item)
|
|
172
|
-
if ctype == SQLType.TIMESTAMP_POSIX:
|
|
181
|
+
if ctype == SQLType.TIMESTAMP_POSIX and item:
|
|
173
182
|
item = from_timestamp_posix(item)
|
|
174
183
|
|
|
175
|
-
if _column.tableName ==
|
|
184
|
+
if _column.tableName == "None" and _column.schema == "None":
|
|
176
185
|
# Ignore for anonymous tables
|
|
177
186
|
pass
|
|
178
187
|
elif item is None:
|
|
@@ -285,8 +294,9 @@ class _ResultSetRow:
|
|
|
285
294
|
rowItems[i] = curr_offset
|
|
286
295
|
prev_offset = curr_offset
|
|
287
296
|
except IndexError:
|
|
288
|
-
raise IndexError(
|
|
289
|
-
|
|
297
|
+
raise IndexError(
|
|
298
|
+
"Row incomplete: " + str(self.colCount) + " items expected, but " + str(i) + " were found"
|
|
299
|
+
)
|
|
290
300
|
self.update(rowItems)
|
|
291
301
|
return True
|
|
292
302
|
|
|
@@ -319,8 +329,9 @@ class _ResultSetRow:
|
|
|
319
329
|
rowItems[i] = curr_offset
|
|
320
330
|
prev_offset = curr_offset
|
|
321
331
|
except IndexError:
|
|
322
|
-
raise IndexError(
|
|
323
|
-
|
|
332
|
+
raise IndexError(
|
|
333
|
+
"Row incomplete: " + str(self.colCount) + " items expected, but " + str(i) + " were found"
|
|
334
|
+
)
|
|
324
335
|
return self.update(rowItems)
|
|
325
336
|
|
|
326
337
|
def update(self, rowItems):
|
|
@@ -330,7 +341,7 @@ class _ResultSetRow:
|
|
|
330
341
|
colIndexOffsets[idx] = rowItems[i]
|
|
331
342
|
colIndexOffsets[-1] = self._last_list_item.next_offset
|
|
332
343
|
self.rowItems = colIndexOffsets
|
|
333
|
-
return self.rowItems[:self.colCount]
|
|
344
|
+
return self.rowItems[: self.colCount]
|
|
334
345
|
self.rowItems = rowItems
|
|
335
346
|
self._offsets = self.DataRow(self)
|
|
336
347
|
self._new_buffer = False
|
|
@@ -580,7 +580,10 @@ class _PreParser(object):
|
|
|
580
580
|
break
|
|
581
581
|
if token.TokenType is TOKEN.CONSTANT:
|
|
582
582
|
values += '?'
|
|
583
|
-
|
|
583
|
+
param = token.Lexeme
|
|
584
|
+
if param.__len__ and param[0] == "'" and param[0] == param[-1]:
|
|
585
|
+
param = param[1: -1]
|
|
586
|
+
params += [param]
|
|
584
587
|
else:
|
|
585
588
|
values += token.Lexeme
|
|
586
589
|
values += ' '
|
{iris_pex_embedded_python-3.1.3.dist-info → iris_pex_embedded_python-3.1.4.dist-info}/RECORD
RENAMED
|
@@ -29,7 +29,7 @@ grongier/pex/_utils.py,sha256=gvsdr8WhWrE6smlsCxhoF14VUZfitrwqr5J57HkJhi4,29
|
|
|
29
29
|
grongier/pex/wsgi/handlers.py,sha256=NrFLo_YbAh-x_PlWhAiWkQnUUN2Ss9HoEm63dDWCBpQ,2947
|
|
30
30
|
intersystems_iris/_BufferReader.py,sha256=BXjHQs-sclAnvW9mvdlIrtku9m2Jf67Rc5rsZll7a5g,299
|
|
31
31
|
intersystems_iris/_BufferWriter.py,sha256=i2BKM99J8pB5fGn-Gjdo4vcwXPEZQymsLEQd69nJrhs,1337
|
|
32
|
-
intersystems_iris/_ConnectionInformation.py,sha256=
|
|
32
|
+
intersystems_iris/_ConnectionInformation.py,sha256=45bPmGaXF3lG6aPClYr6qkdAUrtgDg5kvMbZKkgl_xA,1970
|
|
33
33
|
intersystems_iris/_ConnectionParameters.py,sha256=5-VwMJP_6Ya0lNnMf0UuwJQQfwHcozjknnUekMwCgQ4,578
|
|
34
34
|
intersystems_iris/_Constant.py,sha256=g2NdV669sNH4kUoAjQFNq2xWaEMQiPMoQytNNrrXOnk,1483
|
|
35
35
|
intersystems_iris/_DBList.py,sha256=D0m_N50ZhpUnGwQiPZ1ZPtNecqROZvSnVbP46RY6juA,20340
|
|
@@ -62,16 +62,16 @@ intersystems_iris/_SharedMemorySocket.py,sha256=2iUaS1FdJNSCUEaE-VT0O_dxF6NRwqZS
|
|
|
62
62
|
intersystems_iris/__init__.py,sha256=Tk1tD28LwvF6X3yXQsJFLE1Bc-PR3gUJWcX5UnNYOdY,1773
|
|
63
63
|
intersystems_iris/__main__.py,sha256=rCtINTfJcADMAsw1ja-MEO7Q-XekrWthYowzWV8xGIQ,218
|
|
64
64
|
intersystems_iris/dbapi/_Column.py,sha256=VCLHLXs3wuGcUa9w_qy7HBFsuGvhmmI3kGYBagQg59U,2535
|
|
65
|
-
intersystems_iris/dbapi/_DBAPI.py,sha256=
|
|
65
|
+
intersystems_iris/dbapi/_DBAPI.py,sha256=LcJ42rkuyMBLW8ucaQFxAmSyPX_8atbCSpLj_W1uCiE,103150
|
|
66
66
|
intersystems_iris/dbapi/_Descriptor.py,sha256=IjyITxvjygDrhpk-0lGhdqQPh91SG6nTb1vi-AqyJNI,1391
|
|
67
67
|
intersystems_iris/dbapi/_IRISStream.py,sha256=dGJntWo4HXgM1nUHZl2hA4xHkBFEU2xkoEplVDFWhnA,2115
|
|
68
68
|
intersystems_iris/dbapi/_Message.py,sha256=jpLG3HZElqp981iNPFW8UNRO3NbHf6poEv6yywX0Ssw,4076
|
|
69
69
|
intersystems_iris/dbapi/_Parameter.py,sha256=lvPlQkoLlyEjg5J_a9t2I_6vRDkAav6kN1fGyukH4DY,5293
|
|
70
70
|
intersystems_iris/dbapi/_ParameterCollection.py,sha256=kcgNiGv2nH5AwuA6LlPpM4dWqhSqRyD3VtwqHqDGRGU,5541
|
|
71
|
-
intersystems_iris/dbapi/_ResultSetRow.py,sha256=
|
|
71
|
+
intersystems_iris/dbapi/_ResultSetRow.py,sha256=tEQCttO6L2McLfcP7-PIltIu5L9cNzTI1jZ2IR7tdRg,13777
|
|
72
72
|
intersystems_iris/dbapi/_SQLType.py,sha256=IlDacXwQzUMWaJ02Zsu2bUfvUC3-5mBx-m6mE0Yp7ts,557
|
|
73
73
|
intersystems_iris/dbapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
74
|
-
intersystems_iris/dbapi/preparser/_PreParser.py,sha256=
|
|
74
|
+
intersystems_iris/dbapi/preparser/_PreParser.py,sha256=yyX0iUO8vq2L8duelrndFr-xPn30UPp4N-nkTl0fbCo,78990
|
|
75
75
|
intersystems_iris/dbapi/preparser/_Scanner.py,sha256=xA8rkKsaVba_mAgoXEeliyuMxNKe4vVmmw_klukdf_U,16163
|
|
76
76
|
intersystems_iris/dbapi/preparser/_Token.py,sha256=9ZYrjvYJtMApAR7RtYzp32Hcoo3jB_YpG7ECo7p6QHA,2304
|
|
77
77
|
intersystems_iris/dbapi/preparser/_TokenList.py,sha256=P74kA3DXxi7imt0mea4LPjCCc_gk50zsYLOCWON_JvA,6770
|
|
@@ -127,17 +127,11 @@ iop/cls/IOP/PrivateSession/Message/Start.cls,sha256=uk-WTe66GicCshgmVy3F5ugHiAyP
|
|
|
127
127
|
iop/cls/IOP/PrivateSession/Message/Stop.cls,sha256=7g3gKFUjNg0WXBLuWnj-VnCs5G6hSE09YTzGEp0zbGc,1390
|
|
128
128
|
iop/cls/IOP/Service/WSGI.cls,sha256=VLNCXEwmHW9dBnE51uGE1nvGX6T4HjhqePT3LVhsjAE,10440
|
|
129
129
|
iop/wsgi/handlers.py,sha256=NrFLo_YbAh-x_PlWhAiWkQnUUN2Ss9HoEm63dDWCBpQ,2947
|
|
130
|
-
iris/__init__.py,sha256=QcMbcm3nmNwDGguQGSjcgHksOVf0qtS0MZFZbcRoxE4,1711
|
|
131
|
-
iris/__init__.pyi,sha256=HPv6Lot6yZt8XXj3Rb0CrVO9ChDbKVpE3ID1SIqAlwU,9766
|
|
132
|
-
iris/_cli.py,sha256=kxjGqRqQJFdNy0f6YMHEX-xacmXauSt3HAGVm-CbNhk,1061
|
|
133
|
-
iris/iris_ipm.py,sha256=Q0jcNItjywlqOPZr0hgdTFSeLPNEmB-tcICOI_cXnaY,790
|
|
134
|
-
iris/iris_ipm.pyi,sha256=j7CNUZcjeDu5sgeWUZJO_Qi4vQmHh6aD-jPWv8OdoUs,374
|
|
135
|
-
iris/iris_utils.py,sha256=kg80O3yRpHIutM-mCyr4xCeTvKWPE-Kai-b6Dxw4vQ4,9882
|
|
136
130
|
irisnative/_IRISNative.py,sha256=HQ4nBhc8t8_5OtxdMG-kx1aa-T1znf2I8obZOPLOPzg,665
|
|
137
131
|
irisnative/__init__.py,sha256=6YmvBLQSURsCPKaNg7LK-xpo4ipDjrlhKuwdfdNb3Kg,341
|
|
138
|
-
iris_pex_embedded_python-3.1.
|
|
139
|
-
iris_pex_embedded_python-3.1.
|
|
140
|
-
iris_pex_embedded_python-3.1.
|
|
141
|
-
iris_pex_embedded_python-3.1.
|
|
142
|
-
iris_pex_embedded_python-3.1.
|
|
143
|
-
iris_pex_embedded_python-3.1.
|
|
132
|
+
iris_pex_embedded_python-3.1.4.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
|
|
133
|
+
iris_pex_embedded_python-3.1.4.dist-info/METADATA,sha256=jb_TqfdfWUOkrYONZeQ0qpVgzNQMg-F8F8RMUH0drJo,50120
|
|
134
|
+
iris_pex_embedded_python-3.1.4.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
|
|
135
|
+
iris_pex_embedded_python-3.1.4.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
|
|
136
|
+
iris_pex_embedded_python-3.1.4.dist-info/top_level.txt,sha256=VWDlX4YF4qFVRGrG3-Gs0kgREol02i8gIpsHNbhfFPw,42
|
|
137
|
+
iris_pex_embedded_python-3.1.4.dist-info/RECORD,,
|
iris/__init__.py
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
from sys import path as __syspath
|
|
2
|
-
import os
|
|
3
|
-
from .iris_ipm import ipm
|
|
4
|
-
|
|
5
|
-
# check for install dir in environment
|
|
6
|
-
# environment to check is IRISINSTALLDIR
|
|
7
|
-
# if not found, raise exception and exit
|
|
8
|
-
# ISC_PACKAGE_INSTALLDIR - defined by default in Docker images
|
|
9
|
-
installdir = os.environ.get('IRISINSTALLDIR') or os.environ.get('ISC_PACKAGE_INSTALLDIR')
|
|
10
|
-
if installdir is None:
|
|
11
|
-
raise Exception("""Cannot find InterSystems IRIS installation directory
|
|
12
|
-
Please set IRISINSTALLDIR environment variable to the InterSystems IRIS installation directory""")
|
|
13
|
-
|
|
14
|
-
# join the install dir with the bin directory
|
|
15
|
-
__syspath.append(os.path.join(installdir, 'bin'))
|
|
16
|
-
# also append lib/python
|
|
17
|
-
__syspath.append(os.path.join(installdir, 'lib', 'python'))
|
|
18
|
-
|
|
19
|
-
# save working directory
|
|
20
|
-
__ospath = os.getcwd()
|
|
21
|
-
|
|
22
|
-
from pythonint import *
|
|
23
|
-
|
|
24
|
-
# restore working directory
|
|
25
|
-
os.chdir(__ospath)
|
|
26
|
-
|
|
27
|
-
# TODO: Figure out how to hide __syspath and __ospath from anyone that
|
|
28
|
-
# imports iris. Tried __all__ but that only applies to this:
|
|
29
|
-
# from iris import *
|
|
30
|
-
|
|
31
|
-
#
|
|
32
|
-
# End-of-file
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
def __getattr__(name):
|
|
36
|
-
try:
|
|
37
|
-
return globals()[name]
|
|
38
|
-
except KeyError:
|
|
39
|
-
return __get_iris_object__(name)
|
|
40
|
-
|
|
41
|
-
def __get_iris_object__(name:str):
|
|
42
|
-
try:
|
|
43
|
-
# replace '_' with '%'
|
|
44
|
-
name = name.replace('_', '%')
|
|
45
|
-
return cls(name)
|
|
46
|
-
except RuntimeError:
|
|
47
|
-
return __get_iris_package__(name)
|
|
48
|
-
|
|
49
|
-
def __get_iris_package__(name:str):
|
|
50
|
-
return IrisPackage(name)
|
|
51
|
-
|
|
52
|
-
class IrisPackage:
|
|
53
|
-
def __init__(self, name:str):
|
|
54
|
-
self.name = name
|
|
55
|
-
|
|
56
|
-
def __getattr__(self, name):
|
|
57
|
-
try:
|
|
58
|
-
return globals()[f"{self.name}.{name}"]
|
|
59
|
-
except KeyError:
|
|
60
|
-
return __get_iris_object__(f"{self.name}.{name}")
|
iris/__init__.pyi
DELETED
|
@@ -1,236 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
from typing import Any
|
|
3
|
-
from iris.iris_ipm import ipm
|
|
4
|
-
from . import iris_ipm
|
|
5
|
-
__all__ = [ 'check_status', 'cls', 'execute', 'gref', 'ipm', 'iris_ipm', 'lock', 'os', 'ref', 'routine', 'sql', 'system', 'tcommit', 'tlevel', 'trollback', 'trollbackone', 'tstart', 'unlock', 'utils']
|
|
6
|
-
def check_status(self, status):
|
|
7
|
-
"""
|
|
8
|
-
Raises an exception on an error status, or returns None if no error condition occurs.
|
|
9
|
-
Example: iris.check_status(st) checks the status code st to see if it contains an error.
|
|
10
|
-
"""
|
|
11
|
-
def cls(self, class_name):
|
|
12
|
-
"""
|
|
13
|
-
Returns a reference to an InterSystems IRIS class.
|
|
14
|
-
Example: iris.cls("%SYSTEM.INetInfo").LocalHostName() calls a method in the class %SYSTEM.INetInfo.
|
|
15
|
-
"""
|
|
16
|
-
def execute(self, statements):
|
|
17
|
-
"""
|
|
18
|
-
execute IRIS statements.
|
|
19
|
-
Example: iris.execute("set x="Hello"\nw x,!\n") returns nothing.
|
|
20
|
-
"""
|
|
21
|
-
def gref(self, global_name) -> global_ref:
|
|
22
|
-
"""
|
|
23
|
-
Returns a reference to an InterSystems IRIS global.
|
|
24
|
-
Example: g = iris.gref("^foo") sets g to a reference to global ^foo
|
|
25
|
-
"""
|
|
26
|
-
def lock(self, lock_list, timeout_value, locktype):
|
|
27
|
-
"""
|
|
28
|
-
Sets locks, given a list of lock names, an optional timeout value (in seconds), and an optional locktype.
|
|
29
|
-
Example: iris.lock(["^foo","^bar"], 30, "S") sets locks "^foo" and "^bar", waiting up to 30 seconds, and using shared locks.
|
|
30
|
-
"""
|
|
31
|
-
def ref(self, value):
|
|
32
|
-
"""
|
|
33
|
-
Creates an iris.ref object with a specified value.
|
|
34
|
-
Example: iris.ref("hello") creates an iris.ref object with the value "hello"
|
|
35
|
-
"""
|
|
36
|
-
def routine(self, routine, args):
|
|
37
|
-
"""
|
|
38
|
-
Invokes an InterSystems IRIS routine, optionally at a given tag.
|
|
39
|
-
Example: iris.routine("Stop^SystemPerformance", "20211221_160620_test") calls tag Stop in routine ^SystemPerformance.
|
|
40
|
-
"""
|
|
41
|
-
def tcommit(self):
|
|
42
|
-
"""
|
|
43
|
-
Marks a successful end of an InterSystems IRIS transaction.
|
|
44
|
-
Example: iris.commit() marks the successful end of a transaction and decrements the nesting level by 1
|
|
45
|
-
"""
|
|
46
|
-
def tlevel(self):
|
|
47
|
-
"""
|
|
48
|
-
Detects whether a transaction is currently in progress and returns the nesting level. Zero means not in a transaction.
|
|
49
|
-
Example: iris.tlevel() returns the current transaction nesting level, or zero if not in a transaction
|
|
50
|
-
"""
|
|
51
|
-
def trollback(self):
|
|
52
|
-
"""
|
|
53
|
-
Terminates the current transaction and restores all journaled database values to their values at the start of the transaction.
|
|
54
|
-
Example: iris.trollback() rolls back all current transactions in progress and resets the transaction nesting level to 0
|
|
55
|
-
"""
|
|
56
|
-
def trollbackone(self):
|
|
57
|
-
"""
|
|
58
|
-
Rolls back the current level of nested transactions, that is, the one initiated by the most recent tstart().
|
|
59
|
-
Example: iris.trollbackone() rolls back the current level of nested transactions and decrements the nesting level by 1
|
|
60
|
-
"""
|
|
61
|
-
def tstart(self):
|
|
62
|
-
"""
|
|
63
|
-
Starts an InterSystems IRIS transaction.
|
|
64
|
-
Example: iris.tstart() marks the beginning of a transaction.
|
|
65
|
-
"""
|
|
66
|
-
def unlock(self, lock_list, timout_value, locktype):
|
|
67
|
-
"""
|
|
68
|
-
Removes locks, given a list of lock names, an optional timeout value (in seconds), and an optional locktype.
|
|
69
|
-
Example: iris.unlock(["^foo","^bar"], 30, "S") removes locks "^foo" and "^bar", waiting up to 30 seconds, and using shared locks.
|
|
70
|
-
"""
|
|
71
|
-
def utils(self):
|
|
72
|
-
"""
|
|
73
|
-
Returns a reference to the InterSystems IRIS utilities class.
|
|
74
|
-
Example: iris.utils().$Job() returns the current job number.
|
|
75
|
-
"""
|
|
76
|
-
# Stubs for the gref object
|
|
77
|
-
class global_ref:
|
|
78
|
-
def data(self, key):
|
|
79
|
-
"""
|
|
80
|
-
Checks if a node of a global contains data and/or has descendants. The key of the node is passed as a list. Passing a key with the
|
|
81
|
-
value None (or an empty list) indicates the root node of the global.\n
|
|
82
|
-
You can use data() to inspect a node to see if it contains data before attempting to access that data and possibly encountering an error.
|
|
83
|
-
The method returns 0 if the node is undefined (contains no data), 1 if the node is defined (contains data), 10 if the node is undefined
|
|
84
|
-
but has descendants, or 11 if the node is defined and has descendants.
|
|
85
|
-
"""
|
|
86
|
-
def get(self, key):
|
|
87
|
-
"""
|
|
88
|
-
Gets the value stored at a node of a global. The key of the node is passed as a list. Passing a key with the value None (or an empty list)
|
|
89
|
-
indicates the root node of the global.
|
|
90
|
-
"""
|
|
91
|
-
def getAsBytes(self, key):
|
|
92
|
-
"""
|
|
93
|
-
Gets a string value stored at a node of a global and converts it to the Python bytes data type. The key of the node is passed as a list.
|
|
94
|
-
Passing a key with the value None (or an empty list) indicates the root node of the global.
|
|
95
|
-
"""
|
|
96
|
-
def keys(self, key):
|
|
97
|
-
"""
|
|
98
|
-
Returns the keys of a global, starting from a given key. The starting key is passed as a list. Passing an empty list indicates the root node of the global.
|
|
99
|
-
"""
|
|
100
|
-
def kill(self, key):
|
|
101
|
-
"""
|
|
102
|
-
Deletes the node of a global, if it exists. The key of the node is passed as a list. This also deletes any descendants of the node.
|
|
103
|
-
Passing a key with the value None (or an empty list) indicates the root node of the global.
|
|
104
|
-
"""
|
|
105
|
-
def order(self, key):
|
|
106
|
-
"""
|
|
107
|
-
Returns the next key in that level of the global, starting from a given key. The starting key is passed as a list.
|
|
108
|
-
If no key follows the starting key, order() returns None.
|
|
109
|
-
"""
|
|
110
|
-
def orderiter(self, key):
|
|
111
|
-
"""
|
|
112
|
-
Returns the keys and values of a global, starting from a given key, down to the next leaf node.
|
|
113
|
-
The starting key is passed as a list. Passing an empty list indicates the root node of the global.
|
|
114
|
-
"""
|
|
115
|
-
def query(self, key):
|
|
116
|
-
"""
|
|
117
|
-
Traverses a global starting at the specified key, returning each key and value.
|
|
118
|
-
The starting key is passed as a list. Passing an empty list indicates the root node of the global.
|
|
119
|
-
"""
|
|
120
|
-
def set(self, key, value):
|
|
121
|
-
"""
|
|
122
|
-
Sets a node in a global to a given value. The key of the node is passed as a list, and value is the value to be stored.
|
|
123
|
-
Passing a key with the value None (or an empty list) indicates the root node of the global.
|
|
124
|
-
"""
|
|
125
|
-
# stubs for the sql object
|
|
126
|
-
class sql:
|
|
127
|
-
"""
|
|
128
|
-
The sql object provides access to the InterSystems IRIS SQL API.
|
|
129
|
-
"""
|
|
130
|
-
def exec(self, query: str) -> Any:
|
|
131
|
-
"""
|
|
132
|
-
Execute a query
|
|
133
|
-
"""
|
|
134
|
-
def prepare(self, query: str) -> PreparedQuery:
|
|
135
|
-
"""
|
|
136
|
-
Prepare a query
|
|
137
|
-
"""
|
|
138
|
-
class PreparedQuery:
|
|
139
|
-
def execute(self, **kwargs) -> Any:
|
|
140
|
-
"""
|
|
141
|
-
Execute a prepared query, you can pass values
|
|
142
|
-
"""
|
|
143
|
-
# stubs for the system object
|
|
144
|
-
class system:
|
|
145
|
-
"""
|
|
146
|
-
The system object provides access to the InterSystems IRIS system API.
|
|
147
|
-
The following classes are available:
|
|
148
|
-
'DocDB', 'Encryption', 'Error', 'Event', 'Monitor', 'Process', 'Python', 'SQL', 'SYS', 'Security', 'Semaphore', 'Status', 'Util', 'Version'
|
|
149
|
-
"""
|
|
150
|
-
class DocDB:
|
|
151
|
-
"""
|
|
152
|
-
The DocDB class provides access to the InterSystems IRIS Document Database API.
|
|
153
|
-
The following methods are available:
|
|
154
|
-
'CreateDatabase', 'DropAllDatabases', 'DropDatabase', 'Exists', 'GetAllDatabases', 'GetDatabase', 'Help'
|
|
155
|
-
"""
|
|
156
|
-
def CreateDatabase(self, name: str, path: str, **kwargs) -> Any:
|
|
157
|
-
"""
|
|
158
|
-
Create a database
|
|
159
|
-
"""
|
|
160
|
-
def DropAllDatabases(self) -> Any:
|
|
161
|
-
"""
|
|
162
|
-
Drop all databases
|
|
163
|
-
"""
|
|
164
|
-
def DropDatabase(self, name: str) -> Any:
|
|
165
|
-
"""
|
|
166
|
-
Drop a database
|
|
167
|
-
"""
|
|
168
|
-
def Exists(self, name: str) -> Any:
|
|
169
|
-
"""
|
|
170
|
-
Check if a database exists
|
|
171
|
-
"""
|
|
172
|
-
def GetAllDatabases(self) -> Any:
|
|
173
|
-
"""
|
|
174
|
-
Get all databases
|
|
175
|
-
"""
|
|
176
|
-
def GetDatabase(self, name: str) -> Any:
|
|
177
|
-
"""
|
|
178
|
-
Get a database
|
|
179
|
-
"""
|
|
180
|
-
def Help(self) -> Any:
|
|
181
|
-
"""
|
|
182
|
-
Get help
|
|
183
|
-
"""
|
|
184
|
-
def Encryption(self) -> Any:
|
|
185
|
-
"""
|
|
186
|
-
The Encryption class provides access to the InterSystems IRIS Encryption API.
|
|
187
|
-
"""
|
|
188
|
-
def Error(self) -> Any:
|
|
189
|
-
"""
|
|
190
|
-
The Error class provides access to the InterSystems IRIS Error API.
|
|
191
|
-
"""
|
|
192
|
-
def Event(self) -> Any:
|
|
193
|
-
"""
|
|
194
|
-
The Event class provides access to the InterSystems IRIS Event API.
|
|
195
|
-
"""
|
|
196
|
-
def Monitor(self) -> Any:
|
|
197
|
-
"""
|
|
198
|
-
The Monitor class provides access to the InterSystems IRIS Monitor API.
|
|
199
|
-
"""
|
|
200
|
-
def Process(self) -> Any:
|
|
201
|
-
"""
|
|
202
|
-
The Process class provides access to the InterSystems IRIS Process API.
|
|
203
|
-
"""
|
|
204
|
-
def Python(self) -> Any:
|
|
205
|
-
"""
|
|
206
|
-
The Python class provides access to the InterSystems IRIS Python API.
|
|
207
|
-
"""
|
|
208
|
-
def SQL(self) -> Any:
|
|
209
|
-
"""
|
|
210
|
-
The SQL class provides access to the InterSystems IRIS SQL API.
|
|
211
|
-
"""
|
|
212
|
-
def SYS(self) -> Any:
|
|
213
|
-
"""
|
|
214
|
-
The SYS class provides access to the InterSystems IRIS SYS API.
|
|
215
|
-
"""
|
|
216
|
-
def Security(self) -> Any:
|
|
217
|
-
"""
|
|
218
|
-
The Security class provides access to the InterSystems IRIS Security API.
|
|
219
|
-
"""
|
|
220
|
-
def Semaphore(self) -> Any:
|
|
221
|
-
"""
|
|
222
|
-
The Semaphore class provides access to the InterSystems IRIS Semaphore API.
|
|
223
|
-
"""
|
|
224
|
-
def Status(self) -> Any:
|
|
225
|
-
"""
|
|
226
|
-
The Status class provides access to the InterSystems IRIS Status API.
|
|
227
|
-
"""
|
|
228
|
-
def Util(self) -> Any:
|
|
229
|
-
"""
|
|
230
|
-
The Util class provides access to the InterSystems IRIS Util API.
|
|
231
|
-
"""
|
|
232
|
-
def Version(self) -> Any:
|
|
233
|
-
"""
|
|
234
|
-
The Version class provides access to the InterSystems IRIS Version API.
|
|
235
|
-
"""
|
|
236
|
-
|
iris/_cli.py
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import sys
|
|
3
|
-
import argparse
|
|
4
|
-
|
|
5
|
-
from . import iris_utils
|
|
6
|
-
import iris
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def bind():
|
|
10
|
-
parser = argparse.ArgumentParser()
|
|
11
|
-
parser.add_argument("--namespace", default="")
|
|
12
|
-
|
|
13
|
-
args = parser.parse_args()
|
|
14
|
-
|
|
15
|
-
libpython = iris_utils.find_libpython()
|
|
16
|
-
if not libpython:
|
|
17
|
-
raise RuntimeError("libpython not found")
|
|
18
|
-
|
|
19
|
-
iris.system.Process.SetNamespace("%SYS")
|
|
20
|
-
config = iris.cls("Config.config").Open()
|
|
21
|
-
|
|
22
|
-
# Set the new libpython path
|
|
23
|
-
config.PythonRuntimeLibrary = libpython
|
|
24
|
-
# Set the new PythonPath to VIRTUAL_ENV + "/lib" + "/python+" + sys.version[:4] + "/site-packages
|
|
25
|
-
config.PythonPath = os.path.join(os.environ["VIRTUAL_ENV"], "lib", "python" + sys.version[:4], "site-packages")
|
|
26
|
-
|
|
27
|
-
config._Save()
|
|
28
|
-
|
|
29
|
-
def unbind():
|
|
30
|
-
iris.system.Process.SetNamespace("%SYS")
|
|
31
|
-
config = iris.cls("Config.config").Open()
|
|
32
|
-
|
|
33
|
-
# Set the new libpython path
|
|
34
|
-
config.PythonRuntimeLibrary = ""
|
|
35
|
-
# Set the new PythonPath to VIRTUAL_ENV + "/lib" + "/python+" + sys.version[:4] + "/site-packages
|
|
36
|
-
config.PythonPath = ""
|
|
37
|
-
|
|
38
|
-
config._Save()
|
iris/iris_ipm.py
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
def ipm(cmd, *args):
|
|
2
|
-
"""
|
|
3
|
-
Executes shell command with IPM:
|
|
4
|
-
Parameters
|
|
5
|
-
----------
|
|
6
|
-
cmd : str
|
|
7
|
-
The command to execute
|
|
8
|
-
Examples
|
|
9
|
-
--------
|
|
10
|
-
`ipm('help')`
|
|
11
|
-
`ipm('load /home/irisowner/dev -v')`
|
|
12
|
-
`ipm('install webterminal')`
|
|
13
|
-
"""
|
|
14
|
-
|
|
15
|
-
import multiprocessing
|
|
16
|
-
import iris
|
|
17
|
-
|
|
18
|
-
def shell(cmd, status):
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
status.put(True)
|
|
22
|
-
|
|
23
|
-
res = iris.cls("%ZPM.PackageManager").Shell(cmd)
|
|
24
|
-
print('')
|
|
25
|
-
if res != 1:
|
|
26
|
-
status.get()
|
|
27
|
-
status.put(False)
|
|
28
|
-
|
|
29
|
-
manager = multiprocessing.Manager()
|
|
30
|
-
status = manager.Queue()
|
|
31
|
-
process = multiprocessing.Process(
|
|
32
|
-
target=shell,
|
|
33
|
-
args=(
|
|
34
|
-
cmd,
|
|
35
|
-
status,
|
|
36
|
-
),
|
|
37
|
-
)
|
|
38
|
-
process.start()
|
|
39
|
-
process.join()
|
|
40
|
-
return status.get()
|
iris/iris_ipm.pyi
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from __future__ import annotations
|
|
2
|
-
__all__ = ['ipm']
|
|
3
|
-
def ipm(cmd, *args):
|
|
4
|
-
"""
|
|
5
|
-
|
|
6
|
-
Executes shell command with IPM:
|
|
7
|
-
Parameters
|
|
8
|
-
----------
|
|
9
|
-
cmd : str
|
|
10
|
-
The command to execute
|
|
11
|
-
Examples
|
|
12
|
-
--------
|
|
13
|
-
`ipm('help')`
|
|
14
|
-
`ipm('load /home/irisowner/dev -v')`
|
|
15
|
-
`ipm('install webterminal')`
|
|
16
|
-
|
|
17
|
-
"""
|
iris/iris_utils.py
DELETED
|
@@ -1,336 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Locate libpython associated with this Python executable.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
# License
|
|
6
|
-
#
|
|
7
|
-
# Copyright 2018, Takafumi Arakaki
|
|
8
|
-
#
|
|
9
|
-
# Permission is hereby granted, free of charge, to any person obtaining
|
|
10
|
-
# a copy of this software and associated documentation files (the
|
|
11
|
-
# "Software"), to deal in the Software without restriction, including
|
|
12
|
-
# without limitation the rights to use, copy, modify, merge, publish,
|
|
13
|
-
# distribute, sublicense, and/or sell copies of the Software, and to
|
|
14
|
-
# permit persons to whom the Software is furnished to do so, subject to
|
|
15
|
-
# the following conditions:
|
|
16
|
-
#
|
|
17
|
-
# The above copyright notice and this permission notice shall be
|
|
18
|
-
# included in all copies or substantial portions of the Software.
|
|
19
|
-
#
|
|
20
|
-
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
21
|
-
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
22
|
-
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
23
|
-
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
24
|
-
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
25
|
-
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
26
|
-
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
27
|
-
|
|
28
|
-
from __future__ import print_function, absolute_import
|
|
29
|
-
|
|
30
|
-
from logging import getLogger
|
|
31
|
-
import ctypes.util
|
|
32
|
-
import functools
|
|
33
|
-
import os
|
|
34
|
-
import sys
|
|
35
|
-
import sysconfig
|
|
36
|
-
import re
|
|
37
|
-
|
|
38
|
-
logger = getLogger("find_libpython")
|
|
39
|
-
|
|
40
|
-
is_windows = os.name == "nt"
|
|
41
|
-
is_apple = sys.platform == "darwin"
|
|
42
|
-
|
|
43
|
-
SHLIB_SUFFIX = sysconfig.get_config_var("SHLIB_SUFFIX")
|
|
44
|
-
if SHLIB_SUFFIX is None:
|
|
45
|
-
if is_windows:
|
|
46
|
-
SHLIB_SUFFIX = ".dll"
|
|
47
|
-
else:
|
|
48
|
-
SHLIB_SUFFIX = ".so"
|
|
49
|
-
if is_apple:
|
|
50
|
-
# sysconfig.get_config_var("SHLIB_SUFFIX") can be ".so" in macOS.
|
|
51
|
-
# Let's not use the value from sysconfig.
|
|
52
|
-
SHLIB_SUFFIX = ".dylib"
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def linked_libpython():
|
|
56
|
-
"""
|
|
57
|
-
Find the linked libpython using dladdr (in *nix).
|
|
58
|
-
|
|
59
|
-
Calling this in Windows always return `None` at the moment.
|
|
60
|
-
|
|
61
|
-
Returns
|
|
62
|
-
-------
|
|
63
|
-
path : str or None
|
|
64
|
-
A path to linked libpython. Return `None` if statically linked.
|
|
65
|
-
"""
|
|
66
|
-
if is_windows:
|
|
67
|
-
return None
|
|
68
|
-
return _linked_libpython_unix()
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
class Dl_info(ctypes.Structure):
|
|
72
|
-
_fields_ = [
|
|
73
|
-
("dli_fname", ctypes.c_char_p),
|
|
74
|
-
("dli_fbase", ctypes.c_void_p),
|
|
75
|
-
("dli_sname", ctypes.c_char_p),
|
|
76
|
-
("dli_saddr", ctypes.c_void_p),
|
|
77
|
-
]
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
def _linked_libpython_unix():
|
|
81
|
-
libdl = ctypes.CDLL(ctypes.util.find_library("dl"))
|
|
82
|
-
libdl.dladdr.argtypes = [ctypes.c_void_p, ctypes.POINTER(Dl_info)]
|
|
83
|
-
libdl.dladdr.restype = ctypes.c_int
|
|
84
|
-
|
|
85
|
-
dlinfo = Dl_info()
|
|
86
|
-
retcode = libdl.dladdr(
|
|
87
|
-
ctypes.cast(ctypes.pythonapi.Py_GetVersion, ctypes.c_void_p),
|
|
88
|
-
ctypes.pointer(dlinfo))
|
|
89
|
-
if retcode == 0: # means error
|
|
90
|
-
return None
|
|
91
|
-
path = os.path.realpath(dlinfo.dli_fname.decode())
|
|
92
|
-
if path == os.path.realpath(sys.executable):
|
|
93
|
-
return None
|
|
94
|
-
return path
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
def library_name(name, suffix=SHLIB_SUFFIX, is_windows=is_windows):
|
|
98
|
-
"""
|
|
99
|
-
Convert a file basename `name` to a library name (no "lib" and ".so" etc.)
|
|
100
|
-
|
|
101
|
-
>>> library_name("libpython3.7m.so") # doctest: +SKIP
|
|
102
|
-
'python3.7m'
|
|
103
|
-
>>> library_name("libpython3.7m.so", suffix=".so", is_windows=False)
|
|
104
|
-
'python3.7m'
|
|
105
|
-
>>> library_name("libpython3.7m.dylib", suffix=".dylib", is_windows=False)
|
|
106
|
-
'python3.7m'
|
|
107
|
-
>>> library_name("python37.dll", suffix=".dll", is_windows=True)
|
|
108
|
-
'python37'
|
|
109
|
-
"""
|
|
110
|
-
if not is_windows and name.startswith("lib"):
|
|
111
|
-
name = name[len("lib"):]
|
|
112
|
-
if suffix and name.endswith(suffix):
|
|
113
|
-
name = name[:-len(suffix)]
|
|
114
|
-
return name
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def append_truthy(list, item):
|
|
118
|
-
if item:
|
|
119
|
-
list.append(item)
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
def uniquifying(items):
|
|
123
|
-
"""
|
|
124
|
-
Yield items while excluding the duplicates and preserving the order.
|
|
125
|
-
|
|
126
|
-
>>> list(uniquifying([1, 2, 1, 2, 3]))
|
|
127
|
-
[1, 2, 3]
|
|
128
|
-
"""
|
|
129
|
-
seen = set()
|
|
130
|
-
for x in items:
|
|
131
|
-
if x not in seen:
|
|
132
|
-
yield x
|
|
133
|
-
seen.add(x)
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def uniquified(func):
|
|
137
|
-
""" Wrap iterator returned from `func` by `uniquifying`. """
|
|
138
|
-
@functools.wraps(func)
|
|
139
|
-
def wrapper(*args, **kwds):
|
|
140
|
-
return uniquifying(func(*args, **kwds))
|
|
141
|
-
return wrapper
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
@uniquified
|
|
145
|
-
def candidate_names(suffix=SHLIB_SUFFIX):
|
|
146
|
-
"""
|
|
147
|
-
Iterate over candidate file names of libpython.
|
|
148
|
-
|
|
149
|
-
Yields
|
|
150
|
-
------
|
|
151
|
-
name : str
|
|
152
|
-
Candidate name libpython.
|
|
153
|
-
"""
|
|
154
|
-
LDLIBRARY = sysconfig.get_config_var("LDLIBRARY")
|
|
155
|
-
if LDLIBRARY:
|
|
156
|
-
yield LDLIBRARY
|
|
157
|
-
|
|
158
|
-
LIBRARY = sysconfig.get_config_var("LIBRARY")
|
|
159
|
-
if LIBRARY:
|
|
160
|
-
yield os.path.splitext(LIBRARY)[0] + suffix
|
|
161
|
-
|
|
162
|
-
dlprefix = "" if is_windows else "lib"
|
|
163
|
-
sysdata = dict(
|
|
164
|
-
v=sys.version_info,
|
|
165
|
-
# VERSION is X.Y in Linux/macOS and XY in Windows:
|
|
166
|
-
VERSION=(sysconfig.get_config_var("VERSION") or
|
|
167
|
-
"{v.major}.{v.minor}".format(v=sys.version_info)),
|
|
168
|
-
ABIFLAGS=(sysconfig.get_config_var("ABIFLAGS") or
|
|
169
|
-
sysconfig.get_config_var("abiflags") or ""),
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
for stem in [
|
|
173
|
-
"python{VERSION}{ABIFLAGS}".format(**sysdata),
|
|
174
|
-
"python{VERSION}".format(**sysdata),
|
|
175
|
-
"python{v.major}".format(**sysdata),
|
|
176
|
-
"python",
|
|
177
|
-
]:
|
|
178
|
-
yield dlprefix + stem + suffix
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
@uniquified
|
|
183
|
-
def candidate_paths(suffix=SHLIB_SUFFIX):
|
|
184
|
-
"""
|
|
185
|
-
Iterate over candidate paths of libpython.
|
|
186
|
-
|
|
187
|
-
Yields
|
|
188
|
-
------
|
|
189
|
-
path : str or None
|
|
190
|
-
Candidate path to libpython. The path may not be a fullpath
|
|
191
|
-
and may not exist.
|
|
192
|
-
"""
|
|
193
|
-
|
|
194
|
-
yield linked_libpython()
|
|
195
|
-
|
|
196
|
-
# List candidates for directories in which libpython may exist
|
|
197
|
-
lib_dirs = []
|
|
198
|
-
append_truthy(lib_dirs, sysconfig.get_config_var('LIBPL'))
|
|
199
|
-
append_truthy(lib_dirs, sysconfig.get_config_var('srcdir'))
|
|
200
|
-
append_truthy(lib_dirs, sysconfig.get_config_var("LIBDIR"))
|
|
201
|
-
|
|
202
|
-
# LIBPL seems to be the right config_var to use. It is the one
|
|
203
|
-
# used in python-config when shared library is not enabled:
|
|
204
|
-
# https://github.com/python/cpython/blob/v3.7.0/Misc/python-config.in#L55-L57
|
|
205
|
-
#
|
|
206
|
-
# But we try other places just in case.
|
|
207
|
-
|
|
208
|
-
if is_windows:
|
|
209
|
-
lib_dirs.append(os.path.join(os.path.dirname(sys.executable)))
|
|
210
|
-
else:
|
|
211
|
-
lib_dirs.append(os.path.join(
|
|
212
|
-
os.path.dirname(os.path.dirname(sys.executable)),
|
|
213
|
-
"lib"))
|
|
214
|
-
|
|
215
|
-
# For macOS:
|
|
216
|
-
append_truthy(lib_dirs, sysconfig.get_config_var("PYTHONFRAMEWORKPREFIX"))
|
|
217
|
-
|
|
218
|
-
lib_dirs.append(sys.exec_prefix)
|
|
219
|
-
lib_dirs.append(os.path.join(sys.exec_prefix, "lib"))
|
|
220
|
-
|
|
221
|
-
lib_basenames = list(candidate_names(suffix=suffix))
|
|
222
|
-
|
|
223
|
-
for directory in lib_dirs:
|
|
224
|
-
for basename in lib_basenames:
|
|
225
|
-
yield os.path.join(directory, basename)
|
|
226
|
-
|
|
227
|
-
# In macOS and Windows, ctypes.util.find_library returns a full path:
|
|
228
|
-
for basename in lib_basenames:
|
|
229
|
-
yield ctypes.util.find_library(library_name(basename))
|
|
230
|
-
|
|
231
|
-
# Possibly useful links:
|
|
232
|
-
# * https://packages.ubuntu.com/bionic/amd64/libpython3.6/filelist
|
|
233
|
-
# * https://github.com/Valloric/ycmd/issues/518
|
|
234
|
-
# * https://github.com/Valloric/ycmd/pull/519
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
def normalize_path(path, suffix=SHLIB_SUFFIX, is_apple=is_apple):
|
|
238
|
-
"""
|
|
239
|
-
Normalize shared library `path` to a real path.
|
|
240
|
-
|
|
241
|
-
If `path` is not a full path, `None` is returned. If `path` does
|
|
242
|
-
not exists, append `SHLIB_SUFFIX` and check if it exists.
|
|
243
|
-
Finally, the path is canonicalized by following the symlinks.
|
|
244
|
-
|
|
245
|
-
Parameters
|
|
246
|
-
----------
|
|
247
|
-
path : str ot None
|
|
248
|
-
A candidate path to a shared library.
|
|
249
|
-
"""
|
|
250
|
-
if not path:
|
|
251
|
-
return None
|
|
252
|
-
if not os.path.isabs(path):
|
|
253
|
-
return None
|
|
254
|
-
if os.path.exists(path):
|
|
255
|
-
return os.path.realpath(path)
|
|
256
|
-
if os.path.exists(path + suffix):
|
|
257
|
-
return os.path.realpath(path + suffix)
|
|
258
|
-
if is_apple:
|
|
259
|
-
return normalize_path(_remove_suffix_apple(path),
|
|
260
|
-
suffix=".so", is_apple=False)
|
|
261
|
-
return None
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
def _remove_suffix_apple(path):
|
|
265
|
-
"""
|
|
266
|
-
Strip off .so or .dylib.
|
|
267
|
-
|
|
268
|
-
>>> _remove_suffix_apple("libpython.so")
|
|
269
|
-
'libpython'
|
|
270
|
-
>>> _remove_suffix_apple("libpython.dylib")
|
|
271
|
-
'libpython'
|
|
272
|
-
>>> _remove_suffix_apple("libpython3.7")
|
|
273
|
-
'libpython3.7'
|
|
274
|
-
"""
|
|
275
|
-
if path.endswith(".dylib"):
|
|
276
|
-
return path[:-len(".dylib")]
|
|
277
|
-
if path.endswith(".so"):
|
|
278
|
-
return path[:-len(".so")]
|
|
279
|
-
return path
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
@uniquified
|
|
283
|
-
def finding_libpython():
|
|
284
|
-
"""
|
|
285
|
-
Iterate over existing libpython paths.
|
|
286
|
-
|
|
287
|
-
The first item is likely to be the best one.
|
|
288
|
-
|
|
289
|
-
Yields
|
|
290
|
-
------
|
|
291
|
-
path : str
|
|
292
|
-
Existing path to a libpython.
|
|
293
|
-
"""
|
|
294
|
-
logger.debug("is_windows = %s", is_windows)
|
|
295
|
-
logger.debug("is_apple = %s", is_apple)
|
|
296
|
-
for path in candidate_paths():
|
|
297
|
-
logger.debug("Candidate: %s", path)
|
|
298
|
-
normalized = normalize_path(path)
|
|
299
|
-
if normalized:
|
|
300
|
-
logger.debug("Found: %s", normalized)
|
|
301
|
-
yield normalized
|
|
302
|
-
else:
|
|
303
|
-
logger.debug("Not found.")
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
def find_libpython():
|
|
307
|
-
"""
|
|
308
|
-
Return a path (`str`) to libpython or `None` if not found.
|
|
309
|
-
|
|
310
|
-
Parameters
|
|
311
|
-
----------
|
|
312
|
-
path : str or None
|
|
313
|
-
Existing path to the (supposedly) correct libpython.
|
|
314
|
-
"""
|
|
315
|
-
for path in finding_libpython():
|
|
316
|
-
return os.path.realpath(path)
|
|
317
|
-
|
|
318
|
-
def update_dynalib_path(dynalib_path):
|
|
319
|
-
# Determine the environment variable based on the operating system
|
|
320
|
-
env_var = 'PATH'
|
|
321
|
-
if not sys.platform.startswith('win'):
|
|
322
|
-
if sys.platform == 'darwin':
|
|
323
|
-
env_var = 'DYLD_LIBRARY_PATH'
|
|
324
|
-
else:
|
|
325
|
-
env_var = 'LD_LIBRARY_PATH'
|
|
326
|
-
|
|
327
|
-
# Get the current value of the environment variable
|
|
328
|
-
current_paths = os.environ.get(env_var, '')
|
|
329
|
-
|
|
330
|
-
# Update the environment variable by appending the dynalib path
|
|
331
|
-
# Note: You can prepend instead by reversing the order in the join
|
|
332
|
-
new_paths = f"{current_paths}:{dynalib_path}" if current_paths else dynalib_path
|
|
333
|
-
|
|
334
|
-
# Update the environment variable
|
|
335
|
-
os.environ[env_var] = new_paths
|
|
336
|
-
|
{iris_pex_embedded_python-3.1.3.dist-info → iris_pex_embedded_python-3.1.4.dist-info}/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|