{ "info": { "author": "The xonsh developers", "author_email": "xonsh@googlegroups.com", "bugtrack_url": null, "classifiers": [ "Intended Audience :: Developers", "License :: OSI Approved", "Programming Language :: Python", "Topic :: Utilities" ], "description": "=======\nlazyasd\n=======\nA package that provides lazy and self-destructive tools for speeding up module\nimports. This is useful whenever startup times are critical, such as for\ncommand line interfaces or other user-facing applications.\n\nThe tools in this module implement two distinct strategies for speeding up\nmodule import. The first is delayed construction of global state and the\nsecond is to import expensive modules in a background thread.\n\nFeel free to use lazyasd as a dependency or, because it is implemented as a\nsingle module, copy the ``lazyasd.py`` file into your project.\n\nLazy Construction\n*****************\nMany operations related to data construction or inspection setup can take\na long time to complete. If only a single copy of the data or a cached\nrepresentation is needed, in Python it is common to move the data to the\nglobal or module level scope.\n\nBy moving to module level, we help ensure that only a single copy of the data\nis ever built. However, by moving to module scope, the single perfomance hit\nnow comes at import time. This is itself wasteful if the data is never used.\nFurthermore, the more data that is built globally, the longer importing the\nmodule takes.\n\nFor example, consider a function that reports if a string contains the word\n``\"foo\"`` using regular expressions. The naive version is relatively slow, per\nfunction call, because it has to construct the regex each time:\n\n.. code-block:: python\n\n import re\n\n def has_foo_simple(s):\n return re.search('foo', s) is not None\n\nThe standard way of improving performance is to compile the regex at global\nscope. Rewriting, we would see:\n\n.. code-block:: python\n\n import re\n\n FOO_RE = re.compile('foo')\n\n def has_foo_compiled(s):\n return FOO_RE.search(s) is not None\n\nNow, each call of ``has_foo_compiled()`` is much faster than a call of\n``has_foo_simple()`` because we have shifted the compiliation to import\ntime. But what if we never actually call ``has_foo()``? In this case,\nthe original version was better because the imports are fast.\n\nHaving the best of both compile-once and don't-compile-on-import is where\nthe lazy and self-destructive tools come in. A ``LazyObject`` instance\nhas a loader function, a context to place the result of the into, and the\nname of the loaded value in the context. The ``LazyObject`` does no\nwork when it is first created. However, whenever an attribute is accessed\n(or a variety of other operations) the loader will be called, the true\nvalue will be constructed, and the ``LazyObject`` will act as a proxy to\nloaded object.\n\nUsing the above regex example, we have minimal import-time and run-time\nperfomance hits with the following lazy implementation:\n\n.. code-block:: python\n\n import re\n from lazyasd import LazyObject\n\n FOO_RE = LazyObject(lambda: re.compile('foo'), globals(), 'FOO_RE')\n\n def has_foo_lazy(s):\n return FOO_RE.search(s) is not None\n\nTo walk through the above, at import time ``FOO_RE`` is a LazyObject, that has a\nlambda loader which returns the regex we care about. If ``FOO_RE`` is never\naccessed this is how it will remain. However, the first time ``has_foo_lazy()``\nis called, accessing the ``search`` method will cause the ``LazyObject`` to:\n\n1. Call the loader (getting ``re.compile('foo')`` as the result)\n2. Place the result in the context, eg ``globals()['FOO_RE'] = re.compile('foo')``\n3. Look up attributes and methods (such as ``search``) on the result.\n\nNow because of the context replacement, ``FOO_RE`` now is a regular expression\nobject. Further calls to ``has_foo_lazy()`` will see ``FOO_RE`` as a regular\nexpression object directly, and not as a ``LazyObject``. In fact, if no lingering\nrefences remain, the original ``LazyObject`` instance can be totally cleaned up\nby the garbage collector!\n\nFor the truly lazy, there is also a ``lazyobject`` decorator:\n\n.. code-block:: python\n\n import re\n from lazyasd import lazyobject\n\n @lazyobject\n def foo_re():\n return re.compile('foo')\n\n def has_foo_lazy(s):\n return foo_re.search(s) is not None\n\nAnother useful pattern is to implement lazy module imports, where the\nmodule is only imported if a member of it used:\n\n.. code-block:: python\n\n import importlib\n from lazyasd import lazyobject\n\n @lazyobject\n def os():\n return importlib.import_module('os')\n\nThe world is beautifully yours, but feel free to take a nap first.\n\nSpecific Laziness\n-----------------\nThe ``LazyBool`` class and ``lazybool`` decorator have the same interface as\nlazy objects. These are provided for objects that are intended to be resolved\nas booleans.\n\nThe ``LazyDict`` class and ``lazydict`` decorator are similar. Here however,\nthe first value is a dictionary of key-loaders. Rather than having a single\nloader, each value is loaded individually when its key is first accessed.\n\n\nBackground Imports\n******************\nEven with all of the above laziness, sometimes it isn't enough. Sometimes a\nmodule is so painful to import and so unavoidable that you need to import\nit on background thread so that the rest of the application can boot up\nin the meantime. This is the purpose of ``load_module_in_background()``.\n\nFor example, if you are using pygments and you want the import to safely\nbe 100x faster, simply drop in the following lines:\n\n.. code-block:: python\n\n # must come before pygments imports\n from lazyasd import load_module_in_background\n load_module_in_background('pkg_resources',\n replacements={'pygments.plugin': 'pkg_resources'})\n\n # now pygments is fast to import\n from pygments.style import Style\n\nThis prevents ``pkg_resources``, which comes from setuptools, from searching your\nentire filesystem for plugins at import time. Like above, this import acts as\nproxy and will block until it is needed. It is also robust if the module has\nalready been imported. In some cases, this background importing is the best a\nthird party application can do.\n\n", "description_content_type": "", "docs_url": null, "download_url": "https://github.com/xonsh/lazyasd/zipball/0.1.4", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/xonsh/lazyasd", "keywords": "", "license": "BSD 3-clause", "maintainer": "", "maintainer_email": "", "name": "lazyasd", "package_url": "https://pypi.org/project/lazyasd/", "platform": "", "project_url": "https://pypi.org/project/lazyasd/", "project_urls": { "Download": "https://github.com/xonsh/lazyasd/zipball/0.1.4", "Homepage": "https://github.com/xonsh/lazyasd" }, "release_url": "https://pypi.org/project/lazyasd/0.1.4/", "requires_dist": null, "requires_python": "", "summary": "Lazy & self-destructive tools for speeding up module imports", "version": "0.1.4" }, "last_serial": 3692909, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "d9ff39917a69ff0288c289afde9e943c", "sha256": "d7b4faf1398bc37158b36f0306361f349a2e6f42dea1bb5e149c104b7ded4f8a" }, "downloads": -1, "filename": "lazyasd-0.1.0.tar.gz", "has_sig": false, "md5_digest": "d9ff39917a69ff0288c289afde9e943c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 6621, "upload_time": "2016-07-21T23:46:21", "url": "https://files.pythonhosted.org/packages/b9/8b/0259248d0e0e2439e19ffe44b015d79850de9a1a26fc94cb21b265135f14/lazyasd-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "61fc0d0f23ec1dc9da8aeb76e2c5b4e0", "sha256": "16af56737a1cf896d2c966f2aecf18f58458a2cead3baccbf271b4f20dafdbad" }, "downloads": -1, "filename": "lazyasd-0.1.1.tar.gz", "has_sig": false, "md5_digest": "61fc0d0f23ec1dc9da8aeb76e2c5b4e0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8136, "upload_time": "2016-07-22T18:08:13", "url": "https://files.pythonhosted.org/packages/b2/d2/8272db94cd3725dad6af0ca9c5a5dab97a698cc5bafb5fee60480f969c0c/lazyasd-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "90c5b11e8e6f395ff9baf0e2cf15f197", "sha256": "c36182c54d10a58a93724e1f998818365d64a34e92368fa667d88a93cf71fe88" }, "downloads": -1, "filename": "lazyasd-0.1.2.tar.gz", "has_sig": false, "md5_digest": "90c5b11e8e6f395ff9baf0e2cf15f197", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8243, "upload_time": "2016-08-17T16:07:00", "url": "https://files.pythonhosted.org/packages/0e/3f/c347860ea234016413ce979b044b4373e0af66c68a56253b73dd34cea992/lazyasd-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "0c9e690612c1efe05fabafff35ffff46", "sha256": "e7c88e26fd74c39a6ff4ea5b518676ec555fcddae1b16e096c82a8e215e6defe" }, "downloads": -1, "filename": "lazyasd-0.1.3.tar.gz", "has_sig": false, "md5_digest": "0c9e690612c1efe05fabafff35ffff46", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8308, "upload_time": "2016-09-05T17:43:19", "url": "https://files.pythonhosted.org/packages/a7/c2/e32ac63f76031bccfbae08e2f20a1c7ad5f04431392ad1f53c43922c421f/lazyasd-0.1.3.tar.gz" } ], "0.1.4": [ { "comment_text": "", "digests": { "md5": "c510082473c81fa9e1eafddf02eec41a", "sha256": "a3196f05cff27f952ad05767e5735fd564b4ea4e89b23f5ea1887229c3db145b" }, "downloads": -1, "filename": "lazyasd-0.1.4.tar.gz", "has_sig": false, "md5_digest": "c510082473c81fa9e1eafddf02eec41a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8380, "upload_time": "2018-03-21T19:06:33", "url": "https://files.pythonhosted.org/packages/b3/15/c9f68c4f477fbaa9fc5ea5e271547956da321787cf7aef79d6971dcb4c84/lazyasd-0.1.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "c510082473c81fa9e1eafddf02eec41a", "sha256": "a3196f05cff27f952ad05767e5735fd564b4ea4e89b23f5ea1887229c3db145b" }, "downloads": -1, "filename": "lazyasd-0.1.4.tar.gz", "has_sig": false, "md5_digest": "c510082473c81fa9e1eafddf02eec41a", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8380, "upload_time": "2018-03-21T19:06:33", "url": "https://files.pythonhosted.org/packages/b3/15/c9f68c4f477fbaa9fc5ea5e271547956da321787cf7aef79d6971dcb4c84/lazyasd-0.1.4.tar.gz" } ] }