Skip to main content

Hunter is a flexible code tracing toolkit.

Project description

Hunter is a flexible code tracing toolkit, not for measuring coverage, but for debugging, logging, inspection and other nefarious purposes. It has a Python API, terminal activation (see Environment variable activation). and supports tracing other processes (see Tracing processes).

  • Free software: BSD license

Installation

pip install hunter

Documentation

https://python-hunter.readthedocs.org/

Overview

The default action is to just print the code being executed. Example:

import hunter
hunter.trace(module='posixpath')

import os
os.path.join('a', 'b')

Would result in:

>>> os.path.join('a', 'b')
         /usr/lib/python3.5/posixpath.py:71    call      def join(a, *p):
         /usr/lib/python3.5/posixpath.py:76    line          sep = _get_sep(a)
         /usr/lib/python3.5/posixpath.py:39    call      def _get_sep(path):
         /usr/lib/python3.5/posixpath.py:40    line          if isinstance(path, bytes):
         /usr/lib/python3.5/posixpath.py:43    line              return '/'
         /usr/lib/python3.5/posixpath.py:43    return            return '/'
                                               ...       return value: '/'
         /usr/lib/python3.5/posixpath.py:77    line          path = a
         /usr/lib/python3.5/posixpath.py:78    line          try:
         /usr/lib/python3.5/posixpath.py:79    line              if not p:
         /usr/lib/python3.5/posixpath.py:81    line              for b in p:
         /usr/lib/python3.5/posixpath.py:82    line                  if b.startswith(sep):
         /usr/lib/python3.5/posixpath.py:84    line                  elif not path or path.endswith(sep):
         /usr/lib/python3.5/posixpath.py:87    line                      path += sep + b
         /usr/lib/python3.5/posixpath.py:81    line              for b in p:
         /usr/lib/python3.5/posixpath.py:91    line          return path
         /usr/lib/python3.5/posixpath.py:91    return        return path
                                               ...       return value: 'a/b'
'a/b'
  • or in a terminal:

https://raw.githubusercontent.com/ionelmc/python-hunter/master/docs/simple-trace.png

Custom actions

The tracer allow custom actions like CallPrinter or VarsPrinter.

With CallPrinter (added in hunter 1.2.0, will be the default action in 2.0.2):

import hunter
hunter.trace(module='posixpath', action=hunter.CallPrinter)

import os
os.path.join('a', 'b')

Would result in:

>>> os.path.join('a', 'b')
         /usr/lib/python3.5/posixpath.py:71    call      => join(a='a')
         /usr/lib/python3.5/posixpath.py:76    line         sep = _get_sep(a)
         /usr/lib/python3.5/posixpath.py:39    call         => _get_sep(path='a')
         /usr/lib/python3.5/posixpath.py:40    line            if isinstance(path, bytes):
         /usr/lib/python3.5/posixpath.py:43    line            return '/'
         /usr/lib/python3.5/posixpath.py:43    return       <= _get_sep: '/'
         /usr/lib/python3.5/posixpath.py:77    line         path = a
         /usr/lib/python3.5/posixpath.py:78    line         try:
         /usr/lib/python3.5/posixpath.py:79    line         if not p:
         /usr/lib/python3.5/posixpath.py:81    line         for b in p:
         /usr/lib/python3.5/posixpath.py:82    line         if b.startswith(sep):
         /usr/lib/python3.5/posixpath.py:84    line         elif not path or path.endswith(sep):
         /usr/lib/python3.5/posixpath.py:87    line         path += sep + b
         /usr/lib/python3.5/posixpath.py:81    line         for b in p:
         /usr/lib/python3.5/posixpath.py:91    line         return path
         /usr/lib/python3.5/posixpath.py:91    return    <= join: 'a/b'
'a/b'

In a terminal it would look like:

https://raw.githubusercontent.com/ionelmc/python-hunter/master/docs/code-trace.png

With VarsPrinter:

import hunter
# note that this kind of invocation will also use the default `CodePrinter`
hunter.trace(hunter.Q(module='posixpath', action=hunter.VarsPrinter('path')))

import os
os.path.join('a', 'b')

Would result in:

>>> os.path.join('a', 'b')
         /usr/lib/python3.5/posixpath.py:71    call      def join(a, *p):
         /usr/lib/python3.5/posixpath.py:76    line          sep = _get_sep(a)
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:39    call      def _get_sep(path):
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:40    line          if isinstance(path, bytes):
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:43    line              return '/'
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:43    return            return '/'
                                               ...       return value: '/'
         /usr/lib/python3.5/posixpath.py:77    line          path = a
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:78    line          try:
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:79    line              if not p:
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:81    line              for b in p:
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:82    line                  if b.startswith(sep):
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:84    line                  elif not path or path.endswith(sep):
                                               vars      path => 'a'
         /usr/lib/python3.5/posixpath.py:87    line                      path += sep + b
                                               vars      path => 'a/b'
         /usr/lib/python3.5/posixpath.py:81    line              for b in p:
                                               vars      path => 'a/b'
         /usr/lib/python3.5/posixpath.py:91    line          return path
                                               vars      path => 'a/b'
         /usr/lib/python3.5/posixpath.py:91    return        return path
                                               ...       return value: 'a/b'
'a/b'

In a terminal it would look like:

https://raw.githubusercontent.com/ionelmc/python-hunter/master/docs/vars-trace.png

You can give it a tree-like configuration where you can optionally configure specific actions for parts of the tree (like dumping variables or a pdb set_trace):

from hunter import trace, Q, Debugger
from pdb import Pdb

trace(
    # drop into a Pdb session if ``foo.bar()`` is called
    Q(module="foo", function="bar", kind="call", action=Debugger(klass=Pdb))
    |  # or
    Q(
        # show code that contains "mumbo.jumbo" on the current line
        lambda event: event.locals.get("mumbo") == "jumbo",
        # and it's not in Python's stdlib
        stdlib=False,
        # and it contains "mumbo" on the current line
        source__contains="mumbo"
    )
)

import foo
foo.func()

With a foo.py like this:

def bar():
    execution_will_get_stopped  # cause we get a Pdb session here

def func():
    mumbo = 1
    mumbo = "jumbo"
    print("not shown in trace")
    print(mumbo)
    mumbo = 2
    print(mumbo) # not shown in trace
    bar()

We get:

>>> foo.func()
not shown in trace
    /home/ionel/osp/python-hunter/foo.py:8     line          print(mumbo)
jumbo
    /home/ionel/osp/python-hunter/foo.py:9     line          mumbo = 2
2
    /home/ionel/osp/python-hunter/foo.py:1     call      def bar():
> /home/ionel/osp/python-hunter/foo.py(2)bar()
-> execution_will_get_stopped  # cause we get a Pdb session here
(Pdb)

In a terminal it would look like:

https://raw.githubusercontent.com/ionelmc/python-hunter/master/docs/tree-trace.png

Tracing processes

In similar fashion to strace Hunter can trace other processes, eg:

hunter-trace --gdb -p 123

If you wanna play it safe (no messy GDB) then pip install 'hunter[remote]' and add this in your code:

from hunter import remote
remote.install()

Then you can do:

hunter-trace -p 123

See docs on the remote feature.

Note: Windows ain’t supported.

Environment variable activation

For your convenience environment variable activation is available. Just run your app like this:

PYTHONHUNTER="module='os.path'" python yourapp.py

On Windows you’d do something like:

set PYTHONHUNTER=module='os.path'
python yourapp.py

The activation works with a clever .pth file that checks for that env var presence and before your app runs does something like this:

from hunter import *
trace(<whatever-you-had-in-the-PYTHONHUNTER-env-var>)

Note that Hunter is activated even if the env var is empty, eg: PYTHONHUNTER="".

Filtering DSL

Hunter supports a flexible query DSL, see the introduction.

Development

To run the all tests run:

tox

FAQ

Why not Smiley?

There’s some obvious overlap with smiley but there are few fundamental differences:

  • Complexity. Smiley is simply over-engineered:

    • It uses IPC and a SQL database.

    • It has a webserver. Lots of dependencies.

    • It uses threads. Side-effects and subtle bugs are introduced in your code.

    • It records everything. Tries to dump any variable. Often fails and stops working.

    Why do you need all that just to debug some stuff in a terminal? Simply put, it’s a nice idea but the design choices work against you when you’re already neck-deep into debugging your own code. In my experience Smiley has been very buggy and unreliable. Your mileage may vary of course.

  • Tracing long running code. This will make Smiley record lots of data, making it unusable.

    Now because Smiley records everything, you’d think it’s better suited for short programs. But alas, if your program runs quickly then it’s pointless to record the execution. You can just run it again.

    It seems there’s only one situation where it’s reasonable to use Smiley: tracing io-bound apps remotely. Those apps don’t execute lots of code, they just wait on network so Smiley’s storage won’t blow out of proportion and tracing overhead might be acceptable.

  • Use-cases. It seems to me Smiley’s purpose is not really debugging code, but more of a “non interactive monitoring” tool.

In contrast, Hunter is very simple:

  • Few dependencies.

  • Low overhead (tracing/filtering code has an optional Cython extension).

  • No storage. This simplifies lots of things.

    The only cost is that you might need to run the code multiple times to get the filtering/actions right. This means Hunter is not really suited for “post-mortem” debugging. If you can’t reproduce the problem anymore then Hunter won’t be of much help.

Why not pytrace?

Pytrace is another tracer tool. It seems quite similar to Smiley - it uses a sqlite database for the events, threads and IPC.

TODO: Expand this.

Why (not) coverage?

For purposes of debugging coverage is a great tool but only as far as “debugging by looking at what code is (not) run”. Checking branch coverage is good but it will only get you as far.

From the other perspective, you’d be wondering if you could use Hunter to measure coverage-like things. You could do it but for that purpose Hunter is very “rough”: it has no builtin storage. You’d have to implement your own storage. You can do it but it wouldn’t give you any advantage over making your own tracer if you don’t need to “pre-filter” whatever you’re recording.

In other words, filtering events is the main selling point of Hunter - it’s fast (cython implementation) and the query API is flexible enough.

Changelog

2.0.2 (2017-11-24)

  • Fixed indentation in CallPrinter action (shoudln’t deindent on exception).

  • Fixed option filtering in Cython Query implementation (filtering on tracer was allowed by mistake).

  • Various fixes to docstrings and docs.

2.0.1 (2017-09-09)

  • Now Py_AddPendingCall is used instead of acquiring the GIL (when using GDB).

2.0.0 (2017-09-02)

  • Added the Event.count and Event.calls attributes.

  • Added the lt/lte/gt/gte lookups.

  • Added convenience aliases for startswith (sw), endswith (ew) and regex (rx).

  • Added a convenience hunter.wrap decorator to start tracing around a function.

  • Added support for remote tracing (with two backends: manhole and GDB) via the hunter-trace bin. Note: Windows is NOT SUPPORTED.

  • Changed the default action to CallPrinter. You’ll need to use action=CodePrinter if you want the old output.

1.4.1 (2016-09-24)

  • Fix support for getting sources for Cython module (it was broken on Windows and Python3.5+).

1.4.0 (2016-09-24)

  • Added support for tracing Cython modules (#30). A # cython: linetrace=True stanza or equivalent is required in Cython modules for this to work.

1.3.0 (2016-04-14)

  • Added Event.thread.

  • Added Event.threadid and Event.threadname (available for filtering with Q objects).

  • Added threading_support argument to hunter.trace: makes new threads be traced and changes action output to include threadname.

  • Added support for using pdb++ in the Debugger action.

  • Added support for using manhole via a new Manhole action.

  • Made the handler a public but readonly property of Tracer objects.

1.2.2 (2016-01-28)

  • Fix broken import. Require fields>=4.0.

  • Simplify a string check in Cython code.

1.2.1 (2016-01-27)

  • Fix “KeyError: ‘normal’” bug in CallPrinter. Create the NO_COLORS dict from the COLOR dicts. Some keys were missing.

1.2.0 (2016-01-24)

  • Fixed printouts of objects that return very large string in __repr__(). Trimmed to 512. Configurable in actions with the repr_limit option.

  • Improved validation of VarsPrinter’s initializer.

  • Added a CallPrinter action.

1.1.0 (2016-01-21)

  • Implemented a destructor (__dealloc__) for the Cython tracer.

  • Improved the restoring of the previous tracer in the Cython tracer (use PyEval_SetTrace) directly.

  • Removed tracer as an allowed filtering argument in hunter.Query.

  • Add basic validation (must be callable) for positional arguments and actions passed into hunter.Q. Closes #23.

  • Fixed stdlib checks (wasn’t very reliable). Closes #24.

1.0.2 (2016-01-05)

  • Fixed missing import in setup.py.

1.0.1 (2015-12-24)

  • Fix a compile issue with the MSVC compiler (seems it don’t like the inline option on the fast_When_call).

1.0.0 (2015-12-24)

  • Implemented fast tracer and query objects in Cython. MAY BE BACKWARDS INCOMPATIBLE

    To force using the old pure-python implementation set the PUREPYTHONHUNTER environment variable to non-empty value.

  • Added filtering operators: contains, startswith, endswith and in. Examples:

    • Q(module_startswith='foo' will match events from foo, foo.bar and foobar.

    • Q(module_startswith=['foo', 'bar'] will match events from foo, foo.bar, foobar, bar, bar.foo and baroo .

    • Q(module_endswith='bar' will match events from foo.bar and foobar.

    • Q(module_contains='ip' will match events from lipsum.

    • Q(module_in=['foo', 'bar'] will match events from foo and bar.

    • Q(module_regex=r"(re|sre.*)\b") will match events from ``re, re.foobar, srefoobar but not from repr.

  • Removed the merge option. Now when you call hunter.trace(...) multiple times only the last one is active. BACKWARDS INCOMPATIBLE

  • Remove the previous_tracer handling. Now when you call hunter.trace(...) the previous tracer (whatever was in sys.gettrace()) is disabled and restored when hunter.stop() is called. BACKWARDS INCOMPATIBLE

  • Fixed CodePrinter to show module name if it fails to get any sources.

0.6.0 (2015-10-10)

  • Added a clear_env_var option on the tracer (disables tracing in subprocess).

  • Added force_colors option on VarsPrinter and CodePrinter.

  • Allowed setting the stream to a file name (option on VarsPrinter and CodePrinter).

  • Bumped up the filename alignment to 40 cols.

  • If not merging then self is not kept as a previous tracer anymore. Closes #16.

  • Fixed handling in VarsPrinter: properly print eval errors and don’t try to show anything if there’s an AttributeError. Closes #18.

  • Added a stdlib boolean flag (for filtering purposes). Closes #15.

  • Fixed broken frames that have “None” for filename or module (so they can still be treated as strings).

  • Corrected output files in the install_lib command so that pip can uninstall the pth file. This only works when it’s installed with pip (sadly, setup.py install/develop and pip install -e will still leave pth garbage on pip uninstall hunter).

0.5.1 (2015-04-15)

  • Fixed Event.globals to actually be the dict of global vars (it was just the locals).

0.5.0 (2015-04-06)

  • Fixed And and Or “single argument unwrapping”.

  • Implemented predicate compression. Example: Or(Or(a, b), c) is converted to Or(a, b, c).

  • Renamed the Event.source to Event.fullsource.

  • Added Event.source that doesn’t do any fancy sourcecode tokenization.

  • Fixed Event.fullsource return value for situations where the tokenizer would fail.

  • Made the print function available in the PYTHONHUNTER env var payload.

  • Added a __repr__ for Event.

0.4.0 (2015-03-29)

  • Disabled colors for Jython (contributed by Claudiu Popa in #12).

  • Test suite fixes for Windows (contributed by Claudiu Popa in #11).

  • Added an introduction section in the docs.

  • Implemented a prettier fallback for when no sources are available for that frame.

  • Implemented fixups in cases where you use action classes as a predicates.

0.3.1 (2015-03-29)

  • Forgot to merge some commits …

0.3.0 (2015-03-29)

  • Added handling for internal repr failures.

  • Fixed issues with displaying code that has non-ascii characters.

  • Implemented better display for call frames so that when a function has decorators the function definition is shown (instead of just the first decorator). See: #8.

0.2.1 (2015-03-28)

  • Added missing color entry for exception events.

  • Added Event.line property. It returns the source code for the line being run.

0.2.0 (2015-03-27)

  • Added color support (and colorama as dependency).

  • Added support for expressions in VarsPrinter.

  • Breaking changes:

    • Renamed F to Q. And Q is now just a convenience wrapper for Query.

    • Renamed the PYTHON_HUNTER env variable to PYTHONHUNTER.

    • Changed When to take positional arguments.

    • Changed output to show 2 path components (still not configurable).

    • Changed VarsPrinter to take positional arguments for the names.

  • Improved error reporting for env variable activation (PYTHONHUNTER).

  • Fixed env var activator (the .pth file) installation with setup.py install (the “egg installs”) and setup.py develop/pip install -e (the “egg links”).

0.1.0 (2015-03-22)

  • First release on PyPI.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hunter-2.0.2.tar.gz (397.9 kB view details)

Uploaded Source

Built Distributions

hunter-2.0.2-cp36-cp36m-win_amd64.whl (400.4 kB view details)

Uploaded CPython 3.6m Windows x86-64

hunter-2.0.2-cp36-cp36m-win32.whl (372.3 kB view details)

Uploaded CPython 3.6m Windows x86

hunter-2.0.2-cp36-cp36m-manylinux1_x86_64.whl (956.2 kB view details)

Uploaded CPython 3.6m

hunter-2.0.2-cp36-cp36m-manylinux1_i686.whl (900.9 kB view details)

Uploaded CPython 3.6m

hunter-2.0.2-cp35-cp35m-win_amd64.whl (398.4 kB view details)

Uploaded CPython 3.5m Windows x86-64

hunter-2.0.2-cp35-cp35m-win32.whl (370.4 kB view details)

Uploaded CPython 3.5m Windows x86

hunter-2.0.2-cp35-cp35m-manylinux1_x86_64.whl (936.9 kB view details)

Uploaded CPython 3.5m

hunter-2.0.2-cp35-cp35m-manylinux1_i686.whl (875.3 kB view details)

Uploaded CPython 3.5m

hunter-2.0.2-cp34-cp34m-win_amd64.whl (392.6 kB view details)

Uploaded CPython 3.4m Windows x86-64

hunter-2.0.2-cp34-cp34m-win32.whl (370.7 kB view details)

Uploaded CPython 3.4m Windows x86

hunter-2.0.2-cp34-cp34m-manylinux1_x86_64.whl (966.7 kB view details)

Uploaded CPython 3.4m

hunter-2.0.2-cp34-cp34m-manylinux1_i686.whl (901.7 kB view details)

Uploaded CPython 3.4m

hunter-2.0.2-cp33-cp33m-win_amd64.whl (393.0 kB view details)

Uploaded CPython 3.3m Windows x86-64

hunter-2.0.2-cp33-cp33m-win32.whl (371.0 kB view details)

Uploaded CPython 3.3m Windows x86

hunter-2.0.2-cp33-cp33m-manylinux1_x86_64.whl (901.4 kB view details)

Uploaded CPython 3.3m

hunter-2.0.2-cp33-cp33m-manylinux1_i686.whl (838.0 kB view details)

Uploaded CPython 3.3m

hunter-2.0.2-cp27-cp27mu-manylinux1_x86_64.whl (859.8 kB view details)

Uploaded CPython 2.7mu

hunter-2.0.2-cp27-cp27mu-manylinux1_i686.whl (797.0 kB view details)

Uploaded CPython 2.7mu

hunter-2.0.2-cp27-cp27m-win_amd64.whl (398.7 kB view details)

Uploaded CPython 2.7m Windows x86-64

hunter-2.0.2-cp27-cp27m-win32.whl (370.1 kB view details)

Uploaded CPython 2.7m Windows x86

hunter-2.0.2-cp27-cp27m-manylinux1_x86_64.whl (859.8 kB view details)

Uploaded CPython 2.7m

hunter-2.0.2-cp27-cp27m-manylinux1_i686.whl (797.1 kB view details)

Uploaded CPython 2.7m

File details

Details for the file hunter-2.0.2.tar.gz.

File metadata

  • Download URL: hunter-2.0.2.tar.gz
  • Upload date:
  • Size: 397.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No

File hashes

Hashes for hunter-2.0.2.tar.gz
Algorithm Hash digest
SHA256 3cbe121d4f2bfddec7afc4fecf9c2591485436fae857ee22caf849a9ab25d419
MD5 0d611a816336b9f832e1be0e61bb5d96
BLAKE2b-256 a1b6f0418e7aaddf97b983a214f384586cc23111401b1b243e4c8bf9543e3581

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp36-cp36m-win_amd64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp36-cp36m-win_amd64.whl
Algorithm Hash digest
SHA256 8a81bebcabc9bdd7a9c0f88f32c8a8f225cb047a46a0c7c6e147d09b4077e744
MD5 ddd23c1a62b52c0d6a753023b4f81828
BLAKE2b-256 57824bcd5e603e9be3ba835d45604e31a0bc336d5714eed8abe494844ddc4db9

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp36-cp36m-win32.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp36-cp36m-win32.whl
Algorithm Hash digest
SHA256 4783726af2bed6d6920fd289b4302b25c4773761427f4db977967f5115211b67
MD5 8f0348597be6489d023e6ba4e0e26cae
BLAKE2b-256 0d16fa38a62c73a318287cadb03fa01c690eef594313918911f6f619f314922a

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp36-cp36m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp36-cp36m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 dfff23143a74be260c963b0ec5bbab753bdd1d20e9d7d3eb577517a1e6dcdc57
MD5 fd6e417ba43c12f24daa8d6c34b3ccd7
BLAKE2b-256 68fa66d255c38e41c8649e7de7053b23c6b9f9d04c469b0bf821f6a24ce5992b

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp36-cp36m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp36-cp36m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 2ec7e42223df17c92eb68b7fa5b16c5c47ed9667183c7e15c43283da4a8b9397
MD5 9d355d4d987660ff56b410a9f686d94d
BLAKE2b-256 a1829afe409dc4661627bfdb2ebfa84551a6567fc33b33b36a0e9f81a040cbaf

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp35-cp35m-win_amd64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp35-cp35m-win_amd64.whl
Algorithm Hash digest
SHA256 bca793144f569877b2c87aea98a5d25fb22616db38048ea9783ebd8a48a989b8
MD5 2a145857c407d3d9b9ae2030d8fb654f
BLAKE2b-256 cf7a0202bb1fc02904f0dd11c4fa10f07b89a2cce44cd04f159858a5a4c494ba

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp35-cp35m-win32.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp35-cp35m-win32.whl
Algorithm Hash digest
SHA256 f9e72075b9d2966261e1e72ceadc30ed3763e1d4ae08e817d1bbd66876d8a40e
MD5 236bad7125c6b6d67eee06f06b3ef628
BLAKE2b-256 0360ed5da8c34b938b04a41f508aabab1f9046b841e7ad6942ab4b3831f21a63

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp35-cp35m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp35-cp35m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 9efd92f22ecb6579d29b2dea005617bf620f459d2f641d9830c0da5af7e244c9
MD5 5fad0cb47a3d49a4c836291594480b09
BLAKE2b-256 1e3a039a2ee77907631b226179eaafa36d5355c688a3b7b6d56ca040bc7ccff0

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp35-cp35m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp35-cp35m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 4d264250822b831d3875e28eafc162cba757d6bd7ba37425365c7dbf3cc1a265
MD5 26d23f85d9fa4a9eb602bfb45e314c41
BLAKE2b-256 9a81a6ed8c1a6191d7baaa4f92c39e20bdc4fc73aa540f6c761380a7b9c4eb9a

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp34-cp34m-win_amd64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp34-cp34m-win_amd64.whl
Algorithm Hash digest
SHA256 5565c968990e8341e581f90a85a5b865e903e9fe139d324faa9f57e8067e032f
MD5 d80710cfc9df50f4a92bbc1203709add
BLAKE2b-256 fcd384c5e9f65c23acee58f41ec2ee4b4380dc353d62698492c333d8c6990b9c

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp34-cp34m-win32.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp34-cp34m-win32.whl
Algorithm Hash digest
SHA256 9adc6f026c61c635c068f7fd9956e81d8c7efb2e359202e0f057c1503d488528
MD5 8184b4df354dbb28d16aae5a4c07efe7
BLAKE2b-256 0c45e714721ef35b5842651c6606e5d17961a70b7bd4abaa2cde1ec821d8a52e

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp34-cp34m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp34-cp34m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 d62d1ee5164832961fc34c1f6301c7b818b06d593ed9e3eacc4f3c53d8ffd9da
MD5 2b54e97379e8fea806e21c8a0b8846c0
BLAKE2b-256 2f532a7b2b6f0056b4bd76e42258734609d595a90794bee286f24d4b8f5109d9

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp34-cp34m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp34-cp34m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 b8dec2bfc9d2f26f842dd708525f778d80a145c84d62c6881e9b5d015878065b
MD5 93ddaddbd5fb2266f4ba7999bd7de945
BLAKE2b-256 ba7b64b63701a866997c024d1944e2f820b2b63f636b83ea01550ded26722849

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp33-cp33m-win_amd64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp33-cp33m-win_amd64.whl
Algorithm Hash digest
SHA256 57f24e27408031a3b35df9acc036e99fb911fbe42a005e619938bcf033bead3d
MD5 6dd30769b3b016513f6fae7a70dcf1d3
BLAKE2b-256 5380f3fd658af5e2c2ce536d3992d2b56b9e1819776cd861b8e615c9dfd69a8d

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp33-cp33m-win32.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp33-cp33m-win32.whl
Algorithm Hash digest
SHA256 4152294d254f7db57cc35294adee71d4ee75d135d0fc787104158a5e54451bdc
MD5 8dc9f1b31520c8dcaa7abeaf829d12e4
BLAKE2b-256 42b4199313f261b04aa74d17e1320746ff3e773db20258fee237a9691491dd50

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp33-cp33m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp33-cp33m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 a9141d09f6a990556b98dae53f3cb764fa54717e5b1b7e5ccbc4408a06c88820
MD5 a1948f5c9cb417e90f795553e74a122a
BLAKE2b-256 e4db67e8dcad2f318fca644903b71f82100152e52c618b5c196269f96062bf1d

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp33-cp33m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp33-cp33m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 029043823f1b15afefeddf6dc5047ee946c9340cfd25d3266ab51033b069f849
MD5 3c2d37bcfccc24f61bf28dd0451fd9f9
BLAKE2b-256 4e35f03526151b7fdeb89059fce99a4bf5475fe18bd7e68536bcaab7c6dcb614

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp27-cp27mu-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp27-cp27mu-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 70cc596ec78318a45cbaf0a7fff65635468bf54e585b938306293070151e0e5b
MD5 fab960286b01ab885c388b109ad1336d
BLAKE2b-256 11fb7545af9aaecec0a8d4445f6962b0ddfdc3f43ab7ccde5057738962d5c8d0

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp27-cp27mu-manylinux1_i686.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp27-cp27mu-manylinux1_i686.whl
Algorithm Hash digest
SHA256 3b0805ef390047edea523c2ea03768609830e9a6ee8db90ed3ff962f7c84ce72
MD5 af15d1e5a91b0487333301a322d1dfd8
BLAKE2b-256 ee7bda13e958eafee21bddfed3f8a7d77cc839087254df06e269f9a12a0eaf6b

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp27-cp27m-win_amd64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp27-cp27m-win_amd64.whl
Algorithm Hash digest
SHA256 68217b017823bd9d02246bafb8f5359222fd55b2c1b060b663ab4ac0d1027f08
MD5 fbc9c3e62438ec78ef5f670b08cb0465
BLAKE2b-256 b4ad4edf0111985bbf3b9457a142b5dc72894907b042b7fb2bb30f1b14ee0e32

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp27-cp27m-win32.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp27-cp27m-win32.whl
Algorithm Hash digest
SHA256 7943a7543c6d07a11ec6a05df27501124127a0044d9dd2172a61e65331cb8b3a
MD5 8d5794ee174e0abd45db2801c4173134
BLAKE2b-256 50c153220660a7946624c4daa05da428b284d6066d4b1b4209189cfe60f647f6

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp27-cp27m-manylinux1_x86_64.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp27-cp27m-manylinux1_x86_64.whl
Algorithm Hash digest
SHA256 85c971d3a74477e57959f7c0cd3d050d7caad698f107e4b906aba4f0b71d1cfd
MD5 2cbc1698c5b3bfdaff57625da3eec9f3
BLAKE2b-256 72519af964099823265c554e5e215c5b73062d63f612367c85a37dd503172b75

See more details on using hashes here.

File details

Details for the file hunter-2.0.2-cp27-cp27m-manylinux1_i686.whl.

File metadata

File hashes

Hashes for hunter-2.0.2-cp27-cp27m-manylinux1_i686.whl
Algorithm Hash digest
SHA256 c34f140754f36806bd15e06f18a103451fefd91714a04cf6e621f8952fe308a6
MD5 18a4bdc890dd8935d0f40c752e819948
BLAKE2b-256 1ec9b53146a059e9fe86576f730cc5a4feb6a62d044072b6fa1ef59ed22197fa

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page