@@ -122,13 +122,6 @@ class Outcome(abc.ABC, Generic[ValueT]):
122
122
hashable.
123
123
124
124
"""
125
- _unwrapped : bool = attr .ib (default = False , eq = False , init = False )
126
-
127
- def _set_unwrapped (self ) -> None :
128
- if self ._unwrapped :
129
- raise AlreadyUsedError
130
- object .__setattr__ (self , '_unwrapped' , True )
131
-
132
125
@abc .abstractmethod
133
126
def unwrap (self ) -> ValueT :
134
127
"""Return or raise the contained value or exception.
@@ -174,19 +167,29 @@ class Value(Outcome[ValueT], Generic[ValueT]):
174
167
"""The contained value."""
175
168
176
169
def __repr__ (self ) -> str :
177
- return f'Value({ self .value !r} )'
170
+ try :
171
+ return f'Value({ self .value !r} )'
172
+ except AttributeError :
173
+ return f'Value(<DEAD>)'
178
174
179
175
def unwrap (self ) -> ValueT :
180
- self ._set_unwrapped ()
181
- return self .value
176
+ try :
177
+ v = self .value
178
+ except AttributeError :
179
+ pass
180
+ else :
181
+ object .__delattr__ (self , "value" )
182
+ try :
183
+ return v
184
+ finally :
185
+ del v
186
+ raise AlreadyUsedError
182
187
183
188
def send (self , gen : Generator [ResultT , ValueT , object ]) -> ResultT :
184
- self ._set_unwrapped ()
185
- return gen .send (self .value )
189
+ return gen .send (self .unwrap ())
186
190
187
191
async def asend (self , agen : AsyncGenerator [ResultT , ValueT ]) -> ResultT :
188
- self ._set_unwrapped ()
189
- return await agen .asend (self .value )
192
+ return await agen .asend (self .unwrap ())
190
193
191
194
192
195
@final
@@ -202,13 +205,28 @@ class Error(Outcome[NoReturn]):
202
205
"""The contained exception object."""
203
206
204
207
def __repr__ (self ) -> str :
205
- return f'Error({ self .error !r} )'
208
+ try :
209
+ return f'Error({ self .error !r} )'
210
+ except AttributeError :
211
+ return 'Error(<DEAD>)'
212
+
213
+ def _unwrap_error (self ) -> BaseException :
214
+ try :
215
+ v = self .error
216
+ except AttributeError :
217
+ pass
218
+ else :
219
+ object .__delattr__ (self , "error" )
220
+ try :
221
+ return v
222
+ finally :
223
+ del v
224
+ raise AlreadyUsedError
206
225
207
226
def unwrap (self ) -> NoReturn :
208
- self ._set_unwrapped ()
209
227
# Tracebacks show the 'raise' line below out of context, so let's give
210
228
# this variable a name that makes sense out of context.
211
- captured_error = self .error
229
+ captured_error = self ._unwrap_error ()
212
230
try :
213
231
raise captured_error
214
232
finally :
@@ -227,12 +245,10 @@ def unwrap(self) -> NoReturn:
227
245
del captured_error , self
228
246
229
247
def send (self , gen : Generator [ResultT , NoReturn , object ]) -> ResultT :
230
- self ._set_unwrapped ()
231
- return gen .throw (self .error )
248
+ return gen .throw (self ._unwrap_error ())
232
249
233
250
async def asend (self , agen : AsyncGenerator [ResultT , NoReturn ]) -> ResultT :
234
- self ._set_unwrapped ()
235
- return await agen .athrow (self .error )
251
+ return await agen .athrow (self ._unwrap_error ())
236
252
237
253
238
254
# A convenience alias to a union of both results, allowing exhaustiveness checking.
0 commit comments