标签: monkeypatching

Django 模板中的正确缩进(无需猴子修补)?

我想为我的独立应用程序生成由 Django 模板系统预处理的人类可读的 HTML 和 CSS 代码(正确缩进)。

我修改了 django.template.base 模块中 NodeList 类的 render 方法。我的代码似乎工作正常,但我使用猴子修补来替换旧的渲染方法。

在这种情况下,是否有一种更优雅的方式不使用猴子修补?或者也许猴子补丁是最好的方法?

我的代码如下所示:

'''
This module monkey-patches Django template system to preserve
indentation when rendering templates.
'''

import re

from django.utils.encoding import force_text
from django.utils.safestring import mark_safe
from django.template.loader import render_to_string
from django.template import Node, NodeList, TextNode
from django.template.loader_tags import (BlockNode, ConstantIncludeNode,
                                         IncludeNode)


NEWLINES = re.compile(r'(\r\n|\r|\n)')
INDENT = re.compile(r'(?:\r\n|\r|\n)([\ \t]+)')


def get_indent(text, i=0):
    '''
    Depending on value of `i`, returns first or last indent
    (or any other …
Run Code Online (Sandbox Code Playgroud)

django monkeypatching indentation django-templates

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

将 Django 的默认小部件更改为自定义小部件

我的用例:我想使用不同的 DateInput。但我想减少代码重复。我希望所有没有明确需要不同 DateInput 小部件的表单都使用我的自定义小部件。

没有猴子补丁的情况下有什么改变可以解决这个问题吗?

例子

模型.py:

class MyModel(models.Model):
    date=models.DateField()
Run Code Online (Sandbox Code Playgroud)

形式.py:

class MyForm(forms.ModelForm):
    class Meta:
        model=MyModel
Run Code Online (Sandbox Code Playgroud)

上面的代码应该使用我的自定义小部件。我不想更改上面的 models.py 和 forms.py,因为有很多。

forms django monkeypatching

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

AttributeError:使用pytest的monkeypatch时

src/mainDir/mainFile.py

mainFile.py 的内容

import src.tempDir.tempFile as temp

data = 'someData'
def foo(self):
    ans = temp.boo(data)
    return ans
Run Code Online (Sandbox Code Playgroud)

src/tempDir/tempFile.py

def boo(data):

   ans = data
   return ans
Run Code Online (Sandbox Code Playgroud)

现在我想测试foo()并在方法中src/tests/test_mainFile.py模拟temp.boo(data)方法foo()

 import src.mainDir.mainFile as mainFunc

  testData = 'testData'
  def test_foo(monkeypatch):
     monkeypatch.setattr('src.tempDir.tempFile', 'boo', testData)
     ans = mainFunc.foo()
     assert ans == testData
Run Code Online (Sandbox Code Playgroud)

但我收到错误

属性错误:“src.tempDir.tempFile”没有属性“boo”

我期望 ans = testData.

我想知道我是否正确地模拟了我的 tempDir.boo() 方法,或者我应该使用 pytest 的模拟程序而不是 Monkeypatch。

python monkeypatching pytest

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

解释 Python 3.6 中的 AST:isinstance、猴子修补、visit_NodeType 与宏?

假设我想编写一个小型解释器,可以使用二元运算 Plus、一元运算Negate和整数常量来计算表达式。

我目前只对 AST 的解释感兴趣,因此为了简单起见,让我们跳过标记化和解析。

在 Haskell 中,有一种或多或少规范的方法来做到这一点:

data Ast = Plus Ast Ast | Negate Ast | IntConst Int

ev :: Ast -> Int
ev (Plus a b) = (ev a) + (ev b)
ev (Negate x) = - (ev x)
ev (IntConst i) = i

main = print $ show $ ev $ (Plus (IntConst 50) (Negate $ IntConst 8))
Run Code Online (Sandbox Code Playgroud)

现在,Python 3.6 似乎没有代数数据类型。我的问题是似乎有很多可能的解决方法。最明显的一个是使用isinstance

class Plus:
  def __init__(self, first, second):
    self.first = first
    self.second …
Run Code Online (Sandbox Code Playgroud)

python monkeypatching visitor-pattern algebraic-data-types python-3.x

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

Python - 猴子补丁失败,为什么?

我想f(*args, **kwargs)从已安装的模块中进行猴子修补。我在自己的代码中使用了装饰器的想法,但是已安装模块中的其他方法无法f正确调用。

这是一个例子:

import numpy as np

def log(func):
    def wrapper(*args, **kwargs):
        print('logging')
        return func(*args, **kwargs)
    return wrapper

if __name__ == "__main__":
    a1 = np.asarray([0, 1, 2])
    print(f'a1={a1}')

    a2 = np.array([0, 1, 2])
    print(f'a2={a2}')

    np.array = log(np.array)

    a3 = np.asarray([0, 1, 2])
    print(f'a3={a3}')

    a4 = np.array([0, 1, 2])
    print(f'a4={a4}')
Run Code Online (Sandbox Code Playgroud)

输出是:

a1=[0 1 2]
a2=[0 1 2]
a3=[0 1 2]
logging
a4=[0 1 2]
Run Code Online (Sandbox Code Playgroud)

我希望结果是:

a1=[0 1 2]
a2=[0 1 2]
logging
a3=[0 1 2]
logging
a4=[0 …
Run Code Online (Sandbox Code Playgroud)

monkeypatching metaprogramming python-import python-3.x python-internals

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

Monkey 从库中修补 Python 类方法

我正在导入其他人制作的库,并且想要更改该库中特定类方法的工作方式,因此我已将该类方法复制到我自己的文件中,并希望在运行时替换它。这对于函数来说似乎工作得很好,但对于类方法来说似乎就不行了。

a.library.package.library_file.py

class LibraryClass(ParentClass):
    @classmethod
    def get_cost(cls, time):
        return int(time * cls.hourly)
Run Code Online (Sandbox Code Playgroud)

我想用这个替换它

class LibraryClass(ParentClass):
    @classmethod
    def get_cost(cls, time):
        return 1234
Run Code Online (Sandbox Code Playgroud)

我尝试只进行正常的替换,这对于常规功能来说效果很好

import a.library.package.library_file

...

a.library.package.library_file.LibraryClass.get_cost = get_cost
Run Code Online (Sandbox Code Playgroud)

但它似乎根本无法正常工作,该方法在错误的时间使用错误的参数调用并导致崩溃。在对 Google、StackOverflow 和 Python 进行一些研究之后,我开始尝试使用模拟类。

from unittest.mock import patch

@patch.object('a.library.package.library_file.LibraryClass', 'get_cost')
def get_cost(cls, time):
    return 1234
Run Code Online (Sandbox Code Playgroud)

好消息是它不会崩溃,坏消息是它没有做任何事情,旧代码仍然存在,就像我的代码不存在一样。

我尝试过各种其他方法来做到这一点,例如

import a.library.package.library_file

@patch.object(a.library.package.library_file.LibraryClass, 'get_cost')
...
Run Code Online (Sandbox Code Playgroud)

或者

from a.library.package.library_file import LibraryClass

@patch.object(LibraryClass, 'get_cost')
...
Run Code Online (Sandbox Code Playgroud)

但每次方法都没有碰过。就像我的代码不存在并且使用旧代码一样。

python monkeypatching

5
推荐指数
2
解决办法
5031
查看次数

Rails 6、Ruby 3.0.2 中的acts_as_commentable 的替代品是什么?

我将我们的应用程序升级到 Rails 6.1.4.4 和 Ruby 3.0.2。我有这颗古老的宝石

\n
gem 'acts_as_commentable'\n
Run Code Online (Sandbox Code Playgroud)\n

锁定在 4.0.2 版本。该 gem 似乎不再受支持,这很遗憾,因为当我启动我的应用程序或控制台时,我现在收到此错误

\n
$ rails c\nYour Gemfile lists the gem rspec-rails (>= 0) more than once.\nYou should probably keep only one of them.\nRemove any duplicate entries and specify the gem only once.\nWhile it's not a problem now, it could cause errors if you change the version of one of them later.\n/Users/myuser/.rvm/gems/ruby-3.0.2/gems/hash_dot-2.5.0/lib/hash.rb:19:in `method_missing': undefined method `arity' for {:as=>:commentable, :dependent=>:destroy}:Hash (NoMethodError)\n    from /Users/myuser/.rvm/gems/ruby-3.0.2/gems/activerecord-6.1.4.4/lib/active_record/associations/builder/association.rb:53:in `build_scope'\n    from /Users/myuser/.rvm/gems/ruby-3.0.2/gems/activerecord-6.1.4.4/lib/active_record/associations/builder/association.rb:47:in `create_reflection'\n    from /Users/myuser/.rvm/gems/ruby-3.0.2/gems/activerecord-6.1.4.4/lib/active_record/associations/builder/association.rb:32:in …
Run Code Online (Sandbox Code Playgroud)

monkeypatching ruby-on-rails acts-as-commentable ruby-on-rails-6 ruby-3

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

Django和猴子修补问题

我最近在业余时间开始尝试使用Django来处理一些Web应用程序.在为一个设计数据模型时,我遇到了使用继承来定义网站用户或使用已经由框架提供的User类进行猴子修补的技术的困境.

我尝试通过(根据以下方式定义了所有模型等而没有错误python manage.py validate)添加字段:

User.add_to_class('location', models.CharField(max_length=250,blank=True))

并执行了syncdb命令.但是,我一直收到这个错误

OperationalError:没有这样的列:auth_user.location

我是在网站的管理员视图还是manage.py shell.必须有一个我缺少的额外步骤,但似乎有关整个猴子修补技术的文档有限.所以,在我诉诸继承之前,我会请求你的帮助.当然欢迎任何代码,提示或指向其他文档的链接.

提前致谢.

PS.我知道这种技术很难看,而且可能是不明智的.;)

python django monkeypatching

4
推荐指数
2
解决办法
1899
查看次数

猴子修补python中的time.time()

我有一个应用程序,为了测试,我需要用特定的时间戳替换time.time()调用,我过去使用ruby完成了

(可在此处获取代码:http://github.com/zemariamm/Back-to-Future/blob/master/back_to_future.rb)

但是我不知道如何使用Python来做到这一点.

任何提示?干杯,泽玛丽亚

ruby python time datetime monkeypatching

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

安全地向Array类添加`sum`方法

我在我的代码中进行了大量的数组求和,所以我想要修补Array类以包含sum方法(它对数组中的所有元素求和):

class Array
  def sum
    self.inject{ |s, t| s + t }
  end
end
Run Code Online (Sandbox Code Playgroud)

但是,我以前从来没有在共享代码中修补任何东西,我怀疑这是一个"安全"的事情(例如,也许其他人已经定义了一个sum方法Array).

那么什么是能够在我正在编写的代码中对数组求和的最佳方法,而不必arr.inject{ |s, t| s + t }每次都写入?猴子补丁有安全的方法吗?我能以某种方式使用模块吗?或者我应该在某个地方编写一个辅助方法,它接收一个数组并返回总和(即def sum_array(arr); return arr.inject{ |s, t| s + t }; end)?(或者还有其他一些方法吗?)

ruby monkeypatching

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