Alo*_*ois 6 pytest python-3.x pathlib
我已经开始使用了pathlib.Path一段时间,我喜欢使用它.现在我已经习惯了,我已经变得草率,忘记了参与str.
此使用时经常发生tox+ py.test基于临时目录tmpdir(这是一个py._path.local.LocalPath):
from pathlib import Path
import pytest
def test_tmpdir(tmpdir):
p = Path(tmpdir) / 'testfile.csv'
Run Code Online (Sandbox Code Playgroud)
我不是str()每次都插入,而是更普遍地解决这个问题,但不能.
首先,我尝试使自己的Path类具有适应性_parse_args:
import pytest
from py._path.local import LocalPath
from pathlib import Path, PurePath
def Path(Path):
@classmethod
def _parse_args(cls, args):
parts = []
for a in args:
if isinstance(a, PurePath):
parts += a._parts
elif isinstance(a, str):
# Force-cast str subclasses to str (issue #21127)
parts.append(str(a))
elif isinstance(a, LocalPath):
parts.append(str(a))
else:
raise TypeError(
"argument should be a path or str object, not %r"
% type(a))
return cls._flavour.parse_parts(parts)
def test_subclass(tmpdir):
p = Path(tmpdir) / 'testfile.csv'
Run Code Online (Sandbox Code Playgroud)
这会抛出一个TypeError: unsupported operand type(s) for /: 'NoneType' and 'str'(尝试过PosixPath同样的结果,不希望特定于Linux).
我试图修补猴子Path:
import pytest
from pathlib import Path
def add_tmpdir():
from py._path.local import LocalPath
org_attr = '_parse_args'
stow_attr = '_org_parse_args'
def parse_args_localpath(cls, args):
args = list(args)
for idx, a in enumerate(args):
if isinstance(a, LocalPath):
args[idx] = str(a)
return getattr(cls, stow_attr)(args)
if hasattr(Path, stow_attr):
return # already done
setattr(Path, stow_attr, getattr(Path, org_attr))
setattr(Path, org_attr, parse_args_localpath)
add_tmpdir()
def test_monkeypatch_path(tmpdir):
p = Path(tmpdir) / 'testfile.csv'
Run Code Online (Sandbox Code Playgroud)
这会抛出一个AttributeError: type object 'Path' has no attribute '_flavour'(也就是修补PurePath的猴子).
最后我尝试了包装Path:
import pytest
import pathlib
def Path(*args):
from py._path.local import LocalPath
args = list(args)
for idx, a in enumerate(args):
if isinstance(a, LocalPath):
args[idx] = str(a)
return pathlib.Path(*args)
def test_tmpdir_path(tmpdir):
p = Path(tmpdir) / 'testfile.csv'
Run Code Online (Sandbox Code Playgroud)
哪个也给了 AttributeError: type object 'Path' has no attribute '_flavour'
我认为最后一个有效,但我无法重现.
难道我做错了什么?为什么这么难?
如果其他人正在研究pytest的tmpdir路径是否与pathlib.Path以下方法配合得很好:
使用python 3.6.5和pytest 3.2.1,问题中发布的代码可以很好地工作,而无需显式转换为str:
from pathlib import Path
def test_tmpdir(tmpdir):
p = Path(tmpdir) / 'testfile.csv'
Run Code Online (Sandbox Code Playgroud)
py.test最后一个(包装)应该可以工作,我怀疑你实际上在一次/运行中测试了所有这些,tox并且猴子补丁仍然有效(这可能解释了为什么它在某些时候起作用,测试文件的顺序等很重要,如果你开始改变全局类上的东西)。
这很困难,因为Path本质上是一个生成器,它会动态决定您是在 Windows 还是 Linux 上,并创建一个WindowsPath响应。PosixPath因此。
BDFL Guido van Rossum 已于2015 年 5 月表示:
听起来确实应该使子类化 Path 变得更容易。
但什么也没发生。pathlib3.6 中对其他标准库的支持有所增加,但 pathlib 本身仍然存在相同的问题。
| 归档时间: |
|
| 查看次数: |
2043 次 |
| 最近记录: |