Bug 1950315 - python-ipyparallel fails to build with Python 3.10: E dateutil.parser._parser.ParserError: String does not contain a date: b''
Summary: python-ipyparallel fails to build with Python 3.10: E dateutil.parser._parser...
Keywords:
Status: CLOSED RAWHIDE
Alias: None
Product: Fedora
Classification: Fedora
Component: python-ipyparallel
Version: rawhide
Hardware: Unspecified
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Mattias Ellert
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks: PYTHON3.10
TreeView+ depends on / blocked
 
Reported: 2021-04-16 11:45 UTC by Tomáš Hrnčiar
Modified: 2021-05-06 16:39 UTC (History)
3 users (show)

Fixed In Version: python-ipyparallel-6.3.0-6.fc35
Doc Type: If docs needed, set a value
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-05-06 16:39:26 UTC
Type: Bug
Embargoed:


Attachments (Terms of Use)

Description Tomáš Hrnčiar 2021-04-16 11:45:47 UTC
python-ipyparallel fails to build with Python 3.10.0a7.

=================================== FAILURES ===================================
_______________________ TestSQLiteBackend.test_datetime ________________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_datetime>

    def test_datetime(self):
        """get/set timestamps with datetime objects"""
        msg_id = self.db.get_history()[-1]
>       rec = self.db.get_record(msg_id)

ipyparallel/tests/test_db.py:148: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:354: in get_record
    cursor = self._db.execute("""SELECT * FROM '%s' WHERE msg_id==?"""%self.table, (msg_id,))
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
______________________ TestSQLiteBackend.test_drop_record ______________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_drop_record>

    def test_drop_record(self):
        msg_id = self.load_records()[-1]
>       rec = self.db.get_record(msg_id)

ipyparallel/tests/test_db.py:60: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:354: in get_record
    cursor = self._db.execute("""SELECT * FROM '%s' WHERE msg_id==?"""%self.table, (msg_id,))
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
____________________ TestSQLiteBackend.test_find_records_dt ____________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_find_records_dt>

    def test_find_records_dt(self):
        """test finding records by date"""
        hist = self.db.get_history()
>       middle = self.db.get_record(hist[len(hist)//2])

ipyparallel/tests/test_db.py:91: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:354: in get_record
    cursor = self._db.execute("""SELECT * FROM '%s' WHERE msg_id==?"""%self.table, (msg_id,))
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
____________________ TestSQLiteBackend.test_find_records_in ____________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_find_records_in>

    def test_find_records_in(self):
        """test finding records with '$in','$nin' operators"""
        hist = self.db.get_history()
        even = hist[::2]
        odd = hist[1::2]
>       recs = self.db.find_records({ 'msg_id' : {'$in' : even}})

ipyparallel/tests/test_db.py:127: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:416: in find_records
    cursor = self._db.execute(query, args)
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
___________________ TestSQLiteBackend.test_find_records_keys ___________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_find_records_keys>

    def test_find_records_keys(self):
        """test extracting subset of record keys"""
>       found = self.db.find_records({'msg_id': {'$ne' : ''}},keys=['submitted', 'completed'])

ipyparallel/tests/test_db.py:106: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:416: in find_records
    cursor = self._db.execute(query, args)
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
__________________ TestSQLiteBackend.test_find_records_msg_id __________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_find_records_msg_id>

    def test_find_records_msg_id(self):
        """ensure msg_id is always in found records"""
>       found = self.db.find_records({'msg_id': {'$ne' : ''}},keys=['submitted', 'completed'])

ipyparallel/tests/test_db.py:112: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:416: in find_records
    cursor = self._db.execute(query, args)
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
______________________ TestSQLiteBackend.test_get_history ______________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_get_history>

    def test_get_history(self):
        msg_ids = self.db.get_history()
        latest = datetime(1984,1,1).replace(tzinfo=utc)
        for msg_id in msg_ids:
>           rec = self.db.get_record(msg_id)

ipyparallel/tests/test_db.py:138: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:354: in get_record
    cursor = self._db.execute("""SELECT * FROM '%s' WHERE msg_id==?"""%self.table, (msg_id,))
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
_________________________ TestSQLiteBackend.test_null __________________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_null>

    def test_null(self):
        """test None comparison queries"""
        msg_ids = self.load_records(10)
    
        query = {'msg_id' : None}
        recs = self.db.find_records(query)
        self.assertEqual(len(recs), 0)
    
        query = {'msg_id' : {'$ne' : None}}
>       recs = self.db.find_records(query)

ipyparallel/tests/test_db.py:170: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:416: in find_records
    cursor = self._db.execute(query, args)
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
_____________________ TestSQLiteBackend.test_pop_safe_find _____________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_pop_safe_find>

    def test_pop_safe_find(self):
        """editing query results shouldn't affect record [find]"""
        msg_id = self.db.get_history()[-1]
>       rec = self.db.find_records({'msg_id' : msg_id})[0]

ipyparallel/tests/test_db.py:188: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:416: in find_records
    cursor = self._db.execute(query, args)
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
__________________ TestSQLiteBackend.test_pop_safe_find_keys ___________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_pop_safe_find_keys>

    def test_pop_safe_find_keys(self):
        """editing query results shouldn't affect record [find+keys]"""
        msg_id = self.db.get_history()[-1]
        rec = self.db.find_records({'msg_id' : msg_id}, keys=['buffers', 'header'])[0]
        rec.pop('buffers')
        rec['garbage'] = 'hello'
        rec['header']['msg_id'] = 'fubar'
>       rec2 = self.db.find_records({'msg_id' : msg_id})[0]

ipyparallel/tests/test_db.py:204: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:416: in find_records
    cursor = self._db.execute(query, args)
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
_____________________ TestSQLiteBackend.test_pop_safe_get ______________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_pop_safe_get>

    def test_pop_safe_get(self):
        """editing query results shouldn't affect record [get]"""
        msg_id = self.db.get_history()[-1]
>       rec = self.db.get_record(msg_id)

ipyparallel/tests/test_db.py:176: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:354: in get_record
    cursor = self._db.execute("""SELECT * FROM '%s' WHERE msg_id==?"""%self.table, (msg_id,))
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
_____________________ TestSQLiteBackend.test_update_record _____________________

self = <ipyparallel.tests.test_db.TestSQLiteBackend testMethod=test_update_record>

    def test_update_record(self):
        now = self._round_to_millisecond(util.utcnow())
        msg_id = self.db.get_history()[-1]
>       rec1 = self.db.get_record(msg_id)

ipyparallel/tests/test_db.py:73: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
ipyparallel/controller/sqlitedb.py:354: in get_record
    cursor = self._db.execute("""SELECT * FROM '%s' WHERE msg_id==?"""%self.table, (msg_id,))
ipyparallel/controller/sqlitedb.py:92: in _convert_timestamp
    return ensure_timezone(dateutil_parse(s))
/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:1374: in parse
    return DEFAULTPARSER.parse(timestr, **kwargs)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <dateutil.parser._parser.parser object at 0x7fd4bbfc6980>, timestr = b''
default = datetime.datetime(2021, 4, 13, 0, 0), ignoretz = False, tzinfos = None
kwargs = {}, res = _result(), skipped_tokens = None

    def parse(self, timestr, default=None,
              ignoretz=False, tzinfos=None, **kwargs):
        """
        Parse the date/time string into a :class:`datetime.datetime` object.
    
        :param timestr:
            Any date/time string using the supported formats.
    
        :param default:
            The default datetime object, if this is a datetime object and not
            ``None``, elements specified in ``timestr`` replace elements in the
            default object.
    
        :param ignoretz:
            If set ``True``, time zones in parsed strings are ignored and a
            naive :class:`datetime.datetime` object is returned.
    
        :param tzinfos:
            Additional time zone names / aliases which may be present in the
            string. This argument maps time zone names (and optionally offsets
            from those time zones) to time zones. This parameter can be a
            dictionary with timezone aliases mapping time zone names to time
            zones or a function taking two parameters (``tzname`` and
            ``tzoffset``) and returning a time zone.
    
            The timezones to which the names are mapped can be an integer
            offset from UTC in seconds or a :class:`tzinfo` object.
    
            .. doctest::
               :options: +NORMALIZE_WHITESPACE
    
                >>> from dateutil.parser import parse
                >>> from dateutil.tz import gettz
                >>> tzinfos = {"BRST": -7200, "CST": gettz("America/Chicago")}
                >>> parse("2012-01-19 17:21:00 BRST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21, tzinfo=tzoffset(u'BRST', -7200))
                >>> parse("2012-01-19 17:21:00 CST", tzinfos=tzinfos)
                datetime.datetime(2012, 1, 19, 17, 21,
                                  tzinfo=tzfile('/usr/share/zoneinfo/America/Chicago'))
    
            This parameter is ignored if ``ignoretz`` is set.
    
        :param \\*\\*kwargs:
            Keyword arguments as passed to ``_parse()``.
    
        :return:
            Returns a :class:`datetime.datetime` object or, if the
            ``fuzzy_with_tokens`` option is ``True``, returns a tuple, the
            first element being a :class:`datetime.datetime` object, the second
            a tuple containing the fuzzy tokens.
    
        :raises ParserError:
            Raised for invalid or unknown string format, if the provided
            :class:`tzinfo` is not in a valid format, or if an invalid date
            would be created.
    
        :raises TypeError:
            Raised for non-string or character stream input.
    
        :raises OverflowError:
            Raised if the parsed date exceeds the largest valid C integer on
            your system.
        """
    
        if default is None:
            default = datetime.datetime.now().replace(hour=0, minute=0,
                                                      second=0, microsecond=0)
    
        res, skipped_tokens = self._parse(timestr, **kwargs)
    
        if res is None:
            raise ParserError("Unknown string format: %s", timestr)
    
        if len(res) == 0:
>           raise ParserError("String does not contain a date: %s", timestr)
E           dateutil.parser._parser.ParserError: String does not contain a date: b''

/usr/lib/python3.10/site-packages/dateutil/parser/_parser.py:652: ParserError
=============================== warnings summary ===============================
ipyparallel/util.py:16
  /builddir/build/BUILD/ipyparallel-6.3.0/ipyparallel/util.py:16: DeprecationWarning: The distutils package is deprecated and slated for removal in Python 3.12. Use setuptools or check PEP 632 for potential alternatives
    from distutils.version import LooseVersion as V

ipyparallel/client/view.py:8
  /builddir/build/BUILD/ipyparallel-6.3.0/ipyparallel/client/view.py:8: DeprecationWarning: the imp module is deprecated in favour of importlib and slated for removal in Python 3.12; see the module's documentation for alternative uses
    import imp

ipyparallel/tests/test_magics.py::TestParallelMagics::test_autopx_blocking
ipyparallel/tests/test_magics.py::TestParallelMagics::test_autopx_nonblocking
  /builddir/build/BUILD/ipyparallel-6.3.0/ipyparallel/client/magics.py:388: DeprecationWarning: "@coroutine" decorator is deprecated since Python 3.8, use "async def" instead
    pxrun_nodes = coroutine(pxrun_nodes)

ipyparallel/tests/test_serialize.py::test_numpy
  /builddir/build/BUILD/ipyparallel-6.3.0/ipyparallel/tests/test_serialize.py:79: DeprecationWarning: Importing from numpy.testing.utils is deprecated since 1.15.0, import from numpy.testing instead.
    from numpy.testing.utils import assert_array_equal

-- Docs: https://docs.pytest.org/en/stable/warnings.html
=========================== short test summary info ============================
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_datetime - dateu...
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_drop_record - da...
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_find_records_dt
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_find_records_in
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_find_records_keys
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_find_records_msg_id
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_get_history - da...
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_null - dateutil....
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_pop_safe_find - ...
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_pop_safe_find_keys
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_pop_safe_get - d...
FAILED ipyparallel/tests/test_db.py::TestSQLiteBackend::test_update_record - ...
= 12 failed, 284 passed, 26 skipped, 6 deselected, 1 xfailed, 1 xpassed, 5 warnings in 115.00s (0:01:55) =

For the build logs, see:
https://copr-be.cloud.fedoraproject.org/results/@python/python3.10/fedora-rawhide-x86_64/02130812-python-ipyparallel/

For all our attempts to build python-ipyparallel with Python 3.10, see:
https://copr.fedorainfracloud.org/coprs/g/python/python3.10/package/python-ipyparallel/

Testing and mass rebuild of packages is happening in copr. You can follow these instructions to test locally in mock if your package builds with Python 3.10:
https://copr.fedorainfracloud.org/coprs/g/python/python3.10/

Let us know here if you have any questions.

Python 3.10 will be included in Fedora 35. To make that update smoother, we're building Fedora packages with early pre-releases of Python 3.10.
A build failure prevents us from testing all dependent packages (transitive [Build]Requires), so if this package is required a lot, it's important for us to get it fixed soon.
We'd appreciate help from the people who know this package best, but if you don't want to work on this now, let us know so we can try to work around it on our side.

Comment 1 Mattias Ellert 2021-04-18 07:00:40 UTC
Hi!

These test failures are due to a regression in python:

https://bugs.python.org/issue43752

It is already fixed upstream:

https://github.com/python/cpython/pull/25228

And merged:

https://github.com/python/cpython/commit/6f1e8ccffa5b1272a36a35405d3c4e4bbba0c082

Rebuilding python-ipyparallel using a python 3.10 build with the above commit added as an additional patch succeeds.

Nothing to be done here - needs to be fixed in python.

Comment 2 Tomáš Hrnčiar 2021-04-19 06:33:45 UTC
Hello,

thanks for the links. Seems like it was fixed in the master branch so it should be released in Python 3.10.0b1 coming in 2 weeks. Let's keep it open for now so it doesn't show up in our automation as "broken & unreported".

Comment 3 Mattias Ellert 2021-05-06 16:39:26 UTC
The sqlite related failures in this report were fixed by the 3.10.0b1 update.
However, some other issues appeared related to some deprecation warnings that caused some other test failures.
The python-ipyparallel-6.3.0-6.fc35 addresses these new issues.
This version builds with python 3.10:
https://copr.fedorainfracloud.org/coprs/g/python/python3.10/package/python-ipyparallel/


Note You need to log in before you can comment on or make changes to this bug.