标签: monkeypatching

如何通过猴子修补来替换课程?

我怎样才能替换ORM类 - 所以它不应该导致递归!

问题:
原始类具有超级调用,当它被替换时 - 它会导致自我继承并导致最大递归深度超过异常.
即类orm正在调用super(orm,self)....并且orm已被另一个继承原始orm的类所取代....

包!

addons  __init__.py  osv  run_app.py

./addons:
__init__.py  test_app1.py  test.py

./osv:
__init__.py  orm.py
Run Code Online (Sandbox Code Playgroud)

orm.py的内容

class orm_template(object):
    def __init__(self, *args, **kw):
        super(orm_template, self).__init__()    
    def fields_get(self, fields):
        return fields    
    def browse(self, id):
        return id

class orm(orm_template):
    def __init__(self, *args, **kw):
        super(orm, self).__init__(*args, **kw)    
    def fields_get(self, fields, context = None):
        return super(orm, self).fields_get(fields)    
    def read(self, fields):
        return fields
Run Code Online (Sandbox Code Playgroud)

addons/init .py的内容

import test    
def main(app):
    print "Running..."
    __import__(app, globals(), locals())
Run Code Online (Sandbox Code Playgroud)

addons/test.py的内容

from osv import orm …
Run Code Online (Sandbox Code Playgroud)

python monkeypatching class

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

猴子修补ActiveResource ::错误

我遇到了一个已经解决的 ActiveResource 问题,并试图将它修补到我的应用程序中而没有太多运气.

我在config/initializers /中添加了一个包含以下内容的文件:

class ActiveResource::Errors < ActiveModel::Errors
    # https://github.com/rails/rails/commit/b09b2a8401c18d1efff21b3919ac280470a6eb8b
    def from_hash(messages, save_cache = false)
      clear unless save_cache

      messages.each do |(key,errors)|
        errors.each do |error|
          if @base.attributes.keys.include?(key)
            add key, error
          elsif key == 'base'
            self[:base] << error
          else
            # reporting an error on an attribute not in attributes
            # format and add themActive  to base
            self[:base] << "#{key.humanize} #{error}"
          end
        end
      end
    end

    # Grabs errors from a json response.
    def from_json(json, save_cache = false)
      decoded = ActiveSupport::JSON.decode(json) …
Run Code Online (Sandbox Code Playgroud)

monkeypatching ruby-on-rails activeresource

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

在Perl中,我可以仅将方法动态添加到包的一个对象中吗?

我正在努力WWW::Mechanize自动化基于网络的后台点击我需要做的是让我的测试电子商务订单进入我需要的状态来测试我对长的多部分的特定部分所做的更改流程.要批量处理大量订单,我需要Home经常点击链接.为了缩短这一点,我WWW::Mechanize在运行时将这样的方法入侵(基于brian d foy 掌握Perl的示例):

{ # Shortcut to go back to the home page by calling $mech->go_home
  # I know I'll get a warning and do not want it!
  no warnings 'once';
  my $homeLink = $mech->find_link( text => 'Home' )->url_abs();
  $homeLink =~ s/system=0/system=1/;
  *WWW::Mechanize::go_home = sub {
    my ($self) = @_;
    return $self->get($homeLink);
  };
}
Run Code Online (Sandbox Code Playgroud)

这很好用,并且不会伤害任何人,因为我使用它的脚本仅供我使用,而不是更大系统的一部分.

但现在我想知道是否有可能实际上只告诉一个$mech具有此方法的WWW::Mechanize对象,而另一个可能稍后创建的对象(比如说,做一些交叉引用而不混淆另一个具有活动会话的对象)我的后台办公室)不能使用那种方法.

我不确定这是否可行,因为如果我理解对象在Perl中的工作方式,那么->操作符会告诉它go_home在包中查找子例程并将第一个参数WWW::Mechanize传递$mech给它.如果这种理解是错误的,请纠正我.

我通过添加一种硬编码检查进行了实验,该检查只允许原始$mech对象使用该功能. …

perl monkeypatching www-mechanize

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

猴子补丁ActiveRecord的PostgreSQLAdapter方法

关于这个问题,我试图覆盖postgresql_version定义的方法ActiveRecord::ConnectionAdapters::PostgreSQLAdapter返回PostgreSQL版本:

module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter

      protected
        # Returns the version of the connected PostgreSQL server.
        def postgresql_version
          80200
        end
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

但补丁未应用.我尝试在config/initializer中并在/ lib文件中要求它.救命?

activerecord monkeypatching ruby-on-rails ruby-on-rails-3

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

让 pytest 中的猴子补丁工作

我正在尝试使用 pytest 为类方法开发一个测试,该方法从字符串列表中随机选择一个字符串。

它看起来本质上类似于下面的 givemeannumber 方法:

import os.path
from random import choice

class Bob(object):
  def getssh():
    return os.path.join(os.path.expanduser("~admin"), '.ssh')

  def givemeanumber():
    nos = [1, 2, 3, 4]
    chosen = choice(nos)
    return chosen
Run Code Online (Sandbox Code Playgroud)

第一种方法,getssh,在 Bob 类中只是pytest 文档中的例子

我的生产代码从数据库中获取字符串列表,然后随机选择一个。所以我希望我的测试获取字符串,然后选择第一个字符串而不是随机选择。这样我就可以针对已知字符串进行测试。

根据我的阅读,我认为我需要使用monkeypatching 来伪造随机化。

这是我到目前为止所得到的

import os.path
from random import choice
from _pytest.monkeypatch import MonkeyPatch
from bob import Bob

class Testbob(object):
    monkeypatch = MonkeyPatch()

    def test_getssh(self):
        def mockreturn(path):
            return '/abc'
        Testbob.monkeypatch.setattr(os.path, 'expanduser', mockreturn)
        x = Bob.getssh()
        assert x == '/abc/.ssh'

    def test_givemeanumber(self):
        Testbob.monkeypatch.setattr('random.choice', …
Run Code Online (Sandbox Code Playgroud)

python monkeypatching pytest

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

具有 __slots __ 的类实例的 Monkeypatch 方法

我一直在尝试解决第三方模块中的错误。该错误最近已修复,但我一直想知道我的问题。也许这个问题将来会对我或其他人有所帮助。

该模块定义了一个类 Runtime,其中包含我使用的几种方法。导入模块后,它会自动创建一个运行时实例,加载配置并将该实例提供给用户(我)使用。

# thirdPartyModule.py

class Runtime:
    def __init__(self, a):
        self.a = a

    def configuration(self, ...):
        ...

    def fun(self):
        print(self.a)

rt = Runtime("twice")
rt.configuration(...)
Run Code Online (Sandbox Code Playgroud)

不幸的是,其中一个运行时方法包含一个错误。我曾经通过用一个工作替代品覆盖实例的方法来修补这个错误,如下所示

# mycode.py

import types
from thirdPartyModule import rt

def newfun(self):
    print(self.a, self.a)

rt.fun = types.MethodType(newfun, rt)
rt.fun()
Run Code Online (Sandbox Code Playgroud)

当我等待开发人员修复错误时,这一切都很好。__slots__或者至少在开发人员添加到类中之前它是这样的:

# thirdPartyModule.py

class Runtime:
    __slots__ = ("a", )

    def __init__(self, a):
        self.a = a

    ...
Run Code Online (Sandbox Code Playgroud)

从那时起,我在这个论坛上尝试了几种方法覆盖解决方案,但都被拒绝了(“AttributeError:'Runtime'对象属性'fun'是只读的”)。

这可能unittest.mock 可以帮助我,但我对嘲笑不太熟悉。我尝试了以下方法但没有成功:

import unittest.mock

rt.fun = mock.Mock(rt.fun, side_effect=newfun)
Run Code Online (Sandbox Code Playgroud)

这会导致相同的 AttributeError。也许我可以模拟整个实例 ( rt = mock.Mock(rt)) …

python methods monkeypatching slots

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

Monkey-patching class.__str__ 使用装饰器不起作用

我正在尝试__str__通过以下装饰器修补类的特殊方法:

def str_patcher(klass):
    def decorator(*args, **kwargs):
        def __str__(self):
            items = {key: value for key, value in self.__dict__.items() if not key.startswith("_")}
            return f"{type(self).__qualname__}({items})"

        klass.__str__ = __str__
        return klass

    return decorator
Run Code Online (Sandbox Code Playgroud)

然后,我做了一个MyClass装饰的类str_patcher

@str_patcher
class MyClass:
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
            setattr(self, key, value)
Run Code Online (Sandbox Code Playgroud)

但是当我打印出来时MyClass(a=1, b=2, c=3),我希望看到,MyClass({a: 1, b: 2, c: 3})但我却看到了<class __main__.MyClass>

为什么是这样?

python monkeypatching class python-3.x python-decorators

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

为什么我尝试猴子修补shutil无法正常工作?

所以我试图monkeypatch shutil模块,以便使用最新的make_archive函数修复,允许创建大型zip文件.

我是一个概念性的证据,所以想到一个快速的黑客来解决这个问题会让我继续我想做的事情.

我的代码:

import shutil
import os

def _make_zipfile(base_name, base_dir, verbose=0, dry_run=0, logger=None):
    zip_filename = base_name + ".zip"
    archive_dir = os.path.dirname(base_name)

    if not os.path.exists(archive_dir):
        if logger is not None:
            logger.info("creating %s", archive_dir)
        if not dry_run:
            os.makedirs(archive_dir)

    # If zipfile module is not available, try spawning an external 'zip'
    # command.
    try:
        import zipfile
    except ImportError:
        zipfile = None

    if zipfile is None:
        shutil._call_external_zip(base_dir, zip_filename, verbose, dry_run)
    else:
        if logger is not None:
            logger.info("creating '%s' and adding '%s' to it", …
Run Code Online (Sandbox Code Playgroud)

python monkeypatching shutil python-2.7

0
推荐指数
1
解决办法
384
查看次数

猴子修补红宝石方法与爆炸

是否有可能在最后使用爆炸来修补方法?

我想要猴子补丁String.upcase!,但我不知道如何实现.

问题是我想要更改原始字符串对象.

这是一个例子:

class String
  def upcase!
    self.mb_chars.upcase.to_s
  end
end
Run Code Online (Sandbox Code Playgroud)

现在,如果我在控制台中输入并尝试它,它不起作用:

[1] pry(main)> asd="asd"
=> "asd"
[2] pry(main)> asd.upcase
=> "ASD"
[3] pry(main)> asd
=> "asd"
[4] pry(main)> asd.upcase!
=> "ASD"
[5] pry(main)> asd
=> "asd"
Run Code Online (Sandbox Code Playgroud)

ruby monkeypatching

0
推荐指数
1
解决办法
331
查看次数

Python3-在__eq__方法中使用super()会引发RuntimeError:super():__class__单元格未找到

我是猴子修补__eq__类的方法。我发现以下作品:

   def eq(obj, other):
       if isinstance(other, str):
          return obj.name.upper() == other.upper()
       else:
          return object.__eq__(obj, other)
Run Code Online (Sandbox Code Playgroud)

这不起作用:

  def eq(obj, other):
     if isinstance(other, str):
         return obj.name.upper() == other.upper()
     else:
        return super().__eq__(other)
Run Code Online (Sandbox Code Playgroud)

这有时可行,但有时会引发错误:

def eq(obj, other):
   if isinstance(other, str):
       return obj.name.upper() == other.upper()
   else:
       return super().__eq__(self, other)
Run Code Online (Sandbox Code Playgroud)

错误:

<ipython-input-128-91287536205d> in eq(obj, other)
      3         return obj.name.upper() == other.upper()
      4     else:
----> 5         return super().__eq__(self, other)
      6 
      7 

RuntimeError: super(): __class__ cell not found
Run Code Online (Sandbox Code Playgroud)

您能解释一下这里发生了什么吗?如何正确替换objectsuper()

python overloading monkeypatching super python-3.x

0
推荐指数
1
解决办法
626
查看次数