Hunter是一款灵活的代码跟踪工具包。
项目描述
Hunter是一款灵活的代码跟踪工具包,不是用于测量覆盖率,而是用于调试、记录、检查等。它有一个简单的Python API、一个方便的终端API和一个可以附加到进程的CLI工具。
免费软件:BSD 2-Clause许可协议
安装
pip install hunter
文档
入门
基本使用涉及将各种过滤器传递给“trace”选项。例如:
import hunter
hunter.trace(module='posixpath', action=hunter.CallPrinter)
import os
os.path.join('a', 'b')
这将导致
>>> os.path.join('a', 'b')
/usr/lib/python3.6/posixpath.py:75 call => join(a='a')
/usr/lib/python3.6/posixpath.py:80 line a = os.fspath(a)
/usr/lib/python3.6/posixpath.py:81 line sep = _get_sep(a)
/usr/lib/python3.6/posixpath.py:41 call => _get_sep(path='a')
/usr/lib/python3.6/posixpath.py:42 line if isinstance(path, bytes):
/usr/lib/python3.6/posixpath.py:45 line return '/'
/usr/lib/python3.6/posixpath.py:45 return <= _get_sep: '/'
/usr/lib/python3.6/posixpath.py:82 line path = a
/usr/lib/python3.6/posixpath.py:83 line try:
/usr/lib/python3.6/posixpath.py:84 line if not p:
/usr/lib/python3.6/posixpath.py:86 line for b in map(os.fspath, p):
/usr/lib/python3.6/posixpath.py:87 line if b.startswith(sep):
/usr/lib/python3.6/posixpath.py:89 line elif not path or path.endswith(sep):
/usr/lib/python3.6/posixpath.py:92 line path += sep + b
/usr/lib/python3.6/posixpath.py:86 line for b in map(os.fspath, p):
/usr/lib/python3.6/posixpath.py:96 line return path
/usr/lib/python3.6/posixpath.py:96 return <= join: 'a/b'
'a/b'
在终端中看起来像这样:
另一个有用的场景是忽略所有标准模块,并强制使用颜色,即使输出被重定向到文件,也会使颜色保持不变。
import hunter
hunter.trace(stdlib=False, action=hunter.CallPrinter(force_colors=True))
操作
可以使用“操作”来控制输出格式。有一个名为“CodePrinter”的替代操作,它不处理嵌套(在Hunter 2.0之前,这是默认操作)。
如果过滤器匹配,则将运行操作。示例
import hunter
hunter.trace(module='posixpath', action=hunter.CodePrinter)
import os
os.path.join('a', 'b')
这将导致
>>> os.path.join('a', 'b')
/usr/lib/python3.6/posixpath.py:75 call def join(a, *p):
/usr/lib/python3.6/posixpath.py:80 line a = os.fspath(a)
/usr/lib/python3.6/posixpath.py:81 line sep = _get_sep(a)
/usr/lib/python3.6/posixpath.py:41 call def _get_sep(path):
/usr/lib/python3.6/posixpath.py:42 line if isinstance(path, bytes):
/usr/lib/python3.6/posixpath.py:45 line return '/'
/usr/lib/python3.6/posixpath.py:45 return return '/'
... return value: '/'
/usr/lib/python3.6/posixpath.py:82 line path = a
/usr/lib/python3.6/posixpath.py:83 line try:
/usr/lib/python3.6/posixpath.py:84 line if not p:
/usr/lib/python3.6/posixpath.py:86 line for b in map(os.fspath, p):
/usr/lib/python3.6/posixpath.py:87 line if b.startswith(sep):
/usr/lib/python3.6/posixpath.py:89 line elif not path or path.endswith(sep):
/usr/lib/python3.6/posixpath.py:92 line path += sep + b
/usr/lib/python3.6/posixpath.py:86 line for b in map(os.fspath, p):
/usr/lib/python3.6/posixpath.py:96 line return path
/usr/lib/python3.6/posixpath.py:96 return return path
... return value: 'a/b'
'a/b'
或者在终端中
另一个有用的操作是 VarsPrinter
import hunter
# note that this kind of invocation will also use the default `CallPrinter` action
hunter.trace(hunter.Q(module='posixpath', action=hunter.VarsPrinter('path')))
import os
os.path.join('a', 'b')
这将导致
>>> os.path.join('a', 'b')
/usr/lib/python3.6/posixpath.py:75 call => join(a='a')
/usr/lib/python3.6/posixpath.py:80 line a = os.fspath(a)
/usr/lib/python3.6/posixpath.py:81 line sep = _get_sep(a)
/usr/lib/python3.6/posixpath.py:41 call [path => 'a']
/usr/lib/python3.6/posixpath.py:41 call => _get_sep(path='a')
/usr/lib/python3.6/posixpath.py:42 line [path => 'a']
/usr/lib/python3.6/posixpath.py:42 line if isinstance(path, bytes):
/usr/lib/python3.6/posixpath.py:45 line [path => 'a']
/usr/lib/python3.6/posixpath.py:45 line return '/'
/usr/lib/python3.6/posixpath.py:45 return [path => 'a']
/usr/lib/python3.6/posixpath.py:45 return <= _get_sep: '/'
/usr/lib/python3.6/posixpath.py:82 line path = a
/usr/lib/python3.6/posixpath.py:83 line [path => 'a']
/usr/lib/python3.6/posixpath.py:83 line try:
/usr/lib/python3.6/posixpath.py:84 line [path => 'a']
/usr/lib/python3.6/posixpath.py:84 line if not p:
/usr/lib/python3.6/posixpath.py:86 line [path => 'a']
/usr/lib/python3.6/posixpath.py:86 line for b in map(os.fspath, p):
/usr/lib/python3.6/posixpath.py:87 line [path => 'a']
/usr/lib/python3.6/posixpath.py:87 line if b.startswith(sep):
/usr/lib/python3.6/posixpath.py:89 line [path => 'a']
/usr/lib/python3.6/posixpath.py:89 line elif not path or path.endswith(sep):
/usr/lib/python3.6/posixpath.py:92 line [path => 'a']
/usr/lib/python3.6/posixpath.py:92 line path += sep + b
/usr/lib/python3.6/posixpath.py:86 line [path => 'a/b']
/usr/lib/python3.6/posixpath.py:86 line for b in map(os.fspath, p):
/usr/lib/python3.6/posixpath.py:96 line [path => 'a/b']
/usr/lib/python3.6/posixpath.py:96 line return path
/usr/lib/python3.6/posixpath.py:96 return [path => 'a/b']
/usr/lib/python3.6/posixpath.py:96 return <= join: 'a/b'
'a/b'
在终端中看起来像这样:
您可以给它一个树状配置,您可以为树的一部分(如变量转储或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()
具有类似于 foo.py 的配置
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()
我们得到
>>> 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)
在终端中看起来像这样:
跟踪进程
类似于 strace 的方式,Hunter 可以跟踪其他进程,例如
hunter-trace --gdb -p 123
如果您想确保安全(没有杂乱的 GDB),则在您的代码中添加以下内容
from hunter import remote remote.install()
然后您可以这样做
hunter-trace -p 123
请参阅有关远程功能的文档。
注意: Windows 不受支持。
环境变量激活
为了您的方便,提供了环境变量激活。只需像这样运行您的应用程序
PYTHONHUNTER="module='os.path'" python yourapp.py
在 Windows 上,您会这样做
set PYTHONHUNTER=module='os.path' python yourapp.py
激活使用一个聪明的 .pth 文件,该文件检查该环境变量的存在,并在您的应用程序运行之前执行类似以下操作
from hunter import * trace(<whatever-you-had-in-the-PYTHONHUNTER-env-var>)
请注意,即使环境变量为空,Hunter 也会激活,例如:PYTHONHUNTER=""。
环境变量配置
有时您总是使用相同的选项(如 stdlib=False 或 force_colors=True)。为了节省打字时间,您可以在环境中设置以下内容
PYTHONHUNTERCONFIG="stdlib=False,force_colors=True"
这相当于 PYTHONHUNTER="stdlib=False,action=CallPrinter(force_colors=True)"。
注意
仅设置 PYTHONHUNTERCONFIG 不会激活 hunter。
支持所有内置操作的选项。
虽然支持谓词,但这可能存在问题。以下是不会跟踪任何内容的设置示例
PYTHONHUNTERCONFIG="Q(module_startswith='django')" PYTHONHUNTER="Q(module_startswith='celery')"
相当于
PYTHONHUNTER="Q(module_startswith='django'),Q(module_startswith='celery')"
相当于
PYTHONHUNTER="Q(module_startswith='django')&Q(module_startswith='celery')"
过滤 DSL
Hunter 支持灵活的查询 DSL,请参阅 介绍。
开发
要运行所有测试,请执行
tox
设计说明
Hunter 并非万能。作为此库的设计目标,一些事情被故意设计得简洁且冗长(以避免复杂性、混淆和不一致性)。这有几个后果
有 运算符,但没有否定运算符。相反,您应该否定查询对象,例如:~Q(module='re')。
没有专门的运算符或过滤器 - 所有过滤器的行为完全相同。例如
没有针对包的过滤器。您应该使用运算符通过模块进行过滤。
没有针对参数、返回值或变量的过滤器。您应该编写自己的过滤函数并处理窥探对象的难题。
分层最少。有一些 辅助函数 进行一些参数处理和转换,以节省您的打字时间,但这就是全部。
库不试图隐藏 Python 中跟踪的机制 - 如果您使用 sys.settrace,则与 Python 发送到跟踪函数的内容一一对应。
没有存储。您应该将输出重定向到文件。
您应该将其视为帮助您理解和调试大型应用程序的工具,或是一个减轻您 settrace 繁琐部分的框架,而不是帮助您学习 Python 的工具。
常见问题解答
为什么不使用 Smiley?
与 Smiley 有一些明显的重叠,但也有一些根本性的区别
复杂性。Smiley 简直是过度设计
它使用 IPC 和 SQL 数据库。
它有一个 Web 服务器。有许多依赖项。
它使用线程。引入了副作用和微妙的错误。
它记录一切。尝试转储任何变量。经常失败并停止工作。
为什么你需要这么多东西来在终端中调试一些东西呢?简单来说,这确实是个好主意,但在你深陷自己的代码调试时,设计选择却对你不利。根据我的经验,Smiley非常容易出错且不可靠。当然,你的体验可能会有所不同。
跟踪长时间运行的代码。这将导致Smiley记录大量数据,使其无法使用。
由于Smiley记录了所有内容,你可能会认为它更适合短程序。但遗憾的是,如果你的程序运行得很快,记录执行过程就没有意义了。你可以直接再次运行它。
似乎只有一种情况下使用Smiley是合理的:远程跟踪I/O密集型应用程序。这些应用程序不会执行大量代码,只是等待网络,因此Smiley的存储不会过载,跟踪开销也可能可以接受。
用例。在我看来,Smiley的真正目的不是调试代码,而更像是一个“非交互式监控”工具。
相比之下,Hunter非常简单
依赖项很少。
开销低(跟踪/过滤代码有一个可选的Cython扩展)。
无存储。这简化了许多事情。
唯一的成本是可能需要多次运行代码才能正确设置过滤/操作。这意味着Hunter并不适合“事后”调试。如果你无法再次重现问题,Hunter就不会有多大帮助。
为什么不使用pytrace?
Pytrace是另一个跟踪工具。它似乎与Smiley非常相似——它使用sqlite数据库来存储事件、线程和IPC,因此可以合理地预期会遇到相同类型的问题。
为什么不使用PySnooper或snoop?
snoop是PySnooper的改进版本。两者更适合跟踪小程序或函数,因为输出更详细,不太适合跟踪大型应用程序,而Hunter提供了更灵活的设置、过滤能力、速度和简洁性。
为什么不使用覆盖率?
对于调试而言,coverage是一个伟大的工具,但它只适用于“通过查看代码是否(未)运行来调试”。检查分支覆盖率是好的,但它只能带你到这里。
从另一个角度来看,你可能想知道是否可以使用Hunter来测量类似覆盖率的东西。你可以做到,但为了这个目的,Hunter非常“粗糙”——它没有内置的存储。你可以自己实现存储,但如果你不需要“预过滤”你记录的内容,这不会给你带来任何优势,因为你不需要自己制作跟踪器。
换句话说,过滤事件是Hunter的主要卖点——它速度快(Cython实现),查询API足够灵活。
使用Hunter的项目
关于Hunter值得注意的使用情况(如果你构建了一个依赖于hunter的工具,请提交PR)
Crunch-io/diagnose - 一个运行时仪器库。
talwrii/huntrace - 一个替代的CLI(类似于ltrace)。
anki-code/xunter - 一个专为xonsh shell制作的性能分析工具。
更多使用该工具的项目请参阅https://github.com/ionelmc/python-hunter/network/dependents
变更日志
3.7.0 (2024-05-02)
删除对Python 3.7的支持。
升级linters和重构各种字符串格式化以及其他清理工作。
升级Cython到最新版本(3.0.10)。
Linux wheels现在应该回来了。
将文档主题切换到furo。
3.6.1 (2023-04-26)
添加了对Decimal对象的safe repr支持。
3.6.0 (2023-04-25)
为Python 3.11添加了C扩展支持。这可能会导致所有Python运行时最多10%的性能下降(取决于具体用例)。不幸的是,现在一些兼容层被用于获取帧详情。这是为了能够与Python 3.11兼容并提高未来的兼容性。
为ZoneInfo对象添加了安全的repr支持。
C扩展文件现在使用Cython 3.0b2预先构建。
用ruff替换了flake8/isort的pre-commit钩子。
禁用了可编辑的wheel(PEP-0662),因为它们不包括hunter.pth文件。可能会有一种方法来做这件事,但我还没有想出一个方法来在不非常脆弱的解决方案中定制setuptools的内部来修改< cite>editable_wheel命令。
3.5.1 (2022-09-27)
修复了在Ctrl-C时
中断的破坏性。
3.5.0 (2022-09-11)
在
装饰器中添加了对生成器和协程的支持。 不再支持Python 3.6。
3.4.3 (2021-12-15)
删除了大部分Python 2支持代码。
修复了setup.py中的某些重构回归,并使3.4.x系列只能在Python 3.6及以后的版本上安装。
撤回了3.4.0、3.4.1、3.4.2版本,以避免在Python 2.7上安装时出现问题。
3.4.2 (2021-12-15)
修复了CI以正确生成win32 wheel。
3.4.1 (2021-12-14)
添加了对构建pp37.pp38标签的wheel的支持(基本上是一个仅适用于这两个PyPy版本的通用wheel)。
3.4.0 (2021-12-14)
将CI切换到GitHub Actions,这有几个后果
不再支持Python 2.7。您仍然可以安装它,但不再进行测试,并且Python 2特定的处理将在某个时候被删除。
Linux wheel现在提供在musllinux和manylinux2014变体中。
在PyPy上完全跳过了扩展构建。
为PyPy提供了一个纯标签为平台特定wheel(为了在这些平台上快速安装)。
3.3.8 (2021-06-23)
修复了CI问题,该问题会发布两次相同类型的wheel。
3.3.7 (2021-06-23)
修复了在Windows(至少)上检测stdlib时的一个bug。
3.3.6 (2021-06-23)
修复了3.3.4中的回归:stdlib过滤器已损坏。
改进了.pth文件(PYTHONHUNTER环境变量激活)以使用干净的eval环境。不再提供诸如line(来自site.py机制)之类的虚假变量。
修复了VarsSnooper中的一个bug,该bug会在发出双return事件的罕见情况下使其失败。
3.3.5 (2021-06-11)
添加了对Python 3.10的支持。
在safe_repr中添加了对时间对象和fold选项的支持。
跳过了3.3.4版本,因为我搞砸了CI。
3.3.3 (2021-05-04)
修复了在停止后tracer仍然对其他线程活跃的问题。
不幸的是,Python只允许移除当前线程的跟踪函数 - 现在hunter.tracer.Tracer如果被标记为已停止,将自行卸载。
这修复了在使用ipdb和hunter.actions.Debugger操作同时启用线程支持(默认)时出现的虚假错误。
3.3.2 (2021-03-25)
将CI更改为构建Python 3.9 wheel。Python 3.5不再进行测试,并且不再构建wheel,以保持简单。
改进了文档。
3.3.1 (2020-10-24)
修复了CI/test问题,这些问题阻止了所有21个wheel的发布。
3.3.0 (2020-10-23)
修复了处理,以便hunter.event.Event.module始终是"?"字符串,而不是None。以前,在跟踪特别糟糕的代码时它是None,这破坏了各种断言。
同样地,如果不可用文件名,hunter.event.Event.filename 现在为 "?"。
基于之前的变化,动作代码现在用于显示缺失的模块/文件名更为简洁。
修改了 hunter.actions.CallPrinter,使得内置函数的跟踪事件显示不同。这些事件在使用配置模式(例如:trace(profile=True))时出现。
修复了如果 hunter.event.Event.module 是 Unicode 字符串时可能出现的失败。现在它始终是常规字符串。仅适用于 Python 2。
修复了在跟踪具有元组参数的函数时参数显示的问题。关闭了 #88。仅适用于 Python 2。
当发生内部错误时,改进了错误报告。现在记录了触发事件的某些详细信息。
3.2.2 (2020-09-04)
修复了 hunter.event.Event.builtin 中的值问题。现在它始终是布尔值,并且可以在过滤器中一致使用(例如:builtin=True,function='getattr')。
3.2.1 (2020-08-18)
在 safe_repr 中添加了对正则表达式、日期和日期时间的支持。
修复了在 hunter.actions.CallPrinter 中使用位置和关键字参数时调用参数显示的问题。
3.2.0 (2020-08-16)
实现了 hunter.actions.StackPrinter 动作。
实现了 hunter.predicates.Backlog 断言。由 Dan Ailenei 贡献,在 #81。
在文档中略微改进了贡献部分。由 Tom Schraitle 贡献,在 #85。
通过避免在 hunter.predicates.Backlog 的 Cython 实现中进行大量的不必要的 PyObject_GetAttr 调用来提高过滤性能。
实现了 hunter.actions.ErrorSnooper 动作。
添加了对配置模式(例如:trace(profile=True))的支持。此模式将使用 setprofile 而不是 settrace。
添加了 ARM64 轮和 CI。
添加了 hunter.event.Event.instruction 和 hunter.event.Event.builtin(在配置模式下可用)。
添加了更多的食谱条目。
3.1.3 (2020-02-02)
再次改进了 stdlib 检查,以更好地处理某些路径。
3.1.2 (2019-01-19)
真正修复了 <frozen importlib.something stdlib 检查。
3.1.1 (2019-01-19)
将所有 <frozen importlib.something 文件标记为 stdlib 的一部分。
3.1.0 (2019-01-19)
添加了 hunter.actions.ErrorSnooper - 一种检测静默异常的动作。
添加了 hunter.load_config 并修复了从 PYTHONHUNTERCONFIG 环境变量加载配置过晚的问题。
修改了 hunter.From 辅助函数,使其自动将 depth 和 calls 过滤器移动到断言(这样它们在 hunter.predicates.From 激活后进行过滤)。
修改了 hunter.predicates.From,使其向断言传递事件的副本。该副本将调整 depth 和 calls 属性,以适应 hunter.predicates.From 激活的点。
修复了在使用断言时使用 & 和 | 运算符时的一堆不一致性和错误。
修复了 detached events <hunter.event.Event.detach>(hunter.event.Event.function_object 和 hunter.event.Event.arg)上的许多损坏字段。
改进了各种文档字符串,并添加了一个配置文档部分。
改进了测试(更多覆盖率)。
3.0.5 (2019-12-06)
真正修复了 safe_repr 以避免副作用(现在避免了 isinstance/issubclass,它们可能导致代码在特殊属性/方法中使用描述符时产生副作用)。
3.0.4 (2019-10-26)
真正修复了操作中的 stream 设置(在没有任何 stream 的情况下使用 force_colors 是错误的)。参见:hunter.actions.ColorStreamAction。
修复了 hunter.predicates.From 断言的 __repr__,使其包括 watermark。
为 Python 3.8 添加了二进制轮。
3.0.3 (2019-10-13)
在 pypy 上修复了 safe_repr,使其在方法对象上更安全。参见:hunter.actions.ColorStreamAction。
3.0.2 (2019-10-10)
修复了从 PYTHONHUNTERCONFIG 环境变量设置 stream 的问题。参见:hunter.actions.ColorStreamAction。
修复了一些文档的小问题。
3.0.1 (2019-06-17)
修复了颜色缺失源消息的问题(颜色泄露到下一行)。
3.0.0 (2019-06-17)
该软件包现在使用 setuptools-scm 进行开发构建(可在 https://test.pypi.org/project/hunter/ 获取)。因此,安装 sdist 将会下载 setuptools-scm。
使用最新的 Cython 重新编译了 cython 模块。Hunter 可以像以前一样安装而无需 Cython。
重构了一些 cython 模块,以包含更多类型信息并避免使用已弃用的属性语法。
将 unsafe_repr 选项替换为 repr_func。现在您可以在内置操作中使用自己的自定义 repr 函数。向后不兼容
修复了在 ipython/jupyter 中使用 Hunter 时的错误文件名处理。现在应该可以正确显示源代码。
从 VarsPrinter 操作中移除了 globals 选项。现在始终会查找全局变量。向后不兼容
在 VarsPrinter 操作中添加了对 locals 的支持。现在您可以这样做 VarsPrinter('len(foobar)')。
始终传递模块全局字典给 linecache 方法。现在从 PEP-302 载入器中提取的源代码可以正确打印。由 Mikhail Borisov 在 #65 贡献。
进行了各种代码清理、样式和文档字符串修复。
添加了 hunter.From 辅助函数,允许直接作为关键字参数传递过滤器。
添加了 hunter.event.Event.detach,以存储事件而不会泄漏或产生副作用(由于对 Frame 对象、局部或全局变量的长期引用)。
重构了操作内部,以简化子类化。
向 hunter.actions.ColorStreamAction 基类添加了 hunter.actions.ColorStreamAction.filename_prefix、hunter.actions.ColorStreamAction.output、hunter.actions.ColorStreamAction.pid_prefix、hunter.actions.ColorStreamAction.thread_prefix、hunter.actions.ColorStreamAction.try_repr 和 hunter.actions.ColorStreamAction.try_source 方法。
添加了 hunter.actions.VarsSnooper - 这是 PySnooper 启发的 hunter.actions.VarsPrinter 变体。它将记录并显示变量更改,当然,有泄漏或使用过多内存的风险:)
修复了 tracers,以记录错误并在内部失败时自动停止。以前在某些情况下可能错误地静默地丢弃了错误。
2.2.1 (2019-01-19)
修复了更改日志中的链接。
修复了 Travis 配置中的一些问题。
2.2.0 (2019-01-19)
添加了 hunter.predicates.From 断言,用于从特定点进行跟踪。它在返回到相同的调用深度并具有可配置偏移量后停止。
修复了在某些情况下 PYTHONHUNTERCONFIG 不工作的问题(配置值在错误的时间被解析)。
在CI测试中对即将发布到PyPI的轮进行了测试(tox-wheel)。
增强了event.stdlib的可靠性:将pkg_resources视为标准库的一部分,并将更多路径视为标准库。
降低了使用hunter-trace CLI(通过hunter.remote.install())附加时进行的get_peercred检查的难度。这会稍微降低安全性,但可以在OSX上工作。
在Travis测试网格中添加了OSX。
2.1.0 (2018-11-17)
默认启用threading_support,但输出自动(此外,现在允许使用1或0)。
添加了显示pid前缀的pid_alignment和force_pid操作选项。
修复了各种类中关于__eq__的一些错误。
停止支持Python 3.3。
删除了对fields的依赖。
操作现在使用简化的实现来表示,该实现试图避免在跟踪时调用用户类的__repr__,以避免创建副作用。
添加了对PYTHONHUNTERCONFIG环境变量的支持(存储默认值并不激活hunter)。
2.0.2 (2017-11-24)
修复了hunter.actions.CallPrinter操作中的缩进问题(在异常时不应该缩进)。
修复了Cython查询实现中的选项过滤(错误地允许对tracer进行过滤)。
修复了文档字符串和文档的多个问题。
2.0.1 (2017-09-09)
现在使用Py_AddPendingCall代替获取GIL(当使用GDB时)。
2.0.0 (2017-09-02)
添加了hunter.event.Event.count和hunter.event.Event.calls属性。
添加了lt/lte/gt/gte查找。
为startswith(sw)、endswith(ew)、contains(has)和regex(rx)添加了便利别名。
添加了一个便利的hunter.wrap装饰器,用于在函数周围开始跟踪。
通过hunter-trace二进制文件添加了对远程跟踪的支持(使用两个后端:manhole和GDB)。注意:**Windows不支持**。
将默认操作更改为hunter.actions.CallPrinter。如果您想使用旧输出,则需要使用action=CodePrinter。
1.4.1 (2016-09-24)
修复了对Cython模块获取源的支持(在Windows和Python3.5+上已损坏)。
1.4.0 (2016-09-24)
添加了对跟踪Cython模块的支持(#30)。Cython模块需要包含# cython: linetrace=True或等效语句才能正常工作。
1.3.0 (2016-04-14)
添加了hunter.event.Event.thread。
添加了hunter.event.Event.threadid和hunter.event.Event.threadname(可用于通过hunter.Q进行过滤)。
将hunter.event.Event.threading_support参数添加到hunter.trace。它使新线程被跟踪,并将操作输出更改为包括线程名称。
在hunter.actions.Debugger操作中添加了对使用pdb++的支持。
通过新的hunter.actions.Manhole操作添加了对使用manhole的支持。
将hunter.event.Event.handler作为一个公共但只读属性。
1.2.2 (2016-01-28)
修复了损坏的导入。需要fields>=4.0。
简化了Cython代码中的字符串检查。
1.2.1 (2016-01-27)
修复 hunter.actions.CallPrinter 中的 “KeyError: ‘normal’” 错误。从 COLOR 字典创建 NO_COLORS 字典。一些键缺失。
1.2.0 (2016-01-24)
修复了返回非常长字符串的对象的打印输出(在 __repr__() 中)。已截断为 512 字节。可以通过 repr_limit 选项在 actions 中配置。
改进了 hunter.actions.VarsPrinter 的初始化验证。
添加了 hunter.actions.CallPrinter 动作。
1.1.0 (2016-01-21)
1.0.2 (2016-01-05)
修复了 setup.py 中的缺失导入。
1.0.1 (2015-12-24)
修复了与 MSVC 编译器的编译问题(似乎它不喜欢 fast_When_call 上的内联选项)。
1.0.0 (2015-12-24)
在 Cython 中实现了快速跟踪器和查询对象。**可能不向后兼容**
要强制使用旧的纯 Python 实现,请将 PUREPYTHONHUNTER 环境变量设置为非空值。
添加了过滤运算符:contains、startswith、endswith 和 in。示例
Q(module_startswith='foo' 将匹配来自 foo、foo.bar 和 foobar 的事件。
Q(module_startswith=['foo', 'bar'] 将匹配来自 foo、foo.bar、foobar、bar、bar.foo 和 baroo 的事件。
Q(module_endswith='bar' 将匹配来自 foo.bar 和 foobar 的事件。
Q(module_contains='ip' 将匹配来自 lipsum 的事件。
Q(module_in=['foo', 'bar'] 将匹配来自 foo 和 bar 的事件。
Q(module_regex=r"(re|sre.*)\b") 将匹配来自 re、re.foobar 和 srefoobar 的事件,但不匹配来自 repr 的事件。
移除了 merge 选项。现在,当多次调用 hunter.trace(...) 时,只有最后一个有效。**可能不向后兼容**
移除了 previous_tracer 的处理。现在,当调用 hunter.trace(...) 时,将禁用先前的跟踪器(sys.gettrace() 中的任何内容),并在调用 hunter.stop() 时恢复。**可能不向后兼容**
修复了 CodePrinter 以在无法获取任何源时显示模块名称。
0.6.0 (2015-10-10)
在跟踪器上添加了 clear_env_var 选项(在子进程中禁用跟踪)。
在 hunter.actions.VarsPrinter 和 hunter.actions.CodePrinter 上添加了 force_colors 选项。
允许将 stream 设置为文件名(在 hunter.actions.VarsPrinter 和 hunter.actions.CodePrinter 上有选项)。
将文件名对齐增加到 40 列。
如果不合并,则self不再作为之前的追踪器保留。解决了#16。
修复了VarsPrinter的处理方式:正确打印eval错误,并在发生AttributeError时不要尝试显示任何内容。解决了#18。
添加了一个stdlib布尔标志(用于过滤目的)。解决了#15。
修复了文件名或模块为“None”的损坏帧(这样它们仍然可以被视为字符串)。
修复了install_lib命令的输出文件,以便pip可以卸载.pth文件。这仅在用pip安装时有效(遗憾的是,setup.py install/develop和pip install -e仍然会在pip卸载hunter时留下.pth垃圾)。
0.5.1 (2015-04-15)
修复了
,使其实际上是全局变量的dict(它只是局部变量)。
0.5.0 (2015-04-06)
修复了
和 的“单参数解包”。 实现了谓词压缩。例如:Or(Or(a, b), c)被转换为Or(a, b, c)。
将
重命名为 。 添加了一个
,它不进行任何花哨的源代码标记。 修复了tokenizer失败情况下的
返回值。 在PYTHONHUNTER环境变量有效负载中提供了打印函数。
为
添加了__repr__。
0.4.0 (2015-03-29)
0.3.1 (2015-03-29)
忘记合并一些提交……
0.3.0 (2015-03-29)
添加了对内部repr失败的处理。
修复了显示非ascii字符代码的问题。
实现了对调用帧的更好显示,以便当函数有装饰器时显示函数定义(而不仅仅是第一个装饰器)。参见:#8。
0.2.1 (2015-03-28)
为异常事件添加了缺少的颜色条目。
添加了
属性。它返回正在运行的源代码的行。
0.2.0 (2015-03-27)
添加了颜色支持(以及colorama作为依赖项)。
为
添加了对表达式的支持。 破坏性更改
将
重命名为 。现在 只是 的便利包装。 将PYTHON_HUNTER环境变量重命名为PYTHONHUNTER。
将
更改为接受位置参数。 将输出更改为显示2个路径组件(仍然不可配置)。
将
更改为接受名称的位置参数。
改进了环境变量激活的错误报告(PYTHONHUNTER)。
修复了使用setup.py install(“egg安装”)和setup.py develop/pip install -e(“egg链接”)安装环境变量激活器(.pth文件)。
0.1.0 (2015-03-22)
在PyPI上的第一次发布。
项目详细信息
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解有关 安装包 的更多信息。
源代码分发
构建分发
hunter-3.7.0.tar.gz 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 16f4fb4dbde366bac61ebf235bc4d075bfd8748009c8a4e0327d2fbca6f611d6 |
|
MD5 | 61c0c6f0ae46b6de1c385b3b7b36c345 |
|
BLAKE2b-256 | 8f92f21e6066609232e5fa564b98ece34eaab70caee2e854ea1b45776a33edcb |
hunter-3.7.0-pp310.pp38.pp39-none-any.whl 的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | b9955013d2e8eb4d0472823153086cba7c36f894ea3acab43aface1d9d27444c |
|
MD5 | 57b8ff39889a8536454ee1b06aa2855b |
|
BLAKE2b-256 | 13238549752fc57eff4b1ae113703b4d7943180b0aedb9d3513126b3605ca03f |
哈希值 for hunter-3.7.0-cp312-cp312-musllinux_1_1_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | fa34b19b00be465054f1001158e6ac89511ce7b3bb40f8e7bc56a9ae18184c5b |
|
MD5 | c0a1cffbce7204c26c2eaf6b19d74d34 |
|
BLAKE2b-256 | e2f6b2a0b707ce4c03a16ead5d200bf430d50e0eb4120622b2bda02f6e963e12 |
哈希值 for hunter-3.7.0-cp312-cp312-musllinux_1_1_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 161bc2b522449696d06943c0fdc61219c15f8a407d4f06ddfc71689e43a77d80 |
|
MD5 | 1402907971219e37b7154773f5672b7e |
|
BLAKE2b-256 | 9050674d31e1ee47eec0ef78ccb57b8327b12cc23dcb158e080c1f5490c0372c |
哈希值 for hunter-3.7.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | ab774df3dcf99c1b933afe91c1d5ed7e9bfa53826bd88c7b37cd0650db9e4ce9 |
|
MD5 | fc449795cfcd9c4f4e1752d352a2a0a9 |
|
BLAKE2b-256 | ccc544aac92dbc04c6cad054558676c87745a4117a71d510863943c82def6885 |
哈希值 for hunter-3.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e8948f11a0dfb3d19112cf67539d9ade7517ea22c5b3471b0566c7d62075f090 |
|
MD5 | 8a861d616091075f76486d97a3ffe33a |
|
BLAKE2b-256 | 6a7e2b45e6cfbd198a568342695515b9c31e780e27d3c73691e73ad5f87b709a |
哈希值 for hunter-3.7.0-cp312-cp312-macosx_11_0_arm64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | c5aebe6d72749d509a2001ebf4bc6cba2a6bafb7dd645b8a6a027dcc2c966465 |
|
MD5 | 3888858d6229337eb921cee391cfb267 |
|
BLAKE2b-256 | 43d720c368f004ae0701fe713c5560a6e917357f1fa4f54aa15dee858e273101 |
哈希值 for hunter-3.7.0-cp311-cp311-musllinux_1_1_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 1fe660d266547f85644bce8230e714e6984bfaa94e8513d77c8c8b5562aeefae |
|
MD5 | 71fe753358604d26839b21a70141bed8 |
|
BLAKE2b-256 | 73d56015311386c1776d0866abd206e2d718b1718009c0fd90b8f848e00815f3 |
哈希值 for hunter-3.7.0-cp311-cp311-musllinux_1_1_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 403a54ba425dda94cb00ebc47c71a2e7c8e8c2e4188dc9b1b6848ce2e13059d0 |
|
MD5 | b12c967eabbdc1c44e246c688283b16b |
|
BLAKE2b-256 | 3ec46378617564856d629a88bd5a9c984497f53fe01af0e9ff38bd838fd1aa3d |
哈希值 for hunter-3.7.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e3b94da39b1881492cfda6f4630c27815c17823078ddefb9dfaf3d79d0c7ee89 |
|
MD5 | e63b8bb9f4316ea25a858be2969e6047 |
|
BLAKE2b-256 | 9b142644682b1584559b51615d539763c565c029fd46cdcceb93ced14e07775a |
哈希值 for hunter-3.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 1c3516266c3dceae92636c7f21808f0ca2cd571d368bff79da57c7fb505398f5 |
|
MD5 | 3891ad1123de5ebf4cf3806c1ad3c3ea |
|
BLAKE2b-256 | 747f9499b1e3b533f323ec61b4af566efe8ea27d665b6dfabb24e7c7ef346615 |
哈希值 用于 hunter-3.7.0-cp311-cp311-macosx_11_0_arm64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 94efe2df941a6186e0aa7fc0b87df6686d9455ac77fc48f67a0d10237397591f |
|
MD5 | 60aa488c7d47cf6e3a48ec2b168c6850 |
|
BLAKE2b-256 | ba1cee08e1a9fe5715e435c468a841f632a63b67553bc7a4c51c25fc100d186c |
哈希值 用于 hunter-3.7.0-cp310-cp310-musllinux_1_1_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 5c1c28456cf4f04a3aeee0a7b5807d1aec0ac25806252421948b5db6daffd522 |
|
MD5 | 78a8b439c591b0bd745b060fa2bb8a88 |
|
BLAKE2b-256 | 38f9b31b69d369cbc678124a939f59842a3ad1ec097dcdbd6070fa067de16fa7 |
哈希值 用于 hunter-3.7.0-cp310-cp310-musllinux_1_1_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2d44d0d47e7c37b0e9790fa8141f3cbdc4208a5562b26ba05efb956f2681e0ed |
|
MD5 | ecd15be6cc07392888bf45b5aa708726 |
|
BLAKE2b-256 | 3706b68e84e4f6fa05947f7a93facf5c68955cb6fa4dafa35a25ad02a3af5899 |
哈希值 用于 hunter-3.7.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 76bb34aafc609e711d436f70bc29a7ebcd9179c0ef827c7ba96da2d4c91bc4a3 |
|
MD5 | 4cf70904ba4a98d3604241b0f51b1a98 |
|
BLAKE2b-256 | 366c9d9a742bb4d78a74e9e2f1c7c579e839a5d71e9369c7fe342055fcade455 |
哈希值 用于 hunter-3.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 7bf1a6eeed9c3d1d87cc436d8be099626416e2ca0ca487100b7ada5e48e7ae72 |
|
MD5 | 6b74ed8c427d724342df9cb5832adbba |
|
BLAKE2b-256 | 84ec3bc2477a7d8b22bf40b99bea303cf5b585f9da21ab43bc34b1f2b4d5b969 |
哈希值 用于 hunter-3.7.0-cp310-cp310-macosx_11_0_arm64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 0107fef8c95aa9574f42f2c6e4de97dc205f18dbc81c1789f1eedf2cb28da21a |
|
MD5 | a1472faf999fdb9876d5fd3568c192fa |
|
BLAKE2b-256 | a1a1232a39e9ca8afd597509046f27f6460f17078bf54aea86197ff2d7631e73 |
哈希值 用于 hunter-3.7.0-cp39-cp39-musllinux_1_1_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 49b0da542802a5c873f9e6a7ec95c52428e3565e1922386f5df0e20b907f47d9 |
|
MD5 | d1b4de8a3d129b06d4b1ac845c839d36 |
|
BLAKE2b-256 | 309543e74b75e8b0671ca6c76a62e5eb1ed917c64b085f4d217093bae771c4d3 |
哈希值 用于 hunter-3.7.0-cp39-cp39-musllinux_1_1_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | b97bf277f4471f9061d7c6f9c23ce66f5132fb98374d5ee28f55310eecd5fe1f |
|
MD5 | 6cfeaeac8ddb64b647d1e2df0abef934 |
|
BLAKE2b-256 | ee5e81899db03bbca74cb989685571f59ca85955e0d80616b53106ae178bb467 |
哈希值 用于 hunter-3.7.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 57e0895d1b1b7ad57204ec484c08cb720d5a2fcbe7c4f8f05add05c0dc1527eb |
|
MD5 | 726b44a083244bd9540f564530f229f9 |
|
BLAKE2b-256 | dcfcab11568de8ed772dbd395452b340a0c7c92ea1d8d7b741e74a956a023abf |
哈希值 用于 hunter-3.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 0de84cbf88b6f57ce573cd46f64493cb3e0739e689a8895d932cbcb631691d9b |
|
MD5 | cd42feedd556a1ee84cb438c8a069b23 |
|
BLAKE2b-256 | 575cfb632014859fb3d5bdd73e33592c8b4f701a5392f87ba6488479d41bbe92 |
哈希值 用于 hunter-3.7.0-cp38-cp38-musllinux_1_1_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 6602b5d90a0cd2ff8feac470a78c412bed79226608afb0ff6d416b7008a47ae0 |
|
MD5 | 4f026c7a48bbe90c27564503372863ca |
|
BLAKE2b-256 | 867772a79a98c5d9e7fad27787fc69cc18ca42d0aa2d0e251006173ba97402af |
哈希值 用于 hunter-3.7.0-cp38-cp38-musllinux_1_1_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 7f3a5d81d665bf986ca557817006cbe85b5a89d08ec7fe795c1c1ad0d254868b |
|
MD5 | 4b0f67bbcc2488eec9295ba3c2b34d01 |
|
BLAKE2b-256 | 9524340afcf8cbeb6325469394521761e7b4f6359be8cc44b937a81ff96a5831 |
哈希值 用于 hunter-3.7.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e795e8de62f3132d52b655033e444a17e4179d902f91fd4d5ba8936452b23a57 |
|
MD5 | 9061cae47856ac090ed05001ec05b9e0 |
|
BLAKE2b-256 | e4cb02f74d95f64be2c4e584f38e8b5fb8aeb915af1b98e439b19f95b4e06857 |
哈希值 用于 hunter-3.7.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 5473821bd45973443ca6053b9fd64bf62bff78914b25f8c6d9460c0ffdbdc956 |
|
MD5 | c26ca188d95212b5c8ac7ebd6023fa73 |
|
BLAKE2b-256 | a525874f01ac6f5333c12c96e03ba2c97e7626f39facbd0bb6cd237095af04ca |