def test_most_built_in_classes_cannot_be_monkey_patched(self): try: int.is_even = lambda self: (self % 2) == 0 except Exception as ex: err_msg = ex.args[0] self.assertRegex(err_msg, "can't set attributes of built-in")
时间: 2024-04-21 22:27:58 浏览: 66
这个修改后的测试用例中,`int.is_even` 属性被定义为一个 lambda 函数,用于判断一个整数是否为偶数。由于 `int` 类型是不可变类型,因此对其属性进行修改时会抛出一个异常,这个异常信息被保存在 `err_msg` 变量中。然后通过 `self.assertRegex()` 方法来判断异常信息中是否包含 "can't set attributes of built-in" 字符串,如果包含则测试通过,否则测试失败。
然而,由于内置类型是不允许被猴子补丁的,因此这个测试用例无法通过。如果你想要测试猴子补丁,可以将 `int` 类型改为自己定义的一个类,然后再进行猴子补丁。具体可以参考我上一个回答中的示例代码。
相关问题
#!/usr/bin/env python # -*- coding: utf-8 -*- # # Related to AboutOpenClasses in the Ruby Koans # from runner.koan import * class AboutMonkeyPatching(Koan): class Dog: def bark(self): return "WOOF" def test_as_defined_dogs_do_bark(self): fido = self.Dog() self.assertEqual('WOOF', fido.bark()) # ------------------------------------------------------------------ # Add a new method to an existing class. def test_after_patching_dogs_can_both_wag_and_bark(self): def wag(self): return "HAPPY" self.Dog.wag = wag fido = self.Dog() self.assertEqual('HAPPY', fido.wag()) self.assertEqual('WOOF', fido.bark()) # ------------------------------------------------------------------ def test_most_built_in_classes_cannot_be_monkey_patched(self): try: int.is_even = lambda self: (self % 2) == 0 except Exception as ex: err_msg = ex.args[0] self.assertRegex(err_msg, "can't set attributes of built-in") # ------------------------------------------------------------------ class MyInt(int): pass def test_subclasses_of_built_in_classes_can_be_be_monkey_patched(self): self.MyInt.is_even = lambda self: (self % 2) == 0 self.assertEqual(False, self.MyInt(1).is_even()) self.assertEqual(True, self.MyInt(2).is_even())
这段代码是一个 Python 的单元测试,测试了 Monkey Patching 的一些特性。Monkey Patching 是指在运行时动态修改类或对象的行为。在这段代码中,定义了一个 Dog 类,其中有一个 bark 方法。然后通过 Monkey Patching 的方式给 Dog 类添加了一个新的方法 wag。接着展示了一个不能被 Monkey Patching 的内置类型 int,以及一个继承自 int 的自定义类 MyInt,展示了后者可以进行 Monkey Patching。最后通过几个测试用例来验证 Monkey Patching 的效果。其中包括:
- 测试原本定义的 Dog 类是否能够正常运作。
- 测试 Monkey Patching 后 Dog 类是否能够正常运作。
- 测试不能被 Monkey Patching 的内置类型 int。
- 测试继承自内置类型 int 的自定义类 MyInt 是否可以进行 Monkey Patching,并验证 Monkey Patching 的效果。
MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may lead to errors, including RecursionError on Python 3.6. It may also silently lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. See https://github.com/gevent/gevent/issues/1016. Modules that had direct imports (NOT patched): ['urllib3.util (D:\\Python\\venv\\lib\\site-packages\\urllib3\\util\\__init__.py)', 'urllib3.util.ssl_ (D:\\Python\\venv\\lib\\site-packages\\urllib3\\util\\ssl_.py)']. monkey.patch_all()
这是一条警告信息,意思是在 ssl 模块被导入后再进行 Monkey Patch 可能会导致错误,特别是在 Python 3.6 上可能会出现递归错误(RecursionError),在 Python 3.7 上还可能导致不正确的行为。建议在导入 ssl 模块之前进行 Monkey Patch。同时,这条信息还列出了那些已经被直接导入的模块,这些模块不应该被 Monkey Patch。最后,代码中调用了 monkey.patch_all() 方法,这个方法会自动对一些常用模块进行 Monkey Patch。
阅读全文