bluesky / bluesky-widgets

Components for graphical applications that interact with bluesky libraries
http://blueskyproject.io/bluesky-widgets
BSD 3-Clause "New" or "Revised" License
5 stars 21 forks source link

Error handling old datetimes (ADA_LOVELACE_BIRTHDAY) #115

Open ronpandolfi opened 3 years ago

ronpandolfi commented 3 years ago

I'm receiving the following error. Qt is able to recover from this normally, however (as a side effect) this causes a hard crash in certain debugging modes.

 Traceback (most recent call last):
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\bluesky_live\event.py", line 514, in _invoke_callback
    cb(event)
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\bluesky_widgets\qt\_search_input.py", line 207, in on_since_model_changed
    qdatetime = as_qdatetime(event.date)
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\bluesky_widgets\qt\_search_input.py", line 22, in as_qdatetime
    int(secs_since_epoch(datetime) - datetime.utcoffset() / timedelta(seconds=1))
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\dateutil\tz\tz.py", line 222, in utcoffset
    if self._isdst(dt):
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\dateutil\tz\tz.py", line 291, in _isdst
    dstval = self._naive_is_dst(dt)
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\dateutil\tz\tz.py", line 260, in _naive_is_dst
    return time.localtime(timestamp + time.timezone).tm_isdst
 OSError: [Errno 22] Invalid argument

The above exception was the direct cause of the following exception:

 Traceback (most recent call last):
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\bluesky_widgets\qt\_search_input.py", line 253, in on_toggle_all
    self.model.since = ADA_LOVELACE_BIRTHDAY
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\bluesky_widgets\models\search.py", line 349, in since
    self.events.since(date=since)
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\bluesky_live\event.py", line 499, in __call__
    self._invoke_callback(cb, event)
   File "C:\Users\LBL\.virtualenvs\xi-cam\lib\site-packages\bluesky_live\event.py", line 522, in _invoke_callback
    raise CallbackException(message) from err
 bluesky_live.event.CallbackException: Encountered exception while processing Event <Event blocked=False handled=False native=None source=<SearchInput {}> sources=[<SearchInput {}>] type=since> from <SearchInput {}> with callback <bound method QtSearchInput.on_since_model_changed of <bluesky_widgets.qt._search_input.QtSearchInput object at 0x0000021EAC3B1670>>

I've confirmed that datetime.utcoffset() is failing because timestamp is a negative value. Is ADA_LOVELACE_BIRTHDAY too far back? Here is a glimpse at the contents of the datetime var: image

@ihumphrey

ronpandolfi commented 3 years ago

Modifying this default minimum datetime to the lowest possible timestamp value datetime(1970, 1, 1, tzinfo=LOCAL_TIMEZONE) would fix this issue.

danielballan commented 3 years ago

That's too bad, using ADA_LOVELACE_BIRTHDAY was a nice touch of @JulReinhardt's.

Is it generically the case that time.localtime(timestamp + time.timezone).tm_isdst just doesn't work on historical times, times before 1970?

ronpandolfi commented 3 years ago

I'm getting different behaviors on different environments. On 3.8.1, time.localtime(-1) breaks; on 3.9.2 it works.

Edit: added patch number to versions, fyi

danielballan commented 3 years ago

Interesting. I guess our options are:

  1. Find another API for this that is not broken in some versions of Python.
  2. Give up and change the default date.

(2) would be unsatisfying but if no one finds time for (1) in the near future it’s fair to consider it.

danielballan commented 3 years ago

@ronpandolfi I haven't had time to circle back to this yet. Do you have time to submit a PR? To put in writing what we agreed on the call, I'm fine with (2) for expedience but we should open a GitHub issue to track down the underlying problem. I suspect we are misusing an API. If times-before-1970 actually broke between Python releases I am sure it would be a Big Deal.

I had hoped to get to this myself, but it's not going to happen this week.

whs92 commented 2 years ago

I have just seen this error for the first time use python 3.9.5, trying to run on Windows 10.

I am unable to start bluesky-widgets-demo because of it. I tried changing the default date to a time after the unix epoch so that it wasn't negative:

ADA_LOVELACE_BIRTHDAY = datetime(1970, 1, 2, tzinfo=LOCAL_TIMEZONE)

But then I get another error and still can't start the application:

QLayout: Attempting to add QLayout "" to QtSearchInput "", which already has a layout
c:\users\sissy_user\bluesky\bluesky-widgets\bluesky_widgets\models\search.py:128: PytzUsageWarning: The zone attribute is specific to pytz's interface; please migrate to a new time zone provider. For more details on how to do so, see https://pytz-deprecation-shim.readthedocs.io/en/latest/migration.html
  timezone = tzlocal.get_localzone().zone
Traceback (most recent call last):
  File "c:\users\sissy_user\bluesky\bluesky-widgets\bluesky_widgets\qt\threading.py", line 117, in run
    self.returned.emit(result)
  File "c:\users\sissy_user\bluesky\bluesky-widgets\bluesky_widgets\qt\threading.py", line 66, in __getattr__
    return getattr(self._signals, name)
RuntimeError: wrapped C/C++ object of type WorkerBaseSignals has been deleted

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\sissy_user\bluesky\bluesky-widgets\bluesky_widgets\qt\threading.py", line 119, in run
    self.errored.emit(exc)
  File "c:\users\sissy_user\bluesky\bluesky-widgets\bluesky_widgets\qt\threading.py", line 66, in __getattr__
    return getattr(self._signals, name)
RuntimeError: wrapped C/C++ object of type WorkerBaseSignals has been deleted

Is this a red herring? I am not really sure where to look the error message doesn't tell me much that I understand. @ronpandolfi in the original error report you mention that you only see this cause a crash in certain debugging modes. How do I find out what mode I am in?