iterators.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. from wtforms import Form, FormField, FieldList
  2. from pydantic.fields import Shape
  3. from .utils import *
  4. def iter_field(field, leafs_only=True, path=(), parent=None):
  5. if issubclass(field.field_class, FormField):
  6. field_class = field.kwargs['form_class']
  7. if path and not leafs_only:
  8. yield path, field_class
  9. for subfield_name, subfield in field_class._unbound_fields:
  10. yield from iter_field(subfield, leafs_only, path + (subfield_name,), parent)
  11. elif issubclass(field.field_class, FieldList):
  12. yield from iter_field(field.args[0], leafs_only, path, path)
  13. else:
  14. yield path, field, parent
  15. def iter_form_class(form_class, leafs_only=True, path=()):
  16. field = getattr(form_class, path[-1]) if path else form_class
  17. if path and not leafs_only:
  18. yield path, field
  19. try:
  20. for subfield_name, subfield in field._unbound_fields:
  21. yield from iter_field(subfield, leafs_only, path + (subfield_name,))
  22. except TypeError as e:
  23. # Ensure that the _unbound_fields is populated (that happens on first
  24. # instantiation)
  25. form_class()
  26. yield from iter_form_class(field, leafs_only, path)
  27. def iter_form(form, leafs_only=True):
  28. for key, field, iterate_on in iter_form_class(form.__class__):
  29. if iterate_on:
  30. value = rgetattr(form, iterate_on)
  31. for n, entry in enumerate(value.entries):
  32. yield key + (n,), entry
  33. continue
  34. yield key, field
  35. def iter_schema_class_field(field, leafs_only=True, path=(), parent=None):
  36. type_ = field.type_
  37. if hasattr(type_, '__fields__'):
  38. if path and not leafs_only:
  39. yield path, field, None
  40. for key, sub_field in type_.__fields__.items():
  41. yield from iter_schema_class_field(sub_field, leafs_only, path + (key,), field)
  42. else:
  43. iterate_on = None
  44. if parent and parent.shape != Shape.SINGLETON:
  45. iterate_on = path[:-1]
  46. elif field.shape != Shape.SINGLETON:
  47. iterate_on = path
  48. yield path, field, iterate_on
  49. def iter_schema_class(schema, leafs_only=True, path=()):
  50. for key, field in schema.__fields__.items():
  51. yield from iter_schema_class_field(field, leafs_only, path + (key,))
  52. def iter_schema(schema, leafs_only=True):
  53. for key, field, iterate_on in iter_schema_class(schema.__class__, leafs_only):
  54. if iterate_on:
  55. sub_values = rgetattr(schema, iterate_on)
  56. if isinstance(sub_values, list):
  57. for n, sub_value in enumerate(sub_values):
  58. yield key + (n,), sub_value
  59. else:
  60. raise NotImplementedError()
  61. continue
  62. yield key, rgetattr(schema, key)