{ "info": { "author": "Security Compass", "author_email": "jed@securitycompass.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "Scoped Objects\n==============\n\n``Scoped`` is a mixin class that creates a thread-local stack for each of its\nsubclasses. Instances of the subclass can be pushed and popped on this stack,\nand the instance at the top of the stack is always available as a property of\nthe class. ``Scoped`` classes are typically used to make parameters implicitly\navailable within a (dynamic) scope, without having to pass them around as\nfunction arguments. ``Scoped`` helps you do this in a safe and convenient way,\nand provides very informative error messages when you do something wrong.\n\n\nExamples\n--------\n\nA ``Scoped`` class can be used to pass around contextual data:\n\n.. code-block:: python\n\n class Session(Scoped):\n def __init__(self, user):\n self.user = user\n\n def print_current_user():\n print(Session.current.user)\n\n with Session(some_guy):\n print_current_user()\n\n\nIt can also be used to provide dependencies:\n\n.. code-block:: python\n\n class Clock(Scoped):\n def __init__(self, now=None):\n self._now = now\n\n def now(self):\n return self._now or datetime.now()\n\n Clock.default = Clock()\n\n def print_time()\n print(Clock.current.now())\n\n print_time() # Prints the real time\n\n def test_print_fake_time(self):\n with Clock(datetime(2000, 1, 1)):\n print_time() # Prints a fake time\n\n\nOpening and Closing\n-------------------\n\n``Scoped`` objects are best used as context managers (i.e. using the ``with``\nstatement), but for situations where this isn't possible, you can also open\nand close them \"manually\":\n\n.. code-block:: python\n\n class Transaction(Scoped):\n ...\n\n transaction = Transaction().open()\n try:\n ...\n finally:\n transaction.close()\n\nObviously, you will need to do whatever is necessary to ensure that every\ncall to ``open`` is matched by a call to ``close``.\n\n\nOptions\n-------\n\nThe behavior of ``Scoped`` subclasses can be customized by declaring\noptions in a nested class named ``ScopedOptions``. Except where noted,\noptions are automatically inherited by subclasses that do not override\nthem:\n\n.. code-block:: python\n\n class Thingy(Scoped):\n class ScopedOptions:\n\n # If True, instances will share the stack of their parent class.\n # If False, this class will have its own stack independent of any\n # ancestors. The default is to inherit the stack, unless subclassing\n # Scoped directly. This option is NOT inherited by subclasses.\n inherit_stack = False\n\n # Maximum number of scopes that can be nested on this stack.\n # This cannot be overridden if inheriting the parent stack.\n max_nesting = 16\n\n # If True, instances can be re-opened after being closed.\n # If False, instances can only be opened and closed once, and will\n # raise a LifecycleError on any attempt to reopen them.\n allow_reuse = False\n\n\nDefault Instance\n----------------\n\nAn instance of a Scoped subclass can be assigned to the ``default`` property\nof the class. This instance will be the value of the ``current`` property\nwhen the stack is empty i.e. when no other instances are open. The default\ninstance itself is not opened by virtue of being the default. Opening it\nwill push it onto the stack like any other instance.\n\n\nErrors\n------\n\n``Scoped`` has three inner exception classes that it will raise for various\nerror conditions: ``Scoped.Error`` is the base class for the other two, which\nare ``Scoped.Missing`` and ``Scoped.Lifecycle``.\n\n``Scoped.Missing`` is raised when an attempt is made to access a scoped object\nthat is not available, i.e. when accessing ``Scoped.current`` with an empty\nstack and no default instance.\n\n``Scoped.Lifecycle`` is raised on any attempt to open or close a scoped object\nat the wrong time e.g. opening an object that is already open, closing an object\nthat is not at the top of the stack, and various other cases.\n\nBoth of these exceptions are automatically subclassed along with their containing\nclass. Each subclass of ``Scoped`` gets its own exception classes that inherit\nfrom the base exceptions. This allows you to easily handle errors from particular\nscoped classes without worrying about catching unrelated errors from other scoped\nclasses.\n\nDocs\n----\n\n`The complete documentation for depocs can be found on readthedocs.org `_\n\nFAQ\n---\n\nQ: What does the name \"depocs\" mean?\n\nA: It's \"scoped\" spelled backwards. :smile:\n\n\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/sdelements/depocs", "keywords": "development thread-local", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "depocs", "package_url": "https://pypi.org/project/depocs/", "platform": "", "project_url": "https://pypi.org/project/depocs/", "project_urls": { "Homepage": "https://github.com/sdelements/depocs" }, "release_url": "https://pypi.org/project/depocs/1.0.1/", "requires_dist": [ "six (==1.12.0)" ], "requires_python": "", "summary": "Scoped thread-local mixin class", "version": "1.0.1" }, "last_serial": 4765577, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "7815d2819243319ceefa77922fc49ef8", "sha256": "3d6ac60053500d4e6c2748a65fe2827fe64b24caf0010d095d69a2236d8c180e" }, "downloads": -1, "filename": "depocs-1.0.0.tar.gz", "has_sig": false, "md5_digest": "7815d2819243319ceefa77922fc49ef8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5991, "upload_time": "2015-01-13T21:49:31", "url": "https://files.pythonhosted.org/packages/25/96/e6081bc62c974c3bc08d32092eaa0556613d5fcf779c96a25eceec448ae7/depocs-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "67297e1aa85e5f4ee214dc108206fd5a", "sha256": "1a10b3f7f827db0154b4d41a3710e1996c7f0b21a48a05ea4e2aa53e68c32db2" }, "downloads": -1, "filename": "depocs-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "67297e1aa85e5f4ee214dc108206fd5a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6120, "upload_time": "2019-01-31T21:29:28", "url": "https://files.pythonhosted.org/packages/dc/f8/45596297a7538ed3d75ea0e2273007d0cad5d99d649afdbc629f8f755675/depocs-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "856df55256454c7b56d3ed10aa451dd7", "sha256": "4ca4bd3ce41d4a583ebf032ae1d63e66b8a4194cbd107b9acbcf5f12bf14abba" }, "downloads": -1, "filename": "depocs-1.0.1.tar.gz", "has_sig": false, "md5_digest": "856df55256454c7b56d3ed10aa451dd7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6460, "upload_time": "2019-01-31T21:29:30", "url": "https://files.pythonhosted.org/packages/f5/ef/5e492c1d76f151eb9d75b18202bd89a3612769d6133b0b010a364483e295/depocs-1.0.1.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "67297e1aa85e5f4ee214dc108206fd5a", "sha256": "1a10b3f7f827db0154b4d41a3710e1996c7f0b21a48a05ea4e2aa53e68c32db2" }, "downloads": -1, "filename": "depocs-1.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "67297e1aa85e5f4ee214dc108206fd5a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 6120, "upload_time": "2019-01-31T21:29:28", "url": "https://files.pythonhosted.org/packages/dc/f8/45596297a7538ed3d75ea0e2273007d0cad5d99d649afdbc629f8f755675/depocs-1.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "856df55256454c7b56d3ed10aa451dd7", "sha256": "4ca4bd3ce41d4a583ebf032ae1d63e66b8a4194cbd107b9acbcf5f12bf14abba" }, "downloads": -1, "filename": "depocs-1.0.1.tar.gz", "has_sig": false, "md5_digest": "856df55256454c7b56d3ed10aa451dd7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6460, "upload_time": "2019-01-31T21:29:30", "url": "https://files.pythonhosted.org/packages/f5/ef/5e492c1d76f151eb9d75b18202bd89a3612769d6133b0b010a364483e295/depocs-1.0.1.tar.gz" } ] }