2016-12-22 18 views
1

pytest имеет этот пример в monkeypatching документы:Почему для monkeypatching os.path требуется аргумент path?

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' 

Когда я удалить path аргумент из функции mockreturn, я получаю ошибку

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.

Любое освещение, для которого происходит здесь волшебство, было бы очень полезно!

ответ

1

Вы пытаетесь заменить os.path.expanduser, который принимает один аргумент с макетом, который вообще не принимает аргументы, что приводит к ошибке при вызове. Под капотом monkeypatch.setattr использует встроенный setattr поэтому оригинальная версия в основном делает следующее, который работает так как expanduser и mock принимать один аргумент:

>>> 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 
+0

Спасибо, я просто не нажал/не увидел, что 'expanduser' - это, конечно, функция, которая предоставляет путь, а pathlib.Path.home() работает без него. –