-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make bool(CANothing)
always return True
#45
Comments
Suggestion:
|
Can't make the warning in aioca as this will be too noisy because of the |
This issue is exasperating, because it arises from a combination of two mistakes:
I have raised DiamondLightSource/cothread#67 against https://github.com/DiamondLightSource/cothread |
Unfortunately we cannot just delete the implementation of I don't know what a suitable fix is. |
@coretl , can you please expand on the underlying issue here? Are you catching In a little more detail with "bikeshed" names: class ca_nothing_exception(Exception):
...
class ca_nothing:
...
def __bool__(self): return self.ok and when Am not sure what this would break. |
Here's another option, we give That covers the majority use case of truthiness with |
Yes, this is what the Task/Future interface in asyncio is doing. The co-routine calls
Snap! Yes, that makes sense. I think your solution of splitting into 2 classes rather than mine of an So |
Yes, and I think this should be easy enough to implement. Unfortunately I think we're stuck with the Here is my first thought for a patch against cothread; I imagine an aioca patch would be similar: diff --git a/src/cothread/catools.py b/src/cothread/catools.py
index a209829..069a062 100644
--- a/src/cothread/catools.py
+++ b/src/cothread/catools.py
@@ -83,10 +83,9 @@ K = 1024
CA_ACTION_STACK = _check_env('CATOOLS_ACTION_STACK', 0)
-class ca_nothing(Exception):
+class ca_nothing:
'''This value is returned as a success or failure indicator from caput,
- as a failure indicator from caget, and may be raised as an exception to
- report a data error on caget or caput with wait.'''
+ or as a failure indicator from caget.'''
def __init__(self, name, errorcode = cadef.ECA_NORMAL):
'''Initialise with PV name and associated errorcode.'''
@@ -102,13 +101,34 @@ class ca_nothing(Exception):
def __bool__(self):
return self.ok
- __nonzero__ = __bool__ # For python 2
+
+# Naming convention compatible alias
+CANothing = ca_nothing
+
+
+class ca_nothing_exception(Exception):
+ '''This exception may be raised as an exception to report a data error on
+ caget or caput with wait.'''
+
+ def __init__(self, name, errorcode = cadef.ECA_NORMAL):
+ '''Initialise with PV name and associated errorcode.'''
+ self.ok = errorcode == cadef.ECA_NORMAL
+ self.name = name
+ self.errorcode = errorcode
+
+ def __repr__(self):
+ return 'ca_nothing_exception(%r, %d)' % (self.name, self.errorcode)
+
+ def __str__(self):
+ return '%s: %s' % (self.name, cadef.ca_message(self.errorcode))
def __iter__(self):
'''This is *not* supposed to be an iterable object, but the base class
appears to have a different opinion. So enforce this.'''
raise TypeError('iteration over non-sequence')
+CANothingException = ca_nothing_exception
+
def maybe_throw(function):
'''Function decorator for optionally catching exceptions. Exceptions
@@ -125,8 +145,8 @@ def maybe_throw(function):
# will be raised anyway, which seems fair enough!
try:
return function(pv, *args, **kargs)
- except ca_nothing as error:
- return error
+ except ca_nothing_exception as error:
+ return ca_nothing(error.name, error.errorcode)
except cadef.CAException as error:
return ca_nothing(pv, error.status)
except cadef.Disconnected:
@@ -145,7 +165,7 @@ def ca_timeout(event, timeout, name):
try:
return event.Wait(timeout)
except cothread.Timedout as timeout:
- raise ca_nothing(name, cadef.ECA_TIMEOUT) from timeout
+ raise ca_nothing_exception(name, cadef.ECA_TIMEOUT) from timeout
# ----------------------------------------------------------------------------
@@ -593,7 +613,8 @@ def _caget_event_handler(args):
else:
cothread.Callback(done.Signal, value)
else:
- cothread.Callback(done.SignalException, ca_nothing(pv, args.status))
+ cothread.Callback(
+ done.SignalException, ca_nothing_exception(pv, args.status))
@maybe_throw
@@ -772,7 +793,8 @@ def _caput_event_handler(args):
if args.status == cadef.ECA_NORMAL:
cothread.Callback(done.Signal)
else:
- cothread.Callback(done.SignalException, ca_nothing(pv, args.status))
+ cothread.Callback(
+ done.SignalException, ca_nothing_exception(pv, args.status))
if callback is not None:
cothread.Callback(callback, ca_nothing(pv, args.status))
Exceptions are raised in fewer places than I was expecting. |
https://github.com/dls-controls/aioca/blob/12a0a68c249b90cd375b9432ed438c7a7e85ab97/aioca/_catools.py#L92-L93
Causes issues with various python internals, like
concurrent.futures.result
which does:https://github.com/python/cpython/blob/d5a8d4b19670b930cd6cb5e18e267877ebe49233/Lib/concurrent/futures/_base.py#L399
So if we put a
CANothing
in as a result it shows as no exception...The text was updated successfully, but these errors were encountered: