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.

@@ -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: self._iris_install_dir = 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.utcfromtimestamp(time).replace(tzinfo=None)
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__(self, connection, columns=None, rowcount=0, ):
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('Row', [col.name for col in self._columns], rename=True)
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 == 'None' and _column.schema == 'None':
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("Row incomplete: " + str(self.colCount) +
289
- " items expected, but " + str(i) + " were found")
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("Row incomplete: " + str(self.colCount) +
323
- " items expected, but " + str(i) + " were found")
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
- params += [token.Lexeme]
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 += ' '
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: iris_pex_embedded_python
3
- Version: 3.1.3
3
+ Version: 3.1.4
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License
@@ -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=Xr6sOPy3uKFyOG05hTmutDHTNjHDhCnCVwH0TTNEwBE,1896
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=sqkUxjhK683icHlE56ywygV8ODz7yudeIJOQSQTeb78,102938
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=2dLyHhP46BncGw--qEdLV1twphk69P5SFPMyEYNAwFo,13494
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=024w-s3n_JNsk_ISC8avJMK3QEZE3hSuD0Nr8arJdZw,78828
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.3.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
139
- iris_pex_embedded_python-3.1.3.dist-info/METADATA,sha256=tOAb3jq9OHmTL3V9-G8pqf-BqQyFh5GlMsTzRdkcFpA,50120
140
- iris_pex_embedded_python-3.1.3.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
141
- iris_pex_embedded_python-3.1.3.dist-info/entry_points.txt,sha256=pj-i4LSDyiSP6xpHlVjMCbg1Pik7dC3_sdGY3Yp9Vhk,38
142
- iris_pex_embedded_python-3.1.3.dist-info/top_level.txt,sha256=jkWtvFKOp1Q-uO_VpGpfx5TcW7DS39z1liOAVp6zLig,47
143
- iris_pex_embedded_python-3.1.3.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (75.3.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,5 +1,4 @@
1
1
  grongier
2
2
  intersystems_iris
3
3
  iop
4
- iris
5
4
  irisnative
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
-