Metadata-Version: 2.1
Name: preoccupied.proxytype
Version: 0.3.0
Summary: static typing support for dynamic proxy classes
Home-page: https://github.com/obriencj/python-proxytype
Author: Christopher O'Brien
Author-email: obriencj@preoccupied.net
License: GNU General Public License v3 (GPLv3)
Project-URL: Source, https://github.com/obriencj/python-proxytype
Project-URL: Issues, https://github.com/obriencj/python-proxytype/issues
Platform: any
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Natural Language :: English
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: Utilities
Description-Content-Type: text/markdown
License-File: LICENSE

# Overview

`preoccupied.proxytype` is a [Python] package providing a [MyPy]
plugin and a class decorator for triggering that plugin. The decorator
can be used to indicate that a decorated class should be considered
during static analysis to posess all of the methods from another
class.

[python]: https://python.org

[MyPy]: https://mypy-lang.org

This pattern is distinct from inheritance, in that it will also apply
a transformation to the return type of the copied methods. It is valid
for this transformed return type to be incompatible with the original
template class's method signature.

This is useful in situations where a dynamic class wraps or proxies
its calls to another instance, optionally decorating them in the
process.

The class decorator has no behavior at runtime -- it does not
implement the proxying. It is only there to provide a way to declare
such behavior during static analysis.


## Installation

Install from the latest PyPI release

```bash
pip install --user preoccupied.proxytype
```

Install from a git checkout

```bash
make install
```


## Enable plugin

At runtime the proxytype class decorator does not introduce a MyPy
dependency. However in order for it to operate during MyPy's static
analysis checks the plugin must be enabled. For example in `setup.cfg`

```ini filename=setup.cfg
[mypy]
plugins =
  preoccupied.proxytype
```


## Usage of proxytype

At runtime the proxytype class decorator has no impact. During static
analysis via MyPy the proxytype class decorator can be used to
virtually annotate that class with the methods from the originating
type. Methods brought across to the decorated type will have their
self argument type updated, and can optionally have their return type
modified to be a wrapped generic around the original return type.

For example:

```python
from preoccupied.proxytype import proxytype


class ClientSession:
    def doSomething(self, how_many: int, etc: Any) -> List[int]:
        ...

    def doAnother(self, wut: Any, **kwds: Any) -> bool:
        ...

    def getName(self) -> str:
        ...


RT = TypeVar("RT")

class DelayResult(Generic[RT]):
    resultValue: RT


@proxytype(ClientSession, DelayResult)
class DelayClientSession:
    def getName(self) -> str:
        ...
```

This will cause static analysys via MyPy of the `DelayClientSession`
to appear as if it had been declared as:

```python
class DelayClientSession:
    def doSomething(self, how_many: int, etc: Any) -> DelayResult[List[int]]:
        ...

    def doAnother(self, wut: Any, **kwds: Any) -> DelayResult[bool]:
        ...

    def getName(self) -> str:
        ...
```


## Contact

author: Christopher O'Brien  <obriencj@preoccupied.net>

original git repository: <https://github.com/obriencj/python-proxytype>

pypi project: <https://pypi.org/project/preoccupied.proxytype>


## License

This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 3 of the
License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, see
<http://www.gnu.org/licenses/>.
