leaf-common 1.4.2__tar.gz → 1.4.4__tar.gz

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 (181) hide show
  1. {leaf_common-1.4.2 → leaf_common-1.4.4}/PKG-INFO +1 -1
  2. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/asyncio/asyncio_executor.py +18 -12
  3. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/config/config_filter.py +2 -2
  4. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/config/config_filter_chain.py +4 -3
  5. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/config/config_handler.py +39 -37
  6. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/config/config_util.py +6 -1
  7. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/config/dictionary_overlay.py +40 -33
  8. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/config/file_of_class.py +2 -5
  9. leaf_common-1.4.4/leaf_common/filters/composite_string_filter.py +59 -0
  10. leaf_common-1.4.4/leaf_common/filters/string_filter.py +35 -0
  11. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/dictionary_extractor.py +2 -3
  12. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/field_extractor.py +12 -14
  13. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/resolution/resolver_util.py +5 -2
  14. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/utils/exception_util.py +3 -1
  15. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common.egg-info/PKG-INFO +1 -1
  16. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common.egg-info/SOURCES.txt +2 -0
  17. {leaf_common-1.4.2 → leaf_common-1.4.4}/.coveragerc +0 -0
  18. {leaf_common-1.4.2 → leaf_common-1.4.4}/.flake8 +0 -0
  19. {leaf_common-1.4.2 → leaf_common-1.4.4}/.github/workflows/checkmarx.yml +0 -0
  20. {leaf_common-1.4.2 → leaf_common-1.4.4}/.github/workflows/codeql.yml +0 -0
  21. {leaf_common-1.4.2 → leaf_common-1.4.4}/.github/workflows/publish.yml +0 -0
  22. {leaf_common-1.4.2 → leaf_common-1.4.4}/.github/workflows/tests.yml +0 -0
  23. {leaf_common-1.4.2 → leaf_common-1.4.4}/.gitignore +0 -0
  24. {leaf_common-1.4.2 → leaf_common-1.4.4}/.pylintrc +0 -0
  25. {leaf_common-1.4.2 → leaf_common-1.4.4}/CODE_OF_CONDUCT.md +0 -0
  26. {leaf_common-1.4.2 → leaf_common-1.4.4}/CONTRIBUTING.md +0 -0
  27. {leaf_common-1.4.2 → leaf_common-1.4.4}/LICENSE.txt +0 -0
  28. {leaf_common-1.4.2 → leaf_common-1.4.4}/Makefile +0 -0
  29. {leaf_common-1.4.2 → leaf_common-1.4.4}/NOTICE.txt +0 -0
  30. {leaf_common-1.4.2 → leaf_common-1.4.4}/README.md +0 -0
  31. {leaf_common-1.4.2 → leaf_common-1.4.4}/SECURITY.md +0 -0
  32. {leaf_common-1.4.2 → leaf_common-1.4.4}/SUPPORT.md +0 -0
  33. {leaf_common-1.4.2 → leaf_common-1.4.4}/build_scripts/copyright_config.json +0 -0
  34. {leaf_common-1.4.2 → leaf_common-1.4.4}/build_scripts/run_flake8.sh +0 -0
  35. {leaf_common-1.4.2 → leaf_common-1.4.4}/build_scripts/run_pylint.sh +0 -0
  36. {leaf_common-1.4.2 → leaf_common-1.4.4}/build_scripts/source_available_copyright.txt +0 -0
  37. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/__init__.py +0 -0
  38. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/asyncio/__init__.py +0 -0
  39. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/asyncio/async_to_sync_generator.py +0 -0
  40. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/asyncio/asyncio_executor_pool.py +0 -0
  41. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/asyncio/asyncio_threadpool_executor.py +0 -0
  42. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/asyncio/event_loop_factory.py +0 -0
  43. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/asyncio/event_loop_lag_monitor.py +0 -0
  44. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/asyncio/task_executor.py +0 -0
  45. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/config/__init__.py +0 -0
  46. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/config/environment_defaults.py +0 -0
  47. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/__init__.py +0 -0
  48. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/conditional_logger.py +0 -0
  49. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/example_logging_config.hocon +0 -0
  50. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/logging_setup.py +0 -0
  51. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/message_types.py +0 -0
  52. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/sensitive_logger.py +0 -0
  53. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/service_log_record.py +0 -0
  54. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/stream_to_logger.py +0 -0
  55. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/logging/structured_log_record.py +0 -0
  56. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/__init__.py +0 -0
  57. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/boolean_list_parser.py +0 -0
  58. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/boolean_parser.py +0 -0
  59. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/canonical_multi_config_parser.py +0 -0
  60. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/list_parser.py +0 -0
  61. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/parser.py +0 -0
  62. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/parsers/string_parser.py +0 -0
  63. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/__init__.py +0 -0
  64. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/easy/__init__.py +0 -0
  65. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/easy/abstract_easy_persistence.py +0 -0
  66. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/easy/composite_persistor.py +0 -0
  67. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/easy/easy_hocon_persistence.py +0 -0
  68. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/easy/easy_json_persistence.py +0 -0
  69. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/easy/easy_txt_persistence.py +0 -0
  70. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/easy/easy_yaml_persistence.py +0 -0
  71. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/README.md +0 -0
  72. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/__init__.py +0 -0
  73. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/abstract_persistence.py +0 -0
  74. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/hocon_persistence.py +0 -0
  75. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/json_gzip_persistence.py +0 -0
  76. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/json_persistence.py +0 -0
  77. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/null_persistence.py +0 -0
  78. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/override_file_extension_provider.py +0 -0
  79. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/persistence_factory.py +0 -0
  80. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/raw_bytes_persistence.py +0 -0
  81. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/reference_helper.py +0 -0
  82. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/simple_file_persistence.py +0 -0
  83. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/text_persistence.py +0 -0
  84. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/factory/yaml_persistence.py +0 -0
  85. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/interface/__init__.py +0 -0
  86. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/interface/persistence.py +0 -0
  87. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/interface/persistence_mechanism.py +0 -0
  88. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/interface/persistor.py +0 -0
  89. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/interface/restorer.py +0 -0
  90. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/mechanism/__init__.py +0 -0
  91. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/mechanism/abstract_persistence_mechanism.py +0 -0
  92. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/mechanism/local_file_persistence_mechanism.py +0 -0
  93. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/mechanism/persistence_mechanism_factory.py +0 -0
  94. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/mechanism/persistence_mechanisms.py +0 -0
  95. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/persistence/mechanism/s3_file_persistence_mechanism.py +0 -0
  96. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/profiling/__init__.py +0 -0
  97. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/profiling/async_profiling_lock.py +0 -0
  98. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/profiling/memory_util.py +0 -0
  99. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/profiling/profiling_lock.py +0 -0
  100. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/resolution/__init__.py +0 -0
  101. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/resolution/deprecation_redirect.py +0 -0
  102. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/resolution/resolver.py +0 -0
  103. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/__init__.py +0 -0
  104. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/__init__.py +0 -0
  105. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/buffered_gzip_serialization_format.py +0 -0
  106. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/chained_serialization_format.py +0 -0
  107. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/conversion_policy.py +0 -0
  108. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/gzip_serialization_format.py +0 -0
  109. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/hocon_serialization_format.py +0 -0
  110. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/json_serialization_format.py +0 -0
  111. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/raw_bytes_serialization_format.py +0 -0
  112. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/serialization_formats.py +0 -0
  113. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/text_serialization_format.py +0 -0
  114. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/format/yaml_serialization_format.py +0 -0
  115. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/interface/__init__.py +0 -0
  116. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/interface/deserializer.py +0 -0
  117. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/interface/dictionary_converter.py +0 -0
  118. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/interface/file_extension_provider.py +0 -0
  119. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/interface/reference_pruner.py +0 -0
  120. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/interface/serialization_format.py +0 -0
  121. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/interface/serializer.py +0 -0
  122. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/prep/__init__.py +0 -0
  123. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/prep/empty_dictionary_converter.py +0 -0
  124. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/prep/pass_through_dictionary_converter.py +0 -0
  125. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/prep/pass_through_reference_pruner.py +0 -0
  126. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/prep/redactor_dictionary_converter.py +0 -0
  127. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/util/__init__.py +0 -0
  128. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/util/bytes_decoder.py +0 -0
  129. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/serialization/util/text_file_reader.py +0 -0
  130. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/time/__init__.py +0 -0
  131. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/time/time_util.py +0 -0
  132. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/time/timeout.py +0 -0
  133. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/time/timeout_reached_exception.py +0 -0
  134. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/utils/__init__.py +0 -0
  135. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/utils/async_atomic_counter.py +0 -0
  136. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/utils/atomic_counter.py +0 -0
  137. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/utils/startable.py +0 -0
  138. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/validation/__init__.py +0 -0
  139. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/validation/composite_dictionary_validator.py +0 -0
  140. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common/validation/dictionary_validator.py +0 -0
  141. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common.egg-info/dependency_links.txt +0 -0
  142. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common.egg-info/requires.txt +0 -0
  143. {leaf_common-1.4.2 → leaf_common-1.4.4}/leaf_common.egg-info/top_level.txt +0 -0
  144. {leaf_common-1.4.2 → leaf_common-1.4.4}/pyproject.toml +0 -0
  145. {leaf_common-1.4.2 → leaf_common-1.4.4}/requirements-build.txt +0 -0
  146. {leaf_common-1.4.2 → leaf_common-1.4.4}/requirements.txt +0 -0
  147. {leaf_common-1.4.2 → leaf_common-1.4.4}/setup.cfg +0 -0
  148. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/__init__.py +0 -0
  149. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/__init__.py +0 -0
  150. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/async_test_helpers.py +0 -0
  151. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/asyncio_executor_metrics_test.py +0 -0
  152. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/asyncio_executor_not_started_test.py +0 -0
  153. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/asyncio_executor_pool_dump_tasks_test.py +0 -0
  154. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/asyncio_executor_pool_gc_test.py +0 -0
  155. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/asyncio_executor_pool_metrics_test.py +0 -0
  156. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/asyncio_executor_started_test.py +0 -0
  157. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/asyncio_threadpool_executor_metrics_test.py +0 -0
  158. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/callable_class.py +0 -0
  159. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/event_loop_factory_test.py +0 -0
  160. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/asyncio/sync_test_helpers.py +0 -0
  161. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/config/__init__.py +0 -0
  162. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/config/dictionary_overlay_test.py +0 -0
  163. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/config/test_config_util.py +0 -0
  164. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/parsers/__init__.py +0 -0
  165. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/parsers/boolean_parser_test.py +0 -0
  166. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/parsers/canonical_multi_config_parser_test.py +0 -0
  167. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/resolution/__init__.py +0 -0
  168. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/resolution/resolver_util_test.py +0 -0
  169. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/resolution/test_deprecation_redirect.py +0 -0
  170. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/serialization/__init__.py +0 -0
  171. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/serialization/encoding/__init__.py +0 -0
  172. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/serialization/encoding/decode_text_test.py +0 -0
  173. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/serialization/encoding/text_file_reader_test.py +0 -0
  174. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/serialization/format/__init__.py +0 -0
  175. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/serialization/format/hocon_serialization_format_test.py +0 -0
  176. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/serialization/prep/__init__.py +0 -0
  177. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/serialization/prep/redactor_dictionary_converter_test.py +0 -0
  178. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/time/__init__.py +0 -0
  179. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/time/timeout_test.py +0 -0
  180. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/utils/__init__.py +0 -0
  181. {leaf_common-1.4.2 → leaf_common-1.4.4}/tests/utils/test_exception_util.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: leaf-common
3
- Version: 1.4.2
3
+ Version: 1.4.4
4
4
  Summary: LEAF team common code library
5
5
  Author-email: Dan Fink <Daniel.Fink@cognizant.com>
6
6
  License-Expression: Apache-2.0
@@ -22,6 +22,7 @@ from typing import Awaitable
22
22
  from typing import Callable
23
23
  from typing import Dict
24
24
  from typing import List
25
+ from typing import Set
25
26
  from typing import Tuple
26
27
 
27
28
  from functools import partial
@@ -161,7 +162,7 @@ class AsyncioExecutor(TaskExecutor):
161
162
 
162
163
  # If we reach here, the loop was stopped.
163
164
  # We should gather any remaining tasks and finish them.
164
- pending = all_tasks(loop=loop)
165
+ pending: Set[Task] = all_tasks(loop=loop)
165
166
  if pending:
166
167
  # We want all possibly pending tasks to execute -
167
168
  # don't need them to raise exceptions.
@@ -185,9 +186,9 @@ class AsyncioExecutor(TaskExecutor):
185
186
  # Call the default exception handler first
186
187
  loop.default_exception_handler(context)
187
188
 
188
- message = context.get("message", None)
189
- exception = context.get("exception", None)
190
- formatted_exception = format_exception(exception)
189
+ message: str = context.get("message", None)
190
+ exception: Exception = context.get("exception", None)
191
+ formatted_exception: List[str] = format_exception(exception)
191
192
  print(f"Event loop traceback ({message}):\n{formatted_exception}")
192
193
 
193
194
  def get_function_name(self, function, submitter_id: str) -> str:
@@ -345,7 +346,7 @@ class AsyncioExecutor(TaskExecutor):
345
346
  "task": task,
346
347
  "raise_exception": raise_exception
347
348
  }
348
- task_id = id(task)
349
+ task_id: int = id(task)
349
350
  self._background_tasks[task_id] = task_info_dict
350
351
  task.add_done_callback(self.submission_done)
351
352
  return task
@@ -353,11 +354,13 @@ class AsyncioExecutor(TaskExecutor):
353
354
  @staticmethod
354
355
  async def _cancel_and_drain(tasks: List[AsyncFuture]):
355
356
  # Request cancellation for tasks that are not already done:
356
- pending = []
357
+ pending: List[AsyncFuture] = []
357
358
  for task in tasks:
358
- if not task.done():
359
- task.cancel("cancel-and-drain")
360
- pending.append(task)
359
+ test_task: AsyncFuture = task
360
+ test_task_done: bool = test_task.done()
361
+ if not test_task_done:
362
+ test_task.cancel("cancel-and-drain")
363
+ pending.append(test_task)
361
364
  # Don't raise exceptions in the tasks being cancelled -
362
365
  # we don't really need to react to them.
363
366
  _ = await gather(*pending, return_exceptions=True)
@@ -457,11 +460,14 @@ class AsyncioExecutor(TaskExecutor):
457
460
  # pylint: disable=broad-exception-caught
458
461
  except Exception as exc:
459
462
  formatted_exception: List[str] = format_exception(exc)
463
+ sensitive_logger = SensitiveLogger(self.logger)
460
464
  for line in formatted_exception:
465
+ # Respect const-ness
466
+ use_line: str = line
461
467
  if line.endswith("\n"):
462
- line = line[:-1]
463
- sensitive_logger = SensitiveLogger(self.logger)
464
- sensitive_logger.info("%s", line)
468
+ # Remove the newline
469
+ use_line = line[:-1]
470
+ sensitive_logger.info("%s", use_line)
465
471
 
466
472
  # As a last gesture, remove the background task from the map
467
473
  # we use to keep its reference around. Do it safely:
@@ -18,6 +18,7 @@
18
18
  See class comment for details
19
19
  """
20
20
 
21
+ from typing import Any
21
22
  from typing import Dict
22
23
 
23
24
 
@@ -32,8 +33,7 @@ class ConfigFilter():
32
33
  thus allowing config modification at an early stage in an app's lifecyle.
33
34
  """
34
35
 
35
- def filter_config(self, basis_config: Dict[str, object]) \
36
- -> Dict[str, object]:
36
+ def filter_config(self, basis_config: Dict[str, Any]) -> Dict[str, Any]:
37
37
  """
38
38
  Filters the given basis config.
39
39
 
@@ -17,6 +17,7 @@
17
17
  """
18
18
  See class comment for details.
19
19
  """
20
+ from typing import Any
20
21
  from typing import Dict
21
22
  from typing import List
22
23
 
@@ -48,8 +49,7 @@ class ConfigFilterChain(ConfigFilter):
48
49
  """
49
50
  self._filters.append(one_filter)
50
51
 
51
- def filter_config(self, basis_config: Dict[str, object]) \
52
- -> Dict[str, object]:
52
+ def filter_config(self, basis_config: Dict[str, Any]) -> Dict[str, Any]:
53
53
  """
54
54
  Filters the given basis config.
55
55
 
@@ -62,9 +62,10 @@ class ConfigFilterChain(ConfigFilter):
62
62
  :return: A config dictionary, potentially modified as per the
63
63
  policy encapsulated by the implementation
64
64
  """
65
- filtered = basis_config
65
+ filtered: Dict[str, Any] = basis_config
66
66
 
67
67
  # Go through the filter chain
68
+ one_filter: ConfigFilter = None
68
69
  for one_filter in self._filters:
69
70
  filtered = one_filter.filter_config(filtered)
70
71
 
@@ -14,11 +14,9 @@
14
14
  # limitations under the License.
15
15
  #
16
16
  # END COPYRIGHT
17
- """
18
- See class comment for details.
19
- """
20
17
  from typing import Any
21
18
  from typing import Dict
19
+ from typing import Union
22
20
 
23
21
  from copy import deepcopy
24
22
  from collections.abc import Mapping
@@ -33,8 +31,9 @@ class ConfigHandler():
33
31
  An abstract class which handles configuration dictionaries
34
32
  """
35
33
 
36
- def import_config(self, config_source, default_config=None,
37
- must_exist=True):
34
+ def import_config(self, config_source: Union[str, Dict[str, Any]],
35
+ default_config: Dict[str, Any] = None,
36
+ must_exist: bool = True) -> Dict[str, Any]:
38
37
  """
39
38
  Main entry point for reading config files
40
39
  :param config_source: Either a string filename reference to a
@@ -54,12 +53,12 @@ class ConfigHandler():
54
53
  """
55
54
 
56
55
  # Set up a very basic config dictionary
57
- config = {}
56
+ config: Dict[str, Any] = {}
58
57
  if default_config is not None and isinstance(default_config, dict):
59
58
  config = deepcopy(default_config)
60
59
 
61
60
  # Potentially read config from a file, if config arg is a string filename
62
- update_source = {}
61
+ update_source: Dict[str, Any] = {}
63
62
  if isinstance(config_source, str):
64
63
  update_source = self.read_config_from_file(config_source, must_exist)
65
64
 
@@ -68,23 +67,25 @@ class ConfigHandler():
68
67
  elif isinstance(config_source, dict):
69
68
  update_source = config_source
70
69
 
71
- new_config = self.deep_update(config, update_source)
70
+ new_config: Dict[str, Any] = self.deep_update(config, update_source)
72
71
  return new_config
73
72
 
74
- def deep_update(self, dest, source):
73
+ def deep_update(self, dest: Dict[str, Any], source: Dict[str, Any]) -> Dict[str, Any]:
75
74
  """
76
75
  Performs overlay functionality
77
76
  DEF: Use DictionaryOverlay class instead.
78
77
  """
78
+ key: str = None
79
+ value: Any = None
79
80
  for key, value in source.items():
80
81
  if isinstance(value, Mapping):
81
- recurse = self.deep_update(dest.get(key, {}), value)
82
+ recurse: Dict[str, Any] = self.deep_update(dest.get(key, {}), value)
82
83
  dest[key] = recurse
83
84
  else:
84
85
  dest[key] = source[key]
85
86
  return dest
86
87
 
87
- def read_config_from_file(self, filepath, must_exist) -> Dict[str, Any]:
88
+ def read_config_from_file(self, filepath: str, must_exist: bool) -> Dict[str, Any]:
88
89
  """
89
90
  :param filepath: The file to parse
90
91
  :param must_exist: When True, an error is
@@ -96,23 +97,24 @@ class ConfigHandler():
96
97
  """
97
98
 
98
99
  # Create a map of our parser methods
99
- file_extension_to_parser_map = {
100
- '.conf': 'parse_hocon',
101
- '.hocon': 'parse_hocon',
100
+ file_extension_to_parser_map: Dict[str, str] = {
101
+ ".conf": "parse_hocon",
102
+ ".hocon": "parse_hocon",
102
103
  # Treat json separately as it's been shown that large json files
103
104
  # are really slow for the hocon parser to load.
104
- '.json': 'parse_json',
105
- '.properties': 'parse_hocon',
106
- '.yaml': 'parse_yaml'
105
+ ".json": "parse_json",
106
+ ".properties": "parse_hocon",
107
+ ".yaml": "parse_yaml"
107
108
  }
108
109
 
109
110
  # See what the filepath extension says to use
110
- parser = None
111
+ parser: str = None
112
+ file_extension: str = None
111
113
  for file_extension in list(file_extension_to_parser_map.keys()):
112
114
  if filepath.endswith(file_extension):
113
115
  parser = file_extension_to_parser_map.get(file_extension)
114
116
 
115
- message = f"Could not read {filepath} as config. Unknown file extension."
117
+ message: str = f"Could not read {filepath} as config. Unknown file extension."
116
118
 
117
119
  config: Dict[str, Any] = {}
118
120
  if parser is not None:
@@ -127,7 +129,7 @@ class ConfigHandler():
127
129
 
128
130
  return config
129
131
 
130
- def parse_with_method(self, parser, filepath, must_exist):
132
+ def parse_with_method(self, parser: str, filepath: str, must_exist: bool) -> Dict[str, Any]:
131
133
  """
132
134
  :param parser: The parser method on this class to use
133
135
  :param filepath: The file to parse
@@ -137,14 +139,17 @@ class ConfigHandler():
137
139
  ignored and a dictionary value of None is returned
138
140
  :return: The dictionary parsed from the config file
139
141
  """
140
- # Python magic to get a handle to the method
141
- parser_method = getattr(self, parser)
142
-
143
- # Call the parser method with the filepath, get dictionary back
144
- config = parser_method(filepath, must_exist)
142
+ config: Dict[str, Any] = None
143
+
144
+ if parser == "parse_hocon":
145
+ config = self.parse_hocon(filepath, must_exist)
146
+ elif parser == "parse_json":
147
+ config = self.parse_json(filepath, must_exist)
148
+ elif parser == "parse_yaml":
149
+ config = self.parse_yaml(filepath, must_exist)
145
150
  return config
146
151
 
147
- def parse_json(self, filepath, must_exist):
152
+ def parse_json(self, filepath: str, must_exist: bool) -> Dict[str, Any]:
148
153
  """
149
154
  :param filepath: The json file to parse
150
155
  :param must_exist: When True, an error is
@@ -153,12 +158,11 @@ class ConfigHandler():
153
158
  ignored and a dictionary value of None is returned
154
159
  :return: The dictionary parsed from the hocon config file
155
160
  """
156
- persistence = EasyJsonPersistence(full_ref=filepath,
157
- must_exist=must_exist)
158
- config = persistence.restore()
161
+ persistence = EasyJsonPersistence(full_ref=filepath, must_exist=must_exist)
162
+ config: Dict[str, Any] = persistence.restore(None)
159
163
  return config
160
164
 
161
- def parse_hocon(self, filepath, must_exist):
165
+ def parse_hocon(self, filepath: str, must_exist: bool) -> Dict[str, Any]:
162
166
  """
163
167
  :param filepath: The hocon file to parse
164
168
  :param must_exist: When True, an error is
@@ -167,12 +171,11 @@ class ConfigHandler():
167
171
  ignored and a dictionary value of None is returned
168
172
  :return: The dictionary parsed from the hocon config file
169
173
  """
170
- persistence = EasyHoconPersistence(full_ref=filepath,
171
- must_exist=must_exist)
172
- config = persistence.restore()
174
+ persistence = EasyHoconPersistence(full_ref=filepath, must_exist=must_exist)
175
+ config: Dict[str, Any] = persistence.restore(None)
173
176
  return config
174
177
 
175
- def parse_yaml(self, filepath, must_exist):
178
+ def parse_yaml(self, filepath: str, must_exist: bool) -> Dict[str, Any]:
176
179
  """
177
180
  :param filepath: The yaml file to parse
178
181
  :param must_exist: When True, an error is
@@ -181,7 +184,6 @@ class ConfigHandler():
181
184
  ignored and a dictionary value of None is returned
182
185
  :return: The dictionary parsed from the yaml config file
183
186
  """
184
- persistence = EasyYamlPersistence(full_ref=filepath,
185
- must_exist=must_exist)
186
- config = persistence.restore()
187
+ persistence = EasyYamlPersistence(full_ref=filepath, must_exist=must_exist)
188
+ config: Dict[str, Any] = persistence.restore(None)
187
189
  return config
@@ -56,16 +56,21 @@ class ConfigUtil:
56
56
  """
57
57
  if key not in config:
58
58
  return default
59
+
59
60
  value: Any = config[key]
60
61
  if isinstance(value, bool):
61
62
  return value
63
+
62
64
  if isinstance(value, str):
63
- lowered = value.strip().lower()
65
+ string_value: str = value
66
+ lowered: str = string_value.strip().lower()
64
67
  if lowered in ("true", "yes"):
65
68
  return True
66
69
  if lowered in ("false", "no"):
67
70
  return False
68
71
  return default
72
+
69
73
  if isinstance(value, int):
70
74
  return value != 0
75
+
71
76
  return default
@@ -14,9 +14,10 @@
14
14
  # limitations under the License.
15
15
  #
16
16
  # END COPYRIGHT
17
- """
18
- See class comment for details.
19
- """
17
+ from typing import Any
18
+ from typing import Dict
19
+ from typing import List
20
+ from typing import Set
20
21
 
21
22
 
22
23
  class DictionaryOverlay():
@@ -24,7 +25,8 @@ class DictionaryOverlay():
24
25
  Policy class assisting with deep dictionary updates.
25
26
  """
26
27
 
27
- def overlay(self, basis, overlay, allow_overlay_only_items=True):
28
+ def overlay(self, basis: Dict[str, Any], overlay: Dict[str, Any],
29
+ allow_overlay_only_items: bool = True) -> Dict[str, Any]:
28
30
  """
29
31
  :param basis: The basis dictionary to be overlayed.
30
32
  Unmodified on exit.
@@ -42,20 +44,21 @@ class DictionaryOverlay():
42
44
  are both dictionaries, this method recurses.
43
45
  """
44
46
 
45
- overlay_only_items = set()
46
- result = self._do_overlay(basis, overlay, overlay_only_items, '')
47
+ overlay_only_items: Set[str] = set()
48
+ result: Dict[str, Any] = self._do_overlay(basis, overlay, overlay_only_items, '')
47
49
  # Now, let's check if we had items present in "overlay"
48
50
  # but not in "basis" dictionary.
49
51
  # If YES - always print out warning message;
50
52
  # and if we don't allow overlay-only items, raise an exception.
51
- if len(overlay_only_items) > 0 \
52
- and not allow_overlay_only_items:
53
- separator = ', '
54
- message = separator.join(overlay_only_items)
53
+ if len(overlay_only_items) > 0 and not allow_overlay_only_items:
54
+ separator: str = ", "
55
+ overlay_only_list: List[str] = sorted(list(overlay_only_items))
56
+ message: str = separator.join(overlay_only_list)
55
57
  raise ValueError(f"overlay items not present in basis: {message}")
56
58
  return result
57
59
 
58
- def _do_overlay(self, basis, overlay, overlay_only_items, items_prefix):
60
+ def _do_overlay(self, basis: Dict[str, Any], overlay: Dict[str, Any],
61
+ overlay_only_items: Set[str], items_prefix: str) -> Dict[str, Any]:
59
62
  """
60
63
  :param basis: The basis dictionary to be overlayed.
61
64
  Unmodified on exit.
@@ -77,46 +80,49 @@ class DictionaryOverlay():
77
80
  if basis is None and overlay is None:
78
81
  return None
79
82
 
83
+ use_basis: Dict[str, Any] = basis
80
84
  if basis is None:
81
- basis = {}
85
+ use_basis = {}
82
86
 
83
- if not isinstance(basis, dict):
87
+ if not isinstance(use_basis, dict):
84
88
  raise ValueError("basis is not a dictionary")
85
89
 
90
+ use_overlay: Dict[str, Any] = overlay
86
91
  if overlay is None:
87
- overlay = {}
92
+ use_overlay = {}
88
93
 
89
- if not isinstance(overlay, dict):
94
+ if not isinstance(use_overlay, dict):
90
95
  raise ValueError("overlay is not a dictionary")
91
96
 
92
97
  # Do not modify any incoming arguments
93
- result = {}
94
- result.update(basis)
98
+ result: Dict[str, Any] = {}
99
+ result.update(use_basis)
95
100
 
96
- for key in overlay.keys():
101
+ key: str = None
102
+ for key in use_overlay.keys():
97
103
 
98
104
  # Any key we do not have, we just copy over the value from overlay.
99
- if key not in basis:
100
- result[key] = overlay[key]
101
- overlay_only_items.add(items_prefix+key)
105
+ if key not in use_basis.keys():
106
+ result[key] = use_overlay[key]
107
+ add_key: str = items_prefix + key
108
+ overlay_only_items.add(add_key)
102
109
  continue
103
110
 
104
- basis_value = basis.get(key)
105
- overlay_value = overlay.get(key)
111
+ basis_value: Any = use_basis.get(key)
112
+ overlay_value: Any = use_overlay.get(key)
106
113
 
107
- if basis_value is not None \
108
- and overlay_value is not None:
114
+ if basis_value is not None and overlay_value is not None:
109
115
  # Adjust overlay value type here:
110
116
  # if "basis" contains say A = 3 and overlay contains A = '3',
111
117
  # we try to convert overlay string to numeric type
112
118
  # by parsing it. This takes care of situation
113
119
  # when overlay value comes from environment variable,
114
120
  # which is always a string.
115
- overlay_value = self._convert_overlay_value(basis_value, overlay_value)
121
+ overlay_value: Any = self._convert_overlay_value(basis_value, overlay_value)
116
122
 
117
123
  # By default, the result value for the key will be the overlay
118
124
  # value itself.
119
- result_value = overlay_value
125
+ result_value: Any = overlay_value
120
126
 
121
127
  # ... except if both values are dictionaries.
122
128
  # In that case, recurse.
@@ -131,7 +137,7 @@ class DictionaryOverlay():
131
137
 
132
138
  return result
133
139
 
134
- def _convert_overlay_value(self, basis_value, overlay_value):
140
+ def _convert_overlay_value(self, basis_value: Any, overlay_value: Any) -> Any:
135
141
  """
136
142
  Given basis value from configuration and overlay value
137
143
  we need to replace it with, convert overlay value if necessary.
@@ -145,12 +151,13 @@ class DictionaryOverlay():
145
151
  in configuration.
146
152
  """
147
153
 
154
+ use_value: Any = overlay_value
148
155
  if isinstance(overlay_value, str):
156
+ string_value: str = overlay_value
149
157
  if isinstance(basis_value, bool):
150
- overlay_value = \
151
- bool(overlay_value.strip().lower() == 'true')
158
+ use_value = bool(string_value.strip().lower() == 'true')
152
159
  elif isinstance(basis_value, int):
153
- overlay_value = int(float(overlay_value))
160
+ use_value = int(float(string_value))
154
161
  elif isinstance(basis_value, float):
155
- overlay_value = float(overlay_value)
156
- return overlay_value
162
+ use_value = float(string_value)
163
+ return use_value
@@ -14,12 +14,9 @@
14
14
  # limitations under the License.
15
15
  #
16
16
  # END COPYRIGHT
17
- """
18
- See class comment for details.
19
- """
20
17
 
21
18
  from pathlib import Path
22
- import os
19
+ from os.path import expanduser
23
20
 
24
21
 
25
22
  class FileOfClass:
@@ -105,7 +102,7 @@ class FileOfClass:
105
102
 
106
103
  if basis == "~":
107
104
  # Special case if we are looking under user's home directory
108
- basis = os.path.expanduser("~")
105
+ basis = expanduser("~")
109
106
  basis_abs_path: str = str(Path(basis).resolve())
110
107
 
111
108
  if not test_abs_path.startswith(basis_abs_path):
@@ -0,0 +1,59 @@
1
+
2
+ # Copyright © 2019-2026 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ # END COPYRIGHT
17
+ from typing import List
18
+
19
+ from leaf_common.filters.string_filter import StringFilter
20
+
21
+
22
+ class CompositeStringFilter(StringFilter):
23
+ """
24
+ An implementation of the StringFilter interface which puts together
25
+ multiple string filter operations in a certain order
26
+ """
27
+
28
+ def __init__(self, filters: List[StringFilter] = None):
29
+ """
30
+ Constructor
31
+
32
+ :param filters: A list of StringFilter class instances to apply in order
33
+ """
34
+
35
+ self._filters: List[StringFilter] = []
36
+
37
+ if filters is not None:
38
+ one_filter: StringFilter = None
39
+ for one_filter in filters:
40
+ self.add_filter(one_filter)
41
+
42
+ def add_filter(self, new_filter: StringFilter):
43
+ """
44
+ :param new_filter: The StringFilter to be added to the list to be applied
45
+ """
46
+ self._filters.append(new_filter)
47
+
48
+ def filter(self, in_string: str) -> str:
49
+ """
50
+ :param in_string: an input string to filter
51
+ :return: a filtered version of the in_string, according to implementation policy
52
+ """
53
+ accumulator: str = in_string
54
+
55
+ string_filter: StringFilter = None
56
+ for string_filter in self._filters:
57
+ accumulator = string_filter.filter(accumulator)
58
+
59
+ return accumulator
@@ -0,0 +1,35 @@
1
+
2
+ # Copyright © 2019-2026 Cognizant Technology Solutions Corp, www.cognizant.com.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+ # END COPYRIGHT
17
+
18
+
19
+ # pylint: disable=too-few-public-methods
20
+ class StringFilter:
21
+ """
22
+ Interface whose filter() method takes one string and returns another string
23
+ which is a filtered version of the input.
24
+
25
+ These kinds of things are necessary for the following reasons:
26
+ * Tensorflow only likes column names with certain characters in them
27
+ * HTML UI sometimes only likes certain characters in strings.
28
+ """
29
+
30
+ def filter(self, in_string: str) -> str:
31
+ """
32
+ :param in_string: an input string to filter
33
+ :return: a filtered version of the in_string, according to implementation policy
34
+ """
35
+ raise NotImplementedError
@@ -29,8 +29,7 @@ class DictionaryExtractor():
29
29
  Policy class that pairs a specific dictionary instance with a FieldExtractor.
30
30
  """
31
31
 
32
- def __init__(self, dictionary: Dict[str, Any],
33
- delimiter: str = "."):
32
+ def __init__(self, dictionary: Dict[str, Any], delimiter: str = "."):
34
33
  """
35
34
  Constructor
36
35
 
@@ -41,7 +40,7 @@ class DictionaryExtractor():
41
40
  self.delimiter: str = delimiter
42
41
  self.extractor = FieldExtractor()
43
42
 
44
- def get(self, field_name, default_value=None):
43
+ def get(self, field_name: str, default_value: Any = None) -> Any:
45
44
  """
46
45
  :param field_name: the fully specified field name.
47
46
  :param default_value: a default value if the field is not found.