{ "info": { "author": "Joe Rickerby", "author_email": "joerick@mac.com", "bugtrack_url": null, "classifiers": [ "Environment :: Console", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: MacOS", "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Programming Language :: Python :: 2.7", "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", "Topic :: Software Development :: Debuggers", "Topic :: Software Development :: Testing" ], "description": "pyinstrument\n============\n\n [![PyPI version](https://badge.fury.io/py/pyinstrument.svg)](https://badge.fury.io/py/pyinstrument) [![Build Status](https://travis-ci.org/joerick/pyinstrument.svg?branch=master)](https://travis-ci.org/joerick/pyinstrument)\n\n[![Screenshot](screenshot.jpg)](https://raw.githubusercontent.com/joerick/pyinstrument/master/screenshot.jpg)\n\nPyinstrument is a Python profiler. A profiler is a tool to help you 'optimize'\nyour code - make it faster. It sounds obvious, but to get the biggest speed\nincrease you should [focus on the slowest part of your program](https://en.wikipedia.org/wiki/Amdahl%27s_law).\nPyinstrument helps you find it!\n\nDocumentation\n-------------\n\n* [Installation](#installation)\n* [How to use it](#how-to-use-it)\n * [Python script](#profile-a-python-script)\n * [Chunk of code](#profile-a-specific-chunk-of-code)\n * [Django](#profile-a-web-request-in-django)\n * [Flask](#profile-a-web-request-in-flask)\n* [How does it work?](#how-does-it-work)\n* [Changelog](#changelog)\n* [Further information](#further-information)\n * [Call stack profiling?](#call-stack-profiling)\n* [Contributing](#contributing)\n\nInstallation\n------------\n\n pip install pyinstrument\n\nPyinstrument supports Python 2.7 and 3.3+.\n\n> To run Pyinstrument from a git checkout or from a source tarball, there's a build step.\nTake a look at [Contributing](#contributing) for more info.\n\nHow to use it\n-------------\n\n### Profile a Python script\n\nCall Pyinstrument directly from the command line. Instead of writing\n`python script.py`, type `pyinstrument script.py`. Your script will run as\nnormal, and at the end (or when you press `^C`), Pyinstrument will output a\ncolored summary showing where most of the time was spent.\n\nHere are the options you can use:\n\n Usage: pyinstrument [options] scriptfile [arg] ...\n\n Options:\n --version show program's version number and exit\n -h, --help show this help message and exit\n --load-prev=ID Instead of running a script, load a previous report\n -m MODULE_NAME run library module as a script, like 'python -m\n module'\n -o OUTFILE, --outfile=OUTFILE\n save to \n -r RENDERER, --renderer=RENDERER\n how the report should be rendered. One of: 'text',\n 'html', 'json', or python import path to a renderer\n class\n -t, --timeline render as a timeline - preserve ordering and don't\n condense repeated calls\n --hide=EXPR glob-style pattern matching the file paths whose\n frames to hide. Defaults to '*/lib/*'.\n --hide-regex=REGEX regex matching the file paths whose frames to hide.\n Useful if --hide doesn't give enough control.\n --show-all (text renderer only) show external library code\n --unicode (text renderer only) force unicode text output\n --no-unicode (text renderer only) force ascii text output\n --color (text renderer only) force ansi color text output\n --no-color (text renderer only) force no color text output\n\n**Protip:** `-r html` will give you a interactive profile report as HTML - you\ncan really explore this way!\n\n### Profile a specific chunk of code\n\nPyinstrument also has a Python API. Just surround your code with Pyinstrument,\nlike this:\n\n```python\nfrom pyinstrument import Profiler\n\nprofiler = Profiler()\nprofiler.start()\n\n# code you want to profile\n\nprofiler.stop()\n\nprint(profiler.output_text(unicode=True, color=True))\n```\n\n(You can omit the `unicode` and `color` flags if your output/terminal does\nnot support them.)\n\n### Profile a web request in Django\n\nTo profile Django web requests, add\n`pyinstrument.middleware.ProfilerMiddleware` to `MIDDLEWARE_CLASSES` in your\n`settings.py`.\n\nOnce installed, add `?profile` to the end of a request URL to activate the\nprofiler. Your request will run as normal, but instead of getting the response,\nyou'll get pyinstrument's analysis of the request in a web page.\n\nIf you're writing an API, it's not easy to change the URL when you want to\nprofile something. In this case, add `PYINSTRUMENT_PROFILE_DIR = 'profiles'`\nto your `settings.py`. Pyinstrument will profile every request and save the\nHTML output to the folder `profiles` in your working directory.\n\n### Profile a web request in Flask\n\nA simple setup to profile a Flask application is the following:\n\n```python\nfrom flask import Flask, g, make_response, request\napp = Flask(__name__)\n\n@app.before_request\ndef before_request():\n if \"profile\" in request.args:\n g.profiler = Profiler()\n g.profiler.start()\n\n\n@app.after_request\ndef after_request(response):\n if not hasattr(g, \"profiler\"):\n return response\n g.profiler.stop()\n output_html = g.profiler.output_html()\n return make_response(output_html)\n```\n\nThis will check for the `?profile` query param on each request and if found,\nit starts profiling. After each request where the profiler was running it\ncreates the html output and returns that instead of the actual response.\n\n### Profile something else?\n\nI'd love to have more ways to profile using Pyinstrument - e.g. other\nweb frameworks. PRs are encouraged!\n\nHow is it different to `profile` or `cProfile`?\n-----------------------------------------------\n\n### Statistical profiling (not tracing)\n\nPyinstrument is a statistical profiler - it doesn't track every\nfunction call that your program makes. Instead, it's recording the call stack\nevery 1ms.\n\nThat gives some advantages over other profilers. Firstly, statistical\nprofilers are much lower-overhead than tracing profilers.\n\n| | Django template render \u00d7 4000 | Overhead\n| -------------|:---------------------------------------------------|---------:\n| Base | `\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ` 0.33s | \n| | |\n| pyinstrument | `\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ` 0.43s | 30%\n| cProfile | `\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588 ` 0.61s | 84%\n| profile | `\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588...\u2588\u2588` 6.79s | 2057%\n\nBut low overhead is also important because it can distort the results. When\nusing a tracing profiler, code that makes a lot of Python function calls\ninvokes the profiler a lot, making it slower. This distorts the \nresults, and might lead you to optimise the wrong part of your program!\n\n### Full-stack recording\n\nThe standard Python profilers [`profile`][1] and [`cProfile`][2] show you a\nbig list of functions, ordered by the time spent in each function.\nThis is great, but it can be difficult to interpret _why_ those functions are\ngetting called. It's more helpful to know why those functions are called, and\nwhich parts of user code were involved.\n\n[1]: http://docs.python.org/2/library/profile.html#module-profile\n[2]: http://docs.python.org/2/library/profile.html#module-cProfile\n\nFor example, let's say I want to figure out why a web request in Django is\nslow. If I use cProfile, I might get this:\n\n 151940 function calls (147672 primitive calls) in 1.696 seconds\n\n Ordered by: cumulative time\n\n ncalls tottime percall cumtime percall filename:lineno(function)\n 1 0.000 0.000 1.696 1.696 profile:0( at 0x1053d6a30, file \"./manage.py\", line 2>)\n 1 0.001 0.001 1.693 1.693 manage.py:2()\n 1 0.000 0.000 1.586 1.586 __init__.py:394(execute_from_command_line)\n 1 0.000 0.000 1.586 1.586 __init__.py:350(execute)\n 1 0.000 0.000 1.142 1.142 __init__.py:254(fetch_command)\n 43 0.013 0.000 1.124 0.026 __init__.py:1()\n 388 0.008 0.000 1.062 0.003 re.py:226(_compile)\n 158 0.005 0.000 1.048 0.007 sre_compile.py:496(compile)\n 1 0.001 0.001 1.042 1.042 __init__.py:78(get_commands)\n 153 0.001 0.000 1.036 0.007 re.py:188(compile)\n 106/102 0.001 0.000 1.030 0.010 __init__.py:52(__getattr__)\n 1 0.000 0.000 1.029 1.029 __init__.py:31(_setup)\n 1 0.000 0.000 1.021 1.021 __init__.py:57(_configure_logging)\n 2 0.002 0.001 1.011 0.505 log.py:1()\n\nIt's often hard to understand how your own code relates to these traces.\n\nPyinstrument records the entire stack, so tracking expensive calls is much\neasier. It also hides library frames by default, letting you focus on your\napp/module is affecting performance.\n\n```\n _ ._ __/__ _ _ _ _ _/_ Recorded: 14:53:35 Samples: 131\n /_//_/// /_\\ / //_// / //_'/ // Duration: 3.131 CPU time: 0.195\n/ _/ v3.0.0b3\n\nProgram: examples/django_example/manage.py runserver --nothreading --noreload\n\n3.131 manage.py:2\n\u2514\u2500 3.118 execute_from_command_line django/core/management/__init__.py:378\n [473 frames hidden] django, socketserver, selectors, wsgi...\n 2.836 select selectors.py:365\n 0.126 _get_response django/core/handlers/base.py:96\n \u2514\u2500 0.126 hello_world django_example/views.py:4\n```\n\n### 'Wall-clock' time (not CPU time)\n\nPyinstrument records duration using 'wall-clock' time. When you're writing a\nprogram that downloads data, reads files, and talks to databases, all that\ntime is *included* in the tracked time by pyinstrument.\n\nThat's really important when debugging performance problems, since Python is\noften used as a 'glue' language between other services. The problem might not\nbe in your program, but you should still be able to find why it's slow.\n\nHow does it work?\n-----------------\n\nPyinstrument interrupts the program every 1ms and records the entire stack at\nthat point. It does this using a C extension and `PyEval_SetProfile`, but only\ntaking readings every 1ms. Check out [this blog post](http://joerick.me/posts/2017/12/15/pyinstrument-20/) for more info.\n\nYou might be surprised at how few samples make up a report, but don't worry,\nit won't decrease accuracy. The default interval of 1ms is a lower bound for\nrecording a stackframe, but if there is a long time spent in a single function\ncall, it will be recorded at the end of that call. So effectively those\nsamples were 'bunched up' and recorded at the end.\n\nChangelog\n---------\n\n### v3.0.3\n\n- Fixed bug with the Django middleware on Windows where profiling would fail\n because we were trying to put an illegal character '?' in the profile path.\n (#66)\n\n### v3.0.2\n\n- Add `--show` and `--show-regex` options, to mark certain files to be\n displayed. This helps to profile inside specific modules, while hiding\n others. For example, `pyinstrument --show '*/sympy/*' script.py`.\n\n### v3.0.1\n\n- Fix #60: pass all arguments after -m module_name to the called module\n- Fix crash during HTML/JSON output when no frames were captured.\n\n### v3.0.0\n\n- Pyinstrument will now hide traces through libraries that you're using by default. So instead of showing you loads of frames going through the internals of something external e.g. urllib, it lets you focus on your code.\n\n | Before | After |\n | --- | ---\n | ![image](https://user-images.githubusercontent.com/1244307/50928250-1e50db00-1452-11e9-9164-6050a3c950ed.png) | ![image](https://user-images.githubusercontent.com/1244307/50928326-4c361f80-1452-11e9-91e8-cea735584806.png) | \n\n To go back to the old behaviour, use `--show-all` on the command line.\n\n- 'Entry' frames of hidden groups are shown, so you know which call is the problem\n- Really slow frames in the groups are shown too, e.g. the 'read' call on the socket\n- Application code is highlighted in the console\n- Additional metrics are shown at the top of the trace - timestamp, number of samples, duration, CPU time\n- Hidden code is controlled by the `--hide` or `--hide-regex` options - matching on the path of the code files. \n ```\n --hide=EXPR glob-style pattern matching the file paths whose\n frames to hide. Defaults to '*/lib/*'.\n --hide-regex=REGEX regex matching the file paths whose frames to hide.\n Useful if --hide doesn't give enough control.\n ```\n\n- Outputting a timeline is supported from the command line.\n\n ```\n -t, --timeline render as a timeline - preserve ordering and don't\n condense repeated calls\n ```\n\n- Because there are a few rendering options now, you can load a previous profiling session using `--load-prev` - pyinstrument keeps the last 10 sessions.\n\n- Hidden groups can also call back into application code, that looks like this:\n\n ![image](https://user-images.githubusercontent.com/1244307/50928591-fca42380-1452-11e9-8320-3c851cf5210e.png)\n\n- (internal) When recording timelines, frame trees are completely linear now, allowing \n for the creation of super-accurate frame charts.\n\n- (internal) The HTML renderer has been rewritten as a Vue.js app. All the console improvements apply to the HTML output too, plus it's interactive.\n\n- (internal) A lot of unit and integration tests added!\n\nYikes! See #49 for the gory details. I hope you like it.\n\n### v2.3.0\n\n- Big refactor! \n - `Recorders` have been removed. The frame recording is now internal to the `Profiler` object.\n This means the 'frame' objects are more general-purpose, which paves the way for...\n - Processors! These are functions that mutate the tree to sculpt the output.\n They are used by the renderers to filter the output to the correct form. Now, instead of\n a time-aggregating recorder, the profiler just uses timeline-style recording (this is \n lower-overhead anyway) and the aggregation is done as a processing step.\n - The upshot of this is that it's now way easier to alter the tree to filter stuff out, and\n do more advanced things like combining frames that we don't care about. More features to\n come that use this in v3.0!\n- Importlib frames are removed - you won't see them at all. Their children are retained, so\n imports are just transparent.\n- Django profile file name is now limited to a hundred of characters (#50)\n- Fix bug with --html option (#53)\n- Add `--version` command line option\n\n### v2.2.1\n\n- Fix crash when using on the command line.\n\n### v2.2.0\n\n- Added support for JSON output. Use `pyinstrument --renderer=json scriptfile.py`. \n [PR](https://github.com/joerick/pyinstrument/pull/46)\n- [@iddan](https://github.com/iddan) has put together an\n [interactive viewer](https://python-flame-chart.netlify.com/) using the JSON output!\n\n ![image](https://user-images.githubusercontent.com/1244307/44622790-3ca9a600-a8b8-11e8-8dc2-f33ce433c03d.png)\n\n- When running `pyinstrument --html` and you don't pipe the output to a file, pyinstrument will write the console output to a temp file and open that in a browser.\n\n### v2.1.0\n\n- Added support for running modules with pyinstrument via the command line. The new syntax\n is the `-m` flag e.g. `pyinstrument -m module_name`! [PR](https://github.com/joerick/pyinstrument/pull/45#pullrequestreview-143383557) \n\n### v2.0.4 \n\n- Fix crashes due to multi-threaded use of pyinstrument. The fix is in the C extension,\n over at https://github.com/joerick/pyinstrument_cext/pull/3\n\n### v2.0.3\n\n- Pyinstrument can now be used in a `with` block.\n\n For example:\n\n\t\tprofiler = pyinstrument.Profiler()\n\t\twith profiler:\n\t\t # do some work here...\n\t\tprint(profiler.output_text())\n- Middleware fix for older versions of Django\n\n### v2.0.2\n\n- Fix for max recursion error when used to profile programs with a lot of frames on the stack.\n\n### v2.0.1\n\n- Ensure license is included in the sdist.\n\n### v2.0.0\n\n- **Pyinstrument uses a new profiling mode**. Rather than using\n signals, pyintrument uses a new statistical profiler built on\n PyEval_SetProfile. This means no more main thread restriction, no more \n IO errors when using Pyinstrument, and no need for a separate more \n 'setprofile' mode!\n\n- **Renderers**. Users can customize Pyinstrument to use alternative renderers\n with the `renderer` argument on `Profiler.output()`, or using the `--renderer`\n argument on the command line.\n\n- **Recorders**. To support other use cases of Pyinstrument (e.g. flame charts),\n pyinstrument now has a 'timeline' recorder mode. This mode records captured\n frames in a linear way, so the program execution can be viewed on a\n timeline.\n\n### v0.13\n\n- `pyinstrument` command. You can now profile python scripts from the shell\n by running `$ pyinstrument script.py`. This is now equivalent to \n `python -m pyinstrument`. Thanks @asmeurer!\n\n### v0.12\n\n- Application code is highlighted in HTML traces to make it easier to spot\n\n- Added `PYINSTRUMENT_PROFILE_DIR` option to the Django interface, which \n will log profiles of all requests to a file the specified folder. Useful\n for profiling API calls.\n\n- Added `PYINSTRUMENT_USE_SIGNAL` option to the Django interface, for use\n when signal mode presents problems.\n\nContributing\n------------\n\nTo run pyinstrument from the git repo or a source checkout, you must first run\n\n python setup.py build\n\nThis compiles the Javascript code needed for the HTML output. You will need\n[node](https://nodejs.org/en/) installed (Node isn't required for the pip\ninstall as the Javascript is already pre-built in the wheel).\n\nTo setup a dev envronment, do:\n\n virtualenv --python=python3 env\n . env/bin/activate\n pip install -r requirements-dev.txt\n\n> Note: if you get an SSL error doing the above, it might be due to setuptools trying\n> to install pytest-runner, since it's listed in setup_requires. The workaround is to \n> make sure your pip is up-to-date (`curl https://bootstrap.pypa.io/get-pip.py | python`)\n> and then install it first `pip install pytest-runner`. Then try \n> `pip install -r requirements-dev.txt`.\n\nTo get some sample output:\n\n pyinstrument examples/wikipedia_article_word_count.py\n\nTo run the tests:\n\n python setup.py test\n\n\n", "description_content_type": "text/markdown", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/joerick/pyinstrument", "keywords": "profiling,profile,profiler,cpu,time,sampling", "license": "", "maintainer": "", "maintainer_email": "", "name": "pyinstrument", "package_url": "https://pypi.org/project/pyinstrument/", "platform": "", "project_url": "https://pypi.org/project/pyinstrument/", "project_urls": { "Homepage": "https://github.com/joerick/pyinstrument" }, "release_url": "https://pypi.org/project/pyinstrument/3.0.3/", "requires_dist": [ "pyinstrument-cext (>=0.2.2)" ], "requires_python": "", "summary": "Call stack profiler for Python. Shows you why your code is slow!", "version": "3.0.3" }, "last_serial": 5290961, "releases": { "0.10.1": [ { "comment_text": "", "digests": { "md5": "0a3013166901368de905816acf042898", "sha256": "837beeecf33aa5c19b545194c5fe3ee656498ab1ce47e0e19bde41cf57ac1abe" }, "downloads": -1, "filename": "pyinstrument-0.10.1.tar.gz", "has_sig": false, "md5_digest": "0a3013166901368de905816acf042898", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43527, "upload_time": "2014-06-06T19:33:26", "url": "https://files.pythonhosted.org/packages/3f/36/392b1bdb483e80511938d7b6710fc7f08120639a50aa51ee115216447ae4/pyinstrument-0.10.1.tar.gz" } ], "0.11": [ { "comment_text": "", "digests": { "md5": "de3a8b4473a0cfc0bf5ba5d77c1e91d0", "sha256": "5059d9052c1a77019859c210c8b8455f207ee1b9cfdd0d93fcd22dec741a5ce4" }, "downloads": -1, "filename": "pyinstrument-0.11.tar.gz", "has_sig": false, "md5_digest": "de3a8b4473a0cfc0bf5ba5d77c1e91d0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 43939, "upload_time": "2014-06-30T18:21:54", "url": "https://files.pythonhosted.org/packages/76/31/580bd1b89215d1b7f86f5fef64c3173ad5d6d43fe6cd097d3734fc3b21a8/pyinstrument-0.11.tar.gz" } ], "0.12": [ { "comment_text": "", "digests": { "md5": "9070d94052797bebca8cdd40c1d8abb1", "sha256": "276ad384d69334ba324114adc5695dea07252c6910ab81dba5924151643bbf81" }, "downloads": -1, "filename": "pyinstrument-0.12.tar.gz", "has_sig": false, "md5_digest": "9070d94052797bebca8cdd40c1d8abb1", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45079, "upload_time": "2014-08-06T11:54:22", "url": "https://files.pythonhosted.org/packages/5d/5c/e5eefc7a001d243f5c60a6e4260f1fd4b868f654d7c1423fe52459d42f59/pyinstrument-0.12.tar.gz" } ], "0.13": [ { "comment_text": "", "digests": { "md5": "b7c9a0d6d6e9ab6c9890aaba29e90e89", "sha256": "35daf6768110954d128a8668dd4aa1328cba1108d1e3f7bd3d0a3e0049b09b09" }, "downloads": -1, "filename": "pyinstrument-0.13.tar.gz", "has_sig": false, "md5_digest": "b7c9a0d6d6e9ab6c9890aaba29e90e89", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45407, "upload_time": "2014-08-20T14:22:55", "url": "https://files.pythonhosted.org/packages/b3/3e/c21a23a7079d8b873d07a3039d2baa4b8405f3472c29784e4df367b0890f/pyinstrument-0.13.tar.gz" } ], "0.13.1": [ { "comment_text": "", "digests": { "md5": "e347036acc50720c0903dc2221b2605d", "sha256": "590b45431b5211d2b0f3ea8210e4541a9c740f14c38b7120e8773b7961b79bb3" }, "downloads": -1, "filename": "pyinstrument-0.13.1.tar.gz", "has_sig": false, "md5_digest": "e347036acc50720c0903dc2221b2605d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45395, "upload_time": "2014-08-20T20:41:31", "url": "https://files.pythonhosted.org/packages/64/56/d7a0d48973dcf58ea74d5f004e16e94969e03ae783b46f86f42f35a6b81b/pyinstrument-0.13.1.tar.gz" } ], "0.13.2": [ { "comment_text": "", "digests": { "md5": "5dbc797e31c714139babdaf55742df4c", "sha256": "a0a645d69df12551214311fdf2e454c12b96cb0abc0f5dcc3067d8ef71713e02" }, "downloads": -1, "filename": "pyinstrument-0.13.2.tar.gz", "has_sig": false, "md5_digest": "5dbc797e31c714139babdaf55742df4c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 45357, "upload_time": "2017-06-11T16:06:54", "url": "https://files.pythonhosted.org/packages/fa/6e/ae6fcd3d7e8b38e88fc444ef2bf5d41945ee1d63249fa5cd20bef56b1fb6/pyinstrument-0.13.2.tar.gz" } ], "2.0.0": [ { "comment_text": "", "digests": { "md5": "02f0161a991d30551dd5a4fd9606b06e", "sha256": "d27121269d62f157ef848ff29334b7c17c16d1aef618ada75aa0ffcb5920d8df" }, "downloads": -1, "filename": "pyinstrument-2.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "02f0161a991d30551dd5a4fd9606b06e", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 53589, "upload_time": "2017-12-15T17:34:57", "url": "https://files.pythonhosted.org/packages/d4/f8/3a2d82e2d2eb7f2c517009c7e50cdee527c8d78e2208511087158e6c5c2f/pyinstrument-2.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "72deff1fc93f3b376730b02eed2a34b8", "sha256": "f5af44833cc22d0d5e52e9d5a80ee31d3402762f23a5694d21e200f7f988706c" }, "downloads": -1, "filename": "pyinstrument-2.0.0.tar.gz", "has_sig": false, "md5_digest": "72deff1fc93f3b376730b02eed2a34b8", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 53943, "upload_time": "2017-12-15T17:35:00", "url": "https://files.pythonhosted.org/packages/8e/5f/c30bb7789a7993694395af09aa105f9ce766b5d5be5271564665287c0650/pyinstrument-2.0.0.tar.gz" } ], "2.0.0b1": [ { "comment_text": "", "digests": { "md5": "29b2dd0a8bcf701285b6e8f4962ae894", "sha256": "9918528de77d70485eecb524833fac7df544d234dbb56ec33ec483f5dd90dadb" }, "downloads": -1, "filename": "pyinstrument-2.0.0b1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "29b2dd0a8bcf701285b6e8f4962ae894", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 53624, "upload_time": "2017-12-01T11:36:55", "url": "https://files.pythonhosted.org/packages/11/09/8635a2c872780e333e2ab09ae85659d00367cc5273cdcb97d0de8f8bdf49/pyinstrument-2.0.0b1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f25a3fedd0dd6d1d9708d5737bd79afd", "sha256": "d3b59e63d4bd2b14d87c0ab63dfc6d7d0eb388c142d91670d2e54572abb3ef57" }, "downloads": -1, "filename": "pyinstrument-2.0.0b1.tar.gz", "has_sig": false, "md5_digest": "f25a3fedd0dd6d1d9708d5737bd79afd", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 53665, "upload_time": "2017-12-01T11:34:45", "url": "https://files.pythonhosted.org/packages/17/3c/e3ffd5fe81d3bf4e68318310a1f242a5b7b13c251bcebfed64766491ab58/pyinstrument-2.0.0b1.tar.gz" } ], "2.0.1": [ { "comment_text": "", "digests": { "md5": "a8d152471f8c01f549b69cdfb92f15f2", "sha256": "6856fa6c08a77d23b2772b705dd6c8143e1b1dc4617036822a3f518453743dfd" }, "downloads": -1, "filename": "pyinstrument-2.0.1.tar.gz", "has_sig": false, "md5_digest": "a8d152471f8c01f549b69cdfb92f15f2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 54932, "upload_time": "2018-01-16T09:55:42", "url": "https://files.pythonhosted.org/packages/24/de/a73cb5f7f46dbaae1154a9dc935c4d5f7a73ec22a52a06f780778b3278be/pyinstrument-2.0.1.tar.gz" } ], "2.0.2": [ { "comment_text": "", "digests": { "md5": "2e9f2a7ecf568375d8ae22904d4f3579", "sha256": "c04f3a0771185c66db7acb92db518be3db79253aad790f7c81da57d5ed9253bd" }, "downloads": -1, "filename": "pyinstrument-2.0.2.tar.gz", "has_sig": false, "md5_digest": "2e9f2a7ecf568375d8ae22904d4f3579", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55186, "upload_time": "2018-02-11T16:24:04", "url": "https://files.pythonhosted.org/packages/b4/d2/ea2272ebb0ba44ac81d514cf567a083fab23b0e85115739f8e810ac82f9e/pyinstrument-2.0.2.tar.gz" } ], "2.0.3": [ { "comment_text": "", "digests": { "md5": "9f31d6cb85cc88eee0673a43bab3dc6a", "sha256": "8a5ab31b71c67c7de4f490371bfc1216c05c0f3751527331c257a1cbefac6020" }, "downloads": -1, "filename": "pyinstrument-2.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9f31d6cb85cc88eee0673a43bab3dc6a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 52717, "upload_time": "2018-07-17T17:15:41", "url": "https://files.pythonhosted.org/packages/43/7c/09704933e73562eb6f8b3cbea0f2067c510e771cbf0cb2b45221380d676b/pyinstrument-2.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "1afc0eed6490968ef8c7d89ba2350bac", "sha256": "100eed3db3e8b54ba3e175db27f92a75e8226e366f68b71612935ead49738b21" }, "downloads": -1, "filename": "pyinstrument-2.0.3.tar.gz", "has_sig": false, "md5_digest": "1afc0eed6490968ef8c7d89ba2350bac", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 55654, "upload_time": "2018-07-17T17:15:42", "url": "https://files.pythonhosted.org/packages/d1/ba/1aa73a0bf2649986890ccbfc992e40a34398a1037cc5eb0833665b8d0dd0/pyinstrument-2.0.3.tar.gz" } ], "2.1.1": [ { "comment_text": "", "digests": { "md5": "4fd44e4b5a1093a200c61f92dba1edda", "sha256": "b63cb9043babae952ed53558c308ff0b93f0e79f0fa49a5e6c17a5ed77061d3e" }, "downloads": -1, "filename": "pyinstrument-2.1.1.tar.gz", "has_sig": false, "md5_digest": "4fd44e4b5a1093a200c61f92dba1edda", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 56208, "upload_time": "2018-08-04T15:13:28", "url": "https://files.pythonhosted.org/packages/51/6f/c208c4af7dbf79613cda20213be47d1b70efe1f71d4fd329084b5409601c/pyinstrument-2.1.1.tar.gz" } ], "2.2.1": [ { "comment_text": "", "digests": { "md5": "f6e705c967a46bcd4df9aac3b5d79825", "sha256": "c8535ab56af2e46450df7f3eb97bc9a9554481e240af6ad7f4156140055099c3" }, "downloads": -1, "filename": "pyinstrument-2.2.1.tar.gz", "has_sig": false, "md5_digest": "f6e705c967a46bcd4df9aac3b5d79825", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 57254, "upload_time": "2018-08-25T21:52:08", "url": "https://files.pythonhosted.org/packages/4c/df/9b1ede43b74558322b6f6367d7b0018b3bb9eaec9bd9d4d35b967412b559/pyinstrument-2.2.1.tar.gz" } ], "2.3.0": [ { "comment_text": "", "digests": { "md5": "03853b89f38c72b5e02d8153e4d3d3d7", "sha256": "87bf23dd12ebd214c516ee98d2abe707401f5818aafa425d868ce63bfa7bd074" }, "downloads": -1, "filename": "pyinstrument-2.3.0.tar.gz", "has_sig": false, "md5_digest": "03853b89f38c72b5e02d8153e4d3d3d7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 58797, "upload_time": "2018-10-20T22:54:48", "url": "https://files.pythonhosted.org/packages/51/c5/db0a16f236cd810fe9035d1f154cc3449be222983ec9fd095b144049df65/pyinstrument-2.3.0.tar.gz" } ], "3.0.0": [ { "comment_text": "", "digests": { "md5": "45a5a8565d68d670ca97ea9b808113ff", "sha256": "765d50fe67ef7906f39ddf05120fc359ffe9f2a4e7bafa03c30d6254edfd0908" }, "downloads": -1, "filename": "pyinstrument-3.0.0-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "45a5a8565d68d670ca97ea9b808113ff", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 72830, "upload_time": "2019-01-09T21:20:35", "url": "https://files.pythonhosted.org/packages/ff/d5/ac2a2f7f09c7b4c987de55da62cab038889438eb1b1ed46754f0d2f852cc/pyinstrument-3.0.0-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "f8161e47483c3f9b23a67760e347d823", "sha256": "37945d83935d57a91cea46ecf25ff63e4d4d95d63519320b7e89b3959560fcad" }, "downloads": -1, "filename": "pyinstrument-3.0.0.tar.gz", "has_sig": false, "md5_digest": "f8161e47483c3f9b23a67760e347d823", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 197822, "upload_time": "2019-01-09T21:21:08", "url": "https://files.pythonhosted.org/packages/da/32/410afd7d30c69a2f7a8041ca15b056bee6f8258d4b2267694e09b8dc3ebb/pyinstrument-3.0.0.tar.gz" } ], "3.0.0b1": [ { "comment_text": "", "digests": { "md5": "e3febb8996b2dfebfe8718231bfbfd60", "sha256": "6d21730e41b16265d8a383928a36eb96ef5f6bf0a20fd75fd829a1c02b0d188f" }, "downloads": -1, "filename": "pyinstrument-3.0.0b1.tar.gz", "has_sig": false, "md5_digest": "e3febb8996b2dfebfe8718231bfbfd60", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 65379, "upload_time": "2018-12-09T12:37:00", "url": "https://files.pythonhosted.org/packages/2c/72/62507210a8e6553f11a3187083835bb42ade2d6cd5c13e4682c87dbcb939/pyinstrument-3.0.0b1.tar.gz" } ], "3.0.0b2": [ { "comment_text": "", "digests": { "md5": "60ecfa110184c59a884f08d5f260cb94", "sha256": "6be8a39684be893b9c9ed4b84bb7ae3be059c8d845138563c88cbfeb4788181e" }, "downloads": -1, "filename": "pyinstrument-3.0.0b2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "60ecfa110184c59a884f08d5f260cb94", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 66225, "upload_time": "2018-12-10T18:55:41", "url": "https://files.pythonhosted.org/packages/c6/f0/3cb11329e72fd9b1b2bea959f6f7aa5d58acbcac28cd6424cfd324fb8134/pyinstrument-3.0.0b2-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4f0e983f10bbc17a3714850a76affb32", "sha256": "4fc52f941c6cd8541c1d5bbc93ebed4ff2cc6c3f24f0b987d2cabe37a9927e39" }, "downloads": -1, "filename": "pyinstrument-3.0.0b2.tar.gz", "has_sig": false, "md5_digest": "4f0e983f10bbc17a3714850a76affb32", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 183172, "upload_time": "2018-12-10T18:48:15", "url": "https://files.pythonhosted.org/packages/59/5c/032c03b916c0ef965843a120c9b8b575952a8d6cc03b2eaead05981a0440/pyinstrument-3.0.0b2.tar.gz" } ], "3.0.0b3": [ { "comment_text": "", "digests": { "md5": "8807adf21b798a6f23779d6a847564cb", "sha256": "bb850b9aeede30a8d99244f57c3cfc8c60bb81eacf027bd3358131c3c8da1917" }, "downloads": -1, "filename": "pyinstrument-3.0.0b3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "8807adf21b798a6f23779d6a847564cb", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 71445, "upload_time": "2019-01-06T21:33:31", "url": "https://files.pythonhosted.org/packages/78/b9/8285766f0eef93c8b108090d079fce4393609e342b8e8f76de44c3665a5a/pyinstrument-3.0.0b3-py2.py3-none-any.whl" } ], "3.0.1": [ { "comment_text": "", "digests": { "md5": "6cd9e3784092ebac04f422922e185c7c", "sha256": "256218ff3e18a31c8175a9182c3da7a7dbdc44298d5780660dcf4d8d805d00d8" }, "downloads": -1, "filename": "pyinstrument-3.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "6cd9e3784092ebac04f422922e185c7c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 73385, "upload_time": "2019-02-03T21:35:12", "url": "https://files.pythonhosted.org/packages/a9/ad/428d9a27facbb475b8b9e0615f733fb2b30cd62a3d4835950eec89879d8b/pyinstrument-3.0.1-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "4c886594241207233cf3aadcec12226f", "sha256": "e50b9be2a3a8ff8e4e8dd27c1f3113b9fa39f4b797a6d41bf5538a90d58aaa2a" }, "downloads": -1, "filename": "pyinstrument-3.0.1.tar.gz", "has_sig": false, "md5_digest": "4c886594241207233cf3aadcec12226f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 198656, "upload_time": "2019-02-03T21:35:44", "url": "https://files.pythonhosted.org/packages/d2/66/72e011393d19b45bc41baa27900277fec2a52510b9678404beeca7d1a271/pyinstrument-3.0.1.tar.gz" } ], "3.0.2": [ { "comment_text": "", "digests": { "md5": "eded877ba9caa055bcfd5af59f09d50a", "sha256": "9f9e8df7a7a2c022d23895fefa50ddcdae5c5db64d20e675ae3ff716ad74399e" }, "downloads": -1, "filename": "pyinstrument-3.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "eded877ba9caa055bcfd5af59f09d50a", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 73944, "upload_time": "2019-04-06T14:25:04", "url": "https://files.pythonhosted.org/packages/e6/ed/63a1fbc3ca4a521541548b99eab980c7a2f2a596a42d57490689b93ce4e1/pyinstrument-3.0.2-py2.py3-none-any.whl" } ], "3.0.3": [ { "comment_text": "", "digests": { "md5": "5aaa2d864f2db97e2d4ee66620eef002", "sha256": "0e53a81a696a7d5e59e85b54c2e90ce8b6db161fe1d9a7e29675ff48fcf4cfbb" }, "downloads": -1, "filename": "pyinstrument-3.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5aaa2d864f2db97e2d4ee66620eef002", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 74120, "upload_time": "2019-05-20T08:24:04", "url": "https://files.pythonhosted.org/packages/84/ea/6719e8d8ded29fe01f4fd5d52a89cd3a1af46dd86353d1529ce1f16fafc7/pyinstrument-3.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5e5d96d228ccadf49d70bb7eeae6255d", "sha256": "747e80cdc4d9d7a484aa50719e369b215af9492313eef5756e4a6b4341babea5" }, "downloads": -1, "filename": "pyinstrument-3.0.3.tar.gz", "has_sig": false, "md5_digest": "5e5d96d228ccadf49d70bb7eeae6255d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 199747, "upload_time": "2019-05-20T08:24:08", "url": "https://files.pythonhosted.org/packages/21/58/0f8a00b3896306e43de064797af1d753841d96ba8316d2d10c854219aec3/pyinstrument-3.0.3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "5aaa2d864f2db97e2d4ee66620eef002", "sha256": "0e53a81a696a7d5e59e85b54c2e90ce8b6db161fe1d9a7e29675ff48fcf4cfbb" }, "downloads": -1, "filename": "pyinstrument-3.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "5aaa2d864f2db97e2d4ee66620eef002", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 74120, "upload_time": "2019-05-20T08:24:04", "url": "https://files.pythonhosted.org/packages/84/ea/6719e8d8ded29fe01f4fd5d52a89cd3a1af46dd86353d1529ce1f16fafc7/pyinstrument-3.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "5e5d96d228ccadf49d70bb7eeae6255d", "sha256": "747e80cdc4d9d7a484aa50719e369b215af9492313eef5756e4a6b4341babea5" }, "downloads": -1, "filename": "pyinstrument-3.0.3.tar.gz", "has_sig": false, "md5_digest": "5e5d96d228ccadf49d70bb7eeae6255d", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 199747, "upload_time": "2019-05-20T08:24:08", "url": "https://files.pythonhosted.org/packages/21/58/0f8a00b3896306e43de064797af1d753841d96ba8316d2d10c854219aec3/pyinstrument-3.0.3.tar.gz" } ] }