echo icon indicating copy to clipboard operation
echo copied to clipboard

Implement a new type of callback called validators, which get called before a value changes

Open astrofrog opened this issue 1 year ago • 3 comments

This is an experimental pull request adding a new type of callback called 'validators'. The idea here is that one can do e.g.:

In [1]: from echo import HasCallbackProperties, CallbackProperty, ValidationException, SilentValidationException
   ...: 
   ...: class State(HasCallbackProperties):
   ...: 
   ...:     a = CallbackProperty()
   ...:     b = CallbackProperty()
   ...: 
   ...: state = State()
   ...: state.a = 1
   ...: state.b = 2.2
   ...: 

In [2]: def add_one_and_silent_ignore(new_value):
   ...:     if new_value == 'ignore':
   ...:         raise SilentValidationException()
   ...:     return new_value + 1
   ...: 
   ...: def preserve_type(old_value, new_value):
   ...:     if type(new_value) is not type(old_value):
   ...:         raise ValidationException('types should not change')
   ...: 
   ...: state.add_callback('a', add_one_and_silent_ignore, validator=True)
   ...: state.add_callback('b', preserve_type, validator=True, echo_old=True)
   ...: 
   ...: 

In [3]: state.a = 3

In [4]: state.a
Out[4]: 4

In [5]: state.a = 'ignore'

In [6]: state.a
Out[6]: 4

In [7]: state.b = 3.2

In [8]: state.b = 3
---------------------------------------------------------------------------
ValidationException                       Traceback (most recent call last)
...
ValidationException: types should not change

This demonstrates several features:

  • Checks can be carried out on the type and value of the new value (and the old one if echo_old is passed)
  • Validators can raise either full exceptions (ValidationException) or SilentValidationException, the latter of which means that the change will be silently abandonned
  • Validators can change the value to be set, either in-place or by returning a new object

astrofrog avatar Sep 16 '24 11:09 astrofrog

Codecov Report

Attention: Patch coverage is 98.71795% with 1 line in your changes missing coverage. Please review.

Project coverage is 96.81%. Comparing base (d4d9d2f) to head (b0662e5). Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
echo/core.py 96.15% 1 Missing :warning:
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #42      +/-   ##
==========================================
+ Coverage   96.70%   96.81%   +0.11%     
==========================================
  Files          18       18              
  Lines        2274     2327      +53     
==========================================
+ Hits         2199     2253      +54     
+ Misses         75       74       -1     

:umbrella: View full report in Codecov by Sentry.
:loudspeaker: Have feedback on the report? Share it here.

:rocket: New features to boost your workflow:
  • :snowflake: Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

codecov[bot] avatar Sep 16 '24 11:09 codecov[bot]

@kecnry - I lost track, did we say that this PR is going to be needed for jdaviz, or did we decide it wasn't necessary? (just to know whether to merge & release)

astrofrog avatar Feb 27 '25 15:02 astrofrog

@astrofrog I believe we would like this in Jdaviz, I will work today on implementing our intended use case and get back to you ASAP with an update

gibsongreen avatar Feb 27 '25 15:02 gibsongreen

@gibsongreen - just to check, did you get a chance to try this out in the end?

astrofrog avatar Apr 28 '25 14:04 astrofrog

@astrofrog Yes I did! I have a local copy working with Jdaviz, I just need to push the changes and have a couple of people try it out on our end before merging this PR

gibsongreen avatar Apr 29 '25 13:04 gibsongreen

Hey @astrofrog we tested this out in Jdaviz and it does seem to do the trick for the two use cases we were considering! Thank you for keeping tabs on this and whenever you have time to merge it that great!

gibsongreen avatar May 07 '25 15:05 gibsongreen