<&lt ;:' str'不支持的操作数类型和' int'在阅读文件时

时间:2017-08-07 12:23:29

标签: python django pytest

我正在编写单元测试用例。我创建一个文件对象并读取它,但我收到以下错误:

  

<&lt ;:' str'不支持的操作数类型和' int'

方法:

def uploadExamineeDetails(request, exam_id):
    try:
        upload_file = request.FILES['upload-file']
    except Exception:
        return [_('Uploaded file is required.')]
    try:
        exam = get_object_or_404_from_admin(CourseExam, request, exam_id)
        book = xlrd.open_workbook(file_contents=upload_file.read())
        # further code

我的测试代码:

def test_uploadExamineeDetails(self):

    self.examinee_result = os.path.join(os.path.dirname(settings.BASE_DIR),\
                                        'var/sample_files_for_testing/examinees_result_upload.xls')
    file = File(open(self.file, errors='ignore'))
    uploaded_file = InMemoryUploadedFile(file=file, field_name='upload-file', name='examinee_result.xls',
                                        content_type = 'application/vnd.ms-excel', size = file.size, charset = None)
    self.request.FILES['upload-file'] = uploaded_file
    xlrd.open_workbook(file_contents=uploaded_file.read())
    response = uploadExamineeDetails(self.request, 1)
    assert isinstance(response, tuple), 'should upload the examinee details'

excel文件中的数据:

[{'Enrollment Number': '', 'Username': 'exam_course_manager',
 'row_num': 1, 'Obtained Score': 60.0, 'GR Number': ''},
 {'Enrollment Number': '', 'Username': 'instructor',
 'row_num': 2, 'Obtained Score': 20.0, 'GR Number': ''}]

回溯:

       (py_3.5_dj_1.9) dikshaj@PTU16SPSD79:~/Projects/DROANA_3.0/droana/droana$ py.test  droana/apps/course_planner/tests/test_methods.py 
============================= test session starts ==============================
platform linux -- Python 3.5.2, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
Django settings: droana.test_settings (from command line option)
rootdir: /home/dikshaj/Projects/DROANA_3.0/droana/droana, inifile: pytest.ini
plugins: django-3.1.2, cov-2.4.0, ipdb-0.1.dev2
collected 1 items 

droana/apps/course_planner/tests/test_methods.py F

----------- coverage: platform linux, python 3.5.2-final-0 -----------
Coverage HTML written to dir htmlcov


=================================== FAILURES ===================================
____________________ TestMethods.test_uploadExamineeDetails ____________________

self = <droana.apps.course_planner.tests.test_methods.TestMethods testMethod=test_uploadExamineeDetails>

    def test_uploadExamineeDetails(self):
        """
            Test uploadExamineeDetails method
            """
        self.examinee_result = os.path.join(os.path.dirname(settings.BASE_DIR),\
                                            'var/sample_files_for_testing/examinees_result_upload.xls')
        file = File(open(self.file, errors='ignore'))
        uploaded_file = InMemoryUploadedFile(file=file, field_name='upload-file', name='examinee_result.xls',
                                            content_type = 'application/vnd.ms-excel', size = file.size, charset = None)
        self.request.FILES['upload-file'] = uploaded_file
>       xlrd.open_workbook(file_contents=uploaded_file.read())

droana/apps/course_planner/tests/test_methods.py:100: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/opt/myvirtual/py_3.5_dj_1.9/lib/python3.5/site-packages/xlrd/__init__.py:435: in open_workbook
    ragged_rows=ragged_rows,
/opt/myvirtual/py_3.5_dj_1.9/lib/python3.5/site-packages/xlrd/book.py:91: in open_workbook_xls
    biff_version = bk.getbof(XL_WORKBOOK_GLOBALS)
/opt/myvirtual/py_3.5_dj_1.9/lib/python3.5/site-packages/xlrd/book.py:1226: in getbof
    opcode = self.get2bytes()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <xlrd.book.Book object at 0x7fb57b458c88>

    def get2bytes(self):
        pos = self._position
        buff_two = self.mem[pos:pos+2]
        lenbuff = len(buff_two)
        self._position += lenbuff
        if lenbuff < 2:
            return MY_EOF
        lo, hi = buff_two
>       return (BYTES_ORD(hi) << 8) | BYTES_ORD(lo)
E       TypeError: unsupported operand type(s) for <<: 'str' and 'int'

/opt/myvirtual/py_3.5_dj_1.9/lib/python3.5/site-packages/xlrd/book.py:631: TypeError

代码在读取此行时抛出异常:

xlrd.open_workbook(file_contents=upload_file.read())

这就是我所做的。我创建一个文件,将其存储在目录中,然后打开它并创建一个内存对象,如代码所示。根据错误我得到的是,当您尝试将字符串与int进行比较时会发生此错误。但我不明白为什么会出现在阅读文件中,以及在哪里。

有人知道问题是什么吗?

1 个答案:

答案 0 :(得分:5)

以二进制模式打开文件:

file = File(open(self.file, 'rb'))

默认情况下,文件以模式'r'打开,模式将文件作为Unicode字符流(在Python 3上键入str)读入。 xlrd中的get2bytes方法需要一个字节流,在'rb'模式下打开文件时会返回该字节流。

这个要求似乎被xlrd错误记录,xlrd表示任何"string or an mmap.mmap object or some other behave-alike object"都会为file_contents做。在查看代码时,BYTES_ORDdefined as the identity function on Python 3,因此当file_contents传递到get2bytes时,str blob将导致'c'[0] << 8,失败,但bytes blob将导致b'c'[0] << 8成功(因为bytes blob中的每个元素都是int)。