标签: monkeypatching

我如何修补ruby的URI.parse方法

一些流行的博客网站通常在其URL中使用方括号,但ruby的内置URI.parse()方法会对它们产生阻碍,引发一个令人讨厌的异常,如:http://redmine.ruby-lang.org/issues/show/ 1466

我正在尝试编写一个简单的猴子补丁,它使用方括号优雅地处理URL.以下是我到目前为止的情况:

require 'uri'

module URI

    def self.parse_with_safety(uri)
        safe_uri = uri.replace('[', '%5B')
        safe_uri = safe_uri.replace(']', '%5D')
        URI.parse_without_safety(safe_uri)
    end

    alias_method_chain :parse, :safety

end
Run Code Online (Sandbox Code Playgroud)

但是在运行时会产生错误:

/Library/Ruby/Gems/1.8/gems/activesupport-2.3.8/lib/active_support/core_ext/module/aliasing.rb:33:in alias_method:NameError:模块'URI'的未定义方法'解析'

我怎样才能成功修补URI.parse?

ruby uri monkeypatching

7
推荐指数
1
解决办法
2737
查看次数

在python中将基类添加到现有对象

我有几个不同种类的对象(不同的函数名称,不同的签名),我对它们进行修补,以便有一种从不同函数访问它们的通用方法.简而言之,有一个调度程序可以获取我想要修补的对象,并根据它调用不同修补程序的对象类型.修补程序将向对象添加方法:

def patcher_of_some_type(object):

    def target(self, value):
        # do something and call self methods

    object.target = types.MethodType(target, object)

    # many more of these
Run Code Online (Sandbox Code Playgroud)

随着程序变得越来越复杂,围绕对象(或对象类)的包装似乎更好.一些修补程序共享公共代码或相互关联.但我不控制对象创建,也不控制类创建.我只得到了这些物品.即使我能做到这一点,我只想包装(或修补)某些对象,而不是所有对象.

一种解决方案可能是为现有对象添加基类,但我不确定这是多么可维护和安全.还有其他解决方案吗?

python inheritance monkeypatching metaclass

7
推荐指数
2
解决办法
6838
查看次数

猴子补丁XMLHTTPRequest.onreadystatechange

如何修补猴子XMLHTTPRequestonreadystatechange功能.我正在尝试添加一个函数,当从页面发出的每个ajax请求返回时,将调用该函数.

我知道这听起来像一个可怕的想法,但用例非常奇特.我想在控制台(jqconsole)中使用某个SDK,但在控制台内显示ajax调用的状态和结果,而不修改外部SDK.

我看过这篇文章有很多信息,但猴子修补回调似乎超出了我的JavaScript技能.

PS不能使用jQuery,因为它只支持从jQuery调用的jjj调用,而不是XMLHTTPRequests直接来自这里的情况.

javascript ajax monkeypatching xmlhttprequest

7
推荐指数
1
解决办法
3237
查看次数

Django Rest Framework Json数据猴子修补

我遇到像3.333333333那样的浮点数问题,我想把它变成3.33.我不想改变Serializer这类价值来自的所有类.有数千个序列化器,它们有多个字段,其值为3.333333333.

你能帮我找一下猴子补丁类型的解决方案,这样我就可以编写一个类或函数来转换浮点值.

python django json monkeypatching django-rest-framework

7
推荐指数
1
解决办法
512
查看次数

猴子修补时放置代码的位置

我读到的关于猴子修补的一切都说要做这样的事情:

class String
  def foo
    #your special code 
  end
end
Run Code Online (Sandbox Code Playgroud)

但我找不到任何关于放置此代码的说明.在rails应用程序中,我可以把它放在我想要的任何疯狂的地方吗?在模块中?一个模型?

我是否需要在我定义monkeypatch的文件中包含一些内容?我是否需要在我想要使用它的地方包含我的monkeypatch?

ruby monkeypatching ruby-on-rails

7
推荐指数
2
解决办法
6322
查看次数

Monkeypatch 在单元测试中持续存在 python

我有一个自定义框架,它为不同的客户端运行不同的代码。我对某些方法进行了猴子修补,以便为客户定制功能。

这是简化的模式:

    #import monkeypatches here
    if self.config['client'] == 'cool_dudes':
        from app.monkeypatches import Stuff
    if self.config['client'] == 'cool_dudettes':
        from app.monkeypatches import OtherStuff
Run Code Online (Sandbox Code Playgroud)

这是一个补丁示例:

from app.framework.stuff import Stuff

def function_override(self):
  return pass

Stuff.function = function_override
Run Code Online (Sandbox Code Playgroud)

当程序以批处理方式执行时,这种方法效果很好,每次都从头开始旋转。然而,当运行单元测试时,我发现猴子补丁在测试中持续存在,导致意外的行为。

我意识到使用面向对象的继承方法来进行这些重写会好得多,但我继承了这个代码库,并且目前无权重新构建它到那种程度。

除非正确地重新构建程序,否则如何防止这些猴子补丁在单元测试中持续存在?

python unit-testing monkeypatching

7
推荐指数
1
解决办法
1528
查看次数

pytest-monkeypatch 一个装饰器(不使用模拟/补丁)

我正在使用 pytest 和 Monkeypatch 固定装置编写一些测试。按照规则,我导入类和方法以从它们正在使用的模块而不是源代码中模拟出来。

我正在为其编写测试的应用程序是一个使用标准环境的 Google App Engine 应用程序。因此我必须使用 python 2.7,我使用的实际版本是 2.7.15 - pytest 版本是 3.5.0

到目前为止,一切都运行良好,但在尝试模拟装饰器函数时遇到了问题。

从顶部开始。在一个名为decorators.py的py文件中包含所有auth装饰器,包括我想要模拟的装饰器。所讨论的装饰器是一个模块函数,而不是类的一部分。

def user_login_required(handler):
    def is_authenticated(self, *args, **kwargs):
        u = self.auth.get_user_by_session()
        if u.access == '' or u.access is None:
            # return the response
            self.redirect('/admin', permanent=True)
        else:
            return handler(self, *args, **kwargs)
    return is_authenticated
Run Code Online (Sandbox Code Playgroud)

该装饰器应用于Web请求功能。名为 handlers (handlers.UserDetails) 的文件夹中名为 UserDetails.py 的文件中的基本示例

from decorators import user_login_required

class UserDetailsHandler(BaseHandler):
    @user_login_required
    def get(self):
        # Do web stuff, return html, etc
Run Code Online (Sandbox Code Playgroud)

在测试模块中,我设置测试如下:

from handlers.UserDetails import user_login_required

@pytest.mark.parametrize('params', get_params, ids=get_ids)
def …
Run Code Online (Sandbox Code Playgroud)

python monkeypatching pytest

7
推荐指数
1
解决办法
6232
查看次数

避免在单元测试中运行顶层模块代码

我正在尝试对一些导入模块的 Python 3 代码进行单元测试。不幸的是,模块的编写方式,简单地导入它会产生令人不快的副作用,这对测试来说并不重要。我试图用unitest.mock.patch它来解决它,但运气不佳。

这是说明性示例的结构:

.
??? work
    ??? __init__.py
    ??? test_work.py
    ??? work.py
    ??? work_caller.py
Run Code Online (Sandbox Code Playgroud)

__init__.py 是一个空文件

工作.py

.
??? work
    ??? __init__.py
    ??? test_work.py
    ??? work.py
    ??? work_caller.py
Run Code Online (Sandbox Code Playgroud)

work_caller.py

import os


def work_on():
    path = os.getcwd()
    print(f"Working on {path}")
    return path

def unpleasant_side_effect():
    print("I am an unpleasant side effect of importing this module")

# Note that this is called simply by importing this file
unpleasant_side_effect()
Run Code Online (Sandbox Code Playgroud)

测试工作.py

from work.work import work_on

class WorkCaller:
    def call_work(self):
        # Do …
Run Code Online (Sandbox Code Playgroud)

python unit-testing monkeypatching

7
推荐指数
1
解决办法
382
查看次数

Python 中使用继承类对类进行猴子修补

在阅读了有关 Python 中猴子修补类的问题的答案后,我尝试将建议的解决方案应用于以下情况。

假设我们有一个模块a.py

class A(object):
    def foo(self):
        print(1)

class AA(A):
    pass
Run Code Online (Sandbox Code Playgroud)

让我们尝试按如下方式对其进行猴子修补。当我们猴子补丁类时它起作用A

>>> import a
>>> class B(object):
...     def foo(self):
...             print(3)
... 
>>> a.A = B
>>> x = a.A()
>>> x.foo()
3
Run Code Online (Sandbox Code Playgroud)

但是如果我们尝试继承的类,它就不会被修补:

>>> y = a.AA()
>>> y.foo()
1
Run Code Online (Sandbox Code Playgroud)

有什么方法可以用所有继承的类来猴子修补该类吗?

编辑

目前,对我来说最好的解决方案如下:

>>> class AB(B, a.AA):
...     pass
... 
>>> a.AA = AB
>>> x = a.AA()
>>> x.foo()
3
Run Code Online (Sandbox Code Playgroud)

的任何复杂结构都将被继承,并且和a.AA之间的唯一区别是方法。这样,我们就不会修改任何内部类属性(如或)。唯一剩下的缺点是我们需要为每个继承的类执行此操作。ABa.AAfoo()__base____dict__

这是最好的方法吗?

python inheritance monkeypatching

7
推荐指数
1
解决办法
2031
查看次数

fastai.fastcore 补丁装饰器与简单的猴子补丁

fastai我试图了解使用's fastcore.basics.patch_toDecorator的附加值。方法如下fastcore

from fastcore.basics import patch_to


class _T3(int):
    pass


@patch_to(_T3)
def func1(self, a):
    return self + a
Run Code Online (Sandbox Code Playgroud)

这是简单的猴子修补方法:

class simple_T3(int):
    pass


def func1(self, a):
    return self + a


simple_T3.func1 = func1
Run Code Online (Sandbox Code Playgroud)

检查这两个类没有发现任何差异。我知道简单的猴子修补可能会在更复杂的情况下导致问题,所以很高兴知道这些情况是什么?换句话说,它的附加值是多少fastcore.basics.patch_to

python monkeypatching python-3.x fast-ai

7
推荐指数
1
解决办法
470
查看次数