【问题标题】:Why does monkeypatching os.path require a path argument?为什么monkeypatching os.path 需要一个路径参数?
【发布时间】:2017-05-07 13:24:25
【问题描述】:

pytest 在monkeypatching 文档中有这个例子:

import os.path
def getssh(): # pseudo application code
    return os.path.join(os.path.expanduser("~admin"), '.ssh')

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

当我从 mockreturn 函数中删除 path 参数时,我得到了错误

    def getssh():  # pseudo application code
>       return os.path.join(os.path.expanduser("~admin"), '.ssh')
E       TypeError: mockreturn() takes 0 positional arguments but 1 was given

我不明白是什么提供了位置参数?

另外,当我为 pathlib.Path.home() 重新实现相同的东西时,我不能在那里有这个参数path,否则它将不起作用。不幸的是,文档没有说明不祥的path 论点。

任何关于这里发生的魔法的照明都会非常有帮助!

【问题讨论】:

    标签: python pytest monkeypatching


    【解决方案1】:

    您正在尝试用一个完全不带参数的模拟替换带有一个参数的os.path.expanduser,这在调用时会导致错误。 在后台monkeypatch.setattr 使用内置的setattr,因此原始版本基本上是在执行以下操作,因为expandusermock 都采用单个参数:

    >>> import os.path
    >>> def mock(path):
    ...     return '/abc'
    ... 
    >>> setattr(os.path, 'expanduser', mock)
    >>> os.path.expanduser('~admin')
    '/abc'
    

    现在,如果您尝试将 expanduser 替换为不带参数的方法并继续以相同的方式调用它,您将收到错误:

    >>> setattr(os.path, 'expanduser', mock)
    >>> os.path.expanduser('~admin')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: mock() takes 0 positional arguments but 1 was given
    

    请注意,如果您尝试直接调用 mock,您将得到完全相同的错误:

    >>> mock('~admin')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: mock() takes 0 positional arguments but 1 was given
    

    【讨论】:

    • 谢谢,我只是没有点击/看到expanduser当然是提供路径的函数,而pathlib.Path.home()没有它也可以工作。
    猜你喜欢
    • 1970-01-01
    • 2020-04-22
    • 2012-11-08
    • 1970-01-01
    • 1970-01-01
    • 2019-03-11
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    相关资源
    最近更新 更多