reliable-finalizer


Namereliable-finalizer JSON
Version 1.0.0 PyPI version JSON
download
home_pagehttps://github.com/TimurTimergalin/reliable-finalizer
SummaryPython utility for creation of reliable finalizer as an alternative to __del__ method
upload_time2024-08-19 18:28:45
maintainerNone
docs_urlNone
authorTimurTimergalin
requires_python>=3.2
licenseNone
keywords python finalize
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # reliable-finalizer
`reliable-finalizer` is a small utility library for convenient implementation
of finalizers in python
## Installation
```
pip install reliable-finalizer
```
## Usage

```python
from reliable_finalizer import reliable_finalizer

class UsefulClass:
    ...  # This is a class that requires some cleanup on instance destruction
    
    # This method will be called on object before it is garbage collected OR at the end of the program
    @reliable_finalizer
    def destruct(self): 
        ...  # The cleanup code       
```

## Why use `reliable-finalizer`?
This library's purpose is to provide convenient syntax for reliable finalization in Python.
The built-in solution for finalization, [\_\_del\_\_()](https://docs.python.org/3/reference/datamodel.html#object.__del__), does not make guarantees strong enough to be adequately used
with an arbitrary interpreter (although it is somewhat consistent in [CPython](https://docs.python.org/3/glossary.html#term-CPython)).
Namely, it can be called multiple times, and is not guaranteed to be called at all! - `__del__()` is not a great place for cleanup code.

Standard library offers a more robust solution: [weakref.finalize()](https://docs.python.org/3/library/weakref.html#finalizer-objects). It does basically the same thing `__del__()` does, but gives stronger guarantees about its behavior: the callback is invoked once and only once.

`reliable_finalizer` decorator is a utility for creating such finalizers. Any instance of a class with `reliable_finalizer`-decorated method will have a finalizer assigned to it.
Because of that, using `reliable_finalizer` is syntactically similar to using `__del__()` - all one needs is to create a method.

## Additional details and limitations
### Manual finalizer invocation 
Calling a method decorated with `reliable_finalizer` on an instance invokes the underlying finalizer, so calling it manually is completely fine - it will still only be called once. This can be useful, for example, if you want to additionally implement [context manager protocol](https://docs.python.org/3/reference/datamodel.html#context-managers) in your class:
```python
from reliable_finalizer import reliable_finalizer

class UsefulClass:
    ...  # This is a class that requires some cleanup on instance destruction
    
    # This method will be called on object before it is garbage collected OR at the end of the program
    @reliable_finalizer
    def destruct(self): 
        ...  # The cleanup code 
    
    def __enter__(self):
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.destruct()
```
### Using finalizers with slots
When using `reliable_finalizer`, the underlying weakref finalizer of an instance is saved to its `__finalizer__` attribute.
If your class does not have a `__dict__` slot, it must have `__finalizer__` slot in order to use `reliable_finalizer`:
```python
from reliable_finalizer import reliable_finalizer

class UsefulClass:
    ...  # This is a class that requires some cleanup on instance destruction
    
    __slots__ = [
        ...,  # Slots for the class
        '__finalizer__'  # This slot is required for reliable_finalizer to work, if "__dict__" is not a slot 
    ]
    
    # This method will be called on object before it is garbage collected OR at the end of the program
    @reliable_finalizer
    def destruct(self): 
        ...  # The cleanup code       
```

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/TimurTimergalin/reliable-finalizer",
    "name": "reliable-finalizer",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.2",
    "maintainer_email": null,
    "keywords": "python finalize",
    "author": "TimurTimergalin",
    "author_email": "tmtimergalin8080@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/a5/fe/d6090a5192d99de95bedf80135c6d163238d1174e7f48bda08fa43597cc4/reliable_finalizer-1.0.0.tar.gz",
    "platform": null,
    "description": "# reliable-finalizer\r\n`reliable-finalizer` is a small utility library for convenient implementation\r\nof finalizers in python\r\n## Installation\r\n```\r\npip install reliable-finalizer\r\n```\r\n## Usage\r\n\r\n```python\r\nfrom reliable_finalizer import reliable_finalizer\r\n\r\nclass UsefulClass:\r\n    ...  # This is a class that requires some cleanup on instance destruction\r\n    \r\n    # This method will be called on object before it is garbage collected OR at the end of the program\r\n    @reliable_finalizer\r\n    def destruct(self): \r\n        ...  # The cleanup code       \r\n```\r\n\r\n## Why use `reliable-finalizer`?\r\nThis library's purpose is to provide convenient syntax for reliable finalization in Python.\r\nThe built-in solution for finalization, [\\_\\_del\\_\\_()](https://docs.python.org/3/reference/datamodel.html#object.__del__), does not make guarantees strong enough to be adequately used\r\nwith an arbitrary interpreter (although it is somewhat consistent in [CPython](https://docs.python.org/3/glossary.html#term-CPython)).\r\nNamely, it can be called multiple times, and is not guaranteed to be called at all! - `__del__()` is not a great place for cleanup code.\r\n\r\nStandard library offers a more robust solution: [weakref.finalize()](https://docs.python.org/3/library/weakref.html#finalizer-objects). It does basically the same thing `__del__()` does, but gives stronger guarantees about its behavior: the callback is invoked once and only once.\r\n\r\n`reliable_finalizer` decorator is a utility for creating such finalizers. Any instance of a class with `reliable_finalizer`-decorated method will have a finalizer assigned to it.\r\nBecause of that, using `reliable_finalizer` is syntactically similar to using `__del__()` - all one needs is to create a method.\r\n\r\n## Additional details and limitations\r\n### Manual finalizer invocation \r\nCalling a method decorated with `reliable_finalizer` on an instance invokes the underlying finalizer, so calling it manually is completely fine - it will still only be called once. This can be useful, for example, if you want to additionally implement [context manager protocol](https://docs.python.org/3/reference/datamodel.html#context-managers) in your class:\r\n```python\r\nfrom reliable_finalizer import reliable_finalizer\r\n\r\nclass UsefulClass:\r\n    ...  # This is a class that requires some cleanup on instance destruction\r\n    \r\n    # This method will be called on object before it is garbage collected OR at the end of the program\r\n    @reliable_finalizer\r\n    def destruct(self): \r\n        ...  # The cleanup code \r\n    \r\n    def __enter__(self):\r\n        return self\r\n    \r\n    def __exit__(self, exc_type, exc_val, exc_tb):\r\n        self.destruct()\r\n```\r\n### Using finalizers with slots\r\nWhen using `reliable_finalizer`, the underlying weakref finalizer of an instance is saved to its `__finalizer__` attribute.\r\nIf your class does not have a `__dict__` slot, it must have `__finalizer__` slot in order to use `reliable_finalizer`:\r\n```python\r\nfrom reliable_finalizer import reliable_finalizer\r\n\r\nclass UsefulClass:\r\n    ...  # This is a class that requires some cleanup on instance destruction\r\n    \r\n    __slots__ = [\r\n        ...,  # Slots for the class\r\n        '__finalizer__'  # This slot is required for reliable_finalizer to work, if \"__dict__\" is not a slot \r\n    ]\r\n    \r\n    # This method will be called on object before it is garbage collected OR at the end of the program\r\n    @reliable_finalizer\r\n    def destruct(self): \r\n        ...  # The cleanup code       \r\n```\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Python utility for creation of reliable finalizer as an alternative to __del__ method",
    "version": "1.0.0",
    "project_urls": {
        "Homepage": "https://github.com/TimurTimergalin/reliable-finalizer"
    },
    "split_keywords": [
        "python",
        "finalize"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5a3bb97f775477f163f64fc47c07899e782d7bda847acf3398cd7477dcbf39ba",
                "md5": "48a0bc3f8d4f019054ee65deaa56b666",
                "sha256": "881c2f59ea531cece00d543da96baa6bf74f39c8b95307ccfd135261f52f851e"
            },
            "downloads": -1,
            "filename": "reliable_finalizer-1.0.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "48a0bc3f8d4f019054ee65deaa56b666",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.2",
            "size": 4102,
            "upload_time": "2024-08-19T18:28:44",
            "upload_time_iso_8601": "2024-08-19T18:28:44.392046Z",
            "url": "https://files.pythonhosted.org/packages/5a/3b/b97f775477f163f64fc47c07899e782d7bda847acf3398cd7477dcbf39ba/reliable_finalizer-1.0.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "a5fed6090a5192d99de95bedf80135c6d163238d1174e7f48bda08fa43597cc4",
                "md5": "8e62ac6ca33db77bad089d0b3c5648f0",
                "sha256": "df404c5165efda3adb379b51e00a38739cdfeb694e44679fc48afc892c81d684"
            },
            "downloads": -1,
            "filename": "reliable_finalizer-1.0.0.tar.gz",
            "has_sig": false,
            "md5_digest": "8e62ac6ca33db77bad089d0b3c5648f0",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.2",
            "size": 3725,
            "upload_time": "2024-08-19T18:28:45",
            "upload_time_iso_8601": "2024-08-19T18:28:45.921740Z",
            "url": "https://files.pythonhosted.org/packages/a5/fe/d6090a5192d99de95bedf80135c6d163238d1174e7f48bda08fa43597cc4/reliable_finalizer-1.0.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-08-19 18:28:45",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "TimurTimergalin",
    "github_project": "reliable-finalizer",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "lcname": "reliable-finalizer"
}
        
Elapsed time: 0.35382s