2017-08-07 1 views
2

Je suis en train d'écrire des cas de tests unitaires. Je crée un objet de fichier et de le lire, mais je reçois l'erreur suivante:type d'opérande non pris en charge (s) pour <<: « str » et « int » en lisant le fichier

unsupported operand type(s) for <<: 'str' and 'int'

Méthode:

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 

Mon code d'essai:

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' 

données dans le fichier 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': ''}] 

Traceback:

 (py_3.5_dj_1.9) [email protected]:~/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 

Le code lance une exception en lisant cette ligne:

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

C'est ce que je l'ai fait. Je crée un fichier, le stocke dans le répertoire, puis l'ouvre et crée un objet dans la mémoire, comme indiqué dans le code. Selon l'erreur, je comprends que cette erreur se produit lorsque vous essayez de comparer une chaîne à int. mais je ne comprends pas pourquoi cela se produit dans la lecture du fichier, et où.

Est-ce que quelqu'un sait quel est le problème?

+2

Pouvez-vous inclure la trace de la pile que vous voyez dans votre question? Pour ce que ça vaut, le message d'erreur que vous avez montré implique l'opérateur de décalage de bits (<<), que je ne vois pas dans votre code, donc je devine que le code de la bibliothèque que vous utilisez lance l'erreur. La trace de pile aidera à affiner les paramètres qui pourraient causer le problème. –

+0

J'ai ajouté traceback, même si je télécharge un fichier txt qui pose toujours le même problème. Je pense que le problème se produit en lisant le fichier. Je serai très reconnaissant si quelqu'un peut me donner la solution de ce problème. –

+0

Cela ressemble à un problème avec xlrd, mais je ne trouve pas de solution en ligne et je ne suis pas familier avec cette bibliothèque. Si vous modifiez la ligne 'xlrd.open_workbook (file_contents = upload_file.read())' 'à xlrd.open_workbook (nom = 'nom de fichier sur-disk.xls')', où vous avez enregistré au large de la déposer le contenu dans un fichier réel, le problème persiste-t-il? –

Répondre

2

Ouvrez le fichier en mode binaire:

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

Par défaut, les fichiers sont ouverts en mode 'r', qui se lit dans le fichier en tant que flux de caractères Unicode (type str sur Python 3). Cette méthode get2bytes dans xlrd attend un flux d'octets, qui est retourné lors de l'ouverture du fichier en mode 'rb'.

Cette exigence semble être mal documentée par xlrd, qui indique que tout "string or an mmap.mmap object or some other behave-alike object" fera l'affaire file_contents. En regardant dans le code, BYTES_ORD est defined as the identity function on Python 3, de sorte que lorsque file_contents est passé dans get2bytes, une goutte str se traduira par 'c'[0] << 8, qui échoue, mais une tache bytes se traduira par b'c'[0] << 8, qui succède (parce que chaque élément d'une goutte bytes est un int).

+0

Cela fonctionne. Merci beaucoup. –