execsql2 2.0.1__py3-none-any.whl → 2.1.2__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.
Files changed (90) hide show
  1. execsql/cli.py +322 -108
  2. execsql/config.py +134 -114
  3. execsql/db/access.py +89 -65
  4. execsql/db/base.py +97 -68
  5. execsql/db/dsn.py +45 -29
  6. execsql/db/duckdb.py +4 -5
  7. execsql/db/factory.py +27 -27
  8. execsql/db/firebird.py +30 -18
  9. execsql/db/mysql.py +38 -14
  10. execsql/db/oracle.py +58 -33
  11. execsql/db/postgres.py +68 -28
  12. execsql/db/sqlite.py +36 -27
  13. execsql/db/sqlserver.py +45 -30
  14. execsql/exceptions.py +68 -64
  15. execsql/exporters/__init__.py +1 -1
  16. execsql/exporters/base.py +42 -17
  17. execsql/exporters/delimited.py +60 -59
  18. execsql/exporters/duckdb.py +8 -12
  19. execsql/exporters/feather.py +32 -24
  20. execsql/exporters/html.py +33 -30
  21. execsql/exporters/json.py +18 -17
  22. execsql/exporters/latex.py +11 -13
  23. execsql/exporters/ods.py +50 -46
  24. execsql/exporters/parquet.py +32 -0
  25. execsql/exporters/pretty.py +16 -15
  26. execsql/exporters/raw.py +9 -11
  27. execsql/exporters/sqlite.py +38 -38
  28. execsql/exporters/templates.py +15 -72
  29. execsql/exporters/values.py +13 -12
  30. execsql/exporters/xls.py +26 -26
  31. execsql/exporters/xml.py +12 -12
  32. execsql/exporters/zip.py +0 -3
  33. execsql/gui/__init__.py +2 -2
  34. execsql/gui/console.py +0 -1
  35. execsql/gui/desktop.py +6 -7
  36. execsql/gui/tui.py +8 -14
  37. execsql/importers/base.py +6 -9
  38. execsql/importers/csv.py +10 -17
  39. execsql/importers/feather.py +16 -22
  40. execsql/importers/ods.py +3 -4
  41. execsql/importers/xls.py +5 -6
  42. execsql/metacommands/__init__.py +8 -8
  43. execsql/metacommands/conditions.py +41 -33
  44. execsql/metacommands/connect.py +113 -99
  45. execsql/metacommands/control.py +38 -26
  46. execsql/metacommands/data.py +35 -33
  47. execsql/metacommands/debug.py +13 -9
  48. execsql/metacommands/io.py +288 -229
  49. execsql/metacommands/prompt.py +179 -157
  50. execsql/metacommands/script_ext.py +11 -9
  51. execsql/metacommands/system.py +44 -25
  52. execsql/models.py +9 -16
  53. execsql/parser.py +10 -10
  54. execsql/script.py +183 -157
  55. execsql/state.py +170 -208
  56. execsql/types.py +46 -81
  57. execsql/utils/auth.py +114 -14
  58. execsql/utils/crypto.py +31 -4
  59. execsql/utils/datetime.py +7 -7
  60. execsql/utils/errors.py +34 -29
  61. execsql/utils/fileio.py +90 -55
  62. execsql/utils/gui.py +22 -23
  63. execsql/utils/mail.py +15 -17
  64. execsql/utils/numeric.py +2 -3
  65. execsql/utils/regex.py +9 -12
  66. execsql/utils/strings.py +10 -12
  67. execsql/utils/timer.py +0 -2
  68. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/execsql.conf +1 -1
  69. execsql2-2.1.2.dist-info/METADATA +300 -0
  70. execsql2-2.1.2.dist-info/RECORD +96 -0
  71. execsql2-2.0.1.dist-info/METADATA +0 -406
  72. execsql2-2.0.1.dist-info/RECORD +0 -95
  73. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/READ_ME.rst +0 -0
  74. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/config_settings.sqlite +0 -0
  75. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/example_config_prompt.sql +0 -0
  76. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/make_config_db.sql +0 -0
  77. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_compare.sql +0 -0
  78. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_glossary.sql +0 -0
  79. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/md_upsert.sql +0 -0
  80. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_compare.sql +0 -0
  81. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_glossary.sql +0 -0
  82. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/pg_upsert.sql +0 -0
  83. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/script_template.sql +0 -0
  84. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_compare.sql +0 -0
  85. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_glossary.sql +0 -0
  86. {execsql2-2.0.1.data → execsql2-2.1.2.data}/data/execsql2_extras/ss_upsert.sql +0 -0
  87. {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/WHEEL +0 -0
  88. {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/entry_points.txt +0 -0
  89. {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/licenses/LICENSE.txt +0 -0
  90. {execsql2-2.0.1.dist-info → execsql2-2.1.2.dist-info}/licenses/NOTICE +0 -0
@@ -1,4 +1,5 @@
1
1
  from __future__ import annotations
2
+ from execsql.exceptions import ErrInfo
2
3
 
3
4
  """
4
5
  Interactive user prompt metacommand handlers for execsql.
@@ -22,9 +23,39 @@ console prompts to the user:
22
23
 
23
24
  import os
24
25
  import queue as _queue
26
+ from pathlib import Path
25
27
  from typing import Any
26
28
 
27
29
  import execsql.state as _state
30
+ from execsql.script import current_script_line
31
+ from execsql.utils.errors import exception_desc, exit_now
32
+ from execsql.utils.fileio import EncodedFile, check_dir
33
+ from execsql.utils.gui import (
34
+ ActionSpec,
35
+ EntrySpec,
36
+ GUI_ACTION,
37
+ GUI_COMPARE,
38
+ GUI_DIRECTORY,
39
+ GUI_DISPLAY,
40
+ GUI_ENTRY,
41
+ GUI_HALT,
42
+ GUI_MAP,
43
+ GUI_MSG,
44
+ GUI_OPENFILE,
45
+ GUI_PAUSE,
46
+ GUI_SAVEFILE,
47
+ GUI_SELECTROWS,
48
+ GuiSpec,
49
+ QUERY_CONSOLE,
50
+ enable_gui,
51
+ get_yn,
52
+ get_yn_win,
53
+ gui_connect,
54
+ gui_credentials,
55
+ pause,
56
+ pause_win,
57
+ )
58
+ from execsql.utils.strings import unquoted
28
59
 
29
60
 
30
61
  def x_prompt(**kwargs: Any) -> None:
@@ -32,13 +63,13 @@ def x_prompt(**kwargs: Any) -> None:
32
63
  schema = kwargs["schema"]
33
64
  table = kwargs["table"]
34
65
  message = kwargs["message"]
35
- help_url = _state.unquoted(kwargs["help"])
66
+ help_url = unquoted(kwargs["help"])
36
67
  free = kwargs["free"] is not None
37
68
  sq_name = db.schema_qualified_table_name(schema, table)
38
- script, line_no = _state.current_script_line()
69
+ script, line_no = current_script_line()
39
70
  cmd = f"select * from {sq_name};"
40
71
  colnames, rows = db.select_data(cmd)
41
- _state.enable_gui()
72
+ enable_gui()
42
73
  return_queue = _queue.Queue()
43
74
  gui_args = {
44
75
  "title": table,
@@ -49,15 +80,14 @@ def x_prompt(**kwargs: Any) -> None:
49
80
  "help_url": help_url,
50
81
  "free": free,
51
82
  }
52
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_DISPLAY, gui_args, return_queue))
83
+ _state.gui_manager_queue.put(GuiSpec(GUI_DISPLAY, gui_args, return_queue))
53
84
  if not free:
54
85
  user_response = return_queue.get(block=True)
55
86
  btn = user_response["button"]
56
- if not btn:
57
- if _state.status.cancel_halt:
58
- msg = f"Halted from display of {sq_name}"
59
- _state.exec_log.log_exit_halt(script, line_no, msg)
60
- _state.exit_now(2, None)
87
+ if not btn and _state.status.cancel_halt:
88
+ msg = f"Halted from display of {sq_name}"
89
+ _state.exec_log.log_exit_halt(script, line_no, msg)
90
+ exit_now(2, None)
61
91
  return None
62
92
 
63
93
 
@@ -70,14 +100,14 @@ def x_prompt_enter(**kwargs: Any) -> None:
70
100
  schema = kwargs["schema"]
71
101
  table = kwargs["table"]
72
102
  initial = kwargs["initial"]
73
- help_url = _state.unquoted(kwargs["help"])
103
+ help_url = unquoted(kwargs["help"])
74
104
  if table is not None:
75
105
  db = _state.dbs.current()
76
106
  cmd = f"select * from {db.schema_qualified_table_name(schema, table)};"
77
107
  hdrs, rows = db.select_data(cmd)
78
108
  else:
79
109
  hdrs, rows = None, None
80
- _state.enable_gui()
110
+ enable_gui()
81
111
  return_queue = _queue.Queue()
82
112
  gui_args = {
83
113
  "title": "Enter a value",
@@ -93,18 +123,18 @@ def x_prompt_enter(**kwargs: Any) -> None:
93
123
  "help_url": help_url,
94
124
  "free": False,
95
125
  }
96
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_DISPLAY, gui_args, return_queue))
126
+ _state.gui_manager_queue.put(GuiSpec(GUI_DISPLAY, gui_args, return_queue))
97
127
  user_response = return_queue.get(block=True)
98
128
  btnval = user_response["button"]
99
129
  txtval = user_response["return_value"]
100
130
  if btnval is None:
101
131
  if _state.status.cancel_halt:
102
- _state.exec_log.log_exit_halt(*_state.current_script_line(), msg="Quit from prompt to enter a SUB value.")
103
- _state.exit_now(2, None)
132
+ _state.exec_log.log_exit_halt(*current_script_line(), msg="Quit from prompt to enter a SUB value.")
133
+ exit_now(2, None)
104
134
  else:
105
135
  subvarset = _state.subvars if sub_var[0] != "~" else _state.commandliststack[-1].localvars
106
136
  subvarset.add_substitution(sub_var, txtval)
107
- script_name, lno = _state.current_script_line()
137
+ script_name, lno = current_script_line()
108
138
  if as_pw:
109
139
  _state.exec_log.log_status_info(f"Password assigned to variable {{{sub_var}}} on line {lno}.")
110
140
  else:
@@ -120,17 +150,17 @@ def x_prompt_entryform(**kwargs: Any) -> None:
120
150
  display_schema = kwargs["schemadisp"]
121
151
  display_table = kwargs["tabledisp"]
122
152
  message = kwargs["message"]
123
- help_url = _state.unquoted(kwargs["help"])
153
+ help_url = unquoted(kwargs["help"])
124
154
  tbl1 = _state.dbs.current().schema_qualified_table_name(spec_schema, spec_table)
125
155
  try:
126
156
  if not _state.dbs.current().table_exists(spec_table, spec_schema):
127
- raise _state.ErrInfo(
157
+ raise ErrInfo(
128
158
  type="cmd",
129
159
  command_text=kwargs["metacommandline"],
130
160
  other_msg=f"Table {spec_table} does not exist",
131
161
  )
132
162
  except Exception:
133
- pass
163
+ pass # Best-effort check; some adapters lack information_schema.
134
164
  curs = _state.dbs.current().cursor()
135
165
  cmd = f"select * from {tbl1};"
136
166
  curs.execute(cmd)
@@ -139,7 +169,7 @@ def x_prompt_entryform(**kwargs: Any) -> None:
139
169
  cmd = f"select * from {tbl1} order by sequence;"
140
170
  curs.execute(cmd)
141
171
  if not ("sub_var" in colhdrs and "prompt" in colhdrs):
142
- raise _state.ErrInfo(
172
+ raise ErrInfo(
143
173
  type="cmd",
144
174
  command_text=kwargs["metacommandline"],
145
175
  other_msg="The variable name and prompt are required, but missing.",
@@ -155,20 +185,20 @@ def x_prompt_entryform(**kwargs: Any) -> None:
155
185
  v = dict(zip(colhdrs, r))
156
186
  subvar = v.get("sub_var")
157
187
  if not subvar:
158
- raise _state.ErrInfo(
188
+ raise ErrInfo(
159
189
  type="cmd",
160
190
  command_text=kwargs["metacommandline"],
161
191
  other_msg="A substitution variable name must be provided for all of the entry specifications.",
162
192
  )
163
193
  if not subvar_rx.match(subvar):
164
- raise _state.ErrInfo(
194
+ raise ErrInfo(
165
195
  type="cmd",
166
196
  command_text=kwargs["metacommandline"],
167
197
  other_msg=f"Invalid substitution variable name: {subvar}",
168
198
  )
169
199
  prompt_msg = v.get("prompt")
170
200
  if not prompt_msg:
171
- raise _state.ErrInfo(
201
+ raise ErrInfo(
172
202
  type="cmd",
173
203
  command_text=kwargs["metacommandline"],
174
204
  other_msg="A prompt must be provided for all of the entry specifications.",
@@ -181,7 +211,7 @@ def x_prompt_entryform(**kwargs: Any) -> None:
181
211
  else:
182
212
  initial_value = str(v["initial_value"])
183
213
  except Exception:
184
- raise _state.ErrInfo(
214
+ raise ErrInfo(
185
215
  type="cmd",
186
216
  command_text=kwargs["metacommandline"],
187
217
  other_msg=f"The initial value of {v['initial_value']} can't be used.",
@@ -197,7 +227,7 @@ def x_prompt_entryform(**kwargs: Any) -> None:
197
227
  try:
198
228
  entry_width = int(entry_width)
199
229
  except Exception:
200
- raise _state.ErrInfo(
230
+ raise ErrInfo(
201
231
  type="cmd",
202
232
  command_text=kwargs["metacommandline"],
203
233
  other_msg=f"Entry width {entry_width} is not an integer",
@@ -208,7 +238,7 @@ def x_prompt_entryform(**kwargs: Any) -> None:
208
238
  try:
209
239
  entry_height = int(entry_height)
210
240
  except Exception:
211
- raise _state.ErrInfo(
241
+ raise ErrInfo(
212
242
  type="cmd",
213
243
  command_text=kwargs["metacommandline"],
214
244
  other_msg=f"Entry height {entry_height} is not an integer",
@@ -221,7 +251,7 @@ def x_prompt_entryform(**kwargs: Any) -> None:
221
251
  try:
222
252
  entry_col = int(entry_col)
223
253
  except Exception:
224
- raise _state.ErrInfo(
254
+ raise ErrInfo(
225
255
  type="cmd",
226
256
  command_text=kwargs["metacommandline"],
227
257
  other_msg=f"Entry column {entry_col} is not an integer",
@@ -231,7 +261,7 @@ def x_prompt_entryform(**kwargs: Any) -> None:
231
261
  subvarset = _state.subvars if subvar[0] != "~" else _state.commandliststack[-1].localvars
232
262
  subvarset.remove_substitution(subvar)
233
263
  entry_list.append(
234
- _state.EntrySpec(
264
+ EntrySpec(
235
265
  subvar,
236
266
  prompt_msg,
237
267
  required=bool(v.get("required")),
@@ -250,7 +280,7 @@ def x_prompt_entryform(**kwargs: Any) -> None:
250
280
  db = _state.dbs.current()
251
281
  sq_name = db.schema_qualified_table_name(display_schema, display_table)
252
282
  colnames, rows = db.select_data(f"select * from {sq_name};")
253
- _state.enable_gui()
283
+ enable_gui()
254
284
  return_queue = _queue.Queue()
255
285
  gui_args = {
256
286
  "title": "Entry",
@@ -260,11 +290,11 @@ def x_prompt_entryform(**kwargs: Any) -> None:
260
290
  "rowset": rows,
261
291
  "help_url": help_url,
262
292
  }
263
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_ENTRY, gui_args, return_queue))
293
+ _state.gui_manager_queue.put(GuiSpec(GUI_ENTRY, gui_args, return_queue))
264
294
  user_response = return_queue.get(block=True)
265
295
  btn = user_response["button"]
266
296
  entries = user_response["return_value"]
267
- script, line_no = _state.current_script_line()
297
+ script, line_no = current_script_line()
268
298
  if btn:
269
299
  for e in entries:
270
300
  if e.value:
@@ -283,7 +313,7 @@ def x_prompt_entryform(**kwargs: Any) -> None:
283
313
  if _state.status.cancel_halt:
284
314
  msg = f"Halted from entry form {tbl1}"
285
315
  _state.exec_log.log_exit_halt(script, line_no, msg)
286
- _state.exit_now(2, None)
316
+ exit_now(2, None)
287
317
 
288
318
 
289
319
  def x_prompt_pause(**kwargs: Any) -> None:
@@ -301,20 +331,20 @@ def x_prompt_pause(**kwargs: Any) -> None:
301
331
  maxtime_secs = countdown
302
332
  if timeunit and timeunit.lower() == "minutes":
303
333
  maxtime_secs = maxtime_secs * 60
304
- _state.enable_gui()
334
+ enable_gui()
305
335
  return_queue = _queue.Queue()
306
336
  gui_args = {
307
- "title": f"Script {_state.current_script_line()[0]}",
337
+ "title": f"Script {current_script_line()[0]}",
308
338
  "message": msg,
309
339
  "countdown": maxtime_secs,
310
340
  }
311
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_PAUSE, gui_args, return_queue))
341
+ _state.gui_manager_queue.put(GuiSpec(GUI_PAUSE, gui_args, return_queue))
312
342
  user_response = return_queue.get(block=True)
313
343
  quit = user_response["quit"]
314
344
  return_queue.task_done()
315
345
  if quit and _state.status.cancel_halt:
316
- _state.exec_log.log_exit_halt(*_state.current_script_line(), msg=quitmsg)
317
- _state.exit_now(2, None)
346
+ _state.exec_log.log_exit_halt(*current_script_line(), msg=quitmsg)
347
+ exit_now(2, None)
318
348
  return None
319
349
 
320
350
 
@@ -328,20 +358,20 @@ def prompt_compare(button_list: list, **kwargs: Any) -> Any:
328
358
  alias2 = kwargs["alias2"]
329
359
  pks = kwargs["pks"]
330
360
  msg = kwargs["msg"]
331
- help_url = _state.unquoted(kwargs["help"])
361
+ help_url = unquoted(kwargs["help"])
332
362
  badaliasmsg = "Alias %s is not recognized."
333
363
  if alias1 is not None:
334
364
  try:
335
365
  db1 = _state.dbs.aliased_as(alias1)
336
366
  except Exception:
337
- raise _state.ErrInfo(type="error", other_msg=badaliasmsg % alias1)
367
+ raise ErrInfo(type="error", other_msg=badaliasmsg % alias1)
338
368
  else:
339
369
  db1 = _state.dbs.current()
340
370
  if alias2 is not None:
341
371
  try:
342
372
  db2 = _state.dbs.aliased_as(alias2)
343
373
  except Exception:
344
- raise _state.ErrInfo(type="error", other_msg=badaliasmsg % alias2)
374
+ raise ErrInfo(type="error", other_msg=badaliasmsg % alias2)
345
375
  else:
346
376
  db2 = _state.dbs.current()
347
377
  sq_name1 = db1.schema_qualified_table_name(schema1, table1)
@@ -350,19 +380,19 @@ def prompt_compare(button_list: list, **kwargs: Any) -> Any:
350
380
  sql2 = f"select * from {sq_name2};"
351
381
  hdrs1, rows1 = db1.select_data(sql1)
352
382
  if len(rows1) == 0:
353
- raise _state.ErrInfo("error", other_msg=f"There are no data in {sq_name1}.")
383
+ raise ErrInfo("error", other_msg=f"There are no data in {sq_name1}.")
354
384
  hdrs2, rows2 = db2.select_data(sql2)
355
385
  if len(rows2) == 0:
356
- raise _state.ErrInfo("error", other_msg=f"There are no data in {sq_name2}.")
386
+ raise ErrInfo("error", other_msg=f"There are no data in {sq_name2}.")
357
387
  pklist = [pk.replace('"', "").replace(" ", "") for pk in pks.split(",")]
358
388
  sidebyside = orient.lower() == "beside"
359
- if not all([col in hdrs1 for col in pklist]) or not all([col in hdrs2 for col in pklist]):
360
- script, line_no = _state.current_script_line()
361
- raise _state.ErrInfo(
389
+ if not all(col in hdrs1 for col in pklist) or not all(col in hdrs2 for col in pklist):
390
+ script, line_no = current_script_line()
391
+ raise ErrInfo(
362
392
  type="error",
363
393
  other_msg=f"Specified primary key columns do not exist in PROMPT COMPARE metacommand on line {line_no} of {script}.",
364
394
  )
365
- _state.enable_gui()
395
+ enable_gui()
366
396
  return_queue = _queue.Queue()
367
397
  gui_args = {
368
398
  "title": "Compare data",
@@ -376,15 +406,14 @@ def prompt_compare(button_list: list, **kwargs: Any) -> Any:
376
406
  "sidebyside": sidebyside,
377
407
  "help_url": help_url,
378
408
  }
379
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_COMPARE, gui_args, return_queue))
409
+ _state.gui_manager_queue.put(GuiSpec(GUI_COMPARE, gui_args, return_queue))
380
410
  user_response = return_queue.get(block=True)
381
411
  btn = user_response["button"]
382
- if btn is None:
383
- if _state.status.cancel_halt:
384
- script, line_no = _state.current_script_line()
385
- msg = f"Halted from comparison of {sq_name1} and {sq_name2}"
386
- _state.exec_log.log_exit_halt(script, line_no, msg)
387
- _state.exit_now(2, None)
412
+ if btn is None and _state.status.cancel_halt:
413
+ script, line_no = current_script_line()
414
+ msg = f"Halted from comparison of {sq_name1} and {sq_name2}"
415
+ _state.exec_log.log_exit_halt(script, line_no, msg)
416
+ exit_now(2, None)
388
417
  return btn
389
418
 
390
419
 
@@ -394,12 +423,12 @@ def x_prompt_compare(**kwargs: Any) -> None:
394
423
 
395
424
  def x_prompt_ask_compare(**kwargs: Any) -> None:
396
425
  subvar = kwargs["match"]
397
- script, lno = _state.current_script_line()
426
+ script, lno = current_script_line()
398
427
  btn = prompt_compare([("Yes", 1, "y"), ("No", 0, "n")], **kwargs)
399
428
  if btn is None:
400
429
  if _state.status.cancel_halt:
401
430
  _state.exec_log.log_exit_halt(script, lno, msg="Quit from PROMPT ASK COMPARE metacommand")
402
- _state.exit_now(2, None)
431
+ exit_now(2, None)
403
432
  else:
404
433
  respstr = "Yes" if btn == 1 else "No"
405
434
  subvarset = _state.subvars if subvar[0] != "~" else _state.commandliststack[-1].localvars
@@ -412,15 +441,15 @@ def x_prompt_ask(**kwargs: Any) -> None:
412
441
  subvar = kwargs["match"]
413
442
  schema = kwargs["schema"]
414
443
  table = kwargs["table"]
415
- help_url = _state.unquoted(kwargs["help"])
416
- script, lno = _state.current_script_line()
444
+ help_url = unquoted(kwargs["help"])
445
+ script, lno = current_script_line()
417
446
  if table is not None:
418
447
  queryname = _state.dbs.current().schema_qualified_table_name(schema, table)
419
448
  cmd = f"select * from {queryname};"
420
449
  colnames, rows = _state.dbs.current().select_data(cmd)
421
450
  else:
422
451
  colnames, rows = None, None
423
- _state.enable_gui()
452
+ enable_gui()
424
453
  return_queue = _queue.Queue()
425
454
  gui_args = {
426
455
  "title": script,
@@ -430,13 +459,13 @@ def x_prompt_ask(**kwargs: Any) -> None:
430
459
  "rowset": rows,
431
460
  "help_url": help_url,
432
461
  }
433
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_DISPLAY, gui_args, return_queue))
462
+ _state.gui_manager_queue.put(GuiSpec(GUI_DISPLAY, gui_args, return_queue))
434
463
  user_response = return_queue.get(block=True)
435
464
  btn = user_response["button"]
436
465
  if btn is None:
437
466
  if _state.status.cancel_halt:
438
467
  _state.exec_log.log_exit_halt(script, lno, msg=quitmsg)
439
- _state.exit_now(2, None)
468
+ exit_now(2, None)
440
469
  else:
441
470
  respstr = "Yes" if btn == 1 else "No"
442
471
  subvarset = _state.subvars if subvar[0] != "~" else _state.commandliststack[-1].localvars
@@ -458,10 +487,10 @@ def x_prompt_map(**kwargs: Any) -> None:
458
487
  symbol_col = kwargs["symbol_col"]
459
488
  color_col = kwargs["color_col"]
460
489
  sq_name = db.schema_qualified_table_name(schema, table)
461
- script, line_no = _state.current_script_line()
490
+ script, line_no = current_script_line()
462
491
  cmd = f"select * from {sq_name};"
463
492
  colnames, rows = db.select_data(cmd)
464
- _state.enable_gui()
493
+ enable_gui()
465
494
  return_queue = _queue.Queue()
466
495
  gui_args = {
467
496
  "title": table,
@@ -475,14 +504,13 @@ def x_prompt_map(**kwargs: Any) -> None:
475
504
  "symbol_col": symbol_col,
476
505
  "color_col": color_col,
477
506
  }
478
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_MAP, gui_args, return_queue))
507
+ _state.gui_manager_queue.put(GuiSpec(GUI_MAP, gui_args, return_queue))
479
508
  user_response = return_queue.get(block=True)
480
509
  btn = user_response["button"]
481
- if not btn:
482
- if _state.status.cancel_halt:
483
- msg = f"Halted from map of {sq_name}"
484
- _state.exec_log.log_exit_halt(script, line_no, msg)
485
- _state.exit_now(2, None)
510
+ if not btn and _state.status.cancel_halt:
511
+ msg = f"Halted from map of {sq_name}"
512
+ _state.exec_log.log_exit_halt(script, line_no, msg)
513
+ exit_now(2, None)
486
514
  return None
487
515
 
488
516
 
@@ -493,7 +521,7 @@ def x_prompt_action(**kwargs: Any) -> None:
493
521
  display_table = kwargs["tabledisp"]
494
522
  message = kwargs["message"]
495
523
  compact = kwargs["compact"]
496
- help_url = _state.unquoted(kwargs["help"])
524
+ help_url = unquoted(kwargs["help"])
497
525
  if compact is not None:
498
526
  compact = int(compact)
499
527
  do_continue = kwargs["continue"]
@@ -502,13 +530,13 @@ def x_prompt_action(**kwargs: Any) -> None:
502
530
  tbl1 = _state.dbs.current().schema_qualified_table_name(spec_schema, spec_table)
503
531
  try:
504
532
  if not _state.dbs.current().table_exists(spec_table, spec_schema):
505
- raise _state.ErrInfo(
533
+ raise ErrInfo(
506
534
  type="cmd",
507
535
  command_text=kwargs["metacommandline"],
508
536
  other_msg=f"Table {spec_table} does not exist",
509
537
  )
510
538
  except Exception:
511
- pass
539
+ pass # Best-effort check; some adapters lack information_schema.
512
540
  curs = _state.dbs.current().cursor()
513
541
  cmd = f"select * from {tbl1};"
514
542
  curs.execute(cmd)
@@ -517,7 +545,7 @@ def x_prompt_action(**kwargs: Any) -> None:
517
545
  cmd = f"select * from {tbl1} order by sequence;"
518
546
  curs.execute(cmd)
519
547
  if not ("label" in colhdrs and "prompt" in colhdrs and "script" in colhdrs):
520
- raise _state.ErrInfo(
548
+ raise ErrInfo(
521
549
  type="cmd",
522
550
  command_text=kwargs["metacommandline"],
523
551
  other_msg="The columns 'label', 'prompt', and 'script' are required, but one or more is missing.",
@@ -528,20 +556,20 @@ def x_prompt_action(**kwargs: Any) -> None:
528
556
  v = dict(zip(colhdrs, r))
529
557
  button_label = v.get("label")
530
558
  if not button_label:
531
- raise _state.ErrInfo(
559
+ raise ErrInfo(
532
560
  type="cmd",
533
561
  command_text=kwargs["metacommandline"],
534
562
  other_msg="A button label must be provided for all of the action specifications.",
535
563
  )
536
564
  prompt_msg = v.get("prompt")
537
565
  if not prompt_msg:
538
- raise _state.ErrInfo(
566
+ raise ErrInfo(
539
567
  type="cmd",
540
568
  command_text=kwargs["metacommandline"],
541
569
  other_msg="A prompt must be provided for all of the action specifications.",
542
570
  )
543
571
  action_list.append(
544
- _state.ActionSpec(
572
+ ActionSpec(
545
573
  button_label,
546
574
  prompt_msg,
547
575
  v["script"],
@@ -553,7 +581,7 @@ def x_prompt_action(**kwargs: Any) -> None:
553
581
  db = _state.dbs.current()
554
582
  sq_name = db.schema_qualified_table_name(display_schema, display_table)
555
583
  colnames, rows = db.select_data(f"select * from {sq_name};")
556
- _state.enable_gui()
584
+ enable_gui()
557
585
  return_queue = _queue.Queue()
558
586
  gui_args = {
559
587
  "title": "Actions",
@@ -565,15 +593,14 @@ def x_prompt_action(**kwargs: Any) -> None:
565
593
  "column_headers": colnames,
566
594
  "rowset": rows,
567
595
  }
568
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_ACTION, gui_args, return_queue))
596
+ _state.gui_manager_queue.put(GuiSpec(GUI_ACTION, gui_args, return_queue))
569
597
  user_response = return_queue.get(block=True)
570
598
  btn = user_response["button"]
571
- script, line_no = _state.current_script_line()
572
- if not btn:
573
- if _state.status.cancel_halt:
574
- msg = f"Halted from entry form {tbl1}"
575
- _state.exec_log.log_exit_halt(script, line_no, msg)
576
- _state.exit_now(2, None)
599
+ script, line_no = current_script_line()
600
+ if not btn and _state.status.cancel_halt:
601
+ msg = f"Halted from entry form {tbl1}"
602
+ _state.exec_log.log_exit_halt(script, line_no, msg)
603
+ exit_now(2, None)
577
604
 
578
605
 
579
606
  def x_prompt_savefile(**kwargs: Any) -> None:
@@ -586,19 +613,19 @@ def x_prompt_savefile(**kwargs: Any) -> None:
586
613
  try:
587
614
  subvarset = _state.subvars if sub_name[0] != "~" else _state.commandliststack[-1].localvars
588
615
  subvarset.remove_substitution(sub_name)
589
- script, lno = _state.current_script_line()
590
- working_dir = startdir if startdir is not None else os.path.dirname(os.path.abspath(script))
591
- _state.enable_gui()
616
+ script, lno = current_script_line()
617
+ working_dir = startdir if startdir is not None else str(Path(script).resolve().parent)
618
+ enable_gui()
592
619
  return_queue = _queue.Queue()
593
620
  gui_args = {"working_dir": working_dir, "script": script}
594
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_SAVEFILE, gui_args, return_queue))
621
+ _state.gui_manager_queue.put(GuiSpec(GUI_SAVEFILE, gui_args, return_queue))
595
622
  user_response = return_queue.get(block=True)
596
623
  fn = user_response["filename"]
597
624
  if not fn:
598
625
  if _state.status.cancel_halt:
599
626
  msg = "Halted from prompt for name of file to save"
600
627
  _state.exec_log.log_exit_halt(script, lno, msg)
601
- _state.exit_now(2, None)
628
+ exit_now(2, None)
602
629
  else:
603
630
  if os.name != "posix":
604
631
  fn = fn.replace("/", "\\")
@@ -609,7 +636,7 @@ def x_prompt_savefile(**kwargs: Any) -> None:
609
636
  if sub_name2 is not None:
610
637
  subvarset2 = _state.subvars if sub_name2[0] != "~" else _state.commandliststack[-1].localvars
611
638
  subvarset2.remove_substitution(sub_name2)
612
- basefn = os.path.basename(fn)
639
+ basefn = Path(fn).name
613
640
  subvarset2.add_substitution(sub_name2, basefn)
614
641
  _state.exec_log.log_status_info(
615
642
  f"Substitution variable {sub_name2} set to filename {basefn} at line {lno} of {script}",
@@ -617,7 +644,7 @@ def x_prompt_savefile(**kwargs: Any) -> None:
617
644
  if sub_name3 is not None:
618
645
  subvarset3 = _state.subvars if sub_name3[0] != "~" else _state.commandliststack[-1].localvars
619
646
  subvarset3.remove_substitution(sub_name3)
620
- dirname = os.path.dirname(fn)
647
+ dirname = str(Path(fn).parent)
621
648
  if os.name != "posix":
622
649
  dirname = dirname.replace("/", "\\")
623
650
  subvarset3.add_substitution(sub_name3, dirname)
@@ -627,7 +654,7 @@ def x_prompt_savefile(**kwargs: Any) -> None:
627
654
  if sub_name4 is not None:
628
655
  subvarset4 = _state.subvars if sub_name4[0] != "~" else _state.commandliststack[-1].localvars
629
656
  subvarset4.remove_substitution(sub_name4)
630
- root, ext = os.path.splitext(fn)
657
+ ext = Path(fn).suffix
631
658
  if ext is None:
632
659
  subvarset4.add_substitution(sub_name4, "")
633
660
  else:
@@ -636,13 +663,11 @@ def x_prompt_savefile(**kwargs: Any) -> None:
636
663
  if sub_name5 is not None:
637
664
  subvarset5 = _state.subvars if sub_name5[0] != "~" else _state.commandliststack[-1].localvars
638
665
  subvarset5.remove_substitution(sub_name5)
639
- basefn = os.path.basename(fn)
640
- root, ext = os.path.splitext(basefn)
641
- subvarset5.add_substitution(sub_name5, root)
642
- except (_state.ErrInfo, SystemExit):
666
+ subvarset5.add_substitution(sub_name5, Path(fn).stem)
667
+ except (ErrInfo, SystemExit):
643
668
  raise
644
669
  except Exception:
645
- raise _state.ErrInfo(type="exception", exception_msg=_state.exception_desc())
670
+ raise ErrInfo(type="exception", exception_msg=exception_desc())
646
671
  return None
647
672
 
648
673
 
@@ -654,26 +679,26 @@ def x_prompt_openfile(**kwargs: Any) -> None:
654
679
  sub_name5 = kwargs["fnbase_match"]
655
680
  startdir = kwargs["startdir"]
656
681
  if sub_name2 is not None and sub_name2 == sub_name:
657
- raise _state.ErrInfo(
682
+ raise ErrInfo(
658
683
  type="error",
659
684
  other_msg="Different values can't be assigned to the same substitution variable.",
660
685
  )
661
686
  try:
662
687
  subvarset = _state.subvars if sub_name[0] != "~" else _state.commandliststack[-1].localvars
663
688
  subvarset.remove_substitution(sub_name)
664
- script, lno = _state.current_script_line()
665
- working_dir = startdir if startdir is not None else os.path.dirname(os.path.abspath(script))
666
- _state.enable_gui()
689
+ script, lno = current_script_line()
690
+ working_dir = startdir if startdir is not None else str(Path(script).resolve().parent)
691
+ enable_gui()
667
692
  return_queue = _queue.Queue()
668
693
  gui_args = {"working_dir": working_dir, "script": script}
669
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_OPENFILE, gui_args, return_queue))
694
+ _state.gui_manager_queue.put(GuiSpec(GUI_OPENFILE, gui_args, return_queue))
670
695
  user_response = return_queue.get(block=True)
671
696
  fn = user_response["filename"]
672
697
  if not fn:
673
698
  if _state.status.cancel_halt:
674
699
  msg = "Halted from prompt for name of file to open"
675
700
  _state.exec_log.log_exit_halt(script, lno, msg)
676
- _state.exit_now(2, None)
701
+ exit_now(2, None)
677
702
  else:
678
703
  if os.name != "posix":
679
704
  fn = fn.replace("/", "\\")
@@ -684,19 +709,19 @@ def x_prompt_openfile(**kwargs: Any) -> None:
684
709
  if sub_name2 is not None:
685
710
  subvarset2 = _state.subvars if sub_name2[0] != "~" else _state.commandliststack[-1].localvars
686
711
  subvarset2.remove_substitution(sub_name2)
687
- basefn = os.path.basename(fn)
712
+ basefn = Path(fn).name
688
713
  subvarset2.add_substitution(sub_name2, basefn)
689
714
  if sub_name3 is not None:
690
715
  subvarset3 = _state.subvars if sub_name3[0] != "~" else _state.commandliststack[-1].localvars
691
716
  subvarset3.remove_substitution(sub_name3)
692
- dirname = os.path.dirname(fn)
717
+ dirname = str(Path(fn).parent)
693
718
  if os.name != "posix":
694
719
  dirname = dirname.replace("/", "\\")
695
720
  subvarset3.add_substitution(sub_name3, dirname)
696
721
  if sub_name4 is not None:
697
722
  subvarset4 = _state.subvars if sub_name4[0] != "~" else _state.commandliststack[-1].localvars
698
723
  subvarset4.remove_substitution(sub_name4)
699
- root, ext = os.path.splitext(fn)
724
+ ext = Path(fn).suffix
700
725
  if ext is None:
701
726
  subvarset4.add_substitution(sub_name4, "")
702
727
  else:
@@ -705,13 +730,11 @@ def x_prompt_openfile(**kwargs: Any) -> None:
705
730
  if sub_name5 is not None:
706
731
  subvarset5 = _state.subvars if sub_name5[0] != "~" else _state.commandliststack[-1].localvars
707
732
  subvarset5.remove_substitution(sub_name5)
708
- basefn = os.path.basename(fn)
709
- root, ext = os.path.splitext(basefn)
710
- subvarset5.add_substitution(sub_name5, root)
711
- except (_state.ErrInfo, SystemExit):
733
+ subvarset5.add_substitution(sub_name5, Path(fn).stem)
734
+ except (ErrInfo, SystemExit):
712
735
  raise
713
736
  except Exception:
714
- raise _state.ErrInfo(type="exception", exception_msg=_state.exception_desc())
737
+ raise ErrInfo(type="exception", exception_msg=exception_desc())
715
738
  return None
716
739
 
717
740
 
@@ -722,32 +745,32 @@ def x_prompt_directory(**kwargs: Any) -> None:
722
745
  try:
723
746
  subvarset = _state.subvars if sub_name[0] != "~" else _state.commandliststack[-1].localvars
724
747
  subvarset.remove_substitution(sub_name)
725
- script, lno = _state.current_script_line()
726
- working_dir = startdir if startdir is not None else os.path.dirname(os.path.abspath(script))
727
- _state.enable_gui()
748
+ script, lno = current_script_line()
749
+ working_dir = startdir if startdir is not None else str(Path(script).resolve().parent)
750
+ enable_gui()
728
751
  return_queue = _queue.Queue()
729
752
  gui_args = {"working_dir": working_dir, "script": script}
730
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_DIRECTORY, gui_args, return_queue))
753
+ _state.gui_manager_queue.put(GuiSpec(GUI_DIRECTORY, gui_args, return_queue))
731
754
  user_response = return_queue.get(block=True)
732
755
  dirname = user_response["directory"]
733
756
  if not dirname:
734
757
  if _state.status.cancel_halt:
735
758
  msg = "Halted from prompt for name of directory"
736
759
  _state.exec_log.log_exit_halt(script, lno, msg)
737
- _state.exit_now(2, None)
760
+ exit_now(2, None)
738
761
  else:
739
762
  if fullpath is not None:
740
- dirname = os.path.abspath(dirname)
763
+ dirname = str(Path(dirname).resolve())
741
764
  if os.name != "posix":
742
765
  dirname = dirname.replace("/", "\\")
743
766
  subvarset.add_substitution(sub_name, dirname)
744
767
  _state.exec_log.log_status_info(
745
768
  f"Substitution string {sub_name} set to directory {dirname} at line {lno} of {script}",
746
769
  )
747
- except (_state.ErrInfo, SystemExit):
770
+ except (ErrInfo, SystemExit):
748
771
  raise
749
772
  except Exception:
750
- raise _state.ErrInfo(type="exception", exception_msg=_state.exception_desc())
773
+ raise ErrInfo(type="exception", exception_msg=exception_desc())
751
774
  return None
752
775
 
753
776
 
@@ -759,20 +782,20 @@ def prompt_select_rows(button_list: list, **kwargs: Any) -> Any:
759
782
  table2 = kwargs["table2"]
760
783
  alias2 = kwargs["alias2"]
761
784
  msg = kwargs["msg"]
762
- help_url = _state.unquoted(kwargs["help"])
785
+ help_url = unquoted(kwargs["help"])
763
786
  badaliasmsg = "Alias %s is not recognized."
764
787
  if alias1 is not None:
765
788
  try:
766
789
  db1 = _state.dbs.aliased_as(alias1)
767
790
  except Exception:
768
- raise _state.ErrInfo(type="error", other_msg=badaliasmsg % alias1)
791
+ raise ErrInfo(type="error", other_msg=badaliasmsg % alias1)
769
792
  else:
770
793
  db1 = _state.dbs.current()
771
794
  if alias2 is not None:
772
795
  try:
773
796
  db2 = _state.dbs.aliased_as(alias2)
774
797
  except Exception:
775
- raise _state.ErrInfo(type="error", other_msg=badaliasmsg % alias2)
798
+ raise ErrInfo(type="error", other_msg=badaliasmsg % alias2)
776
799
  else:
777
800
  db2 = _state.dbs.current()
778
801
  sq_name1 = db1.schema_qualified_table_name(schema1, table1)
@@ -781,12 +804,12 @@ def prompt_select_rows(button_list: list, **kwargs: Any) -> Any:
781
804
  sql2 = f"select * from {sq_name2};"
782
805
  hdrs1, rows1 = db1.select_data(sql1)
783
806
  if len(rows1) == 0:
784
- raise _state.ErrInfo("error", other_msg=f"There are no data in {sq_name1}.")
807
+ raise ErrInfo("error", other_msg=f"There are no data in {sq_name1}.")
785
808
  hdrs2, rows2 = db2.select_data(sql2)
786
809
  missing_hdrs = [hdr for hdr in hdrs1 if hdr not in hdrs2]
787
810
  if len(missing_hdrs) > 0:
788
- raise _state.ErrInfo("error", other_msg=f"Columns [{', '.join(missing_hdrs)}] are missing from {sq_name2}.")
789
- _state.enable_gui()
811
+ raise ErrInfo("error", other_msg=f"Columns [{', '.join(missing_hdrs)}] are missing from {sq_name2}.")
812
+ enable_gui()
790
813
  return_queue = _queue.Queue()
791
814
  gui_args = {
792
815
  "title": "Select rows",
@@ -800,15 +823,14 @@ def prompt_select_rows(button_list: list, **kwargs: Any) -> Any:
800
823
  "table2": sq_name2,
801
824
  "help_url": help_url,
802
825
  }
803
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_SELECTROWS, gui_args, return_queue))
826
+ _state.gui_manager_queue.put(GuiSpec(GUI_SELECTROWS, gui_args, return_queue))
804
827
  user_response = return_queue.get(block=True)
805
828
  btn = user_response["button"]
806
- if btn is None:
807
- if _state.status.cancel_halt:
808
- script, line_no = _state.current_script_line()
809
- msg = f"Halted from selection of rows from {sq_name1} into {sq_name2}"
810
- _state.exec_log.log_exit_halt(script, line_no, msg)
811
- _state.exit_now(2, None)
829
+ if btn is None and _state.status.cancel_halt:
830
+ script, line_no = current_script_line()
831
+ msg = f"Halted from selection of rows from {sq_name1} into {sq_name2}"
832
+ _state.exec_log.log_exit_halt(script, line_no, msg)
833
+ exit_now(2, None)
812
834
  return btn
813
835
 
814
836
 
@@ -820,22 +842,22 @@ def x_prompt_credentials(**kwargs: Any) -> None:
820
842
  message = kwargs["message"]
821
843
  user = kwargs["user"]
822
844
  pw = kwargs["pw"]
823
- _state.gui_credentials(message, username=user, pwtext=pw, cmd=kwargs["metacommandline"])
845
+ gui_credentials(message, username=user, pwtext=pw, cmd=kwargs["metacommandline"])
824
846
  return None
825
847
 
826
848
 
827
849
  def x_prompt_connect(**kwargs: Any) -> None:
828
850
  alias = kwargs["alias"]
829
851
  message = kwargs["message"]
830
- help_url = _state.unquoted(kwargs["help"])
831
- _state.gui_connect(alias, message, help_url=help_url, cmd=kwargs["metacommandline"])
852
+ help_url = unquoted(kwargs["help"])
853
+ gui_connect(alias, message, help_url=help_url, cmd=kwargs["metacommandline"])
832
854
  return None
833
855
 
834
856
 
835
857
  def x_ask(**kwargs: Any) -> None:
836
858
  message = kwargs["question"]
837
859
  subvar = kwargs["match"]
838
- script, lno = _state.current_script_line()
860
+ script, lno = current_script_line()
839
861
  if _state.gui_console:
840
862
  return_queue = _queue.Queue()
841
863
  gui_args = {
@@ -844,23 +866,23 @@ def x_ask(**kwargs: Any) -> None:
844
866
  "button_list": [("Yes", 1, "y"), ("No", 0, "n")],
845
867
  "free": False,
846
868
  }
847
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_DISPLAY, gui_args, return_queue))
869
+ _state.gui_manager_queue.put(GuiSpec(GUI_DISPLAY, gui_args, return_queue))
848
870
  user_response = return_queue.get(block=True)
849
871
  btn = user_response["button"]
850
872
  if btn is None:
851
873
  if _state.status.cancel_halt:
852
874
  _state.exec_log.log_exit_halt(script, lno, msg="Quit from ASK metacommand")
853
- _state.exit_now(2, None)
875
+ exit_now(2, None)
854
876
  else:
855
877
  respstr = "Yes" if btn == 1 else "No"
856
878
  else:
857
879
  if os.name == "posix":
858
- resp = _state.get_yn(message)
880
+ resp = get_yn(message)
859
881
  else:
860
- resp = _state.get_yn_win(message)
882
+ resp = get_yn_win(message)
861
883
  if resp == chr(27):
862
884
  _state.exec_log.log_exit_halt(script, lno, msg="Quit from ASK metacommand")
863
- _state.exit_now(2, None)
885
+ exit_now(2, None)
864
886
  else:
865
887
  respstr = "Yes" if resp == "y" else "No"
866
888
  subvarset = _state.subvars if subvar[0] != "~" else _state.commandliststack[-1].localvars
@@ -891,39 +913,39 @@ def x_pause(**kwargs: Any) -> None:
891
913
  use_gui = False
892
914
  if _state.gui_manager_thread:
893
915
  return_queue = _queue.Queue()
894
- _state.gui_manager_queue.put(_state.GuiSpec(_state.QUERY_CONSOLE, {}, return_queue))
916
+ _state.gui_manager_queue.put(GuiSpec(QUERY_CONSOLE, {}, return_queue))
895
917
  user_response = return_queue.get(block=True)
896
918
  use_gui = user_response["console_running"]
897
919
  if use_gui or _state.conf.gui_level > 0:
898
- _state.enable_gui()
920
+ enable_gui()
899
921
  return_queue = _queue.Queue()
900
922
  gui_args = {
901
- "title": f"Script {_state.current_script_line()[0]}",
923
+ "title": f"Script {current_script_line()[0]}",
902
924
  "message": msg,
903
925
  "countdown": maxtime_secs,
904
926
  }
905
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_PAUSE, gui_args, return_queue))
927
+ _state.gui_manager_queue.put(GuiSpec(GUI_PAUSE, gui_args, return_queue))
906
928
  user_response = return_queue.get(block=True)
907
929
  quit = user_response["quit"]
908
930
  return_queue.task_done()
909
931
  else:
910
932
  timed_out = False
911
933
  if os.name == "posix":
912
- rv = _state.pause(msg, action=action, countdown=maxtime_secs, timeunit=timeunit)
934
+ rv = pause(msg, action=action, countdown=maxtime_secs, timeunit=timeunit)
913
935
  else:
914
- rv = _state.pause_win(msg, action=action, countdown=maxtime_secs, timeunit=timeunit)
936
+ rv = pause_win(msg, action=action, countdown=maxtime_secs, timeunit=timeunit)
915
937
  quit = rv == 1
916
938
  timed_out = rv == 2
917
939
  if (quit or (timed_out and action == "halt")) and _state.status.cancel_halt:
918
- _state.exec_log.log_exit_halt(*_state.current_script_line(), msg=quitmsg)
919
- _state.exit_now(2, None)
940
+ _state.exec_log.log_exit_halt(*current_script_line(), msg=quitmsg)
941
+ exit_now(2, None)
920
942
  return None
921
943
 
922
944
 
923
945
  def x_halt_msg(**kwargs: Any) -> None:
924
946
  errmsg = kwargs["errmsg"]
925
947
  tee = kwargs["tee"]
926
- tee = False if not tee else True
948
+ tee = bool(tee)
927
949
  outf = kwargs["filename"]
928
950
  errlevel = kwargs["errorlevel"]
929
951
  if errlevel:
@@ -932,8 +954,8 @@ def x_halt_msg(**kwargs: Any) -> None:
932
954
  errlevel = 3
933
955
  conf = _state.conf
934
956
  if outf:
935
- _state.check_dir(outf)
936
- of = _state.EncodedFile(outf, conf.output_encoding).open("a")
957
+ check_dir(outf)
958
+ of = EncodedFile(outf, conf.output_encoding).open("a")
937
959
  of.write(f"{errmsg}\n")
938
960
  of.close()
939
961
  schema = kwargs.get("schema")
@@ -945,7 +967,7 @@ def x_halt_msg(**kwargs: Any) -> None:
945
967
  headers, rows = db.select_data(sql)
946
968
  else:
947
969
  headers, rows = None, None
948
- _state.enable_gui()
970
+ enable_gui()
949
971
  return_queue = _queue.Queue()
950
972
  gui_args = {
951
973
  "title": "HALT",
@@ -956,19 +978,19 @@ def x_halt_msg(**kwargs: Any) -> None:
956
978
  "rowset": rows,
957
979
  "help_url": None,
958
980
  }
959
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_HALT, gui_args, return_queue))
981
+ _state.gui_manager_queue.put(GuiSpec(GUI_HALT, gui_args, return_queue))
960
982
  return_queue.get(block=True)
961
- _state.exec_log.log_exit_halt(*_state.current_script_line(), msg=errmsg)
962
- _state.exit_now(errlevel, None)
983
+ _state.exec_log.log_exit_halt(*current_script_line(), msg=errmsg)
984
+ exit_now(errlevel, None)
963
985
 
964
986
 
965
987
  def x_msg(**kwargs: Any) -> None:
966
988
  message = kwargs["message"]
967
- _state.current_script_line()
968
- _state.enable_gui()
989
+ current_script_line()
990
+ enable_gui()
969
991
  return_queue = _queue.Queue()
970
992
  gui_args = {"title": "Message", "message": message}
971
- _state.gui_manager_queue.put(_state.GuiSpec(_state.GUI_MSG, gui_args, return_queue))
993
+ _state.gui_manager_queue.put(GuiSpec(GUI_MSG, gui_args, return_queue))
972
994
  return_queue.get(block=True)
973
995
  return None
974
996