2011-07-24 6 views
5

filterous es usingiterparse para analizar un simple XML StringIO object en un unit test. Sin embargo, al intentar acceder al objeto StringIO después, Python sale con un mensaje "ValueError: I/O operation on closed file". De acuerdo con el iterparse documentation, "Comenzando con lxml 2.3, el método .close() también se llamará en el caso de error," pero no aparece ningún mensaje de error Exception de iterparse. Mi IO-foo obviamente no es rápido, ¿alguien tiene sugerencias?lxml.etree.iterparse cierra el manejador de archivos de entrada?

El comando y (con suerte) código relevante:

$ python2.6 setup.py test 

setup.py:

from setuptools import setup 
from filterous import filterous as package 

setup(
    ... 
    test_suite = 'tests.tests', 

pruebas/tests.py:

from cStringIO import StringIO 
import unittest 

from filterous import filterous 

XML = '''<posts tag="" total="3" ...''' 

class TestSearch(unittest.TestCase): 
    def setUp(self): 
     self.xml = StringIO(XML) 
     self.result = StringIO() 
    ... 
    def test_empty_tag_not(self): 
     """Empty tag; should get N results.""" 
     filterous.search(
      self.xml, 
      self.result, 
      {'ntag': [u'']}, 
      ['href'], 
      False) 
     self.assertEqual(
      len(self.result.getvalue().splitlines()), 
      self.xml.getvalue().count('<post ')) 

filterous/filterous.py:

from lxml import etree 
... 
def search(file_pointer, out, terms, includes, human_readable = True): 
    ... 
    context = etree.iterparse(file_pointer, tag='posts') 

Rastreo:

ERROR: Empty tag; should get N results. 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "/home/victor/dev/filterous/tests/tests.py", line 149, in test_empty_tag_not 
    self.xml.getvalue().count('<post ')) 
ValueError: I/O operation on closed file 

PS: Las pruebas de todos corrieron bien en 2010-07-27.

Respuesta

0

Docs-fu es el problema. Lo que citó "Comenzando con lxml 2.3, el método .close() también se llamará en el caso de error," no tiene nada que ver con iterparse. Aparece en su página vinculada antes de la sección en iterparse. Es parte de los documentos para la interfaz del analizador de destino. Se refiere al método close() del objeto target (output!), Nada que ver con su StringIO. En cualquier caso, también parece haber ignorado esa pequeña palabra también. Antes de 2.3, lxml cerró el objeto de destino solo si el análisis fue exitoso. Ahora, también lo cierra al error.

¿Por qué quiere "acceder" al objeto StringIO después de que el análisis ha finalizado?

Actualización Al intentar acceder a la base de datos después, ¿te refieres a todas esas llamadas self.xml.getvalue() en tus pruebas? [¡Muestre el rastreo de ferschlugginer en su pregunta para que no tengamos que adivinar!] Si eso está causando el problema (no cuenta como una operación IO), olvide getvalue() ... si fuera a funcionar, ¿no es así? devolver el XML (no convencionalmente nombrado) (invariante)?

1

Parece que funciona bien con StringIO, intente utilizarlo en lugar de cStringIO. No tengo idea de por qué se está cerrando.

Cuestiones relacionadas