可选[Type [Foo]]在Python 3.5.2中引发TypeError

时间:2017-03-22 04:40:21

标签: python python-3.x annotations python-3.5 typing

此代码:

package test;

import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;

public class DirectoryContents {

public static void main(String[] args) throws IOException {

    File f = new File("."); // current directory

    FilenameFilter textFilter = new FilenameFilter() {
        public boolean accept(File dir, String name) {
            String lowercaseName = name.toLowerCase();
            if (lowercaseName.endsWith(".txt")) {
                return true;
            } else {
                return false;
            }
        }
    };

    File[] files = f.listFiles(textFilter);
    for (File file : files) {
        if (file.isDirectory()) {
            System.out.print("directory:");
        } else {
            System.out.print("     file:");
        }
        System.out.println(file.getCanonicalPath());
    }

}

}

将在3.5.2上提升#!/usr/bin/env python from typing import Optional, Type class Foo(object): pass class Bar(Foo): pass def test_me() -> Optional[Type[Foo]]: print("Hi there!") return Bar if __name__ == "__main__": test_me()

TypeError

然而它在3.6上运行良好。如果我将Optional列为Traceback (most recent call last): File "./test.py", line 11, in <module> def test_me() -> Optional[Type[Foo]]: File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 649, in __getitem__ return Union[arg, type(None)] File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 552, in __getitem__ dict(self.__dict__), parameters, _root=True) File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 512, in __new__ for t2 in all_params - {t1} if not isinstance(t2, TypeVar)): File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 512, in <genexpr> for t2 in all_params - {t1} if not isinstance(t2, TypeVar)): File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/typing.py", line 1077, in __subclasscheck__ if super().__subclasscheck__(cls): File "/Users/mnot/.pyenv/versions/3.5.2/lib/python3.5/abc.py", line 225, in __subclasscheck__ for scls in cls.__subclasses__(): TypeError: descriptor '__subclasses__' of 'type' object needs an argument ,则会出现同样的问题。

是否有针对3.5.2的解决方法,同时仍然准确地注释了返回类型?

3 个答案:

答案 0 :(得分:4)

这是Python 3.5.2中的bug

Optional[cls]Union[cls, type(None)]的包装器,它使用__subclasses__()来确定一个类是否是另一个类的子类。

但是,Type是Python 3.5.2中type的子类,这意味着

Union[Type[anything], anything_else]

最终将调用

type.__subclasses__()

...这是一个问题,因为type是一个元类,所以期望用正在寻找其子类的类调用,就像在普通类上调用实例方法需要你一样提供自己的实例,例如str.upper('foo')

通过使Type不再是type的子类,Python 3.5.3中的问题是fixed(并且,正如您已经注意到的那样,3.6)。

答案 1 :(得分:0)

零比雷埃夫斯(Piraeus)

我在使用python 3.5.2时遇到了同样的问题 我已经编辑 usr / lib / python3.5 / typing.py文件

class Type(type, Generic[CT_co], extra=type):

更改为

class Type(Generic[CT_co], extra=type):

然后修复...

答案 2 :(得分:0)

我在python 3.2上遇到了同样的问题

我刚刚安装了较低版本的熊猫

pandas==0.24.2

默认安装版本为

pandas==0.25.1

希望获得帮助。