{ "info": { "author": "Greg Novak", "author_email": "greg.novak@gmail.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", "Operating System :: OS Independent", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.4", "Programming Language :: Python :: 2.5", "Programming Language :: Python :: 2.6", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.1", "Programming Language :: Python :: 3.2", "Programming Language :: Python :: 3.3" ], "description": "====================\n Grasp\n====================\n\nA set of python functions to help with interactive object inspection\nand discovery. \n\nThese help one grok, grasp, or get the gist of running code. They're\nmost useful in the context of an interactive IPython session, but can\nbe used in any Python shell. They're also helpful in the debugger.\nThey produce output that can be parsed programmatically if you find\nthat useful. I'll start with examples using the provided IPython\nmagic commands, since that's how I use them. Then I'll show how to\nuse them in other contexts.\n\nThere are basically three functions provided:\n * gist -- object inspection\n * rtype -- recursive type, deep object inspection\n * apropos -- deep search for things with a given name, value, etc.\n\nYou can find code and dowloads at the Launchpad page or the PyPI page\n\nhttp://launchpad.net/grasp\nhttp://pypi.python.org/pypi/grasp/\n\nWritten and maintained by Greg Novak \n\nIntroduction\n============\n\ngist\n----\n\nSuppose you are confronted with an unfamiliar object. What are\nits characteristics? What kinds of things can it do? What kind \ninformation does it contain? \n\ngist returns all the attributes of the object organized by type:\n\nIn [1]: foo = 5\nIn [2]: %gist foo\nOut[2]: {builtin_function_or_method: [bit_length, conjugate],\n int: [denominator, imag, numerator, real]}\n\nThe return value is a dict with one key for each type. The value of\neach key is a list of strings giving the names of all the attributes\nof the given type. So integer objects have four integer attributes,\nnamed numerator, denomintor, real, and imag, (accessed via foo.real,\netc.) as well as two function attributes (accessed via\nfoo.bit_length(), etc) named bit_length and conjugate.\n\nBy default, attributes with leading underscores are omitted. You can\ninclude them by asking for verbose output with -v (the output below is\ntrimmed for brevity):\n\nIn [3]: %gist -v foo\nOut[3]: {method-wrapper: [__abs__, __add__],\n int: [denominator, imag, numerator, real],\n builtin_function_or_method: [__format__, __getnewargs__,\n bit_length, conjugate],\n str: [__doc__],\n type: [__class__]}\n\n\nYou can pass python code to the magic command, which is evalated.\n(again, output trimmed):\n\nIn [4]: %gist numpy.array([1,2,3])\nOut[4]: {buffer: [data],\n int: [itemsize, nbytes, ndim, size],\n builtin_function_or_method: [all, any, argmax]\n tuple: [shape, strides],\n ndarray: [T, imag, real]}\n\nrtype\n-----\n\nSuppose you are confronted with a list that contains a deeply nested\nstructure of tuples, lists, and so on. What is this object all about?\nAre there regularities in the structure? You want a function like\ntype(), but you want it to be recursive so that it summarizes the\ntype structure of the object as much as possible.\n\nStart with a trivial case:\n\nIn [5]: %rtype 1\nOut[5]: 'int'\n\nIf the object is a tuple of objects, all of the same type, say so.\n\nIn [6]: %rtype [1, 2, 3]\nOut[6]: 'list of 3 int'\n\nWhat if it's a tuple of heterogeneous types? List them all. Note\nthat the return value is now a list of strings.\n\nIn [7]: %rtype [1, 1.1, 2]\nOut[7]: ['list of', 'int', 'float', 'int']\n\nThe rtype function is recursive, so this gets interesting when you add\nanother layer of container objects:\n\nIn [8]: %rtype [(1,2), (3,4), (5,6)]\nOut[8]: ['list of 3', 'tuple of 2 int']\n\nThe rtype function knows about numpy arrays and classifies them\naccording to shape and type.\n\nIn [9]: %rtype [numpy.array([1,2]), numpy.array([3,4]), numpy.array([5,6])]\nOut[9]: ['list of 3', 'ndarray of (2,) int64']\n\napropos\n-------\n\nSuppose I know that matplotlib (a Python plotting library) defines a\nbunch of colormaps, but I don't have any idea where to find them\nwithin the module. I can search recursively through the whole module\nnamespace, returning all of the ways to 'reach' objects with names\nhaving to do with colormaps:\n\nIn [10]: import matplotlib\nIn [11]: %apropos cmap matplotlib\nOut[11]: ['matplotlib.cm.cmapname',\n 'matplotlib.cm.get_cmap']\n\nNote the many layers of indirection that apropos digs through to\narrive at the results. Apropos is similar to the standard %psearch\nmagic command that's included in IPython. The difference is that that\npsearch only handles one level at a time (although it can search\nintermediate modules, as long as you know how many dots separate the\ntarget from the module).\n\nIn [12]: %psearch matplotlib.cmap* \nIn [13]: %psearch matplotlib.*.cmap* \n\nUsing apropos, you can also search for objects whose string\nrepresentation contains a given string. If no object to search is\ngiven, search the entire namespace given by globals()\n\nIn [14]: %apvalue blue \n\nYou can search for objects whose docstring contains a given string.\nUse quotes if the search string contains a space (this works for any\nof the aporpos commands).\n\nIn [15]: %apdoc \"colormap instance\" matplotlib\n\nThere are versions of each of the above that accept regular\nexpressions. \n\nIn [16]: %apname_regex [Cc]olors\n\nIn [17]: %apvalue_regex [Cc]olors\n\nIn [18]: %adoc_regex [Cc]olors\n\nYou can also pass python code as the object in which to search and it\nwill be evaluated, should you find that useful. The apropos commands\nassume that the first argument is the search string and everything\nelse is the object in which to search, so the second argument doesn't\nneed to be quoted if it contains spaces.\n\nIn [18]: %apdoc \"colormap instance\" dict(a=matplotlib, b=numpy)\n\nYou can search for python objects (rather than strings) using %apobj.\nThis gives the name of any object equal to the tuple (1,3,5) in the\nnumpy module.\n\nIn [19]: %apobj (1,3,5) numpy\n\nIf the search object contains spaces, it must be quoted\n\nIn [20]: %apobj \"(1, 3, 5)\" numpy\n\nYou can refer to variables in the user's namespace\n\nIn [21]: foo = numpy.array([1,2,3])\nIn [22]: %apobj foo numpy\nIn [23]: %apobj [foo,37] numpy\n\nWith the %apropos and %aobj commands, you can provide your own\nfunction that returns True if the object should be considered a match\nand false otherwise. This can be a named function on an anonymous\nfunction (probably requiring quotation marks). In the latter case the\ncode will be evaluated. See the docstrings for %apropos and %apobj\nfor details.\n\nIn [24]: def my_search_fn(needle, name, obj): return name and needle in name\n\nIn [25]: %apropos -s my_search_fn Colors \nIn [26]: %apropos -s \"lambda needle, name, obj: name and needle in name\" Colors \n\nFor examples, see the search functions in the grasp module:\n\nIn [27]: %apname search grasp\nOut[27]: ['grasp.search_doc',\n 'grasp.search_doc_regexp',\n 'grasp.search_equal',\n 'grasp.search_name',\n 'grasp.search_name_regexp',\n 'grasp.search_value',\n 'grasp.search_value_regexp']\nIn [28]: grasp.search_doc?\n\nA final note is that apropos is meant to be exhaustive, so it tends to\nreturn more than you need. You generally have to pick through the\nresults a little to find what you want.\n\nInstallation\n============\n\nThere are several possible installation techniques listed here in\nrough order of preference:\n\n1) Using pip (https://pypi.python.org/pypi/pip):\n\n To install system-wide:\n\n pip install grasp\n\n To install in the user-specific Python directory\n (~/Library/Python/2.7/lib/python/site-packages or similar on OS X):\n\n pip install --user grasp\n\n2) Using easy_install (https://pypi.python.org/pypi/distribute):\n\n The same as above, except substitute easy_install for pip\n\n3) Using distutils (included with Python)\n\n This is the standard distutils routine: download the code, extract\n from the archive, and install system-wide via something like\n (adjusting links and version numbers as appropriate):\n\n wget https://pypi.python.org/packages/source/g/grasp/grasp-0.3.0.tar.gz\n tar xzf grasp-0.3.0.tar.gz\n cd grasp-0.3.0\n python setup.py install \n\n If you want to install into a user directory, the last line becomes\n python setup.py install --user\n\n To install somewhere under the user's home directory:\n python setup.py install --home=~/some/place \n\n\nUsage\n=====\n\nTo use grasp from IPython, type\n\n %load_ext grasp\n\nThere are two ways to ensure that grasp is loaded automatically\nwhen IPython starts:\n\n1. Open or create the file ~/.ipython/profile_default/ipython_config.py \n and add this line to it:\n\n c.InteractiveShellApp.extensions = ['grasp']\n\n2. Put the following line into a file with the extension .ipy in the\n directory ~/.ipython/profile_default/startup/\n\n %load_ext grasp\n\nI have used this package on Gnu/Linux and OS X. I have not tested it\non Windows. It should work fine -- the main difference will be\ngetting it installed.\n\n\nNon-IPython Environments\n========================\n\nIf you don't use IPython, you just call the python functions upon\nwhich the magic functions are based directly. The translation between\nthe magic command arguments given above and the arguments of the\nPython functions should be straightforward. The magic commands\nsometimes have shorter, more cryptic names with a view toward saving\nkeystrokes during heavy interactive use. In plain Python it will look\nsomething like this:\n\n>>> import grasp\n>>> grasp.gist([1,2,3], verbose=True)\n>>> grasp.apropos_name('foo', grasp)\n>>> grasp.recursive_type([1,2,3])\n\nIPython has nice pretty-printing facilities, and I took advantage of\nthose in deciding how grasp presents the information it finds. Thus\ngist() returns a dict and relies on IPython to format it in a readable\nway for interactive use. This means that it's possible to use the\noutput programatically. One could, for example, do this to set \nevery attribute of a class with integer type to 42:\n\natts = grasp.gist(object)\nfor att in atts['int']:\n setattr(object, att, 42)\n\nVersion Information\n===================\n\nGrasp passes all tests with Python 2.4 through 2.7. \n\nWhen translated to Python 3 via the 2to3 script, Grasp passes all\ntests on Python 3.1, 3.2, and 3.3. Strictly speaking, for 3.1 there\nare errors with the unittest.expectedFailure decorator, but that seems\nto be a problem with unittest, not Grasp. \n\nThe IPython magic commands work for versions of IPython with the\ndecorators IPython.core.magic.magics_class and\nIPython.core.magic.line_magic. It looks like these were introduced in\nIPython version 0.13. Making it work with older versions of IPython\nwould only involve registering the magic commands in a different way,\nwhich is probably not difficult, but I see no compelling reason to do\nit. \n\nLicense\n=======\n\nI've released the code under the CC0 licence, essentially putting it\ninto the public domain. You can do whatever you want with it. If you\nincorporate grasp into another project, I ask for the courtesy of two\nfavors:\n\n1) Include an appropriate acknowledgement of the fact that your\nproject uses grasp.\n\n2) Let me know (greg.novak@gmail.com) so that I can link to your\nproject from the grasp web site.\n\nAcknowledgements\n================\n\nGrasp was written in 2006 by Greg Novak and\ncleaned up for public consumption by the same in 2013.\n\nThis was written for my own use when developing Python code to produce\nand analyze simulation output using the excellent IPython, Numpy,\nScipy, and matplotlib packages. I have benefited enormously from the\nwork of the authors of those packages over the years.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/grasp/", "keywords": null, "license": "Creative Commons CC0 1.0 Universal (CC0 1.0) Public Domain Dedication", "maintainer": null, "maintainer_email": null, "name": "grasp", "package_url": "https://pypi.org/project/grasp/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/grasp/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pypi.python.org/pypi/grasp/" }, "release_url": "https://pypi.org/project/grasp/0.3.2/", "requires_dist": null, "requires_python": null, "summary": "Useful introspection tools.", "version": "0.3.2" }, "last_serial": 792677, "releases": { "0.3.0": [ { "comment_text": "", "digests": { "md5": "2b71e2243639165431998dba610819b5", "sha256": "f78cf82cb33e7c407bd0eee7da8f34fcde48db069647126763192f84915b8855" }, "downloads": -1, "filename": "grasp-0.3.0.tar.gz", "has_sig": false, "md5_digest": "2b71e2243639165431998dba610819b5", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 18751, "upload_time": "2013-03-28T21:16:43", "url": "https://files.pythonhosted.org/packages/18/fd/f95b29b7e1a6aa16aaefab16340737feb8ed1440e362b461c0ba43214886/grasp-0.3.0.tar.gz" } ], "0.3.1": [ { "comment_text": "", "digests": { "md5": "29eb847619b546adb21e1539e676fa9c", "sha256": "40fc982ef77b2fee7fd25d413387e7f3e1acb9fdb94848ff1bd48f952f70fbf4" }, "downloads": -1, "filename": "grasp-0.3.1.tar.gz", "has_sig": false, "md5_digest": "29eb847619b546adb21e1539e676fa9c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19554, "upload_time": "2013-04-03T09:17:38", "url": "https://files.pythonhosted.org/packages/90/bd/c122258c835883c3ed8c82e38916ce559f12e6e3ceb187f5f0745e9291c7/grasp-0.3.1.tar.gz" } ], "0.3.2": [ { "comment_text": "", "digests": { "md5": "06e26b8c9784908a90e098be1326b959", "sha256": "7e70a7ba1b7023b42cfef004103e333caa410209c8d045cef13629efa26a0818" }, "downloads": -1, "filename": "grasp-0.3.2.tar.gz", "has_sig": false, "md5_digest": "06e26b8c9784908a90e098be1326b959", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24060, "upload_time": "2013-04-24T10:56:12", "url": "https://files.pythonhosted.org/packages/3b/a5/3c825f1f63a1cbb5339730af9888497e8eb352476abfa2cdbe9229a01993/grasp-0.3.2.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "06e26b8c9784908a90e098be1326b959", "sha256": "7e70a7ba1b7023b42cfef004103e333caa410209c8d045cef13629efa26a0818" }, "downloads": -1, "filename": "grasp-0.3.2.tar.gz", "has_sig": false, "md5_digest": "06e26b8c9784908a90e098be1326b959", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 24060, "upload_time": "2013-04-24T10:56:12", "url": "https://files.pythonhosted.org/packages/3b/a5/3c825f1f63a1cbb5339730af9888497e8eb352476abfa2cdbe9229a01993/grasp-0.3.2.tar.gz" } ] }