{ "info": { "author": "Viktor Hercinger", "author_email": "hercinger.viktor@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Natural Language :: English", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: Implementation :: CPython", "Programming Language :: Python :: Implementation :: PyPy" ], "description": "==================================================\nclass_proxy - a transparent proxy class for Python\n==================================================\n\n.. image:: https://badge.fury.io/gh/herczy%2Fclass_proxy.svg\n :target: https://badge.fury.io/gh/herczy%2Fclass_proxy\n\n.. image:: https://badge.fury.io/py/class_proxy.svg\n :target: https://badge.fury.io/py/class_proxy\n\n.. image:: https://travis-ci.org/herczy/class_proxy.svg?branch=master\n :target: https://travis-ci.org/herczy/class_proxy\n\nIntroduction\n============\n\n`class_proxy` can be used to create simple proxy objects for any value. The\nproxy can be any class.\n\nFor example, lets say that we have a parser and need to be able to tell where\na value came from (source file name, line number and column). We might have a\n`Source` class handling this information:\n\n.. code-block:: python\n\n class Source(object):\n def __init__(self, filename, line, column):\n self.filename = filename\n self.line = line\n self.column = column\n\n def __str__(self):\n return \"file {}, line {}, column {}\".format(\n self.filename, self.line, self.column\n )\n\n def __repr__(self):\n return \"Source({!r}, {!r}, {!r})\".format(\n self.filename, self.line, self.column\n )\n\nIf we attach this source to some class we control, there is no problem. But\nwhat if we want to tell where an integer, string or any scalar, builtin came\nfrom?\n\nThe solution is to make a wrapper for the scalar classes:\n\n.. code-block:: python\n\n import class_proxy\n\n class SourceValue(object):\n def __init__(self, source):\n self.source = source\n\n def __str__(self):\n return \"{} (from {})\".format(\n class_proxy.instance(self), self.source\n )\n\n def __repr__(self):\n return \"SourceValue({!r}, {!r})\".format(\n class_proxy.instance(self), self.source\n )\n\n IntProxy = class_proxy.wrap_with(int, SourceValue)\n StrProxy = class_proxy.wrap_with(str, SourceValue)\n\n number = IntProxy(123, Source('example', 1, 2))\n print(number) # will print: 1 (from file example, line 1, column 2)\n\n string = StrProxy('hello', Source('example', 5, 7))\n print(repr(number)) # will print: hello (from file example, line 5, column 7)\n\n other_number = IntProxy(456, Source('example', 7, 8))\n print(number < other_number) # will print: True\n\nThe `class_proxy.instance` call will return the original, wrapped\ninstance for the proxy.\n\nThe `class_proxy.wrap_with` call will create a proxy class expecting the\nwrapped value as the first parameter, while the remaining parameters are passed\nto the `SourceValue` constructor.\n\nWhen retrieving attributes from the proxy class (e.g. `IntProxy`), it\nwill look up the proxy base class first (e.g. `SourceValue`) and later\nthe wrapped class (e.g. `int`). This is the reason we care about what\nclass we're wrapping: we want to be able to wrap the class too, not just\nthe instance.\n\nIn case we're looking up members from the instance, at first we will look it up\nfrom the instance of the proxy class, and then from the wrapped class.\n\nIf you don't care about class values, you can also omit the wrapped class:\n\n.. code-block:: python\n\n GenericProxy = class_proxy.wrap_with(SourceValue)\n\n generic = GenericProxy(SomeGenericClass(1, 2), Source('example', 10, 0))\n\nIn this case, we wrap the `object`.\n\nThere is also a convenience wrapper for the `wrap_with` function, in case\nyou don't need to define it for multiple wrapped classes:\n\n.. code-block:: python\n\n import class_proxy\n\n @class_proxy.proxy_of(int)\n class IntProxy(object):\n def clamp(self, minval, maxval):\n if self < minval:\n result = minval\n\n elif self > maxval:\n result = maxval\n\n else:\n result = class_proxy.instance(self)\n\n return IntProxy(result)\n\n value = IntProxy(50).clamp(-10, 10)\n print(value) # will print: 10\n\nThis also has a generic variant:\n\n.. code-block:: python\n\n import class_proxy\n\n @class_proxy.proxy\n class Proxy(object):\n def map(self, func):\n return func(class_proxy.instance(self))\n\n value = Proxy(100)\n print(value.map(lambda val: -val)) # will print: -100\n\nInspiration\n===========\n\n`class_proxy` was heavily inspired by `zyga/padme`, an excellent tool for\ncreating proxy classes. However, `padme` has a few problems:\n\n* It generates a lot of logs, which can not only be annoying, but create odd\n infinite recursions when trying to format the wrapped value for a log string.\n* The proxied special methods are written out manually, which seems like an\n unneccessary thing.\n\nSo with these limitations I felt the need to write a similar tool that\naddresses the issues above.\n\n\n\n\nHistory\n=======\n\n1.1.0 (2019-03-18)\n------------------\n\n* Custom names can be specified for bound class proxies (by default,\n it is in the format of []).\n\n1.0.1 (2019-03-10)\n------------------\n\n* Added caching for created proxies.\n\n1.0.0 (2019-03-09)\n------------------\n\n* Inspired by `zyga/padme`.\n* Written the basic code.\n* Added files to make it more 'project-y'.\n* Committed to `github.com`.\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/herczy/class_proxy", "keywords": "class_proxy proxy transparent", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "class_proxy", "package_url": "https://pypi.org/project/class_proxy/", "platform": "", "project_url": "https://pypi.org/project/class_proxy/", "project_urls": { "Homepage": "https://github.com/herczy/class_proxy" }, "release_url": "https://pypi.org/project/class_proxy/1.1.0/", "requires_dist": null, "requires_python": "", "summary": "class_proxy is a transparent proxy for Python", "version": "1.1.0" }, "last_serial": 4955173, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "28beae0c5d308391efca23e36e19d430", "sha256": "7f39ec79611dcb2e701bdc68b8cc28f01c201e155260069f3ed2ac007aff531b" }, "downloads": -1, "filename": "class_proxy-1.0.0.tar.gz", "has_sig": false, "md5_digest": "28beae0c5d308391efca23e36e19d430", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6260, "upload_time": "2019-03-09T13:08:25", "url": "https://files.pythonhosted.org/packages/3d/1e/3fc4441045b75a3bbc5330c7b0e130aa184d59f7cc8dbf6b4ccaa8d0d919/class_proxy-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "2a367efbb475358ed723fb05dd6a3d6d", "sha256": "6a9d575f4c8be4757e860f20337fce575acae887638ea00061099ad0f39ae572" }, "downloads": -1, "filename": "class_proxy-1.0.1.tar.gz", "has_sig": false, "md5_digest": "2a367efbb475358ed723fb05dd6a3d6d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6442, "upload_time": "2019-03-10T10:53:53", "url": "https://files.pythonhosted.org/packages/a2/24/e819c8b982cb35ab7fcaca8ce24e67d1e819cf1a31e505cc44e45b0efe6a/class_proxy-1.0.1.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "04e6eb0182206592ea3ee4505edd7ec6", "sha256": "fbd3e5be28f8411d8148cbaf8961c7a296043dab9498ab89a83dcbb3940e6f6e" }, "downloads": -1, "filename": "class_proxy-1.1.0.tar.gz", "has_sig": false, "md5_digest": "04e6eb0182206592ea3ee4505edd7ec6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6593, "upload_time": "2019-03-18T17:39:32", "url": "https://files.pythonhosted.org/packages/1a/fc/0cb8eddc0e7c9e076a91a8ffb2a0d68a11ea2b3a12cb7d004ac9e7f65ecc/class_proxy-1.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "04e6eb0182206592ea3ee4505edd7ec6", "sha256": "fbd3e5be28f8411d8148cbaf8961c7a296043dab9498ab89a83dcbb3940e6f6e" }, "downloads": -1, "filename": "class_proxy-1.1.0.tar.gz", "has_sig": false, "md5_digest": "04e6eb0182206592ea3ee4505edd7ec6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6593, "upload_time": "2019-03-18T17:39:32", "url": "https://files.pythonhosted.org/packages/1a/fc/0cb8eddc0e7c9e076a91a8ffb2a0d68a11ea2b3a12cb7d004ac9e7f65ecc/class_proxy-1.1.0.tar.gz" } ] }