holado 0.10.0__py3-none-any.whl → 0.10.1__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 holado might be problematic. Click here for more details.

@@ -295,15 +295,16 @@ class SessionContext(Context):
295
295
  scenario_context = ScenarioContext(scenario)
296
296
  self.get_feature_context().add_scenario(scenario_context)
297
297
 
298
- # Set variable with scenario context instance
299
- self.get_scenario_context().get_variable_manager().register_variable("SCENARIO_CONTEXT", self.get_scenario_context())
300
-
301
- # Report
298
+ # Report: create scenario report
302
299
  try:
303
300
  self.report_manager.before_scenario(scenario_context, scenario)
304
301
  except:
305
302
  logger.exception(f"{log_prefix}Error while updating report before scenario")
306
303
 
304
+ # Set variable with scenario context instance
305
+ # Note: must be after scenario report creation
306
+ self.get_scenario_context().get_variable_manager().register_variable("SCENARIO_CONTEXT", self.get_scenario_context())
307
+
307
308
  # Behave context
308
309
  try:
309
310
  self.behave_manager.before_scenario()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: holado
3
- Version: 0.10.0
3
+ Version: 0.10.1
4
4
  Summary: HolAdo framework
5
5
  Project-URL: Homepage, https://gitlab.com/holado_framework/python
6
6
  Project-URL: Issues, https://gitlab.com/holado_framework/python/-/issues
@@ -4,7 +4,7 @@ holado/common/__init__.py,sha256=ZjXM-FRQgnfzRNXqcvJOGewDHVRR-U5-ugStSs8U2Xs,152
4
4
  holado/common/context/__init__.py,sha256=3jJBLm8myrYF9jbdV1EhIA6BtnlmjX33eeoDpTzwmLA,1604
5
5
  holado/common/context/context.py,sha256=MV8A6JSpUcTcfia_QzjyDLybQC50rZ-NA0ffotnHXQY,11994
6
6
  holado/common/context/service_manager.py,sha256=LaCn8ukE1aqJynmwoexAYj5hCkdb_F3hXRtUBGqorUE,14087
7
- holado/common/context/session_context.py,sha256=dw4ozOn3o7EZwyfa_luMXLis5BO1z2HpmP91-GFKZLc,23391
7
+ holado/common/context/session_context.py,sha256=TOT2_CqeqQtvuGBfVnuY1cbj8PGhyLPv0mlPJD0e6V0,23474
8
8
  holado/common/handlers/__init__.py,sha256=d0KDUpaAAw1eBXyX08gaRh4RECnJlXjYQ0TcU-Ndicc,1372
9
9
  holado/common/handlers/enums.py,sha256=ieqKVoukEiNyfE3KrKmMOImdbFS1ocUMud8JHe2xNLs,1662
10
10
  holado/common/handlers/object.py,sha256=rDaav8zHTYfKVEaLtEdeXMxYXATGVcs2a7um1f5MvCs,7205
@@ -14,7 +14,7 @@ holado/common/tools/gc_manager.py,sha256=TjQg7MisGRhxuiQ22hB3IuqNhnWCVEWpU253-rO
14
14
  holado_ais/__init__.py,sha256=Mudcgu_7p1hBDBs6LpSz757H4haB0yLHgT70sznG82c,1807
15
15
  holado_ais/ais/MaritimeIdentificationDigits.csv,sha256=r-uHt4wOvxlbA26af9e-N3BKbuiMf6ia3PN0ZGfYk2A,8547
16
16
  holado_ais/ais/ais_manager.py,sha256=QvN94JoUBbSXT08HABl2FNsAVOM-YCmQO5tN9COg6Rc,6496
17
- holado_ais/ais/ais_messages.py,sha256=ppJQOP4L0CAYlG5AFESeDLziN9aK2Q92tXF-wZ6Xkl0,17520
17
+ holado_ais/ais/ais_messages.py,sha256=J-GZJAY2RZpSS3OwzQJc6B_HsmdtRXLAcbfaP9APbUA,17414
18
18
  holado_ais/ais/ais_payload.py,sha256=mdOa_4JIbkFLK4_KUmQF5jUt1nLxvZhmIcqK8i-YY6w,1791
19
19
  holado_ais/ais/enums.py,sha256=bsqfJVg65fWiJwL_VlSKwKgTY0pLoDcI4T06aEOcQnw,1108
20
20
  holado_ais/ais/patch_pyais.py,sha256=M4Fa8GZubXx4auRsk5I1yQPC40IR1p-1iVZIc4PXFfk,49850
@@ -302,7 +302,7 @@ holado_keycloak/tools/keycloak/keycloak_client.py,sha256=QXAsf9rF0pKq1dHhXeZFZOx
302
302
  holado_logging/__init__.py,sha256=erlTOOiI7SVryt3P6X3F2cEvdXflD85su8faAsTMN1Y,2259
303
303
  holado_logging/common/logging/holado_logger.py,sha256=FB5J_YbG41FGljAywMdCPVFJ2BdpMBS8AWPsT9B52S8,3160
304
304
  holado_logging/common/logging/log_config.py,sha256=u6Ax3S1TdBAzeUD3DAcw5WXPYEJeiQie7T_x_K6ZKeo,7049
305
- holado_logging/common/logging/log_manager.py,sha256=gq92IAfnKEX-GKUHexNVgEI0UUrUdiWaC5GLcSTAaUE,13604
305
+ holado_logging/common/logging/log_manager.py,sha256=5dHaqtZlcB78YE8Xk_7KiSd_-toOQFLVIEWBNoMseKI,15477
306
306
  holado_multitask/__init__.py,sha256=EwuwiBmp8ICbPZ8CKPju8tHRTh2rG68PB_wGXczY9rw,2143
307
307
  holado_multitask/multiprocessing/function_process.py,sha256=HFXjpnzWed5J1tjmWMQyRx8AGcY6D1laegHqZ5j1dco,4550
308
308
  holado_multitask/multiprocessing/periodic_function_process.py,sha256=ubbdm2XSwjBGuDDXWX2b-lo_Abkivh4Blj9C8axsa4o,6779
@@ -318,7 +318,7 @@ holado_multitask/multithreading/periodicfunctionthreaded.py,sha256=PCBKpbOIThNGL
318
318
  holado_multitask/multithreading/thread.py,sha256=dKgw1301nTv-8g7y29ecza9ZB5nhbAKCYs1p4KdmLUQ,9376
319
319
  holado_multitask/multithreading/threadsmanager.py,sha256=5a-kV8t0-lwL6a9vCLL3_Oi-i67epcqOWWBz6vIJFEU,8462
320
320
  holado_multitask/multithreading/timer.py,sha256=77tI9WITN2CpQoY82SUYinoGzfx_stpqf2fRLUI1Itk,2638
321
- holado_multitask/multithreading/context/thread_context.py,sha256=pGcySQnqx92NIaVT64Ra3gIV7BpgBFfEy3N8PYTCOlI,3570
321
+ holado_multitask/multithreading/context/thread_context.py,sha256=EWn8zqQZgLlnNhgMsBLULUke3J1VFLtdMR-Jukpvfiw,3773
322
322
  holado_multitask/multithreading/reflection/inspect.py,sha256=yntSXI6YEZDBfqoDnB0KS6HGxs__qTQFwF6FLUDZqCI,2137
323
323
  holado_multitask/multithreading/reflection/sys.py,sha256=1Q7hX9nddjqUvfn-k39SuPQhwLjXJmB9gegV6vNM534,1558
324
324
  holado_multitask/multithreading/reflection/traceback.py,sha256=Bnq-Xp0aA3D4kYtb7JJyXNASw3iU35WRSePredxWziQ,1891
@@ -351,7 +351,7 @@ holado_python/common/tools/comparators/type_comparator.py,sha256=EePE-LrqUeICEQP
351
351
  holado_python/standard_library/csv.py,sha256=G98oLsgovghpiQf4k06bUlXVvLy_D5H9qTK8e68UdcM,8937
352
352
  holado_python/standard_library/hashlib.py,sha256=5hMcHxc4BR4G0uNRqezTonflH_AFSLQum37Kqv1rRSU,4179
353
353
  holado_python/standard_library/multiprocessing.py,sha256=vThmJzdDTtdFyGUL3i3evmt2JBUK-jrorKbEtQ7TSFU,2786
354
- holado_python/standard_library/queue.py,sha256=RIFid85_CMFmanpt61LSaYqeHdlFwAuhcpBhxgyWj_o,3059
354
+ holado_python/standard_library/queue.py,sha256=1iSXGfM4VVYZ9T9nPGholGAxxzku6MmxrTkStofxr0E,3058
355
355
  holado_python/standard_library/typing.py,sha256=8F9Iolh-c9GbDGlNr3V6uPdTEhSBdkLQu46oVwHPYKk,7693
356
356
  holado_python/standard_library/socket/blocking_socket.py,sha256=d7LnOoHY8k6WW4Zzy54AITw4-QDxaXTfXtWUCBBWfI8,10366
357
357
  holado_python/standard_library/socket/echo_server.py,sha256=ntApbwcckiEEBw-qjE487An81i4IEVFRPkoFbUrcCL4,1793
@@ -363,8 +363,8 @@ holado_python/standard_library/ssl/resources/certificates/NOTES.txt,sha256=GlPGG
363
363
  holado_python/standard_library/ssl/resources/certificates/localhost.crt,sha256=iLmZpDuOQVawUlbZkb72g2-uv1c4SAmRJOrm4Th5anY,1123
364
364
  holado_python/standard_library/ssl/resources/certificates/localhost.key,sha256=lP2NCvB9mr2E5sk8whA8FyQRcyU6H7sdWkJeKz80Hyc,1704
365
365
  holado_python/standard_library/ssl/resources/certificates/rootCACert.pem,sha256=ECQDZ8OHRfqpZHCu6JRLMUjiONaPIhKZQF0-kidVrWQ,1424
366
- holado_python/standard_library/ssl/resources/certificates/tcpbin.crt,sha256=fNTwFb1YbCrDS6217atgX9wMP7xEAo3-POIVaWC_00A,1237
367
- holado_python/standard_library/ssl/resources/certificates/tcpbin.key,sha256=puwUXC55YMr8AmXA77WiqYElt-JDYfhDKP8l6iELjd4,1704
366
+ holado_python/standard_library/ssl/resources/certificates/tcpbin.crt,sha256=vD18qCn_hEkCOhFCiTudZnPaQ4huFMZVpA0PMChJv4c,1237
367
+ holado_python/standard_library/ssl/resources/certificates/tcpbin.key,sha256=eQ2wHYKJkQfKHVDYA49pvtRIZvxuKonUHx54-05YXV4,1704
368
368
  holado_python/tests/behave/steps/__init__.py,sha256=TWEk-kBTTDHi9I4nuu48nufmNMdZ9FHAhPZv0A_cWzc,1661
369
369
  holado_python/tests/behave/steps/convert_steps.py,sha256=bZqRvJVp_u6fSPpdu4ne9NwVyZmui7R-AVdO2-H-I1A,2728
370
370
  holado_python/tests/behave/steps/iterable_steps.py,sha256=f4vGIWBH8Qnjq69Q-ZBluYyctQ8SKauazTc41dsktZA,4041
@@ -428,11 +428,11 @@ holado_s3/tools/s3/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuF
428
428
  holado_s3/tools/s3/boto3_s3_client.py,sha256=NaYTvyxqiUZ5UshpLONSLLDEBHQU_etDlXDOqGNxR-w,2360
429
429
  holado_s3/tools/s3/minio_client.py,sha256=B_Ie2fNIqyJE5vXO4iQw3Tg5yk8k-yGBuJtaf4aDQyU,3193
430
430
  holado_s3/tools/s3/moto_server.py,sha256=zft4KgYIFbJot0JyQJCAwEcbGDJIKinqOUIKRuSrSHE,2493
431
- holado_scripting/__init__.py,sha256=wsTcscy-q0EoQq2Hmf1KbEejIez2UUfLp3TdQHMVWlc,3744
431
+ holado_scripting/__init__.py,sha256=1VICcEckplGOYwcPJ6U0TbghWigTOEtcWuYL6z_U14Y,3908
432
432
  holado_scripting/common/tools/dynamic_text_manager.py,sha256=dR9DGVj4nb_icFlnLB3jRQu8DDwTuC3tX46BDyi9xec,3332
433
433
  holado_scripting/common/tools/evaluate_parameters.py,sha256=zru4_vwqIx_KxWVG_luOcmr-0ywjmY7aaEN4TCvCjb4,10405
434
434
  holado_scripting/common/tools/expression_evaluator.py,sha256=pig2dNisHTuRnLh7vR6ciwn0o8rnDvVOQKT44iF0QB4,24309
435
- holado_scripting/common/tools/variable_manager.py,sha256=VGJH_OYPduTCSA_CLMpZUiC_nqAJJtGWZ2mwPEGzpW8,15672
435
+ holado_scripting/common/tools/variable_manager.py,sha256=oFJ8vNMdqA2NO_vAOpUNWetE1i3_2-_jynNJC7Dw_Q0,17611
436
436
  holado_scripting/tests/behave/steps/__init__.py,sha256=GSug7OdldGvwbSuJOuLQVIZ8qU4bsfdvTY6VzSnMbTE,1544
437
437
  holado_scripting/tests/behave/steps/common/tools/variable_convert_steps.py,sha256=sPxZ1U1Wm9LBUjwEKvxE2nfz6cRatlXUZCGIK-QPpi0,7902
438
438
  holado_scripting/tests/behave/steps/common/tools/variable_new_steps.py,sha256=0VqwuzKdD_ZiUxzqF5vPoTbrTIhiPOpWEXK8qljqmQA,6153
@@ -496,8 +496,8 @@ holado_test/behave/behave_manager.py,sha256=TEAfPgBQQONFn_l0s7gm7gDgWU0EejvuaPuF
496
496
  holado_test/behave/independant_runner.py,sha256=QR_IS-qkK_x2FTryb2gRQrqyBU3YUgKqsaIL2xwXPNQ,3189
497
497
  holado_test/behave/scenario/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
498
498
  holado_test/behave/scenario/behave_step_tools.py,sha256=apMS8nvdY-vbXsUIw1mVR4wOy2xWHMOCPJ1QiYNU-hI,6612
499
- holado_test/common/context/feature_context.py,sha256=9U5n-i7xdcSQlCeMM0savlek8doS5fGqkI3sFIiCGTY,3375
500
- holado_test/common/context/scenario_context.py,sha256=pkv5uC-GGQeGyu2MB6m58eWv6TPuQLTV0NM_aGMB7c8,7129
499
+ holado_test/common/context/feature_context.py,sha256=XD5t2O6IDdhh6n4K1n7u5MPm-zI3k38mun_pj8lKQGE,3575
500
+ holado_test/common/context/scenario_context.py,sha256=lj332-EsRazz91Twl64iTcrNiyqOBYCk9kD4ADl73gA,7330
501
501
  holado_test/common/context/step_context.py,sha256=jknJVU0OrzRaqlTJyhwBFjr9uKPe1dgjao32F4RGE8g,2410
502
502
  holado_test/common/exceptions/undefined_step_exception.py,sha256=SHHX22iz4Ip-V4Y3aM2EJFDt30CCS5EaauN6KB-JORo,1461
503
503
  holado_test/scenario/step_tools.py,sha256=iNay6tQPUi4sG-a8PY5LbbLpX0PRakkOj3ls98aEbHM,26375
@@ -671,7 +671,7 @@ test_holado/tools/django/api_rest/api_rest/api1/serializers.py,sha256=o_YxFr-tgC
671
671
  test_holado/tools/django/api_rest/api_rest/api1/tests.py,sha256=mrbGGRNg5jwbTJtWWa7zSKdDyeB4vmgZCRc2nk6VY-g,60
672
672
  test_holado/tools/django/api_rest/api_rest/api1/views.py,sha256=kOt2xT6bxO47_z__5yYR9kcYIWWv4qYzpX0K8Tqonik,758
673
673
  test_holado/tools/django/api_rest/api_rest/api1/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
674
- holado-0.10.0.dist-info/METADATA,sha256=oEi5XHFtWVdRSs9H_2nAI3A3dzSXFYiZosDZqVyflK4,7672
675
- holado-0.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
676
- holado-0.10.0.dist-info/licenses/LICENSE,sha256=IgGmNlcFHnbp7UWrLJqAFvs_HIgjJDTmjCNRircJLsk,1070
677
- holado-0.10.0.dist-info/RECORD,,
674
+ holado-0.10.1.dist-info/METADATA,sha256=Q5DwNRjrAWS6lrHGiUbz7T2pJPXzlvE39zM4hnxx3I0,7672
675
+ holado-0.10.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
676
+ holado-0.10.1.dist-info/licenses/LICENSE,sha256=IgGmNlcFHnbp7UWrLJqAFvs_HIgjJDTmjCNRircJLsk,1070
677
+ holado-0.10.1.dist-info/RECORD,,
@@ -94,13 +94,14 @@ class AISMessages(object):
94
94
 
95
95
  # Extract tagblock of first sentence if present, and add tagblock information in result
96
96
  tag_block_str, _ = self.split_sentence_to_tab_block_and_message(sentences[0])
97
- if not isinstance(tag_block_str, bytes):
98
- tag_block_str = tag_block_str.encode('utf8')
99
- logger.print(f"++++++++++++ {tag_block_str=}")
100
- tag_block = TagBlock(tag_block_str)
101
- tag_block.init()
102
- tag_block_dict = tag_block.asdict() if tag_block is not None else None
103
- if tag_block_dict is not None:
97
+ if tag_block_str is None:
98
+ tag_block_dict = None
99
+ else:
100
+ if not isinstance(tag_block_str, bytes):
101
+ tag_block_str = tag_block_str.encode('utf8')
102
+ tag_block = TagBlock(tag_block_str)
103
+ tag_block.init()
104
+ tag_block_dict = tag_block.asdict()
104
105
  tag_block_dict = {k:v for k,v in tag_block_dict.items() if k != 'raw' and v is not None}
105
106
 
106
107
  # Build result
@@ -175,7 +176,6 @@ class AISMessages(object):
175
176
  seq_id = kwargs.pop('seq_id') if 'seq_id' in kwargs else self.__tag_block_group_id % 10
176
177
  group_id = kwargs.pop('group_id') if 'group_id' in kwargs else None
177
178
 
178
- logger.print(f"+++++++ encode_msg: {msg=} ; {talker_id=} ; {kwargs=}")
179
179
  sentences = pyais.encode_msg(msg, seq_id=seq_id, talker_id=talker_id, **kwargs)
180
180
  return self.__encode_add_tag_block(sentences, tag_block, with_tag_block=with_tag_block, group_id=group_id)
181
181
 
@@ -39,6 +39,7 @@ class LogManager(object):
39
39
  self.on_console = False
40
40
  self.__console_handler = None
41
41
 
42
+ # Manage file handlers
42
43
  self.in_file = True
43
44
  self.__files_lock = threading.Lock()
44
45
  self.__file_names = []
@@ -47,20 +48,26 @@ class LogManager(object):
47
48
  self.__root_file_handler = None
48
49
  self.__root_file_handler_active = False
49
50
 
51
+ # Manage file paths LIFO by loggers
52
+ self.__files_by_logger = {}
53
+
50
54
  # Initialize format according python version
51
55
  from holado_multitask.multitasking.multitask_manager import MultitaskManager
52
56
  if MultitaskManager.has_thread_native_id():
53
57
  # Exists since python 3.8
54
58
  # self.format = '{asctime:s} | {thread_native_id:-5d} | {levelname:5s} | {name:50s} | {message:s}'
55
59
  self.format = '{asctime:s} | {process:-5d}-{thread_native_id:-5d} | {levelname:5s} | {name:50s} | {message:s}'
60
+ self.format_short = '{asctime:s} | {message:s}'
56
61
  self.style = '{'
57
62
  else:
58
63
  if sys.version_info > (3, 2):
59
64
  # self.format = '{asctime:s} | {thread:-5d} | {levelname:5s} | {module:35s} | {message:s}'
60
65
  self.format = '{asctime:s} | {process:-5d}-{thread:-5d} | {levelname:5s} | {name:50s} | {message:s}'
66
+ self.format_short = '{asctime:s} | {message:s}'
61
67
  self.style = '{'
62
68
  else:
63
69
  self.format = '%(asctime)s | %(process)-5d-%(thread)-5d | %(levelname)5s | %(module)35s | %(message)s'
70
+ self.format_short = '%(asctime)s | %(message)s'
64
71
  self.style = '%'
65
72
 
66
73
  def configure(self):
@@ -193,7 +200,6 @@ class LogManager(object):
193
200
 
194
201
  def add_root_file_handler(self):
195
202
  from holado_core.common.exceptions.technical_exception import TechnicalException
196
- from holado_multitask.multitasking.multitask_manager import MultitaskManager
197
203
 
198
204
  logger_ = logging.getLogger()
199
205
 
@@ -201,13 +207,8 @@ class LogManager(object):
201
207
  raise TechnicalException("Root log file is not defined")
202
208
 
203
209
  if self.__root_file_handler is None:
204
- logger_.info("Creating file handler to root file '{}'.".format(self.__root_file_name))
205
- Path(os.path.dirname(self.__root_file_name)).mkdir(parents=True, exist_ok=True)
206
-
207
- self.__root_file_handler = logging.FileHandler(self.__root_file_name, mode='w', encoding='utf8')
208
- self.__root_file_handler.setFormatter(logging.Formatter(fmt=self.format, style=self.style))
209
- if MultitaskManager.has_thread_native_id():
210
- self.__root_file_handler.addFilter(filter_thread_native_id)
210
+ logger.info("Creating file handler to root file '{}'.".format(self.__root_file_name))
211
+ self.__root_file_handler = self.__new_file_handler(self.__root_file_name)
211
212
 
212
213
  logger_.addHandler(self.__root_file_handler)
213
214
  self.__root_file_handler_active = True
@@ -215,15 +216,13 @@ class LogManager(object):
215
216
  def remove_root_file_handler(self, do_reset=False):
216
217
  logger_ = logging.getLogger()
217
218
  if self.__root_file_handler:
218
- logger_.info(f"Removing log destination to root file '{self.__root_file_name}'.")
219
+ logger.info(f"Removing log destination to root file '{self.__root_file_name}'.")
219
220
  logger_.removeHandler(self.__root_file_handler)
220
221
  self.__root_file_handler_active = False
221
222
  if do_reset:
222
223
  self.__root_file_handler = None
223
224
 
224
225
  def add_file_handler(self, file_name, logger_=None):
225
- from holado_multitask.multitasking.multitask_manager import MultitaskManager
226
-
227
226
  if logger_ is None:
228
227
  logger_ = logging.getLogger()
229
228
 
@@ -232,35 +231,59 @@ class LogManager(object):
232
231
  self.add_log_file(file_name)
233
232
 
234
233
  if file_name in self.__file_handlers:
235
- logger_.debug("Log destination already set to file '{}'.".format(file_name))
234
+ logger.debug("Log destination already set to file '{}'.".format(file_name))
236
235
  else:
237
- logger_.info("Adding log destination to file '{}'.".format(file_name))
238
- Path(os.path.dirname(file_name)).mkdir(parents=True, exist_ok=True)
239
-
240
- file_handler = logging.FileHandler(file_name, mode='w', encoding='utf8')
241
- file_handler.setFormatter(logging.Formatter(fmt=self.format, style=self.style))
242
- if MultitaskManager.has_thread_native_id():
243
- file_handler.addFilter(filter_thread_native_id)
244
-
236
+ logger.info("Adding log destination to file '{}'.".format(file_name))
237
+ file_handler = self.__new_file_handler(file_name)
245
238
  self.__file_handlers[file_name] = file_handler
246
- logger_.addHandler(file_handler)
247
-
248
- def remove_file_handler(self, file_name, logger_=None, do_remove_log_file=True):
249
- from holado_core.common.exceptions.technical_exception import TechnicalException
239
+ self.add_existing_file_handler_to_logger(file_name, logger_)
240
+
241
+ def __new_file_handler(self, file_path, use_format_short=False):
242
+ from holado_multitask.multitasking.multitask_manager import MultitaskManager
243
+
244
+ Path(os.path.dirname(file_path)).mkdir(parents=True, exist_ok=True)
245
+
246
+ res = logging.FileHandler(file_path, mode='w', encoding='utf8')
247
+ fmt = self.format_short if use_format_short else self.format
248
+ res.setFormatter(logging.Formatter(fmt=fmt, style=self.style))
249
+ if MultitaskManager.has_thread_native_id():
250
+ res.addFilter(filter_thread_native_id)
250
251
 
252
+ return res
253
+
254
+ def remove_file_handler(self, file_name, logger_=None, do_remove_log_file=True):
251
255
  if logger_ is None:
252
256
  logger_ = logging.getLogger()
253
257
 
254
- if file_name not in self.__file_handlers:
255
- raise TechnicalException(f"Not set log destination to file '{file_name}'")
256
-
257
- logger_.info("Removing log destination to file '{}'.".format(file_name))
258
- logger_.removeHandler(self.__file_handlers[file_name])
258
+ logger.info("Removing log destination to file '{}'.".format(file_name))
259
+ self.remove_existing_file_handler_from_logger(file_name, logger_)
259
260
  del self.__file_handlers[file_name]
260
261
 
261
262
  if do_remove_log_file:
262
263
  self.remove_log_file(file_name)
263
264
 
265
+ def add_existing_file_handler_to_logger(self, file_name, logger_):
266
+ from holado_core.common.exceptions.technical_exception import TechnicalException
267
+
268
+ if self.__root_file_name == file_name:
269
+ file_handler = self.__root_file_handler
270
+ else:
271
+ if file_name not in self.__file_handlers:
272
+ raise TechnicalException(f"Not set log destination to file '{file_name}'")
273
+ file_handler = self.__file_handlers[file_name]
274
+ logger_.addHandler(file_handler)
275
+
276
+ def remove_existing_file_handler_from_logger(self, file_name, logger_):
277
+ from holado_core.common.exceptions.technical_exception import TechnicalException
278
+
279
+ if self.__root_file_name == file_name:
280
+ file_handler = self.__root_file_handler
281
+ else:
282
+ if file_name not in self.__file_handlers:
283
+ raise TechnicalException(f"Not set log destination to file '{file_name}'")
284
+ file_handler = self.__file_handlers[file_name]
285
+ logger_.removeHandler(file_handler)
286
+
264
287
  def __remove_existing_file_handlers(self, log_level_if_exists=None):
265
288
  with self.__files_lock:
266
289
  if len(self.__file_names) > 0:
@@ -289,5 +312,24 @@ class LogManager(object):
289
312
  self.add_root_file_handler()
290
313
  self.remove_file_handler(file_name, do_remove_log_file=do_remove_log_file)
291
314
 
315
+ def enter_log_file_for_logger(self, logger_, file_path, use_format_short=False, switch_in=True):
316
+ logger_name = logger_.name
317
+ if logger_name not in self.__files_by_logger:
318
+ self.__files_by_logger[logger_name] = []
319
+
320
+ if switch_in and len(self.__files_by_logger[logger_name]) > 0:
321
+ logger_.removeHandler(self.__files_by_logger[logger_name][-1][1])
322
+
323
+ file_handler = self.__new_file_handler(file_path, use_format_short=use_format_short)
324
+ logger_.addHandler(file_handler)
325
+ self.__files_by_logger[logger_name].append( (file_path, file_handler) )
326
+
327
+ def leave_log_file_for_logger(self, logger_, switch_out=True):
328
+ logger_name = logger_.name
329
+ _, file_handler = self.__files_by_logger[logger_name].pop()
330
+ logger_.removeHandler(file_handler)
331
+
332
+ if switch_out and len(self.__files_by_logger[logger_name]) > 0:
333
+ logger_.addHandler(self.__files_by_logger[logger_name][-1][1])
292
334
 
293
335
 
@@ -61,7 +61,9 @@ class ThreadContext(Context):
61
61
 
62
62
  manager = VariableManager(var_man)
63
63
  self.set_object("variable_manager", manager)
64
- manager.initialize(SessionContext.instance().dynamic_text_manager, SessionContext.instance().unique_value_manager)
64
+ file_path = SessionContext.instance().report_manager.get_path("logs", f"variable_update-thread_{self.thread_uid}.log")
65
+ manager.initialize(SessionContext.instance().dynamic_text_manager, SessionContext.instance().unique_value_manager,
66
+ variable_update_log_file_path=file_path)
65
67
  return self.get_object("variable_manager")
66
68
 
67
69
 
@@ -61,7 +61,7 @@ class IterableQueue(queue.Queue, typing.Iterable):
61
61
 
62
62
 
63
63
  class IterableLifoQueue(IterableQueue):
64
- '''Copyt of implementation of queue.LifoQueue but inheriting of IterableQueue.'''
64
+ '''Copy of implementation of queue.LifoQueue but inheriting of IterableQueue.'''
65
65
 
66
66
  def _init(self, maxsize):
67
67
  self.queue = []
@@ -2,20 +2,20 @@
2
2
  MIIDZTCCAk2gAwIBAgIBKjANBgkqhkiG9w0BAQsFADCBizELMAkGA1UEBhMCVVMx
3
3
  CzAJBgNVBAgMAkNBMRYwFAYDVQQHDA1TYW4gRnJhbmNpc2NvMQ8wDQYDVQQKDAZ0
4
4
  Y3BiaW4xDDAKBgNVBAsMA29wczETMBEGA1UEAwwKdGNwYmluLmNvbTEjMCEGCSqG
5
- SIb3DQEJARYUaGFycnliYWdkaUBnbWFpbC5jb20wHhcNMjUxMDAyMTMzNjQ1WhcN
6
- MjUxMDAzMTMzNjQ1WjAcMRowGAYDVQQDDBF0Y3BiaW4uY29tLWNsaWVudDCCASIw
7
- DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAK2xah/MsJKGnIpj84nYfBRCeAh8
8
- MmN5dZwUCteehkX+wFhioEx1loAIqcqs6MPe7qQdeROuOZlGeiDR/6X0mnDsgyR4
9
- qUnrIaRHS3EFWGtGp0WRLsQhKNvtxAHL7dErz7BoxTO5gV/w6dcT3uPORfZxkZdm
10
- 6t01t7DwPFktopQju9E8eeMBKVKaO1RrclZKkWEyfuHP3wNpIE6GwsH8jCn4I+r/
11
- Y8Pgd+k4EyCaH+ngtFbS0lEhxxuqTpPRYyQrlEDMa1i/nETuMiL2WFkjEO2gEX/p
12
- w05GlO3YUTDpaXWUWZf+Ck7MYevrFDC57oSZvMwTn5pJrQztvNJjFc+YF6kCAwEA
13
- AaNCMEAwHQYDVR0OBBYEFLuHuKWOQ/U1+OpiGgffNV1faI9qMB8GA1UdIwQYMBaA
14
- FOLuMowBSAZfV5v82LmlaIIOvU/DMA0GCSqGSIb3DQEBCwUAA4IBAQBYIRlg6Paz
15
- ALTKoBm8nRB19n4d7Ay+U1bUBCP2U5vZkUTSu05ttQXT72TaFIaT04pFs9uIHGFZ
16
- 9yhP2DgbuCaexQrvf9yf6nnoCqLjlhJ8Y0NmscK14Hp9GgVSnkXeweL82gFsXB45
17
- FaqqyDn20QiH14nwU2H7g8y/Ys0PIemhjG8UT7OjSLyhkaCkxwYy88N/2YjX3hGH
18
- 9eTHvfMZ+9E7Urh3DevivhfPQnX/6lUAOK7Sr+WTIEjpZ89Lz/rLltRCXoXv75C4
19
- PdRoxB2/lo+3+X1i4B7ujaduZDLaMyPcckbpuTYxjPZtoxhLyYkKgzQTUMwYsVrW
20
- DoI6HuqlfzoH
5
+ SIb3DQEJARYUaGFycnliYWdkaUBnbWFpbC5jb20wHhcNMjUxMDE2MjIzNTE5WhcN
6
+ MjUxMDE3MjIzNTE5WjAcMRowGAYDVQQDDBF0Y3BiaW4uY29tLWNsaWVudDCCASIw
7
+ DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMxmg8CRudZQj9pgRnvPQrWyqn1A
8
+ 55RlXoax8OMEeEQHhreCOj69WV6K9OvHebbAtMNCEyXFwNUNX1XjlhhLcqhY5yLR
9
+ 5k9vgOoq2ribBwdMRnYyIajWp7y53L/J35Qf2FWNeS+3AXv/mWiYnGpTJZHXCMyo
10
+ wOgDqeqz5wzl8ncvj5HWBkZm/mPDwK6fR/4SXMv+NIBooUKGZTST/1Q75/tvPhwf
11
+ dpGWTUd1xKw3TKz63B+jAATdPbIxTnSxJY1uLdBZ1hUguGxrC+nvqgY0283lVz3n
12
+ Jz7P2BCwmwmgRwBLIUw1381QuFJjGlKSglw/HraIfVyJASQqEk2gVil5Gr8CAwEA
13
+ AaNCMEAwHQYDVR0OBBYEFMQRuiY7hUUnl5wxL6R6gnlhyXaiMB8GA1UdIwQYMBaA
14
+ FOLuMowBSAZfV5v82LmlaIIOvU/DMA0GCSqGSIb3DQEBCwUAA4IBAQBAX/CniZsN
15
+ 9YWuDt7CS+YBpLRe46ryZXzmACpmz4uDzRs+3MRnCtOz1121dW0+zuPMdopxwjG2
16
+ GyPirI1mDasoJDn5jRWP1NBvuFN7fcAVsMDi3vBMfzd+oV4Pcgi7uydcd0zX+onp
17
+ 1QIyNwAulQB03gfe6IcPAUwyTOtJoc7yo1W6eH/W+RGmj5BaUP+5SB3EHjqih6ds
18
+ xPc4yJ43N1gYsXRZDoYuqmy+/h0JQmFupPJRAbOFbh3IsunbLXvsKXzlrgKlhsCg
19
+ H0Kc97t7ZQNCzgymNnxsbepNddWwGF8hAj4FruFYtO9rt00aT2bqb9Yw4pRJ+fM8
20
+ nDVx1r7BCieF
21
21
  -----END CERTIFICATE-----
@@ -1,28 +1,28 @@
1
1
  -----BEGIN PRIVATE KEY-----
2
- MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCtsWofzLCShpyK
3
- Y/OJ2HwUQngIfDJjeXWcFArXnoZF/sBYYqBMdZaACKnKrOjD3u6kHXkTrjmZRnog
4
- 0f+l9Jpw7IMkeKlJ6yGkR0txBVhrRqdFkS7EISjb7cQBy+3RK8+waMUzuYFf8OnX
5
- E97jzkX2cZGXZurdNbew8DxZLaKUI7vRPHnjASlSmjtUa3JWSpFhMn7hz98DaSBO
6
- hsLB/Iwp+CPq/2PD4HfpOBMgmh/p4LRW0tJRIccbqk6T0WMkK5RAzGtYv5xE7jIi
7
- 9lhZIxDtoBF/6cNORpTt2FEw6Wl1lFmX/gpOzGHr6xQwue6EmbzME5+aSa0M7bzS
8
- YxXPmBepAgMBAAECggEBAIqgeMTch2jKyxGg6HTyNUWuL0MGbOj7vaROUsD4os4m
9
- nrlsLegYSX/yaiF6k2QQ/4I4i7Prb8kneL3NHS8E5GaQPbLUIrj+UyFcTZfs3j7w
10
- avyY/SxIEuZFBBUy/6HcR6zSUeIQgnNiQiAImfJTZX9l8P9Xgsf+4Zb0hhXe2E1G
11
- TqLAYWnLoxD9us0rryQb37mRIREKcTO3qza+FXk32bWe83f1Dy46JJIChIoQg/QB
12
- hwzSL51ld22fy7p+bsqeI3HUDWHplq4T0lws0SGUd4IvntF9rNGYHAI+aUKwiUBC
13
- g/0se9+GBKeMSjhS11F9/Clg4i0E/tN/poOytA83aAECgYEA3+E0bhbaFAvzzevv
14
- tAWSXkwHSFZ745KsJSJ8OOVkd+ATleyGl3AoRTrDxNqY+R/TvBFaTyiY+zqGV6tj
15
- NI8SaSXuhRzbA9zDL2rSH7GIOeqzUs8PSUMk6JnmfCKk+aTBOoi8ULolHE4N6B45
16
- te3GVgy/luJK22pPLCMsmL+D0ykCgYEAxpzr8T2CPVtl33W+loGbvrqZ1xXgq/7n
17
- IsjHZdVdFsIIxFhtE2A2iO/7vMsLmwkZ7LgbtHcfEPOxjx5VzVt89l1I2lnP0jW+
18
- pjKrN/eyXcHnWLLPCEtXA06oIvyem/VMSGXumu7EcOJZjnG3/PmqCWCjc2UUo2lJ
19
- F2rQdC9bMIECgYEAl3nSdaI0j1e+79bw6kbSz8Z1LvaFAGce3klE72IV5h3QYqIU
20
- NqaGOMEX8DtPQU/NfPPovKJlT6Y7e1nU15zuAgLOLXZmoWhfD9ggr5z45Obtydub
21
- JiCt+ksW7WqrYNWef7JAaAZqUYpmUmUQ+w0UIuihQL9/kpGNW/m4lOkPknECgYAI
22
- gbodWAwXAq4nVwy1t5FrJuTl8HryAvX1aHIZ63yUN/VWK49ocAuF6/l1SaESn94r
23
- ZGtTXHLJMBbf0WXNaOi+SJqRN52OHF0xEySAPiy2lVKKWwZBDbEJZDoRXY6RkX0V
24
- 8L+6hRWG3DsHvdkqjar5wdjeXWr34M+PoDSTdV/LgQKBgFAqJc4I91AK8Ah9Ba8k
25
- LqYtRFGFJ2J+p8QqcibfT6d6tZqWffxiXbQ5bS52/fmM3BdxEHjtzLdA7cOqCh6g
26
- 79kxRb3B5jjq5JvGtLy89VphZ08W9dhzgL/l3KGtgMobfTYUEDaNk33oExhItQnx
27
- F97ecAMIx20oqFFOg6N0unwW
2
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDMZoPAkbnWUI/a
3
+ YEZ7z0K1sqp9QOeUZV6GsfDjBHhEB4a3gjo+vVleivTrx3m2wLTDQhMlxcDVDV9V
4
+ 45YYS3KoWOci0eZPb4DqKtq4mwcHTEZ2MiGo1qe8udy/yd+UH9hVjXkvtwF7/5lo
5
+ mJxqUyWR1wjMqMDoA6nqs+cM5fJ3L4+R1gZGZv5jw8Cun0f+ElzL/jSAaKFChmU0
6
+ k/9UO+f7bz4cH3aRlk1HdcSsN0ys+twfowAE3T2yMU50sSWNbi3QWdYVILhsawvp
7
+ 76oGNNvN5Vc95yc+z9gQsJsJoEcASyFMNd/NULhSYxpSkoJcPx62iH1ciQEkKhJN
8
+ oFYpeRq/AgMBAAECggEAUKjruSRIl6A3BFAVwGnrw1P8H21rdY4DHVg+3Pc4lm/5
9
+ 45TKc1O5XqurNxgCmfG144/BiphdHjYmtvgWlQPA/VoH7B+0qQgxcTb0FQFoZqLc
10
+ 82uZCM2cZ8dYq354cjWW4zvu5LttJIea/EGtB/BD1SdsW4cEiQpZFTtlJBvh8NHo
11
+ 7+o0mPwwBrXmadsLlxDmhQ0Wsw4ltaK7eMBJlLalg9f/3uW4ArW0OXVK1ycszNXM
12
+ 2pfrp9zKYcPzWEP+wrC/6f+AXFDacUIzwxsfNtlI7O57t8pQXf5pkyeBHHlxCvN/
13
+ XYx+UBWip6tRnlZRqNvl/8NC0JpX9P8xaeNp21haAQKBgQD1rlkZ9umlmC9PB5oc
14
+ Tp00KC5KQmgfqRfEBEVzmm4yGHK0OMx0pCnP/ZONZaE4QX4TmeLCnUxgYCdxl6ep
15
+ 406g0i2ig7M+RZ18skh4ubpoiQlLIoNW2mOpV/Hzt53st0HAYogPubrVZAnn/KwA
16
+ zehlj0w1yljBXDsK9c6deCdIgQKBgQDU/E12s8aCC0ngOSZqe0lkDWU/yQfX8BnJ
17
+ cSA3dU1mwGzP+02N5AXZuxwUql1rjE45ERPISQ2+eHtUk3n7QH0+7KNRmj7Jk9xC
18
+ QIN5lExdO3tAXo/muH6PCkyeNrkRSdfNgssYMVJZqbD8O5IM6v6yEbQHOxuskvvu
19
+ uWRxQZTDPwKBgEfqcUqYbGx8z9xibUo7+Oh7mpFCPxiFdt96IJpmajtfzLPUrIS4
20
+ SUUJBVgul7LP+Qfj0+0D/od3nhQyQHIKh8mrvJAF3UItPpxx06UDOP3An2fPAoM6
21
+ ClJX3AtrhF72hdi6/vkbdQVh80RlQjQ6Ef0opTZZtQFk7iOXMJQHx/gBAoGAahxl
22
+ T41Tifirzq1KaWSQ9OsDlZrHcJrrjgPxZA/qBxY5YAk440dGbuqcm+Mg9fMKCb5r
23
+ V66lzU5jS4jKDhZcD9x/pakuPOmQo+VWW106Cn0W88Po967VRth/wZdL7sQWYwoV
24
+ uzDfcVJsnc3j/tGZIQhW4/9b00fLgm0VEKP2xKsCgYEAkylyhMcTA9nuiBGecBFW
25
+ fRbuL6tWcnj3b8lnNOoBFTp6uVSi7VTYcZttGP7zLa9v/LRegawpf1meOarn80Wo
26
+ pz1Ot3ZEgx6iArdgdejSHbps58dTpoXp6YBlZR08G5tw2aHfppJYq2Vz3RLrv5Kf
27
+ k6MQ4yJFgkb+8+cpvp3NxgA=
28
28
  -----END PRIVATE KEY-----
@@ -27,7 +27,8 @@ def register():
27
27
  from holado_scripting.common.tools.variable_manager import VariableManager
28
28
  SessionContext.instance().services.register_service_type("variable_manager", VariableManager,
29
29
  lambda m: m.initialize(SessionContext.instance().dynamic_text_manager,
30
- SessionContext.instance().unique_value_manager) )
30
+ SessionContext.instance().unique_value_manager,
31
+ variable_update_log_file_path=SessionContext.instance().report_manager.get_path("logs", "variable_update.log") ) )
31
32
 
32
33
 
33
34
  from holado_scripting.common.tools.expression_evaluator import ExpressionEvaluator
@@ -22,8 +22,10 @@ from typing import NamedTuple
22
22
  import threading
23
23
  from holado.common.tools.gc_manager import GcManager
24
24
  from holado_python.standard_library.typing import Typing
25
+ from holado.common.context.session_context import SessionContext
25
26
 
26
27
  logger = logging.getLogger(__name__)
28
+ # logger_update = logging.getLogger(__name__ + ".update")
27
29
 
28
30
 
29
31
  class VariableManager(DeleteableObject):
@@ -46,9 +48,22 @@ class VariableManager(DeleteableObject):
46
48
  self.__temporary_variables_lock = threading.Lock()
47
49
  self.__temporary_variables = {}
48
50
 
49
- def initialize(self, dynamic_text_manager, unique_value_manager):
51
+ # Manage variable update log file
52
+ self.__variable_update_log_file_path = None
53
+ self.__is_entered_in_variable_update_log_file = False
54
+ self.__logger_update = logging.getLogger(__name__ + f".update.{id(self)}")
55
+
56
+ def initialize(self, dynamic_text_manager, unique_value_manager, variable_update_log_file_path=None):
57
+ """ Initialize variable manager
58
+ @param dynamic_text_manager Dynamic text manager instance to use
59
+ @param unique_value_manager Unique value manager instance to use
60
+ @param variable_update_log_filename If defined, log all variable updates in given file in addition to normal logs
61
+ """
50
62
  self.__dynamic_text_manager = dynamic_text_manager
51
63
  self.__unique_value_manager = unique_value_manager
64
+
65
+ # Manage variable update log file
66
+ self.__variable_update_log_file_path = variable_update_log_file_path
52
67
 
53
68
  @property
54
69
  def parent(self):
@@ -71,6 +86,19 @@ class VariableManager(DeleteableObject):
71
86
  # # Clear variables
72
87
  # self.__variables.clear()
73
88
 
89
+ # Leave variable update log file
90
+ self.__leave_variable_update_log_file()
91
+
92
+ def __enter_variable_update_log_file(self):
93
+ if self.__variable_update_log_file_path is not None and not self.__is_entered_in_variable_update_log_file:
94
+ SessionContext.instance().log_manager.enter_log_file_for_logger(self.__logger_update, self.__variable_update_log_file_path, use_format_short=True)
95
+ self.__is_entered_in_variable_update_log_file = True
96
+
97
+ def __leave_variable_update_log_file(self):
98
+ if self.__variable_update_log_file_path is not None and self.__is_entered_in_variable_update_log_file:
99
+ SessionContext.instance().log_manager.leave_log_file_for_logger(self.__logger_update)
100
+ self.__is_entered_in_variable_update_log_file = False
101
+
74
102
  @contextmanager
75
103
  def temporary_variables(self):
76
104
  from holado_multitask.multitasking.multitask_manager import MultitaskManager
@@ -125,6 +153,7 @@ class VariableManager(DeleteableObject):
125
153
  def register_variable(self, variable_name, value, accept_expression=True, log_level=logging.INFO):
126
154
  from holado_multitask.multitasking.multitask_manager import MultitaskManager
127
155
 
156
+ self.__enter_variable_update_log_file()
128
157
  if Tools.do_log(logger, logging.TRACE): # @UndefinedVariable
129
158
  logger.trace(f"Setting variable: {variable_name}=[{value}] (type: {Typing.get_object_class_fullname(value)})...")
130
159
 
@@ -134,13 +163,13 @@ class VariableManager(DeleteableObject):
134
163
  self.register_variable(names[0], Object())
135
164
  var = self.get_value(names[0], through_patent=False)
136
165
  setattr(var, names[1], value)
137
- if Tools.do_log(logger, log_level):
138
- logger.log(log_level, f"Set variable expression: {variable_name}=[{value}] (type: {Typing.get_object_class_fullname(value)})")
166
+ if Tools.do_log(self.__logger_update, log_level):
167
+ self.__logger_update.log(log_level, f"Set variable expression: {variable_name}=[{value}] (type: {Typing.get_object_class_fullname(value)})")
139
168
  else:
140
169
  var_name = self.evaluate_variable_name(variable_name)
141
170
  self.__variables[var_name] = value
142
- if Tools.do_log(logger, log_level):
143
- logger.log(log_level, f"Set variable: {var_name}=[{value}] (type: {Typing.get_object_class_fullname(value)})")
171
+ if Tools.do_log(self.__logger_update, log_level):
172
+ self.__logger_update.log(log_level, f"Set variable: {var_name}=[{value}] (type: {Typing.get_object_class_fullname(value)})")
144
173
 
145
174
  # Manage temporary variables
146
175
  uid = MultitaskManager.get_thread_uid()
@@ -149,6 +178,8 @@ class VariableManager(DeleteableObject):
149
178
  self.__temporary_variables[uid].variable_names.add(var_name)
150
179
 
151
180
  def unregister_variable(self, variable_name, through_parent=False, delete_value=False):
181
+ self.__enter_variable_update_log_file()
182
+
152
183
  var_name = self.evaluate_variable_name(variable_name)
153
184
  if self.exists_variable(var_name, through_parent=False):
154
185
  value = self.__variables[var_name]
@@ -161,8 +192,8 @@ class VariableManager(DeleteableObject):
161
192
  except Exception:
162
193
  logger.exception(f"Catched exception while deleting object '{var_name}' (type: {Typing.get_object_class_fullname(value)})")
163
194
  else:
164
- if Tools.do_log(logger, logging.DEBUG):
165
- logger.debug(f"Deleted variable '{var_name}' (type: {Typing.get_object_class_fullname(value)})")
195
+ if Tools.do_log(self.__logger_update, logging.DEBUG):
196
+ self.__logger_update.debug(f"Deleted variable '{var_name}' (type: {Typing.get_object_class_fullname(value)})")
166
197
 
167
198
  del self.__variables[var_name]
168
199
  elif through_parent and self.parent:
@@ -270,6 +301,8 @@ class VariableManager(DeleteableObject):
270
301
  Tools.raise_same_exception_type(exc, f"{exc}\nVariable '{var_name}': {var_repr}", add_from=True)
271
302
 
272
303
  def exec_set_variable_expression(self, expression, value, through_parent=True, log_level=logging.INFO):
304
+ self.__enter_variable_update_log_file()
305
+
273
306
  var_name, expr_rest = self.__extract_expression_name(expression)
274
307
  var_value = self.get_variable_value(var_name, through_parent=through_parent)
275
308
  new_var_name = self.new_local_variable_name(sub_name=self.__regular_variable_name(var_name))
@@ -289,8 +322,8 @@ class VariableManager(DeleteableObject):
289
322
  # Tools.raise_same_exception_type(exc, f"{exc}\nVariable '{var_name}': {var_repr}", add_from=True)
290
323
  raise FunctionalException(f"Failed to set value in variable expression (by exec): {expression}=[{value}] (type: {Typing.get_object_class_fullname(value)})\nVariable '{var_name}': {var_repr}") from exc
291
324
  else:
292
- if Tools.do_log(logger, log_level):
293
- logger.log(log_level, f"Set value in variable expression (by exec): {expression}=[{value}] (type: {Typing.get_object_class_fullname(value)})")
325
+ if Tools.do_log(self.__logger_update, log_level):
326
+ self.__logger_update.log(log_level, f"Set value in variable expression (by exec): {expression}=[{value}] (type: {Typing.get_object_class_fullname(value)})")
294
327
 
295
328
  def __regular_variable_name(self, name):
296
329
  return "".join([c if re.match(r'\w', c) else '_' for c in name])
@@ -73,7 +73,9 @@ class FeatureContext(Context):
73
73
  if not self.has_variable_manager():
74
74
  manager = VariableManager(SessionContext.instance().multitask_manager.get_thread_context().get_variable_manager())
75
75
  self.set_object("variable_manager", manager)
76
- manager.initialize(SessionContext.instance().dynamic_text_manager, SessionContext.instance().unique_value_manager)
76
+ file_path = SessionContext.instance().report_manager.current_feature_report.get_path("logs", "variable_update.log")
77
+ manager.initialize(SessionContext.instance().dynamic_text_manager, SessionContext.instance().unique_value_manager,
78
+ variable_update_log_file_path=file_path)
77
79
  return self.get_object("variable_manager")
78
80
 
79
81
 
@@ -135,7 +135,9 @@ class ScenarioContext(Context):
135
135
  if not self.has_variable_manager():
136
136
  manager = VariableManager(SessionContext.instance().get_feature_context().get_variable_manager())
137
137
  self.set_object("variable_manager", manager)
138
- manager.initialize(self.get_dynamic_text_manager(), SessionContext.instance().unique_value_manager)
138
+ file_path = SessionContext.instance().report_manager.current_scenario_report.get_path("logs", "variable_update.log")
139
+ manager.initialize(self.get_dynamic_text_manager(), SessionContext.instance().unique_value_manager,
140
+ variable_update_log_file_path=file_path)
139
141
  return self.get_object("variable_manager")
140
142
 
141
143
  def has_expression_evaluator(self):