tz.tzstr() fails on parsing timezone data file

Bug #1331576 reported by marcog
10
This bug affects 2 people
Affects Status Importance Assigned to Milestone
dateutil
New
Undecided
Unassigned

Bug Description

With dateutil 2.2, I can't get the tzstr examples working (see below). It throws an error 'str' object has no attribute 'read'. Looking at the code, it fails on self.instream.read(1) while parsing the timezone data file. It works fine on dateutil 2.1.

In [3]: import dateutil.tz

In [4]: dateutil.tz.tzstr('EST5EDT')
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-4-75889fcde3a9> in <module>()
----> 1 dateutil.tz.tzstr("PST")

/Library/Python/2.7/site-packages/dateutil/tz.pyc in __init__(self, s)
    579 self._s = s
    580
--> 581 res = parser._parsetz(s)
    582 if res is None:
    583 raise ValueError("unknown string format")

/Library/Python/2.7/site-packages/dateutil/parser.pyc in _parsetz(tzstr)
    923 DEFAULTTZPARSER = _tzparser()
    924 def _parsetz(tzstr):
--> 925 return DEFAULTTZPARSER.parse(tzstr)
    926
    927

/Library/Python/2.7/site-packages/dateutil/parser.pyc in parse(self, tzstr)
    770 def parse(self, tzstr):
    771 res = self._result()
--> 772 l = _timelex.split(tzstr)
    773 try:
    774

/Library/Python/2.7/site-packages/dateutil/parser.pyc in split(cls, s)
    148
    149 def split(cls, s):
--> 150 return list(cls(s))
    151 split = classmethod(split)
    152

Revision history for this message
Vincent Veselosky (veselosky) wrote :

This also fails for me with python-dateutil 2.1. In both 2.1 and 2.2, the function works as documented under Python 3.3.3. When I run it under Python 2.7.5 it throws the exception shown above.

Revision history for this message
Adrian Likins (alikins) wrote :

Looks like this only fails on python2 if a non-unicode string is used as the tzstr arg.

dateutil.tz.tzstr('EST5EDT')
FAILS

dateutil.tz.tzstr(u'EST5EDT')
PASSES

dateutil.parser._timelex.__init__:35 seems to do it.

    def __init__(self, instream):
        if isinstance(instream, text_type):
            instream = StringIO(instream)
        self.instream = instream

The isinstance() check fails for a non unicode string.

>>> import six
>>> a = 'EST'
>>> isinstance(a, six.text_type)
False
>>> a = u'EST'
>>> isinstance(a, six.text_type)
True

texttype is from 'six' and gets defined as 'unicode' on python2.

So likely only fails on python2 with non unicode strings passed to tzstr().

test.py has tests for similar usage, but test.py has:

    from __future__ import unicode_literals

Turning that off makes the tzstr tests fail. Our code doesn't use unicode_literals, so
str literals passed in cause the errors mentioned.

Something like this (untested) snippet should work:

if isinstance(instream, basestring):
    instream = StringIO(instream)

Revision history for this message
Paul G (p-ganssle) wrote :

I migrated this bug to the github issue tracker: https://github.com/dateutil/dateutil/issues/51

I have also submitted a PR fixing the problem (correctly identified as having to do with the character encoding): https://github.com/dateutil/dateutil/pull/55

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.