{ "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": "==========\namalgamate\n==========\nA package-based, source code amalgamater for collapsing Python packages into\na single module.\n\nThe amalgamate utility enables the possibility of speeding up startup time for\nPython packages at low-to-no run time cost. If this sounds too good to be true,\nread on for the details!\n\nThe big idea here is to glue most of the source files in a package or subpackage\ntogether into a single module, called ``__amalgam__.py``. Combined with some hooks\nin the ``__init__.py``, this should dramatically reduce the number of files that\nare being searched for inside of the package. This is critical in larger\nprojects where import times are the major startup time cost.\n\nThe ``amalgamate.py`` script automatically creates the ``__amalgamate__.py`` file\nfor a package. This will create and solve a dependency graph of all modules in\nthe package. It then will go through each module and glue it into the\n``__amalgamate__.py``, removing duplicate imports as it goes.\n\nAdditionally, the ``amalgamate.py`` script will automatically make most\nnon-package imports lazy. This lets developers write as many imports as they\nwant, without having to worry about startup times. Non-package modules\naren't actually imported in ``__amalgam__.py`` until they are used (ie an\nattribute is accessed).\n\nThis has some funny side effects such as,\n\n1. All of the modules that are amalgamated share the same globals (so be\n careful about naming things),\n2. Debugging makes most things looks like code comes from ``__amalgam__``,\n unless an environment variable is set prior to import.\n3. Not all imports are able to be lazy.\n\n**********\nImports\n**********\nThe way the code amalgamater works is that other modules\nthat are in the same package (and amalgamated) should be imported from-imports,\nwithout an ``as``-clause. For example, suppose that ``z`` is a module in the\npackage ``pkg``, that depends on ``x`` and ``y`` in the same package. ``z``\nshould exclusively use imports like the following::\n\n from pkg.x import a, c, d\n from pkg.y import e, f, g\n\nThese from-imports simulate all of the ``x``, ``y``, and ``z`` modules having\nthe same ``globals()``.\nThis is because the amalgamater puts all such modules in the same globals(),\nwhich is effectively what the from-imports do. For example, ``xonsh.ast`` and\n``xonsh.execer`` are both in the same package (``xonsh``). Thus they should use\nthe above from from-import syntax.\n\nAlternatively, for modules outside of the current package (or modules that are\nnot amalgamated) the import statement should be either ``import pkg.x`` or\n``import pkg.x as name``. This is because these are the only cases where the\namalgamater is able to automatically insert lazy imports in way that is guaranteed\nto be safe. Say we are back in ``z`` and depend on ``dep``, ``collections.abc``,\nand modules in a subpackage, ``pkg.sub``. The following are all acceptable::\n\n import dep\n import collections.abc as abc\n import pkg.dep.mod0\n import pkg.dep.mod1 as mod1\n\nThe important thing here is to simply be consistent for such imports across all\nmodules in the package ``pkg``.\n\n**WARNING:** You should not use the form ``from pkg.i import j`` for modules\noutside of the amalgamated package. This is due to the ambiguity that\n``from pkg.x import name`` may import a variable that cannot be lazily constructed\nOR may import a module. The amalgamater is forced to leave such import statements\nas they were written, which means that they cannot be automatically lazy or\neliminated. They are thus forced to be imported at when ``__amalgam__.py`` is\nimported/\n\nSo the simple rules to follow are that:\n\n1. Import objects from modules in the same package directly in using from-import,\n2. Import objects from modules outside of the package via a direct import\n or import-as statement.\n\n\n*********************\n``__init__.py`` Hooks\n*********************\nTo make this all work, the ``__init__.py`` for the package needs a predefined\nspace for ``amalgamate.py`` to write hooks into. In its simplest form, this\nis defined by the lines::\n\n # amalgamate exclude\n # amalgamate end\n\nThe ``amalgamate.py`` script will fill in between these two line and will over\nwrite them as needed. The initial exclude line accepts a space-separated list\nof module names in the package to exclude from amalgamation::\n\n # amalgamate exclude foo bar baz\n # amalgamate end\n\nYou may also provide as many exclude lines as you want, though there should\nonly be one end line::\n\n # amalgamate exclude foo\n # amalgamate exclude bar\n # amalgamate exclude baz\n # amalgamate end\n\nAlso note that all modules whose names start with a double underscore, like\n``__init__.py`` and ``__main__.py`` are automatically excluded.\n\n\n**********************\nCommand Line Interface\n**********************\nThe command line interface is a list of package names to amalgamate::\n\n $ amalgamate.py pkg pkg.sub0 pkg.sub1\n\nYou may also provide the ``--debug=NAME`` name to declare the environment\nvariable name for import debugging::\n\n $ amalgamate.py --debug=PKG_DEBUG pkg pkg.sub0 pkg.sub1\n\nBy default, this environment variable is simply called ``DEBUG``. If this\nenvironment variable exists and is set to a non-empty string, then all\namalgamated imports are skipped and the modules in the package are imported\nnormally. For example, suppose you have a script that imports your package\nand you would like to see the module names, you could run the script with::\n\n $ env PKG_DEBUG=1 python script.py\n\nto suppress the amalgamated imports.\n\n**************\nSetup Hooks\n**************\nWe recommend running ``amalgamate.py`` every time that setup.py is executed.\nThis keeps ``__amalgam__.py`` and ``__init__.py`` in sync with the rest of\nthe package. Feel free to use the following hook function in your project::\n\n def amalgamate_source():\n \"\"\"Amalgamates source files.\"\"\"\n try:\n import amalgamate\n except ImportError:\n print('Could not import amalgamate, skipping.', file=sys.stderr)\n return\n amalgamate.main(['amalgamate', '--debug=PKG_DEBUG', 'pkg'])\n\nAdditionally, feel free to copy the ``amalgamate.py`` script to your project.\nIt is only a single file!\n\n**************\nDark Wizardry\n**************\nThis is implemented via a syntax tree transformation so developers could write\nmostly normal Python without having to worry about import speed. That accounts for\nthe wizardry.\n\nThe darkness comes from a project called\n`JsonCpp `_. JsonCpp has an\n`amalgamate script `_,\nthat glues the whole project into a single header and single source file.\nThis is an amazing idea. The kicker is that JsonCpp's amalgamate is written in\nPython :)", "description_content_type": null, "docs_url": null, "download_url": "https://github.com/xonsh/amalgamate/zipball/0.1.3", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/xonsh/amalgamate", "keywords": null, "license": "BSD 3-clause", "maintainer": null, "maintainer_email": null, "name": "amalgamate", "package_url": "https://pypi.org/project/amalgamate/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/amalgamate/", "project_urls": { "Download": "https://github.com/xonsh/amalgamate/zipball/0.1.3", "Homepage": "https://github.com/xonsh/amalgamate" }, "release_url": "https://pypi.org/project/amalgamate/0.1.3/", "requires_dist": null, "requires_python": null, "summary": "Collapses Python packages into a single module.", "version": "0.1.3" }, "last_serial": 2261161, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "1d32320ff50ef10fb722fc2d81606a2b", "sha256": "ca0f9b92ce6e0d7000080cece65bd9cc7d401edc0714adfa87da3a88aa299b44" }, "downloads": -1, "filename": "amalgamate-0.1.0.tar.gz", "has_sig": false, "md5_digest": "1d32320ff50ef10fb722fc2d81606a2b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7801, "upload_time": "2016-06-26T06:27:02", "url": "https://files.pythonhosted.org/packages/7f/43/494467bf1f8f61d009ea737c5a977950278d1197f7696ca245227d3bd30c/amalgamate-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "b9d3c9dcb7f108b4e524b683fea8dcf0", "sha256": "18f69e668bc2a9fc46a5ed699da7e5c7dfa849d935ab509594df66d09b6dd262" }, "downloads": -1, "filename": "amalgamate-0.1.1.tar.gz", "has_sig": false, "md5_digest": "b9d3c9dcb7f108b4e524b683fea8dcf0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8322, "upload_time": "2016-06-27T15:50:29", "url": "https://files.pythonhosted.org/packages/f7/03/3dfb053edb705636472220a43155f21b988f8af2381ac949bdac6173e3ca/amalgamate-0.1.1.tar.gz" } ], "0.1.2": [ { "comment_text": "", "digests": { "md5": "e1f67372392322d2d7514efed466d263", "sha256": "e25f5b8266af73991bbf2ca30a8d3f94dfcc82acc1e4d3a802d5a49ef03bd542" }, "downloads": -1, "filename": "amalgamate-0.1.2.tar.gz", "has_sig": false, "md5_digest": "e1f67372392322d2d7514efed466d263", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9610, "upload_time": "2016-07-21T03:13:48", "url": "https://files.pythonhosted.org/packages/7d/06/a3be80b77de065d8205651c0067e5b54b2619400dcf318202b3eb6fc0cc7/amalgamate-0.1.2.tar.gz" } ], "0.1.3": [ { "comment_text": "", "digests": { "md5": "3e5fa4216bf593224baf08ef4ecbfadd", "sha256": "e38696998145ee7b5eaabe7ab60e60108e64448eefcb73eb7f917fe24e6ff761" }, "downloads": -1, "filename": "amalgamate-0.1.3.tar.gz", "has_sig": false, "md5_digest": "3e5fa4216bf593224baf08ef4ecbfadd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10766, "upload_time": "2016-08-04T03:57:25", "url": "https://files.pythonhosted.org/packages/61/25/70108f11c9782da4e258cc3dd75f9b3fa6f645b202536bc73e90d33b8de1/amalgamate-0.1.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3e5fa4216bf593224baf08ef4ecbfadd", "sha256": "e38696998145ee7b5eaabe7ab60e60108e64448eefcb73eb7f917fe24e6ff761" }, "downloads": -1, "filename": "amalgamate-0.1.3.tar.gz", "has_sig": false, "md5_digest": "3e5fa4216bf593224baf08ef4ecbfadd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10766, "upload_time": "2016-08-04T03:57:25", "url": "https://files.pythonhosted.org/packages/61/25/70108f11c9782da4e258cc3dd75f9b3fa6f645b202536bc73e90d33b8de1/amalgamate-0.1.3.tar.gz" } ] }