You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
parse_wpc_surface_bulletin does not handle StringIO object, results in AttributeError: 'str' object has no attribute 'decode' #3923
Traceback (most recent call last):
File "metpy_example.py", line 11, in <module>
parse_wpc_surface_bulletin(sio, year=2000)
~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^
File "/home/akrherz/projects/MetPy/src/metpy/io/text.py", line 102, in parse_wpc_surface_bulletin
text =file.read().decode('utf-8')
^^^^^^^^^^^^^^^^^^AttributeError: 'str' object has no attribute 'decode'. Did you mean: 'encode'?
@akrherz This should work fine if you replace StringIO with BytesIO. I'm not sure how we can detect whether the decode() call is needed without some ugly type-checking for what read() returns.
Given that text comes from a call to read(), this isn't so bad. At the same time, I hesitate because this is essentially undoing/revisiting what was an important Python 2->3 change; I just wonder if we're opening a door to a bunch of complicated problems.
In that case, you'll want to document that parse_wpc_surface_bulletin only accepts ASCII- or UTF-8-encoded binary-mode file-like objects, not text-mode file-like objects nor binary-mode file-like objects with different encodings, so they don't try
You may also want to make a general statement on the metpy.io page that all files are expected to be passed in binary mode, and therefore in-memory examples should use io.BytesIO rather than io.StringIO, to explain why a file with requirements for its text encoding is expected as a binary-mode file rather than a text-mode file
(Alternately, add an encoding argument to parse_wpc_surface_bulletin and open_if_needed, defaulting to UTF-8 in the former and None in the latter, since you expect the file to contain text)
Activity
dopplershift commentedon Sep 26, 2025
@akrherz This should work fine if you replace
StringIOwithBytesIO. I'm not sure how we can detect whether thedecode()call is needed without some ugly type-checking for whatread()returns.DWesl commentedon May 9, 2026
Checking whether decode is possible/succeeds would be simpler:
dopplershift commentedon May 11, 2026
Given that
textcomes from a call toread(), this isn't so bad. At the same time, I hesitate because this is essentially undoing/revisiting what was an important Python 2->3 change; I just wonder if we're opening a door to a bunch of complicated problems.DWesl commentedon May 12, 2026
In that case, you'll want to document that
parse_wpc_surface_bulletinonly accepts ASCII- or UTF-8-encoded binary-mode file-like objects, not text-mode file-like objects nor binary-mode file-like objects with different encodings, so they don't trybut instead
or run the file through
iconvbefore attempting to open it(or even
)
You may also want to make a general statement on the
metpy.iopage that all files are expected to be passed in binary mode, and therefore in-memory examples should useio.BytesIOrather thanio.StringIO, to explain why a file with requirements for its text encoding is expected as a binary-mode file rather than a text-mode file(Alternately, add an
encodingargument toparse_wpc_surface_bulletinandopen_if_needed, defaulting to UTF-8 in the former andNonein the latter, since you expect the file to contain text)