pathlib路径和py.test LocalPath [英] pathlib Path and py.test LocalPath

查看:139
本文介绍了pathlib路径和py.test LocalPath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一段时间前,我已经开始使用pathlib.Path,我喜欢使用它.现在我已经习惯了,我变得草率,忘了将参数强制转换为str.

I have started using pathlib.Path some time ago and I like using it. Now that I have gotten used to it, I have gotten sloppy and forget to cast arguments to str.

当将tox + py.test与基于tmpdir(它是py._path.local.LocalPath)的临时目录一起使用时,通常会发生这种情况:

This often happens when using tox + py.test with temporary directories based on tmpdir (which is a py._path.local.LocalPath):

from pathlib import Path
import pytest

def test_tmpdir(tmpdir):
    p = Path(tmpdir) / 'testfile.csv'

我不是每次都插入str(),而是着眼于更广泛地解决此问题,但不能这样做.

Instead of inserting str() every time, I looked at solving this more generally, but could not.

首先,我尝试制作自己的具有修改后的_parse_args的Path类:

First I tried to make my own Path class that has an adapted _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'

这将抛出一个TypeError: unsupported operand type(s) for /: 'NoneType' and 'str'(也尝试与PosixPath进行相同的结果,所以不希望它不是Linux专用的.)

This throws a TypeError: unsupported operand type(s) for /: 'NoneType' and 'str' (tried with PosixPath as well, same result, would prefer not to be Linux specific).

我试图猴子修补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'

这会抛出一个AttributeError: type object 'Path' has no attribute '_flavour'(也在猴子修补PurePath时).

This throws a AttributeError: type object 'Path' has no attribute '_flavour' (also when monkey-patching 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'

还给出了AttributeError: type object 'Path' has no attribute '_flavour'

我认为最后一点在某些时候可行,但我无法重现.
我做错什么了吗?为什么这么难?

I thought at some point this last one worked, but I cannot reproduce that.
Am I doing something wrong? Why is this so hard?

推荐答案

最后一个(包装)应该可以工作,我怀疑您实际上是在一次py.test/tox运行中测试了所有这些功能,并且认为猴子补丁是仍然有效(如果您开始更改全局类上的内容,这可能会解释为什么它在某些时候起作用,测试文件的顺序等等很重要).

That last one (wrapping) should work, I suspect you actually test all of these in one py.test/tox run and that monkey-patch is still in effect (that might explain why it worked at some point, the order of the test files etc matters if you start to change things on global classes).

之所以很难,是因为Path本质上是一个生成器,它会即时决定您使用的是Windows还是Linux,并创建一个WindowsPath响应. PosixPath相应.

That this is hard, is because of Path essentially being a generator, that on the fly decides whether you are on Windows or Linux, and creates a WindowsPath resp. PosixPath accordingly.

BDFL Guido van Rossum已于2015年5月表示 :

BDFL Guido van Rossum already indicated in May 2015:

听起来确实应该简化子类化Path.

It does sound like subclassing Path should be made easier.

但是什么也没发生.其他标准库在3.6中对pathlib的支持有所增加,但是pathlib本身仍然存在相同的问题.

but nothing happened. Support for pathlib in 3.6 within other standard libraries has increased, but pathlib itself still has the same problems.

这篇关于pathlib路径和py.test LocalPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆