检测 __getattribute__ 调用是否是由于 hasattr

2023-12-04

我正在重新实施__getattribute__为了一堂课。

我想注意到提供属性的任何不正确(当然意味着失败是预料之中的)失败(因为__getattribute__实施结果相当复杂)。为此,如果我的代码在引发之前无法找到/提供该属性,我会记录一条警告AttributeError.

我意识到:

  1. __getattribute__鼓励实现尽可能小、尽可能简单。
  2. 这被认为是错误的__getattribute__根据调用方式/原因,实现的行为会有所不同。
  3. 访问属性的代码也可以try/except而不是使用hasattr.

TL;DR:不过,我想检测是否调用__getattribute__是由于hasattr(相对于访问该属性的“真正”尝试)。


即使通过堆栈检查,这是不可能的。hasattr在 Python 调用堆栈中不生成任何帧对象,因为它是用 C 编写的,并尝试检查最后一个 Python 帧以猜测它是否挂在一个中间hasattr调用很容易出现各种误报和误报。

如果你绝对决心无论如何都要尽力而为,我能想到的最可靠(但仍然脆弱)的拼凑就是猴子补丁builtins.hasattr与一个Python函数does生成一个 Python 堆栈框架:

import builtins
import inspect
import types

_builtin_hasattr = builtins.hasattr
if not isinstance(_builtin_hasattr, types.BuiltinFunctionType):
    raise Exception('hasattr already patched by someone else!')

def hasattr(obj, name):
    return _builtin_hasattr(obj, name)

builtins.hasattr = hasattr

def probably_called_from_hasattr():
    # Caller's caller's frame.
    frame = inspect.currentframe().f_back.f_back
    return frame.f_code is hasattr.__code__

Calling probably_called_from_hasattr inside __getattribute__然后将测试您的__getattribute__可能是从hasattr。这避免了假设调用代码使用名称“hasattr”,或者名称“hasattr”的使用对应于这个特定的情况。__getattribute__打电话,或者说hasattr调用源自 Python 级代码而不是 C。

这里脆弱性的主要来源是如果有人保存了对真实的引用hasattr在猴子补丁通过之前,或者如果其他猴子补丁通过hasattr(例如,如果有人将此代码复制粘贴到同一程序中的另一个文件中)。这isinstance检查尝试捕获其他人猴子修补的大多数情况hasattr摆在我们面前,但它并不完美。

另外,如果hasattr在用 C 编写的对象上触发对您的对象的属性访问,这看起来像您的__getattribute__被叫自hasattr。这是最有可能出现误报的方法;上一段中的所有内容都会给出假阴性。您可以通过检查条目来防止这种情况obj in the hasattr框架的f_locals是它应该是的对象。

最后,如果你的__getattribute__是从装饰器创建的包装器、子类中调用的__getattribute__或类似的内容,这不会被视为来自hasattr,即使包装器或重写是从hasattr,即使您希望它计数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

检测 __getattribute__ 调用是否是由于 hasattr 的相关文章

随机推荐

  • Java String.split() 上逗号后跟非空格

    我正在解析一个数据集 该数据集烦人地决定在 TSV 中以逗号分隔项目 PharmGKB 路径 我正在看着你 但允许在每个逻辑元素中使用逗号 基本上 逗号后跟空格意味着没有分隔符 而逗号后跟字符意味着新元素 这是一 元素 二元素 三元素 应该
  • SqlDataAdapter 未更新

    我正在尝试更新TableTwo用一个DataTable建造使用TableOne 表之间的关系是一个称为外部列TableOneId inside TableTwo 我使用以下代码示例来完成这项工作 使用 DataAdapter 执行批量操作
  • 自动将所有网站链接更改为附属链接

    我希望能够在我的网站上自动将链接更改为附属链接媒体维基安装 这将有助于减少管理链接的时间 以防将来需要更改代码 这是我的 GOG com 联盟计划的设置 我需要将此密钥附加到每个 GOG com 链接的末尾 pp 708a77db476d7
  • xp主题控件透明背景

    我在位图上以及对话框的彩色背景上绘制了一些窗口控件 是否有某种可能的方法使窗口控件的背景透明 目前它们显示对话框的默认彩色背景 示例 我尝试粘贴纯蓝色位图 并且两个按钮控件具有明显的默认彩色矩形背景 通过为 Windows 提供您希望它用来
  • 在父 xml 中添加复选框时,expandablelistview 未展开

    I have developed the sample code of ExpandableListView in android Data is being populated in Adapter and displaying in t
  • 通过 SSL/TLS 下载 Apache CXF wsdl

    我有一个 cxf 服务运行在 https localhost 8443 services MyService wsdl 需要客户证书 WSDL 在这里并不重要 当我删除客户端证书或 https 要求时 我可以调用该服务 服务和客户端类是使用
  • django - 将列表转换回查询集[重复]

    这个问题在这里已经有答案了 我有一些记录想根据计算值进行排序 得到了答案在这里 就像这样 sorted Profile objects all key lambda p p reputation 在这样的 Profile 类上 class
  • Python ctypesgen/ctypes:如何以单字节对齐方式将结构字段写入文件

    使用 ctypesgen 我生成了一个结构体 我们称之为 mystruct 其字段定义如下 somelong ctypes c long somebyte ctypes c ubyte anotherlong ctypes c long s
  • 实例化点和名称绑定

    我对以下示例的实例化点感到困惑 include
  • 如何使用自动工具更改包含文件路径?

    我正在 ubuntu 中开发一个简单的聊天应用程序 它使用 crypto crypto 头文件的文件夹是 usr include crypto 当我将源标签栏上传到CentOS 我发现crypto 的头文件的文件夹是 usr include
  • 如何使用 npm 安装甚至不在 Node 应用程序中使用的全局包?

    我的知识npm这是 它是一个包管理器Node js应用程序 这意味着当您的节点应用程序需要其他人的库 包时 您可以方便地使用npm获取这些依赖项 但我最近遇到了这个命令 npm install g cca 然后我输入cca在我的终端中 现在
  • 在不循环的情况下连接单列中的记录?

    我有一个包含 1 列 varchar 值的表 如果可能的话 我正在寻找一种无需循环即可将这些值连接成单个值的方法 如果循环是解决此问题的最有效方法 那么我会采用这种方法 但我认为在默认使用该方法之前我会要求其他选项 我还想将其保留在 SQL
  • 在 Scala 中对数据库游标进行功能处理

    当我需要使用 JDBC 驱动程序从 PostgreSQL 数据库读取数百万个数据库行时 我总是使用游标 否则我将收到 OutOfMemoryError 这是我使用的模式 伪代码 begin transaction execute decla
  • Javascript 正则表达式允许阿拉伯语中的特定字符

    如何编写正则表达式以允许阿拉伯语中的特定字符或数字 我有这个正则表达式 但它确实匹配所有阿拉伯语和英语 sa zA Z u0600 u06FF 我想限制它只写arabic letters with space s 和破折号 对于将来的使用
  • 在Python中绘制轨道轨迹

    如何在Python中设置三体问题 如何定义求解 ODE 的函数 这三个方程是 x mu np sqrt x 2 y 2 z 2 x y mu np sqrt x 2 y 2 z 2 y and z mu np sqrt x 2 y 2 z
  • c:在子进程中运行的 exec() 中捕获段错误

    EDIT 我正在尝试编写一个简单的冒烟测试 其中测试所有选项和合理参数 我使用 popen 来执行应该测试的程序 使用这种方法不起作用 因为如果进程因信号 SIGINT SIGSEGV 而终止 来自 popen 的管道不会告诉我发生了什么
  • 如何从 SQL Server 中的 URL 读取 JSON 数据

    我正在尝试使用以下代码从 SQL Server 2008 中的 URL 读取 JSON 数据 DECLARE temp table RowNum int DATA NVARCHAR max DECLARE url VARCHAR MAX w
  • ruby on Rails 中的 Bootstrap 模式不工作(不显示)

    我正在使用 Rail4 和 bootstrap sass 3 3 6 我已按照以下步骤操作https coderwall com p ej0mhg open a rails form with twitter bootstrap modal
  • R 中一页上的多个绘图

    如何在 R 上的一个 pdf 页上绘制 7 个不同的图表 我目前使用的是matplot 它似乎没有这个选项 我需要根据数据列绘制数据列 我最初尝试使用点阵库来做到这一点 但我似乎无法弄清楚如何绘制数据列 好像想要一个功能 要创建绘图的 pd
  • 检测 __getattribute__ 调用是否是由于 hasattr

    我正在重新实施 getattribute 为了一堂课 我想注意到提供属性的任何不正确 当然意味着失败是预料之中的 失败 因为 getattribute 实施结果相当复杂 为此 如果我的代码在引发之前无法找到 提供该属性 我会记录一条警告At