Skip to content

Commit 20c75bf

Browse files
committed
remove instances from outcome on unwrap
1 parent 03ed621 commit 20c75bf

File tree

1 file changed

+29
-18
lines changed

1 file changed

+29
-18
lines changed

src/outcome/_impl.py

+29-18
Original file line numberDiff line numberDiff line change
@@ -122,13 +122,6 @@ class Outcome(abc.ABC, Generic[ValueT]):
122122
hashable.
123123
124124
"""
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-
132125
@abc.abstractmethod
133126
def unwrap(self) -> ValueT:
134127
"""Return or raise the contained value or exception.
@@ -177,16 +170,24 @@ def __repr__(self) -> str:
177170
return f'Value({self.value!r})'
178171

179172
def unwrap(self) -> ValueT:
180-
self._set_unwrapped()
181-
return self.value
173+
try:
174+
v = self.value
175+
except AttributeError:
176+
pass
177+
else:
178+
object.__delattr__(self, "value")
179+
try:
180+
return v
181+
finally:
182+
del v
183+
raise AlreadyUsedError
182184

183185
def send(self, gen: Generator[ResultT, ValueT, object]) -> ResultT:
184-
self._set_unwrapped()
185-
return gen.send(self.value)
186+
return gen.send(self.unwrap())
186187

187188
async def asend(self, agen: AsyncGenerator[ResultT, ValueT]) -> ResultT:
188189
self._set_unwrapped()
189-
return await agen.asend(self.value)
190+
return await agen.asend(self.unwrap())
190191

191192

192193
@final
@@ -204,11 +205,23 @@ class Error(Outcome[NoReturn]):
204205
def __repr__(self) -> str:
205206
return f'Error({self.error!r})'
206207

208+
def _unwrap_error(self) -> BaseException:
209+
try:
210+
v = self.error
211+
except AttributeError:
212+
pass
213+
else:
214+
object.__delattr__(self, "error")
215+
try:
216+
return v
217+
finally:
218+
del v
219+
raise AlreadyUsedError
220+
207221
def unwrap(self) -> NoReturn:
208-
self._set_unwrapped()
209222
# Tracebacks show the 'raise' line below out of context, so let's give
210223
# this variable a name that makes sense out of context.
211-
captured_error = self.error
224+
captured_error = self._unwrap_error()
212225
try:
213226
raise captured_error
214227
finally:
@@ -227,12 +240,10 @@ def unwrap(self) -> NoReturn:
227240
del captured_error, self
228241

229242
def send(self, gen: Generator[ResultT, NoReturn, object]) -> ResultT:
230-
self._set_unwrapped()
231-
return gen.throw(self.error)
243+
return gen.throw(self._unwrap_error())
232244

233245
async def asend(self, agen: AsyncGenerator[ResultT, NoReturn]) -> ResultT:
234-
self._set_unwrapped()
235-
return await agen.athrow(self.error)
246+
return await agen.athrow(self._unwrap_error())
236247

237248

238249
# A convenience alias to a union of both results, allowing exhaustiveness checking.

0 commit comments

Comments
 (0)