provide-foundation 0.0.0.dev2__py3-none-any.whl → 0.0.0.dev3__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 (155) hide show
  1. provide/foundation/__init__.py +20 -20
  2. provide/foundation/archive/__init__.py +1 -1
  3. provide/foundation/archive/base.py +15 -14
  4. provide/foundation/archive/bzip2.py +40 -40
  5. provide/foundation/archive/gzip.py +42 -42
  6. provide/foundation/archive/operations.py +90 -91
  7. provide/foundation/archive/tar.py +33 -31
  8. provide/foundation/archive/zip.py +52 -50
  9. provide/foundation/asynctools/__init__.py +20 -0
  10. provide/foundation/asynctools/core.py +126 -0
  11. provide/foundation/cli/__init__.py +2 -2
  12. provide/foundation/cli/commands/deps.py +4 -4
  13. provide/foundation/cli/commands/logs/__init__.py +2 -2
  14. provide/foundation/cli/commands/logs/generate.py +2 -2
  15. provide/foundation/cli/commands/logs/query.py +3 -3
  16. provide/foundation/cli/commands/logs/send.py +2 -2
  17. provide/foundation/cli/commands/logs/tail.py +2 -2
  18. provide/foundation/cli/decorators.py +0 -1
  19. provide/foundation/cli/testing.py +0 -5
  20. provide/foundation/cli/utils.py +1 -2
  21. provide/foundation/config/__init__.py +19 -19
  22. provide/foundation/config/base.py +2 -2
  23. provide/foundation/config/converters.py +81 -83
  24. provide/foundation/config/defaults.py +1 -1
  25. provide/foundation/config/env.py +2 -1
  26. provide/foundation/config/loader.py +1 -1
  27. provide/foundation/config/sync.py +8 -6
  28. provide/foundation/config/types.py +5 -5
  29. provide/foundation/config/validators.py +4 -4
  30. provide/foundation/console/output.py +7 -7
  31. provide/foundation/context/core.py +19 -17
  32. provide/foundation/crypto/certificates/__init__.py +9 -5
  33. provide/foundation/crypto/certificates/base.py +2 -2
  34. provide/foundation/crypto/certificates/certificate.py +48 -19
  35. provide/foundation/crypto/certificates/factory.py +26 -18
  36. provide/foundation/crypto/certificates/generator.py +24 -23
  37. provide/foundation/crypto/certificates/loader.py +24 -16
  38. provide/foundation/crypto/certificates/operations.py +17 -10
  39. provide/foundation/crypto/certificates/trust.py +21 -21
  40. provide/foundation/env/__init__.py +28 -0
  41. provide/foundation/env/core.py +218 -0
  42. provide/foundation/errors/__init__.py +3 -2
  43. provide/foundation/errors/decorators.py +0 -3
  44. provide/foundation/errors/types.py +0 -1
  45. provide/foundation/eventsets/display.py +13 -14
  46. provide/foundation/eventsets/registry.py +61 -31
  47. provide/foundation/eventsets/resolver.py +50 -46
  48. provide/foundation/eventsets/sets/das.py +8 -8
  49. provide/foundation/eventsets/sets/database.py +14 -14
  50. provide/foundation/eventsets/sets/http.py +21 -21
  51. provide/foundation/eventsets/sets/llm.py +16 -16
  52. provide/foundation/eventsets/sets/task_queue.py +13 -13
  53. provide/foundation/eventsets/types.py +7 -7
  54. provide/foundation/file/directory.py +1 -1
  55. provide/foundation/file/lock.py +2 -3
  56. provide/foundation/hub/components.py +19 -21
  57. provide/foundation/hub/config.py +25 -19
  58. provide/foundation/hub/discovery.py +5 -4
  59. provide/foundation/hub/handlers.py +13 -5
  60. provide/foundation/hub/lifecycle.py +10 -9
  61. provide/foundation/hub/manager.py +3 -0
  62. provide/foundation/hub/processors.py +8 -3
  63. provide/foundation/integrations/__init__.py +1 -1
  64. provide/foundation/integrations/openobserve/client.py +2 -2
  65. provide/foundation/integrations/openobserve/commands.py +9 -9
  66. provide/foundation/integrations/openobserve/config.py +2 -2
  67. provide/foundation/integrations/openobserve/otlp.py +2 -2
  68. provide/foundation/integrations/openobserve/search.py +1 -2
  69. provide/foundation/integrations/openobserve/streaming.py +1 -1
  70. provide/foundation/logger/__init__.py +0 -1
  71. provide/foundation/logger/config/base.py +1 -1
  72. provide/foundation/logger/config/logging.py +19 -19
  73. provide/foundation/logger/config/telemetry.py +11 -13
  74. provide/foundation/logger/factories.py +2 -2
  75. provide/foundation/logger/processors/main.py +12 -10
  76. provide/foundation/logger/ratelimit/limiters.py +4 -4
  77. provide/foundation/logger/ratelimit/processor.py +1 -1
  78. provide/foundation/logger/setup/coordinator.py +38 -24
  79. provide/foundation/logger/setup/processors.py +3 -3
  80. provide/foundation/logger/setup/testing.py +14 -0
  81. provide/foundation/logger/trace.py +5 -5
  82. provide/foundation/metrics/__init__.py +1 -1
  83. provide/foundation/metrics/otel.py +3 -1
  84. provide/foundation/observability/__init__.py +1 -1
  85. provide/foundation/process/__init__.py +1 -1
  86. provide/foundation/process/exit.py +6 -5
  87. provide/foundation/process/lifecycle.py +41 -18
  88. provide/foundation/resilience/__init__.py +6 -5
  89. provide/foundation/resilience/circuit.py +32 -30
  90. provide/foundation/resilience/decorators.py +58 -42
  91. provide/foundation/resilience/fallback.py +55 -40
  92. provide/foundation/resilience/retry.py +67 -65
  93. provide/foundation/serialization/__init__.py +16 -0
  94. provide/foundation/serialization/core.py +70 -0
  95. provide/foundation/streams/config.py +8 -9
  96. provide/foundation/streams/console.py +3 -3
  97. provide/foundation/streams/core.py +2 -2
  98. provide/foundation/streams/file.py +1 -1
  99. provide/foundation/testing/__init__.py +22 -7
  100. provide/foundation/testing/archive/__init__.py +7 -7
  101. provide/foundation/testing/archive/fixtures.py +58 -54
  102. provide/foundation/testing/cli.py +3 -6
  103. provide/foundation/testing/common/__init__.py +13 -13
  104. provide/foundation/testing/common/fixtures.py +27 -30
  105. provide/foundation/testing/file/__init__.py +15 -15
  106. provide/foundation/testing/file/content_fixtures.py +65 -92
  107. provide/foundation/testing/file/directory_fixtures.py +19 -19
  108. provide/foundation/testing/file/fixtures.py +14 -17
  109. provide/foundation/testing/file/special_fixtures.py +34 -42
  110. provide/foundation/testing/logger.py +28 -23
  111. provide/foundation/testing/mocking/__init__.py +21 -21
  112. provide/foundation/testing/mocking/fixtures.py +80 -67
  113. provide/foundation/testing/process/__init__.py +23 -23
  114. provide/foundation/testing/process/async_fixtures.py +89 -80
  115. provide/foundation/testing/process/fixtures.py +11 -13
  116. provide/foundation/testing/process/subprocess_fixtures.py +41 -40
  117. provide/foundation/testing/threading/__init__.py +17 -17
  118. provide/foundation/testing/threading/basic_fixtures.py +21 -17
  119. provide/foundation/testing/threading/data_fixtures.py +18 -16
  120. provide/foundation/testing/threading/execution_fixtures.py +67 -52
  121. provide/foundation/testing/threading/fixtures.py +10 -14
  122. provide/foundation/testing/threading/sync_fixtures.py +21 -18
  123. provide/foundation/testing/time/__init__.py +11 -11
  124. provide/foundation/testing/time/fixtures.py +91 -79
  125. provide/foundation/testing/transport/__init__.py +9 -9
  126. provide/foundation/testing/transport/fixtures.py +54 -54
  127. provide/foundation/time/__init__.py +18 -0
  128. provide/foundation/time/core.py +63 -0
  129. provide/foundation/tools/__init__.py +2 -2
  130. provide/foundation/tools/base.py +68 -67
  131. provide/foundation/tools/cache.py +62 -69
  132. provide/foundation/tools/downloader.py +51 -56
  133. provide/foundation/tools/installer.py +51 -57
  134. provide/foundation/tools/registry.py +38 -45
  135. provide/foundation/tools/resolver.py +70 -68
  136. provide/foundation/tools/verifier.py +39 -50
  137. provide/foundation/tracer/spans.py +1 -13
  138. provide/foundation/transport/__init__.py +26 -33
  139. provide/foundation/transport/base.py +32 -30
  140. provide/foundation/transport/client.py +44 -49
  141. provide/foundation/transport/config.py +11 -13
  142. provide/foundation/transport/errors.py +13 -27
  143. provide/foundation/transport/http.py +69 -55
  144. provide/foundation/transport/middleware.py +86 -81
  145. provide/foundation/transport/registry.py +29 -27
  146. provide/foundation/transport/types.py +6 -6
  147. provide/foundation/utils/deps.py +3 -2
  148. provide/foundation/utils/parsing.py +7 -7
  149. {provide_foundation-0.0.0.dev2.dist-info → provide_foundation-0.0.0.dev3.dist-info}/METADATA +2 -2
  150. provide_foundation-0.0.0.dev3.dist-info/RECORD +233 -0
  151. provide_foundation-0.0.0.dev2.dist-info/RECORD +0 -225
  152. {provide_foundation-0.0.0.dev2.dist-info → provide_foundation-0.0.0.dev3.dist-info}/WHEEL +0 -0
  153. {provide_foundation-0.0.0.dev2.dist-info → provide_foundation-0.0.0.dev3.dist-info}/entry_points.txt +0 -0
  154. {provide_foundation-0.0.0.dev2.dist-info → provide_foundation-0.0.0.dev3.dist-info}/licenses/LICENSE +0 -0
  155. {provide_foundation-0.0.0.dev2.dist-info → provide_foundation-0.0.0.dev3.dist-info}/top_level.txt +0 -0
@@ -5,10 +5,10 @@ Fixtures for creating specialized files like binary files, read-only files,
5
5
  symbolic links, and executable files.
6
6
  """
7
7
 
8
+ from collections.abc import Generator
9
+ from pathlib import Path
8
10
  import stat
9
11
  import tempfile
10
- from pathlib import Path
11
- from collections.abc import Generator
12
12
 
13
13
  import pytest
14
14
 
@@ -19,16 +19,16 @@ from provide.foundation.file.safe import safe_delete
19
19
  def binary_file() -> Generator[Path, None, None]:
20
20
  """
21
21
  Create a temporary binary file for testing.
22
-
22
+
23
23
  Yields:
24
24
  Path to a binary file containing sample binary data.
25
25
  """
26
- with tempfile.NamedTemporaryFile(mode='wb', suffix='.bin', delete=False) as f:
26
+ with tempfile.NamedTemporaryFile(mode="wb", suffix=".bin", delete=False) as f:
27
27
  # Write some binary data
28
- f.write(b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09')
29
- f.write(b'\xFF\xFE\xFD\xFC\xFB\xFA\xF9\xF8\xF7\xF6')
28
+ f.write(b"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09")
29
+ f.write(b"\xff\xfe\xfd\xfc\xfb\xfa\xf9\xf8\xf7\xf6")
30
30
  path = Path(f.name)
31
-
31
+
32
32
  yield path
33
33
  safe_delete(path, missing_ok=True)
34
34
 
@@ -37,19 +37,19 @@ def binary_file() -> Generator[Path, None, None]:
37
37
  def readonly_file() -> Generator[Path, None, None]:
38
38
  """
39
39
  Create a read-only file for permission testing.
40
-
40
+
41
41
  Yields:
42
42
  Path to a read-only file.
43
43
  """
44
- with tempfile.NamedTemporaryFile(mode='w', suffix='.txt', delete=False) as f:
44
+ with tempfile.NamedTemporaryFile(mode="w", suffix=".txt", delete=False) as f:
45
45
  f.write("Read-only content")
46
46
  path = Path(f.name)
47
-
47
+
48
48
  # Make file read-only
49
49
  path.chmod(0o444)
50
-
50
+
51
51
  yield path
52
-
52
+
53
53
  # Restore write permission for cleanup
54
54
  path.chmod(0o644)
55
55
  safe_delete(path, missing_ok=True)
@@ -59,41 +59,38 @@ def readonly_file() -> Generator[Path, None, None]:
59
59
  def temp_symlink():
60
60
  """
61
61
  Create temporary symbolic links for testing.
62
-
62
+
63
63
  Returns:
64
64
  Function that creates symbolic links.
65
65
  """
66
66
  created_links = []
67
-
68
- def _make_symlink(
69
- target: Path | str,
70
- link_name: Path | str = None
71
- ) -> Path:
67
+
68
+ def _make_symlink(target: Path | str, link_name: Path | str = None) -> Path:
72
69
  """
73
70
  Create a temporary symbolic link.
74
-
71
+
75
72
  Args:
76
73
  target: Target path for the symlink
77
74
  link_name: Optional link name (auto-generated if None)
78
-
75
+
79
76
  Returns:
80
77
  Path to created symlink
81
78
  """
82
79
  target = Path(target)
83
-
80
+
84
81
  if link_name is None:
85
82
  with tempfile.NamedTemporaryFile(delete=True) as f:
86
83
  link_name = Path(f.name + "_link")
87
84
  else:
88
85
  link_name = Path(link_name)
89
-
86
+
90
87
  link_name.symlink_to(target)
91
88
  created_links.append(link_name)
92
-
89
+
93
90
  return link_name
94
-
91
+
95
92
  yield _make_symlink
96
-
93
+
97
94
  # Cleanup
98
95
  for link in created_links:
99
96
  safe_delete(link, missing_ok=True)
@@ -103,43 +100,38 @@ def temp_symlink():
103
100
  def temp_executable_file():
104
101
  """
105
102
  Create temporary executable files for testing.
106
-
103
+
107
104
  Returns:
108
105
  Function that creates executable files.
109
106
  """
110
107
  created_files = []
111
-
108
+
112
109
  def _make_executable(
113
- content: str = "#!/bin/sh\necho 'test'\n",
114
- suffix: str = ".sh"
110
+ content: str = "#!/bin/sh\necho 'test'\n", suffix: str = ".sh"
115
111
  ) -> Path:
116
112
  """
117
113
  Create a temporary executable file.
118
-
114
+
119
115
  Args:
120
116
  content: Script content
121
117
  suffix: File suffix
122
-
118
+
123
119
  Returns:
124
120
  Path to created executable file
125
121
  """
126
- with tempfile.NamedTemporaryFile(
127
- mode='w',
128
- suffix=suffix,
129
- delete=False
130
- ) as f:
122
+ with tempfile.NamedTemporaryFile(mode="w", suffix=suffix, delete=False) as f:
131
123
  f.write(content)
132
124
  path = Path(f.name)
133
-
125
+
134
126
  # Make executable
135
127
  current = path.stat().st_mode
136
128
  path.chmod(current | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)
137
-
129
+
138
130
  created_files.append(path)
139
131
  return path
140
-
132
+
141
133
  yield _make_executable
142
-
134
+
143
135
  # Cleanup
144
136
  for path in created_files:
145
137
  safe_delete(path, missing_ok=True)
@@ -148,6 +140,6 @@ def temp_executable_file():
148
140
  __all__ = [
149
141
  "binary_file",
150
142
  "readonly_file",
151
- "temp_symlink",
152
143
  "temp_executable_file",
153
- ]
144
+ "temp_symlink",
145
+ ]
@@ -8,10 +8,11 @@ Provides utilities for resetting logger state, managing configurations,
8
8
  and ensuring test isolation for the Foundation logging system.
9
9
  """
10
10
 
11
- import structlog
12
- import pytest
13
11
  from unittest.mock import Mock
14
12
 
13
+ import pytest
14
+ import structlog
15
+
15
16
  from provide.foundation.logger.core import (
16
17
  _LAZY_SETUP_STATE,
17
18
  logger as foundation_logger,
@@ -23,10 +24,10 @@ from provide.foundation.streams.file import reset_streams
23
24
  def mock_logger():
24
25
  """
25
26
  Comprehensive mock logger for testing.
26
-
27
+
27
28
  Provides compatibility with both stdlib logging and structlog interfaces,
28
29
  including method call tracking and common logger attributes.
29
-
30
+
30
31
  Returns:
31
32
  Mock logger with debug, info, warning, error methods and structlog compatibility.
32
33
  """
@@ -39,31 +40,31 @@ def mock_logger():
39
40
  logger.exception = Mock()
40
41
  logger.critical = Mock()
41
42
  logger.fatal = Mock() # Alias for critical
42
-
43
+
43
44
  # Add common logger attributes
44
45
  logger.name = "mock_logger"
45
46
  logger.level = 10 # DEBUG level
46
47
  logger.handlers = []
47
48
  logger.disabled = False
48
-
49
+
49
50
  # Add structlog compatibility methods
50
51
  logger.bind = Mock(return_value=logger)
51
52
  logger.unbind = Mock(return_value=logger)
52
53
  logger.new = Mock(return_value=logger)
53
54
  logger.msg = Mock() # Alternative to info
54
-
55
+
55
56
  # Add trace method for Foundation's extended logging
56
57
  logger.trace = Mock()
57
-
58
+
58
59
  return logger
59
60
 
60
61
 
61
62
  def mock_logger_factory():
62
63
  """
63
64
  Factory function to create mock loggers outside of pytest context.
64
-
65
+
65
66
  Useful for unit tests that need a mock logger but aren't using pytest fixtures.
66
-
67
+
67
68
  Returns:
68
69
  Mock logger with the same interface as the pytest fixture.
69
70
  """
@@ -76,18 +77,18 @@ def mock_logger_factory():
76
77
  logger.exception = Mock()
77
78
  logger.critical = Mock()
78
79
  logger.fatal = Mock()
79
-
80
+
80
81
  logger.name = "mock_logger"
81
82
  logger.level = 10
82
83
  logger.handlers = []
83
84
  logger.disabled = False
84
-
85
+
85
86
  logger.bind = Mock(return_value=logger)
86
87
  logger.unbind = Mock(return_value=logger)
87
88
  logger.new = Mock(return_value=logger)
88
89
  logger.msg = Mock()
89
90
  logger.trace = Mock()
90
-
91
+
91
92
  return logger
92
93
 
93
94
 
@@ -101,7 +102,7 @@ def _reset_opentelemetry_providers() -> None:
101
102
  try:
102
103
  # Reset tracing provider more thoroughly
103
104
  import opentelemetry.trace as otel_trace
104
-
105
+
105
106
  # Reset the Once flag to allow re-initialization
106
107
  if hasattr(otel_trace, "_TRACER_PROVIDER_SET_ONCE"):
107
108
  once_obj = otel_trace._TRACER_PROVIDER_SET_ONCE
@@ -110,11 +111,12 @@ def _reset_opentelemetry_providers() -> None:
110
111
  if hasattr(once_obj, "_lock"):
111
112
  with once_obj._lock:
112
113
  once_obj._done = False
113
-
114
+
114
115
  # Reset to NoOpTracerProvider
115
116
  from opentelemetry.trace import NoOpTracerProvider
117
+
116
118
  otel_trace.set_tracer_provider(NoOpTracerProvider())
117
-
119
+
118
120
  except ImportError:
119
121
  # OpenTelemetry tracing not available
120
122
  pass
@@ -126,7 +128,7 @@ def _reset_opentelemetry_providers() -> None:
126
128
  # Reset metrics provider more thoroughly
127
129
  import opentelemetry.metrics as otel_metrics
128
130
  import opentelemetry.metrics._internal as otel_metrics_internal
129
-
131
+
130
132
  # Reset the Once flag to allow re-initialization
131
133
  if hasattr(otel_metrics_internal, "_METER_PROVIDER_SET_ONCE"):
132
134
  once_obj = otel_metrics_internal._METER_PROVIDER_SET_ONCE
@@ -135,11 +137,12 @@ def _reset_opentelemetry_providers() -> None:
135
137
  if hasattr(once_obj, "_lock"):
136
138
  with once_obj._lock:
137
139
  once_obj._done = False
138
-
140
+
139
141
  # Reset to NoOpMeterProvider
140
142
  from opentelemetry.metrics import NoOpMeterProvider
143
+
141
144
  otel_metrics.set_meter_provider(NoOpMeterProvider())
142
-
145
+
143
146
  except ImportError:
144
147
  # OpenTelemetry metrics not available
145
148
  pass
@@ -187,17 +190,19 @@ def reset_foundation_setup_for_testing() -> None:
187
190
  """
188
191
  # Full reset but with improved OpenTelemetry handling
189
192
  reset_foundation_state()
190
-
193
+
191
194
  # Clear and re-initialize the hub for test isolation
192
195
  try:
193
196
  from provide.foundation.hub.manager import clear_hub
197
+
194
198
  clear_hub()
195
199
  except ImportError:
196
200
  pass
197
-
201
+
198
202
  # Re-register HTTP transport for tests that need it
199
203
  try:
200
204
  from provide.foundation.transport.http import _register_http_transport
205
+
201
206
  _register_http_transport()
202
207
  except ImportError:
203
208
  # Transport module not available
@@ -205,8 +210,8 @@ def reset_foundation_setup_for_testing() -> None:
205
210
 
206
211
 
207
212
  __all__ = [
208
- "reset_foundation_setup_for_testing",
209
- "reset_foundation_state",
210
213
  "mock_logger",
211
214
  "mock_logger_factory",
215
+ "reset_foundation_setup_for_testing",
216
+ "reset_foundation_state",
212
217
  ]
@@ -6,41 +6,41 @@ boilerplate and ensure consistent mocking across all tests.
6
6
  """
7
7
 
8
8
  from provide.foundation.testing.mocking.fixtures import (
9
- Mock,
10
- MagicMock,
9
+ ANY,
11
10
  AsyncMock,
11
+ MagicMock,
12
+ Mock,
12
13
  PropertyMock,
13
- patch,
14
+ assert_mock_calls,
15
+ async_mock_factory,
16
+ auto_patch,
14
17
  call,
15
- ANY,
16
- mock_factory,
17
18
  magic_mock_factory,
18
- async_mock_factory,
19
- property_mock_factory,
19
+ mock_factory,
20
+ mock_open_fixture,
21
+ patch,
20
22
  patch_fixture,
21
23
  patch_multiple_fixture,
22
- auto_patch,
23
- mock_open_fixture,
24
+ property_mock_factory,
24
25
  spy_fixture,
25
- assert_mock_calls,
26
26
  )
27
27
 
28
28
  __all__ = [
29
- "Mock",
30
- "MagicMock",
29
+ "ANY",
31
30
  "AsyncMock",
31
+ "MagicMock",
32
+ "Mock",
32
33
  "PropertyMock",
33
- "patch",
34
+ "assert_mock_calls",
35
+ "async_mock_factory",
36
+ "auto_patch",
34
37
  "call",
35
- "ANY",
36
- "mock_factory",
37
38
  "magic_mock_factory",
38
- "async_mock_factory",
39
- "property_mock_factory",
39
+ "mock_factory",
40
+ "mock_open_fixture",
41
+ "patch",
40
42
  "patch_fixture",
41
43
  "patch_multiple_fixture",
42
- "auto_patch",
43
- "mock_open_fixture",
44
+ "property_mock_factory",
44
45
  "spy_fixture",
45
- "assert_mock_calls",
46
- ]
46
+ ]