Skip to content

Validate after setting multiple fields at once #72

Open
@bharathbhushan1

Description

@bharathbhushan1

The requirement is to set multiple fields which have individual validators where there could be a period where the invariants are not satisfied but at the end of the "transaction", all validators are satisfied. Is there a way to get this done? If not, can we add this as an enhancement?

class Test(object):
  a = field(type_hint=six.integer_types, native=False, default=2)
  b = field(type_hint=six.integer_types, native=False, default=1)

  @a.validator()
  def validate_a(self, new_a):
    return new_a == self.b * 2

  @b.validator()
  def validate_b(self, new_b):
    return new_b == self.a / 2

t = Test()
# Start transaction
t.a = 100   # Fails because the invariant is not satisfied
t.b = 50
# End of transaction

Activity

smarie

smarie commented on Jun 29, 2020

@smarie
Owner

This is a great suggestion ! It seems to connect with similar ideas/suggestions #8 and #25

I do not remember if I already wrote something in the code to prepare this, I'll need to investigate.

Anyway a context manager would seem quite appropriate to disable validation temporarily and set it back on exit:

with validate_once(t):
    t.a = 100
    t.b = 50

Maybe we could think about alternate names or additional complementary helpers, such as

  • with one_validation(t) could be an alternate name to the above

  • with no_validation(t) could be a second symbol, that would not validate at all on exit, as opposed to the above.

  • other names.... ? with direct_access(t), ...

What do you think ?

jgarbers

jgarbers commented on Nov 3, 2020

@jgarbers

I've just started looking at pyfields as an alternative to marshmallow, with the hopes of using it for convenient form and API parameter validation while providing a simple object with fields representing the submitted values. For me the ability to validate all values at once, providing a Flask form object (or some other dict) as input to my constructor, would be particularly helpful -- especially if I could get a marshmallow-like error result out of the process, mapping fieldnames to lists of error messages for those fields that failed validation. Hope this makes sense... been learning a lot this afternoon. Thanks!

smarie

smarie commented on Nov 9, 2020

@smarie
Owner

Thanks @jgarbers for your feedback ! Your message does not really seem to relate to this issue #72 - @bharathbhushan1 meant validation that can not be performed field by field but once all fields have been set. So I would recommend that you open a new dedicated issue.

To give a first level of answer, you can already validate all values at once by passing a **dct to the constructor ; however only the first invalid field will appear in the error message as opposed to what you seem to require.

Maybe this should be solved in a different function that we could generate optionally on the class ? or we could imagine a boolean flag triggering this in the constructor. Or maybe we could make this the default behaviour of the generated constructor ? I have no strong opinion here but performance might be something to consider.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @jgarbers@smarie@bharathbhushan1

        Issue actions

          Validate after setting multiple fields at once · Issue #72 · smarie/python-pyfields