Skip to content
Snippets Groups Projects
Commit 35674d71 authored by Piotr Maślanka's avatar Piotr Maślanka
Browse files

added Closeable, v2.14.2

parent 27fce8c2
No related branches found
Tags v2.1.9
No related merge requests found
# v2.14.2
* satella futures are now generic
* added `Closeable`
......@@ -324,3 +324,8 @@ Subqueue
.. autoclass:: satella.coding.structures.Subqueue
:members:
Closeable
---------
.. autoclass:: satella.coding.Closeable
:members:
__version__ = '2.14.2_a2'
__version__ = '2.14.2'
......@@ -14,7 +14,7 @@ from .metaclasses import metaclass_maker, wrap_with, dont_wrap, wrap_property, D
CopyDocsFrom
from .misc import update_if_not_none, update_key_if_none, update_attr_if_none, queue_iterator, \
update_key_if_not_none, source_to_function, update_key_if_true, \
get_arguments, call_with_arguments, chain_callables
get_arguments, call_with_arguments, chain_callables, Closeable
from .overloading import overload, class_or_instancemethod
from .recast_exceptions import rethrow_as, silence_excs, catch_exception, log_exceptions, \
raises_exception
......
......@@ -6,6 +6,52 @@ from queue import Queue
from satella.coding.recast_exceptions import rethrow_as
class Closeable:
"""
A class that needs to clean up it's own resources.
It's destructor calls .close(). Use like this:
>>> class MyClose(Closeable):
>>> def close(self):
>>> if super().close():
>>> .. clean up ..
Can be also used as a context manager, with close() called upon __exit__.
You should extend both __init__ and close()
"""
def __init__(self):
self.__finalized = False
def close(self) -> bool:
"""
Check if the resource needs cleanup, and clean up this resource.
Use like this:
>>> class MyClose(Closeable):
>>> def close(self):
>>> if super().close():
>>> .. clean up ..
:return: whether the cleanup should proceed
"""
try:
return not self.__finalized
finally:
self.__finalized = True
def __del__(self) -> None:
self.close()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
def queue_iterator(queue: Queue) -> tp.Iterator:
"""
Syntactic sugar for
......
import gc
import unittest
from satella.coding import update_key_if_not_none, overload, class_or_instancemethod, \
update_key_if_true, get_arguments, call_with_arguments, chain_callables
update_key_if_true, get_arguments, call_with_arguments, chain_callables, Closeable
from satella.coding.structures import HashableMixin
from satella.coding.transforms import jsonify, intify
class TestCase(unittest.TestCase):
def test_closeable(self):
a = {'test': False}
class MyClose(Closeable):
def close(self):
if super().close():
a['test'] = True
b = MyClose()
del b
gc.collect()
self.assertTrue(a['test'])
def test_chain_callables(self):
def a():
return 5
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment