iris-pex-embedded-python 2.3.22b3__py3-none-any.whl → 2.3.23b2__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,4 +1,4 @@
1
- Class Grongier.Service.WSGI Extends (%RegisteredObject, %CSP.REST) [ ServerOnly = 1 ]
1
+ Class Grongier.Service.WSGI Extends %CSP.REST [ ServerOnly = 1 ]
2
2
  {
3
3
 
4
4
  Parameter CLASSPATHS;
@@ -7,99 +7,304 @@ Parameter MODULENAME;
7
7
 
8
8
  Parameter APPNAME;
9
9
 
10
- /// Helper method to write data to the output stream
11
- ClassMethod write(data)
12
- {
13
- w data
14
- }
10
+ Parameter DEVMODE = 1;
15
11
 
16
- /// Helper to build the environ
17
- ClassMethod GetEnviron() As %SYS.Python
12
+ /// This method matches the request and method and calls the dispatcher
13
+ ClassMethod Page(skipheader As %Boolean = 0) As %Status [ ProcedureBlock = 1 ]
18
14
  {
19
- //set builtins
20
- set builtins = ##class(%SYS.Python).Import("builtins")
15
+ #dim tSC As %Status = $$$OK
16
+ #dim e As %Exception.AbstractException
17
+
18
+ #dim tAuthorized,tRedirected As %Boolean
19
+ #dim tRedirectRoutine,tURL As %String = ""
20
+ #dim %response As %CSP.Response
21
+
22
+ Try {
21
23
 
22
- //import dict to create environ
23
- set dict = builtins.dict()
24
+ #; Ensure that we honor the requested charset
25
+ Set %response.CharSet=..#CHARSET
24
26
 
25
- #dim %request As %CSP.Request
27
+ #; Ensure that we honor the requested CONTENTTYPE
28
+ If ..#CONTENTTYPE'="" Set %response.ContentType=..#CONTENTTYPE
26
29
 
27
- //set environ
28
- do dict."__setitem__"("SERVER_NAME", $System.INetInfo.LocalHostName())
29
- do dict."__setitem__"("SERVER_PORT", "")
30
- do dict."__setitem__"("SERVER_PROTOCOL", "HTTP/1.1")
31
- do dict."__setitem__"("SERVER_SOFTWARE", "IRIS")
32
- do dict."__setitem__"("SCRIPT_NAME", ..#APPNAME)
33
- do dict."__setitem__"("REQUEST_METHOD", %request.Method)
34
- do dict."__setitem__"("CONTENT_TYPE", %request.ContentType)
35
- do dict."__setitem__"("CHARSET", %request.CharSet)
36
- Set app=$$getapp^%SYS.cspServer(%request.URL,.path,.match,.updatedurl)
37
- do dict."__setitem__"("PATH_INFO", $extract(updatedurl,$length(path),*))
30
+ #; Ensure that we honor the requested HTTP_ACCEPT_LANGUAGE
31
+ Set %response.Domain = ..#DOMAIN
32
+ Do %response.MatchLanguage()
33
+
34
+ #; Record if device re-direction is already active
35
+ Set tRedirected=##class(%Library.Device).ReDirectIO()
36
+
37
+ #; Record the redirect routine
38
+ Set tRedirectRoutine=$System.Device.GetMnemonicRoutine()
39
+
40
+ if ..#DEVMODE {
41
+ #; Not so pretty but help to for reload the WSGI application
42
+ do outputError^%SYS.cspServer2("","","","")
43
+ }
44
+ else {
45
+ #; Now switch to using THIS routine for device redirection
46
+ Use $io::("^%SYS.cspServer2")
38
47
 
39
- // to extract the query string
48
+ #; Switch device redirection on (may already be on but thats ok)
49
+ Do ##class(%Library.Device).ReDirectIO(1)
50
+ }
40
51
 
41
- return dict
42
- }
52
+ #; Ensure that the application is defined (security check)
53
+ If $$$GetSecurityApplicationsDispatchClass(%request.AppData)="" {
54
+
55
+ #; Report not authorized
56
+ Set tSC=..Http403()
57
+
58
+ #; Done
59
+ Quit
60
+ }
61
+
62
+ #; GgiEnvs are not defined in the CSP shell
63
+ Set tURL=$Get(%request.CgiEnvs("CSPLIB"))
64
+ If tURL="" Set tURL=%request.URL
65
+
66
+ #; Do an access check
67
+ Set tSC=..AccessCheck(.tAuthorized)
68
+ If $$$ISERR(tSC) Quit
43
69
 
44
- /// Implement a singleton pattern to get the python app
45
- ClassMethod GetPyhonApp() As %SYS.Python
46
- {
47
- if ..#CLASSPATHS '="" {
48
- set sys = ##class(%SYS.Python).Import("sys")
49
- set delimiter = $s($system.Version.GetOS()="Windows":";",1:":")
50
- set extraClasspaths = $tr(..#CLASSPATHS,delimiter,"|")
51
- for i=1:1:$l(extraClasspaths,"|") {
52
- set onePath = $p(extraClasspaths,"|",i)
53
- set onePath = ##class(%File).NormalizeDirectory(onePath)
54
- if onePath?1"$$IRISHOME"1P.E set onePath = $e($system.Util.InstallDirectory(),1,*-1)_$e(onePath,11,*)
55
- if onePath'="" do sys.path.append(onePath)
70
+ If tAuthorized=0 {
71
+
72
+ #; Don't want the session token
73
+ Set %response.OutputSessionToken=0
74
+
75
+ #; Set the Http Status
76
+ Set %response.Status=..#HTTP403FORBIDDEN
77
+
78
+ #; Done
79
+ Quit
56
80
  }
81
+
82
+ #; Extract the match url from the application name
83
+ Set tMatchUrl = "/"_$Extract(tURL,$Length(%request.Application)+1,*)
84
+
85
+ #; Dispatch the request
86
+ Set tSC=..DispatchRequest(tMatchUrl,%request.Method)
87
+
88
+ } Catch (e) {
89
+ Set tSC=e.AsStatus()
90
+ }
91
+
92
+ If $$$ISERR(tSC) {
93
+
94
+ #; Don't want the session token
95
+ Set %response.OutputSessionToken=0
96
+
97
+ Do ..Http500(##class(%Exception.StatusException).CreateFromStatus(tSC))
98
+ }
99
+
100
+ #; Ensure that at least something is written out as the body
101
+ #; This will trigger the device redirect capture and force headers to be written
102
+ #; (if not already done)
103
+ Write ""
104
+
105
+ #; Reset redirect device if necessary
106
+ If tRedirected {
107
+
108
+ #; Use the original redirected routine
109
+ Use $io::("^"_tRedirectRoutine)
110
+
111
+ #; Switch device redirection on
112
+ Do ##class(%Library.Device).ReDirectIO(1)
57
113
  }
114
+
115
+ #; Any errors should have been caught and reported
116
+ Quit $$$OK
117
+ }
58
118
 
59
- //import module
60
- set module = ##class(%SYS.Python).Import(..#MODULENAME)
119
+ ClassMethod OnPreDispatch(
120
+ pUrl As %String,
121
+ pMethod As %String,
122
+ ByRef pContinue As %Boolean) As %Status
123
+ {
124
+ Set path = ..#CLASSPATHS
125
+ Set appName = ..#APPNAME
126
+ Set module = ..#MODULENAME
127
+ Set devmode = ..#DEVMODE
128
+ Set pContinue = 1
129
+ Do ..DispatchREST(pUrl, path, appName, module, devmode)
130
+ Quit $$$OK
131
+ }
61
132
 
62
- //set builtins
63
- set builtins = ##class(%SYS.Python).Import("builtins")
133
+ ClassMethod DispatchREST(
134
+ PathInfo As %String,
135
+ appPath As %String,
136
+ appName As %String,
137
+ module As %String,
138
+ devmode As %Boolean = 1) As %Status
139
+ {
140
+ Set builtins = ##CLASS(%SYS.Python).Builtins()
141
+ Set interface = ##CLASS(%SYS.Python).Import("grongier.pex.wsgi.handlers")
142
+ Set rawformdata = ""
143
+ Set environ = builtins.dict()
144
+ Set key = %request.NextCgiEnv("")
64
145
 
65
- //set app
66
- set application = builtins.getattr(module, ..#APPNAME)
146
+ // Let's check if the WSGI application has been loaded or not for this session.
147
+
148
+ If (($DATA(%session.Data("application")) && $ISOBJECT(%session.Data("application"))) && 'devmode) {
149
+ Set application = %session.Data("Application")
150
+ }
151
+ Else{
67
152
 
68
- Return application
69
- }
153
+ Set application = ..GetPythonClass(appName, module, appPath)
154
+ If application = "" {
155
+ throw ##class(%Exception.General).%New("Error loading WSGI application: "_module_"."_appName_" from "_appPath)
156
+ }
157
+ Else {
158
+ Set %session.Data("Application") = application
159
+ }
160
+ }
70
161
 
71
- ClassMethod Page(skipheader As %Boolean = 1) As %Status [ Internal, ServerOnly = 1 ]
72
- {
73
- Try {
74
-
75
- //set environ
76
- set environ = ..GetEnviron()
162
+ // Editing some CGI variables that may be incorrect in %request
163
+ // Also filling in environ with as many CGI variables as possible from %request
164
+ // WSGI states that all CGI variables are valid and should be included if possible
165
+ While (key'="") {
166
+ Set value = %request.GetCgiEnv(key)
167
+ If key = "PATH_INFO" {
168
+ Set app=$$getapp^%SYS.cspServer(%request.URL,.path,.match,.updatedurl)
169
+ Set value = $EXTRACT(updatedurl,$LENGTH(path),*)
170
+ }
171
+ If key = "SCRIPT_NAME" {
172
+ //%request will sometimes have Script_name include Path_info
173
+ Set value = $PIECE(%request.Application, "/",1,*-1)
174
+ }
175
+ Do environ."__setitem__"(key,value)
176
+ Set key = %request.NextCgiEnv(key)
177
+ }
77
178
 
78
- //import sys
79
- set sys = ##class(%SYS.Python).Import("sys")
179
+ //Have to set up a correct wsgi.input stream from %request
180
+ Set stream = %request.Content
181
+
182
+ Set contentType = %request.ContentType
183
+ Set contentLength = 0
80
184
 
81
- //set stdin
82
- set builtins = ##class(%SYS.Python).Import("builtins")
83
- set ba = builtins.bytearray()
84
-
85
- while %request.Content.AtEnd = 0 {
86
- do ba.extend(##class(%SYS.Python).Bytes(%request.Content.Read()))
87
- }
88
- //set handler
89
- set handler = ##class(%SYS.Python).Import("grongier.pex.wsgi.handlers").IrisHandler(ba, sys.stdout, sys.stderr,environ)
185
+ If contentType = "application/x-www-form-urlencoded" {
186
+ Set formdict = builtins.dict()
187
+ Set key = $ORDER(%request.Data(""))
188
+ While (key'="") {
189
+ Set value = $GET(%request.Data(key,1))
190
+ Do formdict."__setitem__"(key,value)
191
+ Set key = $ORDER(%request.Data(key))
192
+ }
193
+ Do environ."__setitem__"("formdata", formdict)
194
+ }
195
+ ElseIf contentType = "multipart/form-data" {
196
+ Set boundary = $PIECE(%request.GetCgiEnv("CONTENT_TYPE"), "=",2)
197
+ Set stream = ##CLASS(%CSP.BinaryStream).%New()
90
198
 
91
- // get a singleton app
92
- set application = ..GetPyhonApp()
199
+ Do stream.Write($CHAR(13,10))
93
200
 
94
- //run app
95
- do handler.run(application)
201
+ //Get the Form Data values
96
202
 
97
- }
98
- Catch ex {
99
- return ex.AsStatus()
100
- }
203
+ Set key = $ORDER(%request.Data(""))
204
+ While (key'="") {
205
+ Do stream.Write("--")
206
+ Do stream.Write(boundary)
207
+ Do stream.Write($CHAR(13,10))
208
+ Set value = $GET(%request.Data(key,1))
209
+ Do stream.Write("Content-Disposition: form-data; name=")
210
+ Do stream.Write(""""_key_"""")
211
+ Do stream.Write($CHAR(13,10,13,10))
212
+ Do stream.Write(value)
213
+ Do stream.Write($CHAR(13,10))
214
+ Set key = $ORDER(%request.Data(key))
215
+ }
216
+
217
+ //Now get the possible MIME data streams
218
+ Set key = %request.NextMimeData("")
219
+ While key'="" {
220
+ Set numMimeStreams = %request.CountMimeData(key)
221
+ Set index = %request.NextMimeDataIndex(key, "")
222
+ Do stream.Write("--")
223
+ Do stream.Write(boundary)
224
+ Do stream.Write($CHAR(13,10))
225
+ If numMimeStreams > 1 {
226
+ //I need to create a boundary for a nested multipart content type
227
+ Set internalboundary = "--"
228
+ For i = 1 : 1 : 7 {
229
+ Set internalboundary = internalboundary _ $RANDOM(10)
230
+ }
231
+ While index '= "" {
232
+ Set mimestream = %request.GetMimeData(key, index)
233
+ Set headers = mimestream.Headers
234
+ Do stream.Write("--")
235
+ Do stream.Write(internalboundary)
236
+ Do stream.Write($CHAR(13,10))
237
+ Do stream.Write(headers)
238
+ Do stream.Write($CHAR(13,10,13,10))
239
+ Set sc = stream.CopyFrom(mimestream)
240
+ //TODO error handling
241
+ Do stream.Write($CHAR(13,10))
242
+ Set index = %request.NextMimeDataIndex(key, index)
243
+ }
244
+ Do stream.Write("--")
245
+ Do stream.Write(internalboundary)
246
+ Do stream.Write("--")
247
+ }
248
+ Else {
249
+ Set mimestream = %request.GetMimeData(key, index)
250
+ Set headers = mimestream.Headers
251
+ Do stream.Write(headers)
252
+ Do stream.Write($CHAR(13,10,13,10))
253
+ Set sc = stream.CopyFrom(mimestream)
254
+ //TODO error handling
255
+ Do stream.Write($CHAR(13,10))
256
+ }
257
+ Set key = %request.NextMimeData(key)
258
+ }
259
+ Do stream.Write("--")
260
+ Do stream.Write(boundary)
261
+ Do stream.Write("--")
262
+ Do stream.Rewind()
263
+ }
264
+
265
+
266
+ Try {
267
+ Do interface."make_request"(environ, stream, application, appPath)
268
+ }
269
+ Catch exception {
270
+ throw exception
271
+ }
272
+ Quit $$$OK
273
+ }
274
+
275
+ ClassMethod GetPythonClass(
276
+ pClassname As %String,
277
+ pModule As %String,
278
+ pClasspath As %String) As %SYS.Python
279
+ {
280
+ Try {
281
+ If pClasspath '="" {
282
+ set sys = ##class(%SYS.Python).Import("sys")
283
+
284
+ for i=0:1:(sys.path."__len__"()-1) {
285
+ Try {
286
+ if sys.path."__getitem__"(i) = pClasspath {
287
+ do sys.path."__delitem__"(i)
288
+ }
289
+ }
290
+ Catch ex {
291
+ // do nothing
292
+ }
293
+
294
+ }
295
+ do sys.path.insert(0, pClasspath)
296
+ }
101
297
 
102
- quit $$$OK
298
+ Set importlib = ##class(%SYS.Python).Import("importlib")
299
+ Set builtins = ##class(%SYS.Python).Import("builtins")
300
+ Set module = importlib."import_module"(pModule)
301
+ Set class = builtins.getattr(module, pClassname)
302
+ }
303
+ Catch ex {
304
+ throw ##class(%Exception.General).%New("Error loading WSGI application: "_pModule_"."_pClassname_" from "_pClasspath)
305
+ }
306
+
307
+ Quit class
103
308
  }
104
309
 
105
310
  }
@@ -1,51 +1,104 @@
1
- from wsgiref.handlers import BaseHandler
2
- import io
1
+ import os, sys, importlib, urllib.parse
2
+ from io import BytesIO
3
+
4
+ __ospath = os.getcwd()
5
+
3
6
  import iris
4
7
 
5
- class IrisHandler(BaseHandler):
6
- """Handler that's just initialized with streams, environment, etc.
8
+ os.chdir(__ospath)
9
+
10
+ enc, esc = sys.getfilesystemencoding(), 'surrogateescape'
11
+
12
+ rest_service = iris.cls('%REST.Impl')
13
+
14
+ def get_from_module(app_path, app_module, app_name):
15
+
16
+ # Add the path to the application
17
+ if (app_path not in sys.path) :
18
+ sys.path.append(app_path)
19
+
20
+ # retrieve the application
21
+ return getattr(importlib.import_module(app_module), app_name)
22
+
23
+ # Changes the current working directory to the manager directory of the instance.
24
+ def goto_manager_dir():
25
+ iris.system.Process.CurrentDirectory(iris.system.Util.ManagerDirectory())
26
+
27
+ def unicode_to_wsgi(u):
28
+ # Convert an environment variable to a WSGI "bytes-as-unicode" string
29
+ return u.encode(enc, esc).decode('iso-8859-1')
30
+
31
+ def wsgi_to_bytes(s):
32
+ return s.encode('iso-8859-1')
33
+
34
+ def write(chunk):
35
+ rest_service._WriteResponse(chunk)
36
+
37
+ def start_response(status, response_headers, exc_info=None):
38
+ '''WSGI start_response callable'''
39
+ if exc_info:
40
+ try:
41
+ raise exc_info[1].with_traceback(exc_info[2])
42
+ finally:
43
+ exc_info = None
7
44
 
8
- This handler subclass is intended for synchronous HTTP/1.0 origin servers,
9
- and handles sending the entire response output, given the correct inputs.
45
+ rest_service._SetStatusCode(status)
46
+ for tuple in response_headers:
47
+ rest_service._SetHeader(tuple[0], tuple[1])
48
+ return write
10
49
 
11
- Usage::
12
50
 
13
- handler = SimpleHandler(
14
- inp,out,err,env, multithread=False, multiprocess=True
15
- )
16
- handler.run(app)"""
51
+ # Make request to application
52
+ def make_request(environ, stream, application, path):
17
53
 
18
- server_software = "IrisWSGI/0.1"
19
- wsgi_file_wrapper = None
54
+ # Change the working directory for logging purposes
55
+ goto_manager_dir()
20
56
 
21
- def __init__(self,stdin,stdout,stderr,environ,
22
- multithread=True, multiprocess=False
23
- ):
24
- self.stdin = stdin
25
- self.stdout = stdout
26
- self.stderr = stderr
27
- self.base_env = environ
28
- self.wsgi_multithread = multithread
29
- self.wsgi_multiprocess = multiprocess
57
+ error_log_file = open('WSGI.log', 'a+')
58
+
59
+ # We want the working directory to be the app's directory
60
+ if (not path.endswith(os.path.sep)):
61
+ path = path + os.path.sep
30
62
 
31
- def get_stdin(self):
32
- if not self.stdin:
33
- return None
34
- else:
35
- self.environ["wsgi.input"] = io.BytesIO(self.stdin)
36
- self.environ["CONTENT_LENGTH"] = str(len(self.stdin))
37
- return io.BytesIO(self.stdin)
63
+ #iris.system.Process.CurrentDirectory(path)
64
+
65
+ # Set up the body of the request
66
+ if stream != '':
67
+ bytestream = stream
68
+ elif (environ['CONTENT_TYPE'] == 'application/x-www-form-urlencoded'):
69
+ bytestream = BytesIO()
70
+ part = urllib.parse.urlencode(environ['formdata'])
71
+ bytestream.write(part.encode('utf-8'))
72
+ bytestream.seek(0)
73
+ else:
74
+ bytestream = BytesIO(b'')
38
75
 
76
+ #for k,v in os.environ.items():
77
+ #environ[k] = unicode_to_wsgi(v)
78
+ environ['wsgi.input'] = bytestream
79
+ environ['wsgi.errors'] = error_log_file
80
+ environ['wsgi.version'] = (1, 0)
81
+ environ['wsgi.multithread'] = False
82
+ environ['wsgi.multiprocess'] = True
83
+ environ['wsgi.run_once'] = True
39
84
 
40
- def get_stderr(self):
41
- return self.stderr
42
85
 
43
- def add_cgi_vars(self):
44
- self.environ.update(self.base_env)
86
+ if environ.get('HTTPS', 'off') in ('on', '1'):
87
+ environ['wsgi.url_scheme'] = 'https'
88
+ else:
89
+ environ['wsgi.url_scheme'] = 'http'
90
+
91
+ # Calling WSGI application
92
+ response = application(environ, start_response)
45
93
 
46
- def _write(self,data):
47
- iris.cls('Grongier.Service.WSGI').write(data)
94
+ error_log_file.close()
48
95
 
49
- def _flush(self):
50
- self.stdout.flush()
51
- self._flush = self.stdout.flush
96
+ try:
97
+ for data in response:
98
+ if data:
99
+ # (REST.Impl).Write() needs a utf-8 string
100
+ write(data.decode('utf-8'))
101
+ write(b'')
102
+ finally:
103
+ if hasattr(response, 'close'):
104
+ response.close()
@@ -1,6 +1,7 @@
1
1
  import struct
2
2
  import decimal
3
3
  import functools
4
+ import uuid
4
5
  import math
5
6
  import intersystems_iris._IRISOREF
6
7
  import datetime
@@ -326,6 +327,10 @@ class _DBList(object):
326
327
  offset = cls.__stuff_multibyte(buffer, offset, data, is_oref, locale)
327
328
  return offset
328
329
 
330
+ @classmethod
331
+ def _stuff_uuid(cls, buffer, offset, data, locale, is_unicode, *args):
332
+ return cls._stuff_str(buffer, offset, str(data), locale=locale, is_unicode=is_unicode)
333
+
329
334
  @classmethod
330
335
  def _stuff_datetime(cls, buffer, offset, data, locale, is_unicode, *args):
331
336
  return cls._stuff_str(buffer, offset, data.strftime('%Y-%m-%d %H:%M:%S.%f'), locale=locale, is_unicode=is_unicode)
@@ -496,5 +501,6 @@ _DBList._set_switcher = {
496
501
  float: _DBList._stuff_double,
497
502
  decimal.Decimal: _DBList._stuff_decimal,
498
503
  str: _DBList._stuff_str,
504
+ uuid.UUID: _DBList._stuff_uuid,
499
505
  intersystems_iris._IRISOREF._IRISOREF: _DBList._stuff_str,
500
506
  }
@@ -51,7 +51,7 @@ class _IRISEmbedded:
51
51
  reset_vars(current_vars)
52
52
  self.iris = iris
53
53
  self._connection_info._delimited_ids = 1
54
- self.restore_autocommit = iris.system.SQL.SetAutoCommit(0 if autoCommit is None else 1 if autoCommit else 2)
54
+ self.autoCommit = autoCommit
55
55
 
56
56
  def __enter__(self):
57
57
  return self
@@ -60,7 +60,6 @@ class _IRISEmbedded:
60
60
  self.close()
61
61
 
62
62
  def close(self):
63
- self.iris.system.SQL.SetAutoCommit(self.restore_autocommit)
64
63
  self.iris = None
65
64
 
66
65
  def isClosed(self):
@@ -76,6 +75,7 @@ class _IRISEmbedded:
76
75
  self._pre_preparse_cache[sql] = CachedSQL(cursor)
77
76
 
78
77
  def setAutoCommit(self, autoCommit):
78
+ self.autoCommit = autoCommit
79
79
  return self.iris.system.SQL.SetAutoCommit(0 if autoCommit is None else 1 if autoCommit else 2)
80
80
 
81
81
  def commit(self):
@@ -51,6 +51,7 @@ class _ListWriter(object):
51
51
  param_switcher = {
52
52
  SQLType.LONGVARBINARY: self._set_stream,
53
53
  SQLType.LONGVARCHAR: self._set_stream,
54
+ SQLType.GUID: self._set_uuid,
54
55
  SQLType.DATE: None,
55
56
  SQLType.TIME: None,
56
57
  SQLType.TIMESTAMP: None,
@@ -90,7 +91,10 @@ class _ListWriter(object):
90
91
  def _set_stream(self, stream):
91
92
  self._set(stream)
92
93
  # raise NotImplementedError("Stream functionality not yet available with iris.dbapi")
93
-
94
+
95
+ def _set_uuid(self, val):
96
+ self._set(str(val))
97
+
94
98
  def _set_date_h(self, date):
95
99
  HOROLOG_ORDINAL = datetime.date(1840, 12, 31).toordinal()
96
100
  if isinstance(date, datetime.date):
@@ -2,6 +2,7 @@ import struct
2
2
  import copy
3
3
  import enum
4
4
  import copy
5
+ import uuid
5
6
  import decimal
6
7
  import intersystems_iris
7
8
  from collections import namedtuple
@@ -337,7 +338,7 @@ class _BaseCursor:
337
338
  raise ValueError("INOUT/OUT parameters not permitted")
338
339
 
339
340
  self._prepared_update_execute()
340
-
341
+
341
342
  return self._rowcount
342
343
 
343
344
  def _process_sqlcode(self, sqlcode, message=None):
@@ -367,8 +368,9 @@ class _BaseCursor:
367
368
  if not self._is_batch_update:
368
369
  raise TypeError("Unsupported argument type: " + str(type(item)))
369
370
  for ele in item:
370
- if (not intersystems_iris._DBList._DBList._set_switcher.get(type(ele), None) and not issubclass(
371
- type(ele), enum.Enum)):
371
+ if not intersystems_iris._DBList._DBList._set_switcher.get(type(ele), None) and not issubclass(
372
+ type(ele), enum.Enum
373
+ ):
372
374
  raise TypeError("Unsupported argument type: " + str(type(ele)))
373
375
  elif intersystems_iris._DBList._DBList._set_switcher.get(type(item), None) is None:
374
376
  item = str(item)
@@ -661,7 +663,7 @@ class _BaseCursor:
661
663
  def description(self):
662
664
  if self._statementType is StatementType.UPDATE:
663
665
  return None
664
-
666
+
665
667
  if self._columns is None:
666
668
  return None
667
669
 
@@ -757,7 +759,7 @@ class Cursor(_BaseCursor):
757
759
  return True
758
760
  else:
759
761
  return False
760
-
762
+
761
763
  def _reset_cached_info(self):
762
764
  if not self._connection._preparedCache or not hasattr(self._connection._preparedCache, "__iter__"):
763
765
  return
@@ -1178,7 +1180,7 @@ class Cursor(_BaseCursor):
1178
1180
  sets = self._parameter_sets or 1
1179
1181
  self.params = list(self.params).copy()
1180
1182
  param_types = [param.type for param in self._params._params_list]
1181
-
1183
+
1182
1184
  for i in range(sets):
1183
1185
  params = self._params.collect(i)
1184
1186
  for pi, param in enumerate(params):
@@ -1207,14 +1209,18 @@ class Cursor(_BaseCursor):
1207
1209
  if size == 0:
1208
1210
  break
1209
1211
  size = 4096 if size > 4096 else size
1210
- chunk = value[offset:offset + size]
1212
+ chunk = value[offset : offset + size]
1211
1213
  if not isinstance(chunk, bytes):
1212
1214
  chunk = bytes(chunk, "utf-8")
1213
1215
  offset += size
1214
1216
  full_size -= size
1215
1217
 
1216
1218
  # message header
1217
- code = _Message.STORE_BINARY_STREAM if param_type == SQLType.LONGVARBINARY else _Message.STORE_CHARACTER_STREAM
1219
+ code = (
1220
+ _Message.STORE_BINARY_STREAM
1221
+ if param_type == SQLType.LONGVARBINARY
1222
+ else _Message.STORE_CHARACTER_STREAM
1223
+ )
1218
1224
  self._out_message.wire._write_header(code)
1219
1225
  intersystems_iris._MessageHeader._MessageHeader._set_statement_id(
1220
1226
  self._out_message.wire.buffer, self._statement_id
@@ -2240,10 +2246,23 @@ class EmbdeddedCursor(_BaseCursor):
2240
2246
  self._sql = connection.iris.sql
2241
2247
  self._iris = connection.iris
2242
2248
  self._closed = False
2249
+ self._connection = connection
2250
+ self.restore_selectmode = self._iris.system.SQL.SetSelectMode(1)
2251
+ self.restore_autocommit = self._iris.system.SQL.SetAutoCommit(
2252
+ 0 if self._connection.autoCommit is None else 1 if self._connection.autoCommit else 2
2253
+ )
2243
2254
 
2244
- # $System.SQL.SetSelectMode(1 /* ODBC */)
2245
- # $System.SQL.Util.SetOption("SelectMode", 1 /* ODBC */)
2246
- connection.iris.system.SQL.SetSelectMode(1)
2255
+ def close(self):
2256
+ self._iris.system.SQL.SetSelectMode(self.restore_selectmode)
2257
+ self._iris.system.SQL.SetAutoCommit(self.restore_autocommit)
2258
+ super().close()
2259
+
2260
+ def __del__(self):
2261
+ try:
2262
+ self.close()
2263
+ except:
2264
+ pass
2265
+ return
2247
2266
 
2248
2267
  def _get_cached_info(self):
2249
2268
  return False
@@ -2386,14 +2405,18 @@ class EmbdeddedCursor(_BaseCursor):
2386
2405
  sets = self._parameter_sets or 1
2387
2406
  metadata = self._statement.Statement._Metadata.parameters
2388
2407
  param_types = [metadata.GetAt(i + 1).ODBCType for i in range(metadata.Size)]
2389
-
2408
+
2390
2409
  stream_chunk_size = 32000
2391
2410
 
2392
2411
  for i in range(sets):
2393
2412
  params = self._get_parameters(i)
2394
2413
  for ip, param in enumerate(params):
2395
2414
  if param_types[ip] in (SQLType.LONGVARBINARY, SQLType.LONGVARCHAR):
2396
- stream_class = '%Stream.GlobalBinary' if param_types[ip] == SQLType.LONGVARBINARY else '%Stream.GlobalCharacter'
2415
+ stream_class = (
2416
+ "%Stream.GlobalBinary"
2417
+ if param_types[ip] == SQLType.LONGVARBINARY
2418
+ else "%Stream.GlobalCharacter"
2419
+ )
2397
2420
  stream = self._iris.cls(stream_class)._New()
2398
2421
  while param:
2399
2422
  stream.Write(param[:stream_chunk_size])
@@ -2448,6 +2471,7 @@ class EmbdeddedCursor(_BaseCursor):
2448
2471
  row = namedtuple("Row", [col.name for col in self._columns], rename=True)
2449
2472
 
2450
2473
  _types = {
2474
+ SQLType.GUID: uuid.UUID,
2451
2475
  SQLType.BIGINT: int,
2452
2476
  SQLType.BINARY: bytes,
2453
2477
  SQLType.VARBINARY: bytes,
@@ -1,3 +1,4 @@
1
+ import uuid
1
2
  from datetime import datetime
2
3
  from collections import namedtuple
3
4
  from ._SQLType import SQLType
@@ -67,6 +68,7 @@ class _ResultSetRow:
67
68
 
68
69
  class DataRow:
69
70
  _types = {
71
+ SQLType.GUID: uuid.UUID,
70
72
  SQLType.BIGINT: int,
71
73
  SQLType.BINARY: bytes,
72
74
  SQLType.BIT: None,
@@ -157,6 +159,8 @@ class _ResultSetRow:
157
159
  ctype = _column.type
158
160
  value_type = self._types[ctype] if ctype in self._types else None
159
161
  try:
162
+ if ctype == SQLType.GUID:
163
+ item = uuid.UUID(item)
160
164
  if ctype == SQLType.TIMESTAMP_POSIX:
161
165
  item = from_timestamp_posix(item)
162
166
 
iris/__init__.pyi ADDED
@@ -0,0 +1,187 @@
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):
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 sql object
77
+ class sql:
78
+ """
79
+ The sql object provides access to the InterSystems IRIS SQL API.
80
+ """
81
+ def exec(self, query: str) -> Any:
82
+ """
83
+ Execute a query
84
+ """
85
+ def prepare(self, query: str) -> PreparedQuery:
86
+ """
87
+ Prepare a query
88
+ """
89
+ class PreparedQuery:
90
+ def execute(self, **kwargs) -> Any:
91
+ """
92
+ Execute a prepared query, you can pass values
93
+ """
94
+ # stubs for the system object
95
+ class system:
96
+ """
97
+ The system object provides access to the InterSystems IRIS system API.
98
+ The following classes are available:
99
+ 'DocDB', 'Encryption', 'Error', 'Event', 'Monitor', 'Process', 'Python', 'SQL', 'SYS', 'Security', 'Semaphore', 'Status', 'Util', 'Version'
100
+ """
101
+ class DocDB:
102
+ """
103
+ The DocDB class provides access to the InterSystems IRIS Document Database API.
104
+ The following methods are available:
105
+ 'CreateDatabase', 'DropAllDatabases', 'DropDatabase', 'Exists', 'GetAllDatabases', 'GetDatabase', 'Help'
106
+ """
107
+ def CreateDatabase(self, name: str, path: str, **kwargs) -> Any:
108
+ """
109
+ Create a database
110
+ """
111
+ def DropAllDatabases(self) -> Any:
112
+ """
113
+ Drop all databases
114
+ """
115
+ def DropDatabase(self, name: str) -> Any:
116
+ """
117
+ Drop a database
118
+ """
119
+ def Exists(self, name: str) -> Any:
120
+ """
121
+ Check if a database exists
122
+ """
123
+ def GetAllDatabases(self) -> Any:
124
+ """
125
+ Get all databases
126
+ """
127
+ def GetDatabase(self, name: str) -> Any:
128
+ """
129
+ Get a database
130
+ """
131
+ def Help(self) -> Any:
132
+ """
133
+ Get help
134
+ """
135
+ def Encryption(self) -> Any:
136
+ """
137
+ The Encryption class provides access to the InterSystems IRIS Encryption API.
138
+ """
139
+ def Error(self) -> Any:
140
+ """
141
+ The Error class provides access to the InterSystems IRIS Error API.
142
+ """
143
+ def Event(self) -> Any:
144
+ """
145
+ The Event class provides access to the InterSystems IRIS Event API.
146
+ """
147
+ def Monitor(self) -> Any:
148
+ """
149
+ The Monitor class provides access to the InterSystems IRIS Monitor API.
150
+ """
151
+ def Process(self) -> Any:
152
+ """
153
+ The Process class provides access to the InterSystems IRIS Process API.
154
+ """
155
+ def Python(self) -> Any:
156
+ """
157
+ The Python class provides access to the InterSystems IRIS Python API.
158
+ """
159
+ def SQL(self) -> Any:
160
+ """
161
+ The SQL class provides access to the InterSystems IRIS SQL API.
162
+ """
163
+ def SYS(self) -> Any:
164
+ """
165
+ The SYS class provides access to the InterSystems IRIS SYS API.
166
+ """
167
+ def Security(self) -> Any:
168
+ """
169
+ The Security class provides access to the InterSystems IRIS Security API.
170
+ """
171
+ def Semaphore(self) -> Any:
172
+ """
173
+ The Semaphore class provides access to the InterSystems IRIS Semaphore API.
174
+ """
175
+ def Status(self) -> Any:
176
+ """
177
+ The Status class provides access to the InterSystems IRIS Status API.
178
+ """
179
+ def Util(self) -> Any:
180
+ """
181
+ The Util class provides access to the InterSystems IRIS Util API.
182
+ """
183
+ def Version(self) -> Any:
184
+ """
185
+ The Version class provides access to the InterSystems IRIS Version API.
186
+ """
187
+
iris/iris_ipm.pyi ADDED
@@ -0,0 +1,17 @@
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
+ """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
- Name: iris-pex-embedded-python
3
- Version: 2.3.22b3
2
+ Name: iris_pex_embedded_python
3
+ Version: 2.3.23b2
4
4
  Summary: Iris Interoperability based on Embedded Python
5
5
  Author-email: grongier <guillaume.rongier@intersystems.com>
6
6
  License: MIT License
@@ -18,7 +18,7 @@ grongier/cls/Grongier/PEX/PrivateSession/Message/Ack.cls,sha256=WbBn7pWj5mzruVfL
18
18
  grongier/cls/Grongier/PEX/PrivateSession/Message/Poll.cls,sha256=2lj-e20AH7RR8UgGJaldrk-1kd8WjQJNPiH-duds_4A,987
19
19
  grongier/cls/Grongier/PEX/PrivateSession/Message/Start.cls,sha256=DAtq4DyRqFq2_4Isa0cZjjwuAzdHjsQu8wMppK4myzs,994
20
20
  grongier/cls/Grongier/PEX/PrivateSession/Message/Stop.cls,sha256=ofVKjrN6UPFasalrjPFWYNwlJ5IBlAE62IH8_U07c0g,1435
21
- grongier/cls/Grongier/Service/WSGI.cls,sha256=X_yM4oxTBOfIOzsCGnvutIuqCAfg7hd6Oqfl-Kq3TjM,2979
21
+ grongier/cls/Grongier/Service/WSGI.cls,sha256=2KrnsATyoarrN6un-2sJwNK-ANw36Waa8GgFx97XQKA,10598
22
22
  grongier/pex/__init__.py,sha256=nvcmRCxLy-lpL5GzlCKrmsSK8LF8Q0aKddx6ib8U50E,1166
23
23
  grongier/pex/__main__.py,sha256=ebEYPDOBKiXOlmdI4onpQLzfBKU4wyfijYyquA5dWV4,107
24
24
  grongier/pex/_business_host.py,sha256=G4-eWlQzWMvjaHauISfSoogPsfQYJavmRi563ak6FS8,20858
@@ -35,20 +35,20 @@ grongier/pex/_pickle_message.py,sha256=noKfc2VkXufV3fqjKvNHN_oANQ1YN9ffCaSV0XSTA
35
35
  grongier/pex/_private_session_duplex.py,sha256=Qj_xzwwFnFVwi_Sl7Q7nKk4zmL6UC8iqBAuwnz7mVX8,5033
36
36
  grongier/pex/_private_session_process.py,sha256=_2r_csWcVRLmIUt4O0Y1Hg1FcX6A08lt9DvALQhwu8s,1722
37
37
  grongier/pex/_utils.py,sha256=GjHT5WolQAoeYkhHP3a0uDBlRzPIkyGG_bi-TwrMdjI,15877
38
- grongier/pex/wsgi/handlers.py,sha256=t9i3bNld3bewWWOOm5vrDHa1Dcxvp-SB5cHgPUFrggQ,1417
38
+ grongier/pex/wsgi/handlers.py,sha256=NrFLo_YbAh-x_PlWhAiWkQnUUN2Ss9HoEm63dDWCBpQ,2947
39
39
  intersystems_iris/_BufferReader.py,sha256=BXjHQs-sclAnvW9mvdlIrtku9m2Jf67Rc5rsZll7a5g,299
40
40
  intersystems_iris/_BufferWriter.py,sha256=i2BKM99J8pB5fGn-Gjdo4vcwXPEZQymsLEQd69nJrhs,1337
41
41
  intersystems_iris/_ConnectionInformation.py,sha256=Xr6sOPy3uKFyOG05hTmutDHTNjHDhCnCVwH0TTNEwBE,1896
42
42
  intersystems_iris/_ConnectionParameters.py,sha256=5-VwMJP_6Ya0lNnMf0UuwJQQfwHcozjknnUekMwCgQ4,578
43
43
  intersystems_iris/_Constant.py,sha256=g2NdV669sNH4kUoAjQFNq2xWaEMQiPMoQytNNrrXOnk,1483
44
- intersystems_iris/_DBList.py,sha256=dXg08f87nWduVaClhFOAw_cc0ue_Q9pbaPkbtPVjSlY,20104
44
+ intersystems_iris/_DBList.py,sha256=D0m_N50ZhpUnGwQiPZ1ZPtNecqROZvSnVbP46RY6juA,20340
45
45
  intersystems_iris/_Device.py,sha256=02rNhk32bLrcOdGDOsRHuX79-MLblGvAdBa-XfHtVkw,2311
46
46
  intersystems_iris/_GatewayContext.py,sha256=anipv7v5rDS2Ha2MmXTuMtFjo6UNgzUF3SwKQSS-co8,618
47
47
  intersystems_iris/_GatewayException.py,sha256=Hs5en7W1mhtt2heuoeyhF5IqFKGqbRD5GWyWZUhwDzs,96
48
48
  intersystems_iris/_GatewayUtility.py,sha256=gJTslU_UZBI8bWPTPe6b41DwhaAmlpzUNYT0LkAKXKk,2735
49
49
  intersystems_iris/_IRIS.py,sha256=vlxyMtfvyTkHHw5CkfNYqNbR1zUdAknfbLVTGxEOv3E,49548
50
50
  intersystems_iris/_IRISConnection.py,sha256=MmPIQJPZ28HoSYafvf4r5cbenzDiHmZhKgZXVfSxnCw,21467
51
- intersystems_iris/_IRISEmbedded.py,sha256=27oB-o53b1w3gbXNxyT6Z1DGWd9gc4x1h3Nz9luOhN4,2614
51
+ intersystems_iris/_IRISEmbedded.py,sha256=yYL71oLvHjLK_jF8wcyNjXu3ManQ_PpY2wD4GkOfa-E,2503
52
52
  intersystems_iris/_IRISGlobalNode.py,sha256=o2MEvyRmNrvLAR0dpeQ76r9b8Yw2sKDaaRLFyGYdcDQ,12049
53
53
  intersystems_iris/_IRISGlobalNodeView.py,sha256=0yw9z_mpSLk2m3we5z_vKSjnEdmKfZb11bbASZiiSm8,797
54
54
  intersystems_iris/_IRISIterator.py,sha256=m1n_fRdoO8YPfDi7l-JvJTqdJuxq_kxC60aMxkxLJUE,6906
@@ -61,7 +61,7 @@ intersystems_iris/_InStream.py,sha256=6g4HdDoQ0MFub8Yn-Git8DkJNEoyyAtAhrvjkUdDA7
61
61
  intersystems_iris/_LegacyIterator.py,sha256=K1CPMBDWBCwKVqIq9hBJ2q_uMiBnht_OdN66g7ZqXfw,4130
62
62
  intersystems_iris/_ListItem.py,sha256=k9m0Q0W3e3WuI5cpB1GSZOR9NkkCT87lgvBwYFMzvic,354
63
63
  intersystems_iris/_ListReader.py,sha256=wgK0HC56lI1Wdp9Sr3rax6w8NoR5p2YpklswpNIS5X8,2966
64
- intersystems_iris/_ListWriter.py,sha256=JGmUkzzWUGbwflb9szpRQU305dWqoGkFMvCMwP8uPkE,5515
64
+ intersystems_iris/_ListWriter.py,sha256=zBQd7Mx3ho0jOd_q4RNAhw1ub1kUXVptwRYMN36OQew,5612
65
65
  intersystems_iris/_LogFileStream.py,sha256=Dv3S8-zY3b7P4xXx7w0UVGm2vuz7bWTyaOTg6eK0l2s,3797
66
66
  intersystems_iris/_MessageHeader.py,sha256=N45Qp25ER7ftGA0BRBxErIpavDF-j4qWv_0kobkAp6U,1662
67
67
  intersystems_iris/_OutStream.py,sha256=_I83KPUCv9yBHsaB4QGBeSatypdiMGJxckKdNY1Jzyg,1327
@@ -71,13 +71,13 @@ intersystems_iris/_SharedMemorySocket.py,sha256=2iUaS1FdJNSCUEaE-VT0O_dxF6NRwqZS
71
71
  intersystems_iris/__init__.py,sha256=Tk1tD28LwvF6X3yXQsJFLE1Bc-PR3gUJWcX5UnNYOdY,1773
72
72
  intersystems_iris/__main__.py,sha256=rCtINTfJcADMAsw1ja-MEO7Q-XekrWthYowzWV8xGIQ,218
73
73
  intersystems_iris/dbapi/_Column.py,sha256=VCLHLXs3wuGcUa9w_qy7HBFsuGvhmmI3kGYBagQg59U,2535
74
- intersystems_iris/dbapi/_DBAPI.py,sha256=eV9PA3T1dlMpKY_H2SAarcbNjOujpprKe99qHqtaUPg,102320
74
+ intersystems_iris/dbapi/_DBAPI.py,sha256=sqkUxjhK683icHlE56ywygV8ODz7yudeIJOQSQTeb78,102938
75
75
  intersystems_iris/dbapi/_Descriptor.py,sha256=IjyITxvjygDrhpk-0lGhdqQPh91SG6nTb1vi-AqyJNI,1391
76
76
  intersystems_iris/dbapi/_IRISStream.py,sha256=dGJntWo4HXgM1nUHZl2hA4xHkBFEU2xkoEplVDFWhnA,2115
77
77
  intersystems_iris/dbapi/_Message.py,sha256=jpLG3HZElqp981iNPFW8UNRO3NbHf6poEv6yywX0Ssw,4076
78
78
  intersystems_iris/dbapi/_Parameter.py,sha256=lvPlQkoLlyEjg5J_a9t2I_6vRDkAav6kN1fGyukH4DY,5293
79
79
  intersystems_iris/dbapi/_ParameterCollection.py,sha256=kcgNiGv2nH5AwuA6LlPpM4dWqhSqRyD3VtwqHqDGRGU,5541
80
- intersystems_iris/dbapi/_ResultSetRow.py,sha256=tNKCv5P8XhP9zzdPpBGiXYHLKOScITTBGSqtui1TAM0,12910
80
+ intersystems_iris/dbapi/_ResultSetRow.py,sha256=1V5ixV2VQz0-LDEvVz-khW4e1V6xmlgZ6VyV4PbuQsE,13052
81
81
  intersystems_iris/dbapi/_SQLType.py,sha256=IlDacXwQzUMWaJ02Zsu2bUfvUC3-5mBx-m6mE0Yp7ts,557
82
82
  intersystems_iris/dbapi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
83
83
  intersystems_iris/dbapi/preparser/_PreParser.py,sha256=024w-s3n_JNsk_ISC8avJMK3QEZE3hSuD0Nr8arJdZw,78828
@@ -100,12 +100,14 @@ intersystems_iris/pex/_Message.py,sha256=Ugaa_lsEYke__pI5kdC7phAuyPQ7rxXUcROJL4c
100
100
  intersystems_iris/pex/_OutboundAdapter.py,sha256=ao2Ubbta2DcrQGdzDUD_j1Zsk8bvUfcZNKTZkzPTNBU,1628
101
101
  intersystems_iris/pex/__init__.py,sha256=l_I1dpnluWawbFrGMDC0GLHpuHwjbpd-nho8otFX6TE,1379
102
102
  iris/__init__.py,sha256=VyBPMqjkad0JPoza38YZbBeLHM7jZUMS90t8KKEIW94,1045
103
+ iris/__init__.pyi,sha256=BtE0ZohcTo2EYDQhlqqEndMUnIyQIHUte3OIx3S6DKo,6994
103
104
  iris/iris_ipm.py,sha256=Q0jcNItjywlqOPZr0hgdTFSeLPNEmB-tcICOI_cXnaY,790
105
+ iris/iris_ipm.pyi,sha256=j7CNUZcjeDu5sgeWUZJO_Qi4vQmHh6aD-jPWv8OdoUs,374
104
106
  irisnative/_IRISNative.py,sha256=HQ4nBhc8t8_5OtxdMG-kx1aa-T1znf2I8obZOPLOPzg,665
105
107
  irisnative/__init__.py,sha256=6YmvBLQSURsCPKaNg7LK-xpo4ipDjrlhKuwdfdNb3Kg,341
106
- iris_pex_embedded_python-2.3.22b3.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
107
- iris_pex_embedded_python-2.3.22b3.dist-info/METADATA,sha256=HRUN4b_9Vhwtb2_bKQ-rGCdF2VzqNAMrnW0NyAjc0-8,49682
108
- iris_pex_embedded_python-2.3.22b3.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
109
- iris_pex_embedded_python-2.3.22b3.dist-info/entry_points.txt,sha256=atkAtHoIuwXcZ0jl5gwof0l__ru_lt8WhVYk6HxYf70,47
110
- iris_pex_embedded_python-2.3.22b3.dist-info/top_level.txt,sha256=Tl4ZHgeNefaZW2Oug30vSldhD-tWzixsIfzASBrZ9ps,43
111
- iris_pex_embedded_python-2.3.22b3.dist-info/RECORD,,
108
+ iris_pex_embedded_python-2.3.23b2.dist-info/LICENSE,sha256=rZSiBFId_sfbJ6RL0GjjPX-InNLkNS9ou7eQsikciI8,1089
109
+ iris_pex_embedded_python-2.3.23b2.dist-info/METADATA,sha256=i4jd-lv7DrBSOBzsc01noZTT-lszckwRwEG4DFy312Y,49682
110
+ iris_pex_embedded_python-2.3.23b2.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
111
+ iris_pex_embedded_python-2.3.23b2.dist-info/entry_points.txt,sha256=atkAtHoIuwXcZ0jl5gwof0l__ru_lt8WhVYk6HxYf70,47
112
+ iris_pex_embedded_python-2.3.23b2.dist-info/top_level.txt,sha256=Tl4ZHgeNefaZW2Oug30vSldhD-tWzixsIfzASBrZ9ps,43
113
+ iris_pex_embedded_python-2.3.23b2.dist-info/RECORD,,