provide-foundation 0.0.0.dev1__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 (163) hide show
  1. provide/foundation/__init__.py +36 -10
  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 +93 -96
  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 +15 -9
  13. provide/foundation/cli/commands/logs/__init__.py +3 -3
  14. provide/foundation/cli/commands/logs/generate.py +2 -2
  15. provide/foundation/cli/commands/logs/query.py +4 -4
  16. provide/foundation/cli/commands/logs/send.py +3 -3
  17. provide/foundation/cli/commands/logs/tail.py +3 -3
  18. provide/foundation/cli/decorators.py +11 -11
  19. provide/foundation/cli/main.py +1 -1
  20. provide/foundation/cli/testing.py +2 -40
  21. provide/foundation/cli/utils.py +21 -18
  22. provide/foundation/config/__init__.py +35 -2
  23. provide/foundation/config/base.py +2 -2
  24. provide/foundation/config/converters.py +477 -0
  25. provide/foundation/config/defaults.py +67 -0
  26. provide/foundation/config/env.py +6 -20
  27. provide/foundation/config/loader.py +10 -4
  28. provide/foundation/config/sync.py +8 -6
  29. provide/foundation/config/types.py +5 -5
  30. provide/foundation/config/validators.py +4 -4
  31. provide/foundation/console/input.py +5 -5
  32. provide/foundation/console/output.py +36 -14
  33. provide/foundation/context/__init__.py +8 -4
  34. provide/foundation/context/core.py +88 -110
  35. provide/foundation/crypto/certificates/__init__.py +9 -5
  36. provide/foundation/crypto/certificates/base.py +2 -2
  37. provide/foundation/crypto/certificates/certificate.py +48 -19
  38. provide/foundation/crypto/certificates/factory.py +26 -18
  39. provide/foundation/crypto/certificates/generator.py +24 -23
  40. provide/foundation/crypto/certificates/loader.py +24 -16
  41. provide/foundation/crypto/certificates/operations.py +17 -10
  42. provide/foundation/crypto/certificates/trust.py +21 -21
  43. provide/foundation/env/__init__.py +28 -0
  44. provide/foundation/env/core.py +218 -0
  45. provide/foundation/errors/__init__.py +3 -3
  46. provide/foundation/errors/decorators.py +0 -234
  47. provide/foundation/errors/types.py +0 -98
  48. provide/foundation/eventsets/display.py +13 -14
  49. provide/foundation/eventsets/registry.py +61 -31
  50. provide/foundation/eventsets/resolver.py +50 -46
  51. provide/foundation/eventsets/sets/das.py +8 -8
  52. provide/foundation/eventsets/sets/database.py +14 -14
  53. provide/foundation/eventsets/sets/http.py +21 -21
  54. provide/foundation/eventsets/sets/llm.py +16 -16
  55. provide/foundation/eventsets/sets/task_queue.py +13 -13
  56. provide/foundation/eventsets/types.py +7 -7
  57. provide/foundation/file/directory.py +14 -23
  58. provide/foundation/file/lock.py +4 -3
  59. provide/foundation/hub/components.py +75 -389
  60. provide/foundation/hub/config.py +157 -0
  61. provide/foundation/hub/discovery.py +63 -0
  62. provide/foundation/hub/handlers.py +89 -0
  63. provide/foundation/hub/lifecycle.py +195 -0
  64. provide/foundation/hub/manager.py +7 -4
  65. provide/foundation/hub/processors.py +49 -0
  66. provide/foundation/integrations/__init__.py +11 -0
  67. provide/foundation/{observability → integrations}/openobserve/__init__.py +10 -7
  68. provide/foundation/{observability → integrations}/openobserve/auth.py +1 -1
  69. provide/foundation/{observability → integrations}/openobserve/client.py +14 -14
  70. provide/foundation/{observability → integrations}/openobserve/commands.py +12 -12
  71. provide/foundation/integrations/openobserve/config.py +37 -0
  72. provide/foundation/{observability → integrations}/openobserve/formatters.py +1 -1
  73. provide/foundation/{observability → integrations}/openobserve/otlp.py +2 -2
  74. provide/foundation/{observability → integrations}/openobserve/search.py +2 -3
  75. provide/foundation/{observability → integrations}/openobserve/streaming.py +5 -5
  76. provide/foundation/logger/__init__.py +0 -1
  77. provide/foundation/logger/config/base.py +1 -1
  78. provide/foundation/logger/config/logging.py +69 -299
  79. provide/foundation/logger/config/telemetry.py +39 -121
  80. provide/foundation/logger/factories.py +2 -2
  81. provide/foundation/logger/processors/main.py +12 -10
  82. provide/foundation/logger/ratelimit/limiters.py +4 -4
  83. provide/foundation/logger/ratelimit/processor.py +1 -1
  84. provide/foundation/logger/setup/coordinator.py +39 -25
  85. provide/foundation/logger/setup/processors.py +3 -3
  86. provide/foundation/logger/setup/testing.py +14 -0
  87. provide/foundation/logger/trace.py +5 -5
  88. provide/foundation/metrics/__init__.py +1 -1
  89. provide/foundation/metrics/otel.py +3 -1
  90. provide/foundation/observability/__init__.py +3 -3
  91. provide/foundation/process/__init__.py +9 -0
  92. provide/foundation/process/exit.py +48 -0
  93. provide/foundation/process/lifecycle.py +69 -46
  94. provide/foundation/resilience/__init__.py +36 -0
  95. provide/foundation/resilience/circuit.py +166 -0
  96. provide/foundation/resilience/decorators.py +236 -0
  97. provide/foundation/resilience/fallback.py +208 -0
  98. provide/foundation/resilience/retry.py +327 -0
  99. provide/foundation/serialization/__init__.py +16 -0
  100. provide/foundation/serialization/core.py +70 -0
  101. provide/foundation/streams/config.py +78 -0
  102. provide/foundation/streams/console.py +4 -5
  103. provide/foundation/streams/core.py +5 -2
  104. provide/foundation/streams/file.py +12 -2
  105. provide/foundation/testing/__init__.py +29 -9
  106. provide/foundation/testing/archive/__init__.py +7 -7
  107. provide/foundation/testing/archive/fixtures.py +58 -54
  108. provide/foundation/testing/cli.py +30 -20
  109. provide/foundation/testing/common/__init__.py +13 -15
  110. provide/foundation/testing/common/fixtures.py +27 -57
  111. provide/foundation/testing/file/__init__.py +15 -15
  112. provide/foundation/testing/file/content_fixtures.py +289 -0
  113. provide/foundation/testing/file/directory_fixtures.py +107 -0
  114. provide/foundation/testing/file/fixtures.py +42 -516
  115. provide/foundation/testing/file/special_fixtures.py +145 -0
  116. provide/foundation/testing/logger.py +89 -8
  117. provide/foundation/testing/mocking/__init__.py +21 -21
  118. provide/foundation/testing/mocking/fixtures.py +80 -67
  119. provide/foundation/testing/process/__init__.py +23 -23
  120. provide/foundation/testing/process/async_fixtures.py +414 -0
  121. provide/foundation/testing/process/fixtures.py +48 -571
  122. provide/foundation/testing/process/subprocess_fixtures.py +210 -0
  123. provide/foundation/testing/threading/__init__.py +17 -17
  124. provide/foundation/testing/threading/basic_fixtures.py +105 -0
  125. provide/foundation/testing/threading/data_fixtures.py +101 -0
  126. provide/foundation/testing/threading/execution_fixtures.py +278 -0
  127. provide/foundation/testing/threading/fixtures.py +32 -502
  128. provide/foundation/testing/threading/sync_fixtures.py +100 -0
  129. provide/foundation/testing/time/__init__.py +11 -11
  130. provide/foundation/testing/time/fixtures.py +95 -83
  131. provide/foundation/testing/transport/__init__.py +9 -9
  132. provide/foundation/testing/transport/fixtures.py +54 -54
  133. provide/foundation/time/__init__.py +18 -0
  134. provide/foundation/time/core.py +63 -0
  135. provide/foundation/tools/__init__.py +2 -2
  136. provide/foundation/tools/base.py +68 -67
  137. provide/foundation/tools/cache.py +69 -74
  138. provide/foundation/tools/downloader.py +68 -62
  139. provide/foundation/tools/installer.py +51 -57
  140. provide/foundation/tools/registry.py +38 -45
  141. provide/foundation/tools/resolver.py +70 -68
  142. provide/foundation/tools/verifier.py +39 -50
  143. provide/foundation/tracer/spans.py +2 -14
  144. provide/foundation/transport/__init__.py +26 -33
  145. provide/foundation/transport/base.py +32 -30
  146. provide/foundation/transport/client.py +44 -49
  147. provide/foundation/transport/config.py +36 -107
  148. provide/foundation/transport/errors.py +13 -27
  149. provide/foundation/transport/http.py +69 -55
  150. provide/foundation/transport/middleware.py +113 -114
  151. provide/foundation/transport/registry.py +29 -27
  152. provide/foundation/transport/types.py +6 -6
  153. provide/foundation/utils/deps.py +17 -14
  154. provide/foundation/utils/parsing.py +49 -4
  155. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/METADATA +2 -2
  156. provide_foundation-0.0.0.dev3.dist-info/RECORD +233 -0
  157. provide_foundation-0.0.0.dev1.dist-info/RECORD +0 -200
  158. /provide/foundation/{observability → integrations}/openobserve/exceptions.py +0 -0
  159. /provide/foundation/{observability → integrations}/openobserve/models.py +0 -0
  160. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/WHEEL +0 -0
  161. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/entry_points.txt +0 -0
  162. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/licenses/LICENSE +0 -0
  163. {provide_foundation-0.0.0.dev1.dist-info → provide_foundation-0.0.0.dev3.dist-info}/top_level.txt +0 -0
@@ -20,7 +20,7 @@ EVENT_SET = EventSet(
20
20
  "options": "⚙️❔",
21
21
  "default": "🌐",
22
22
  },
23
- default_key="default"
23
+ default_key="default",
24
24
  ),
25
25
  EventMapping(
26
26
  name="http_status_class",
@@ -37,7 +37,7 @@ EVENT_SET = EventSet(
37
37
  "4xx": {"http.client_error": True},
38
38
  "5xx": {"http.server_error": True},
39
39
  },
40
- default_key="default"
40
+ default_key="default",
41
41
  ),
42
42
  EventMapping(
43
43
  name="http_target_type",
@@ -47,7 +47,7 @@ EVENT_SET = EventSet(
47
47
  "fragment": "#️⃣",
48
48
  "default": "🎯",
49
49
  },
50
- default_key="default"
50
+ default_key="default",
51
51
  ),
52
52
  ],
53
53
  field_mappings=[
@@ -55,99 +55,99 @@ EVENT_SET = EventSet(
55
55
  log_key="http.method",
56
56
  event_set_name="http",
57
57
  description="HTTP request method",
58
- value_type="string"
58
+ value_type="string",
59
59
  ),
60
60
  FieldMapping(
61
61
  log_key="http.status_class",
62
62
  event_set_name="http",
63
63
  description="HTTP status code class",
64
- value_type="string"
64
+ value_type="string",
65
65
  ),
66
66
  FieldMapping(
67
67
  log_key="http.target",
68
68
  event_set_name="http",
69
69
  description="Request target path and query",
70
70
  value_type="string",
71
- default_override_key="path"
71
+ default_override_key="path",
72
72
  ),
73
73
  FieldMapping(
74
74
  log_key="http.url",
75
75
  event_set_name="http",
76
76
  description="Full HTTP URL",
77
- value_type="string"
77
+ value_type="string",
78
78
  ),
79
79
  FieldMapping(
80
80
  log_key="http.scheme",
81
81
  event_set_name="http",
82
82
  description="URL scheme",
83
- value_type="string"
83
+ value_type="string",
84
84
  ),
85
85
  FieldMapping(
86
86
  log_key="http.host",
87
87
  event_set_name="http",
88
88
  description="Request hostname",
89
- value_type="string"
89
+ value_type="string",
90
90
  ),
91
91
  FieldMapping(
92
92
  log_key="http.status_code",
93
93
  event_set_name="http",
94
94
  description="HTTP response status code",
95
- value_type="integer"
95
+ value_type="integer",
96
96
  ),
97
97
  FieldMapping(
98
98
  log_key="http.request.body.size",
99
99
  event_set_name="http",
100
100
  description="Request body size in bytes",
101
- value_type="integer"
101
+ value_type="integer",
102
102
  ),
103
103
  FieldMapping(
104
104
  log_key="http.response.body.size",
105
105
  event_set_name="http",
106
106
  description="Response body size in bytes",
107
- value_type="integer"
107
+ value_type="integer",
108
108
  ),
109
109
  FieldMapping(
110
110
  log_key="client.address",
111
111
  event_set_name="http",
112
112
  description="Client IP address",
113
- value_type="string"
113
+ value_type="string",
114
114
  ),
115
115
  FieldMapping(
116
116
  log_key="server.address",
117
117
  event_set_name="http",
118
118
  description="Server address or hostname",
119
- value_type="string"
119
+ value_type="string",
120
120
  ),
121
121
  FieldMapping(
122
122
  log_key="duration_ms",
123
123
  event_set_name="http",
124
124
  description="Request duration in milliseconds",
125
- value_type="integer"
125
+ value_type="integer",
126
126
  ),
127
127
  FieldMapping(
128
128
  log_key="trace_id",
129
129
  event_set_name="http",
130
130
  description="Distributed trace ID",
131
- value_type="string"
131
+ value_type="string",
132
132
  ),
133
133
  FieldMapping(
134
134
  log_key="span_id",
135
135
  event_set_name="http",
136
136
  description="Span ID",
137
- value_type="string"
137
+ value_type="string",
138
138
  ),
139
139
  FieldMapping(
140
140
  log_key="error.message",
141
141
  event_set_name="http",
142
142
  description="Error message if request failed",
143
- value_type="string"
143
+ value_type="string",
144
144
  ),
145
145
  FieldMapping(
146
146
  log_key="error.type",
147
147
  event_set_name="http",
148
148
  description="Error type if request failed",
149
- value_type="string"
149
+ value_type="string",
150
150
  ),
151
151
  ],
152
- priority=80
153
- )
152
+ priority=80,
153
+ )
@@ -2,7 +2,7 @@
2
2
  Large Language Model (LLM) interaction event set for Foundation.
3
3
  """
4
4
 
5
- from provide.foundation.eventsets.types import EventSet, EventMapping, FieldMapping
5
+ from provide.foundation.eventsets.types import EventMapping, EventSet, FieldMapping
6
6
 
7
7
  EVENT_SET = EventSet(
8
8
  name="llm",
@@ -27,7 +27,7 @@ EVENT_SET = EventSet(
27
27
  "meta": {"llm.vendor": "meta", "llm.api": "llama"},
28
28
  "mistral": {"llm.vendor": "mistral", "llm.api": "mistral"},
29
29
  },
30
- default_key="default"
30
+ default_key="default",
31
31
  ),
32
32
  EventMapping(
33
33
  name="llm_task",
@@ -49,7 +49,7 @@ EVENT_SET = EventSet(
49
49
  "chat": {"llm.type": "conversational"},
50
50
  "tool_use": {"llm.type": "function_calling"},
51
51
  },
52
- default_key="default"
52
+ default_key="default",
53
53
  ),
54
54
  EventMapping(
55
55
  name="llm_outcome",
@@ -70,7 +70,7 @@ EVENT_SET = EventSet(
70
70
  "filtered_input": {"llm.filtered": True, "llm.filter_type": "input"},
71
71
  "filtered_output": {"llm.filtered": True, "llm.filter_type": "output"},
72
72
  },
73
- default_key="default"
73
+ default_key="default",
74
74
  ),
75
75
  ],
76
76
  field_mappings=[
@@ -78,62 +78,62 @@ EVENT_SET = EventSet(
78
78
  log_key="llm.provider",
79
79
  event_set_name="llm",
80
80
  description="LLM provider name",
81
- value_type="string"
81
+ value_type="string",
82
82
  ),
83
83
  FieldMapping(
84
84
  log_key="llm.task",
85
85
  event_set_name="llm",
86
86
  description="LLM task type",
87
- value_type="string"
87
+ value_type="string",
88
88
  ),
89
89
  FieldMapping(
90
90
  log_key="llm.model",
91
91
  event_set_name="llm",
92
92
  description="Model identifier",
93
- value_type="string"
93
+ value_type="string",
94
94
  ),
95
95
  FieldMapping(
96
96
  log_key="llm.outcome",
97
97
  event_set_name="llm",
98
98
  description="Operation outcome",
99
- value_type="string"
99
+ value_type="string",
100
100
  ),
101
101
  FieldMapping(
102
102
  log_key="llm.input.tokens",
103
103
  event_set_name="llm",
104
104
  description="Input token count",
105
- value_type="integer"
105
+ value_type="integer",
106
106
  ),
107
107
  FieldMapping(
108
108
  log_key="llm.output.tokens",
109
109
  event_set_name="llm",
110
110
  description="Output token count",
111
- value_type="integer"
111
+ value_type="integer",
112
112
  ),
113
113
  FieldMapping(
114
114
  log_key="llm.tool.name",
115
115
  event_set_name="llm",
116
116
  description="Tool/function name",
117
- value_type="string"
117
+ value_type="string",
118
118
  ),
119
119
  FieldMapping(
120
120
  log_key="llm.tool.call_id",
121
121
  event_set_name="llm",
122
122
  description="Tool call identifier",
123
- value_type="string"
123
+ value_type="string",
124
124
  ),
125
125
  FieldMapping(
126
126
  log_key="duration_ms",
127
127
  event_set_name="llm",
128
128
  description="LLM operation duration",
129
- value_type="integer"
129
+ value_type="integer",
130
130
  ),
131
131
  FieldMapping(
132
132
  log_key="trace_id",
133
133
  event_set_name="llm",
134
134
  description="Distributed trace ID",
135
- value_type="string"
135
+ value_type="string",
136
136
  ),
137
137
  ],
138
- priority=100 # High priority for LLM operations
139
- )
138
+ priority=100, # High priority for LLM operations
139
+ )
@@ -2,7 +2,7 @@
2
2
  Task queue and async job processing event set for Foundation.
3
3
  """
4
4
 
5
- from provide.foundation.eventsets.types import EventSet, EventMapping, FieldMapping
5
+ from provide.foundation.eventsets.types import EventMapping, EventSet, FieldMapping
6
6
 
7
7
  EVENT_SET = EventSet(
8
8
  name="task_queue",
@@ -25,7 +25,7 @@ EVENT_SET = EventSet(
25
25
  "kafka": {"task.broker": "kafka", "task.streaming": True},
26
26
  "rabbitmq": {"task.broker": "amqp"},
27
27
  },
28
- default_key="default"
28
+ default_key="default",
29
29
  ),
30
30
  EventMapping(
31
31
  name="task_status",
@@ -50,7 +50,7 @@ EVENT_SET = EventSet(
50
50
  "failure": {"task.state": "failed", "task.success": False},
51
51
  "revoked": {"task.state": "cancelled"},
52
52
  },
53
- default_key="default"
53
+ default_key="default",
54
54
  ),
55
55
  ],
56
56
  field_mappings=[
@@ -58,50 +58,50 @@ EVENT_SET = EventSet(
58
58
  log_key="task.system",
59
59
  event_set_name="task_queue",
60
60
  description="Task queue system",
61
- value_type="string"
61
+ value_type="string",
62
62
  ),
63
63
  FieldMapping(
64
64
  log_key="task.status",
65
65
  event_set_name="task_queue",
66
66
  description="Task execution status",
67
- value_type="string"
67
+ value_type="string",
68
68
  ),
69
69
  FieldMapping(
70
70
  log_key="task.id",
71
71
  event_set_name="task_queue",
72
72
  description="Unique task identifier",
73
- value_type="string"
73
+ value_type="string",
74
74
  ),
75
75
  FieldMapping(
76
76
  log_key="task.name",
77
77
  event_set_name="task_queue",
78
78
  description="Task or job name",
79
- value_type="string"
79
+ value_type="string",
80
80
  ),
81
81
  FieldMapping(
82
82
  log_key="task.queue_name",
83
83
  event_set_name="task_queue",
84
84
  description="Queue name",
85
- value_type="string"
85
+ value_type="string",
86
86
  ),
87
87
  FieldMapping(
88
88
  log_key="task.retries",
89
89
  event_set_name="task_queue",
90
90
  description="Retry attempt count",
91
- value_type="integer"
91
+ value_type="integer",
92
92
  ),
93
93
  FieldMapping(
94
94
  log_key="duration_ms",
95
95
  event_set_name="task_queue",
96
96
  description="Task execution duration",
97
- value_type="integer"
97
+ value_type="integer",
98
98
  ),
99
99
  FieldMapping(
100
100
  log_key="trace_id",
101
101
  event_set_name="task_queue",
102
102
  description="Distributed trace ID",
103
- value_type="string"
103
+ value_type="string",
104
104
  ),
105
105
  ],
106
- priority=70
107
- )
106
+ priority=70,
107
+ )
@@ -12,7 +12,7 @@ from attrs import define, field
12
12
  class EventMapping:
13
13
  """
14
14
  Individual event enrichment mapping for a specific domain.
15
-
15
+
16
16
  Attributes:
17
17
  name: Unique identifier for this mapping
18
18
  visual_markers: Mapping of values to visual indicators (e.g., emojis)
@@ -20,7 +20,7 @@ class EventMapping:
20
20
  transformations: Value transformation functions
21
21
  default_key: Key to use when no specific match is found
22
22
  """
23
-
23
+
24
24
  name: str
25
25
  visual_markers: dict[str, str] = field(factory=lambda: {})
26
26
  metadata_fields: dict[str, dict[str, Any]] = field(factory=lambda: {})
@@ -32,7 +32,7 @@ class EventMapping:
32
32
  class FieldMapping:
33
33
  """
34
34
  Maps a log field to an event set for enrichment.
35
-
35
+
36
36
  Attributes:
37
37
  log_key: The field key in log events (e.g., "http.method", "llm.provider")
38
38
  description: Human-readable description of this field
@@ -41,7 +41,7 @@ class FieldMapping:
41
41
  default_override_key: Override the default key for this specific field
42
42
  default_value: Default value to use if field is not present
43
43
  """
44
-
44
+
45
45
  log_key: str
46
46
  description: str | None = field(default=None)
47
47
  value_type: str | None = field(default=None)
@@ -54,7 +54,7 @@ class FieldMapping:
54
54
  class EventSet:
55
55
  """
56
56
  Complete event enrichment domain definition.
57
-
57
+
58
58
  Attributes:
59
59
  name: Unique identifier for this event set
60
60
  description: Human-readable description
@@ -62,9 +62,9 @@ class EventSet:
62
62
  field_mappings: List of field-to-mapping associations
63
63
  priority: Higher priority sets override lower ones
64
64
  """
65
-
65
+
66
66
  name: str
67
67
  description: str | None = field(default=None)
68
68
  mappings: list[EventMapping] = field(factory=lambda: [])
69
69
  field_mappings: list[FieldMapping] = field(factory=lambda: [])
70
- priority: int = field(default=0, converter=int)
70
+ priority: int = field(default=0, converter=int)
@@ -1,11 +1,13 @@
1
1
  """Directory operations and utilities."""
2
2
 
3
3
  from contextlib import contextmanager
4
- from typing import Generator
5
4
  from pathlib import Path
6
5
  import shutil
7
6
  import tempfile
7
+ from typing import Generator
8
8
 
9
+ from provide.foundation.errors.decorators import with_error_handling
10
+ from provide.foundation.errors.handlers import error_boundary
9
11
  from provide.foundation.logger import get_logger
10
12
 
11
13
  log = get_logger(__name__)
@@ -80,17 +82,12 @@ def temp_dir(
80
82
  yield temp_path
81
83
  finally:
82
84
  if cleanup and temp_path and temp_path.exists():
83
- try:
85
+ with error_boundary(Exception, reraise=False):
84
86
  shutil.rmtree(temp_path)
85
87
  log.debug("Cleaned up temp directory", path=str(temp_path))
86
- except Exception as e:
87
- log.warning(
88
- "Failed to cleanup temp directory",
89
- path=str(temp_path),
90
- error=str(e),
91
- )
92
88
 
93
89
 
90
+ @with_error_handling(fallback=False, suppress=(FileNotFoundError,) if False else ())
94
91
  def safe_rmtree(
95
92
  path: Path | str,
96
93
  missing_ok: bool = True,
@@ -109,21 +106,15 @@ def safe_rmtree(
109
106
  """
110
107
  path = Path(path)
111
108
 
112
- try:
113
- if path.exists():
114
- shutil.rmtree(path)
115
- log.debug("Removed directory tree", path=str(path))
116
- return True
117
- elif missing_ok:
118
- log.debug("Directory already absent", path=str(path))
119
- return False
120
- else:
121
- raise FileNotFoundError(f"Directory does not exist: {path}")
122
- except Exception as e:
123
- if not path.exists() and missing_ok:
124
- return False
125
- log.error("Failed to remove directory tree", path=str(path), error=str(e))
126
- raise
109
+ if path.exists():
110
+ shutil.rmtree(path)
111
+ log.debug("Removed directory tree", path=str(path))
112
+ return True
113
+ elif missing_ok:
114
+ log.debug("Directory already absent", path=str(path))
115
+ return False
116
+ else:
117
+ raise FileNotFoundError(f"Directory does not exist: {path}")
127
118
 
128
119
 
129
120
  __all__ = [
@@ -4,6 +4,7 @@ import os
4
4
  from pathlib import Path
5
5
  import time
6
6
 
7
+ from provide.foundation.config.defaults import DEFAULT_FILE_LOCK_TIMEOUT
7
8
  from provide.foundation.errors.resources import LockError
8
9
  from provide.foundation.logger import get_logger
9
10
 
@@ -25,7 +26,7 @@ class FileLock:
25
26
  def __init__(
26
27
  self,
27
28
  path: Path | str,
28
- timeout: float = 10.0,
29
+ timeout: float = DEFAULT_FILE_LOCK_TIMEOUT,
29
30
  check_interval: float = 0.1,
30
31
  ) -> None:
31
32
  """Initialize file lock.
@@ -158,12 +159,12 @@ class FileLock:
158
159
 
159
160
  return False
160
161
 
161
- def __enter__(self):
162
+ def __enter__(self) -> "FileLock":
162
163
  """Context manager entry."""
163
164
  self.acquire()
164
165
  return self
165
166
 
166
- def __exit__(self, exc_type, exc_val, exc_tb):
167
+ def __exit__(self, exc_type: object, exc_val: object, exc_tb: object) -> bool:
167
168
  """Context manager exit."""
168
169
  self.release()
169
170
  return False # Don't suppress exceptions