ecmwf / eccodes-python

Python interface to the ecCodes GRIB/BUFR decoder/encoder
Apache License 2.0
115 stars 33 forks source link

Iterating through eccodes.GribFile throws "ValueError: I/O operation on closed file" #14

Closed blazk closed 1 year ago

blazk commented 4 years ago

I tried running an example similar to https://confluence.ecmwf.int/display/ECC/High-level+Pythonic+Interface+in+ecCodes

#!/usr/bin/env python3

import os, eccodes

input_path = os.path.join(eccodes.codes_samples_path(), 'GRIB2.tmpl')
with eccodes.GribFile(input_path) as grib:
    for msg in grib:
        print(msg['date'])

it throws an error:

Traceback (most recent call last):
  File "./x", line 7, in <module>
    for msg in grib:
ValueError: I/O operation on closed file

This can be fixed by adding ._next_() method in CodesFile class:

    def __next__(self):
        return self.next()

Otherwise ._next_() inherited from the FileIO base class is called and throws "ValueError: I/O operation on closed file".

Maybe fundamentally the problem is CodesFile.__init__() not calling the constructor of its base class (io.FileIO) and as a result CodesFile objects not being properly initialized. The fix above enables iteration, but other stuff still doesn't work properly:

>>> with eccodes.GribFile('sample.grb') as grib:
...     print(grib.closed)
...     print(grib.fileno())
True
Traceback (most recent call last):
  File "<stdin>", line 3, in <module>
ValueError: I/O operation on closed file
cofinoa commented 4 years ago

@blazk as I have also discover, this high level API, needs to be refactored.

I neither understand the io.FileIO as base class for CodesFile

rapto commented 4 years ago

It seems to be fixed in 1.0