pyglove 0.4.5.dev202412140808__tar.gz → 0.4.5.dev202412160810__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) hide show
  1. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/PKG-INFO +1 -1
  2. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/object.py +11 -0
  3. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/object_test.py +20 -0
  4. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/ref.py +21 -8
  5. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/ref_test.py +17 -0
  6. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/annotation_conversion.py +5 -0
  7. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/annotation_conversion_test.py +8 -0
  8. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/class_schema.py +4 -0
  9. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/value_specs.py +79 -5
  10. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/value_specs_test.py +136 -12
  11. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove.egg-info/PKG-INFO +1 -1
  12. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/LICENSE +0 -0
  13. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/README.md +0 -0
  14. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/__init__.py +0 -0
  15. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/__init__.py +0 -0
  16. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/detouring/__init__.py +0 -0
  17. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/detouring/class_detour.py +0 -0
  18. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/detouring/class_detour_test.py +0 -0
  19. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/__init__.py +0 -0
  20. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/base.py +0 -0
  21. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/base_test.py +0 -0
  22. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/categorical.py +0 -0
  23. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/categorical_test.py +0 -0
  24. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/custom.py +0 -0
  25. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/custom_test.py +0 -0
  26. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/deduping.py +0 -0
  27. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/deduping_test.py +0 -0
  28. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/dna_generator.py +0 -0
  29. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/dna_generator_test.py +0 -0
  30. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/numerical.py +0 -0
  31. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/numerical_test.py +0 -0
  32. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/random.py +0 -0
  33. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/random_test.py +0 -0
  34. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/space.py +0 -0
  35. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/space_test.py +0 -0
  36. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/sweeping.py +0 -0
  37. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/geno/sweeping_test.py +0 -0
  38. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/__init__.py +0 -0
  39. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/base.py +0 -0
  40. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/categorical.py +0 -0
  41. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/categorical_test.py +0 -0
  42. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/custom.py +0 -0
  43. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/custom_test.py +0 -0
  44. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/derived.py +0 -0
  45. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/derived_test.py +0 -0
  46. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/dynamic_evaluation.py +0 -0
  47. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/dynamic_evaluation_test.py +0 -0
  48. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/evolvable.py +0 -0
  49. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/evolvable_test.py +0 -0
  50. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/iter.py +0 -0
  51. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/iter_test.py +0 -0
  52. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/numerical.py +0 -0
  53. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/numerical_test.py +0 -0
  54. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/object_template.py +0 -0
  55. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/hyper/object_template_test.py +0 -0
  56. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/io/__init__.py +0 -0
  57. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/io/file_system.py +0 -0
  58. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/io/file_system_test.py +0 -0
  59. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/io/sequence.py +0 -0
  60. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/io/sequence_test.py +0 -0
  61. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/logging.py +0 -0
  62. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/logging_test.py +0 -0
  63. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/__init__.py +0 -0
  64. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/codegen.py +0 -0
  65. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/codegen_test.py +0 -0
  66. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/common_traits.py +0 -0
  67. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/common_traits_test.py +0 -0
  68. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/docstr_utils.py +0 -0
  69. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/docstr_utils_test.py +0 -0
  70. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/error_utils.py +0 -0
  71. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/error_utils_test.py +0 -0
  72. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/formatting.py +0 -0
  73. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/formatting_test.py +0 -0
  74. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/hierarchical.py +0 -0
  75. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/hierarchical_test.py +0 -0
  76. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/json_conversion.py +0 -0
  77. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/json_conversion_test.py +0 -0
  78. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/missing.py +0 -0
  79. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/missing_test.py +0 -0
  80. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/thread_local.py +0 -0
  81. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/thread_local_test.py +0 -0
  82. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/timing.py +0 -0
  83. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/timing_test.py +0 -0
  84. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/value_location.py +0 -0
  85. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/object_utils/value_location_test.py +0 -0
  86. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/patching/__init__.py +0 -0
  87. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/patching/object_factory.py +0 -0
  88. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/patching/object_factory_test.py +0 -0
  89. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/patching/pattern_based.py +0 -0
  90. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/patching/pattern_based_test.py +0 -0
  91. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/patching/rule_based.py +0 -0
  92. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/patching/rule_based_test.py +0 -0
  93. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/__init__.py +0 -0
  94. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/base.py +0 -0
  95. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/base_test.py +0 -0
  96. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/boilerplate.py +0 -0
  97. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/boilerplate_test.py +0 -0
  98. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/class_wrapper.py +0 -0
  99. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/class_wrapper_test.py +0 -0
  100. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/compounding.py +0 -0
  101. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/compounding_test.py +0 -0
  102. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/dict.py +0 -0
  103. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/dict_test.py +0 -0
  104. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/diff.py +0 -0
  105. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/diff_test.py +0 -0
  106. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/flags.py +0 -0
  107. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/flags_test.py +0 -0
  108. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/functor.py +0 -0
  109. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/functor_test.py +0 -0
  110. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/inferred.py +0 -0
  111. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/inferred_test.py +0 -0
  112. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/list.py +0 -0
  113. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/list_test.py +0 -0
  114. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/origin.py +0 -0
  115. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/origin_test.py +0 -0
  116. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/pure_symbolic.py +0 -0
  117. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/symbolize.py +0 -0
  118. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/symbolic/symbolize_test.py +0 -0
  119. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/__init__.py +0 -0
  120. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/backend.py +0 -0
  121. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/backend_test.py +0 -0
  122. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/early_stopping.py +0 -0
  123. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/local_backend.py +0 -0
  124. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/protocols.py +0 -0
  125. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/protocols_test.py +0 -0
  126. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/sample.py +0 -0
  127. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/tuning/sample_test.py +0 -0
  128. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/__init__.py +0 -0
  129. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/annotated.py +0 -0
  130. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/annotated_test.py +0 -0
  131. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/callable_ext.py +0 -0
  132. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/callable_ext_test.py +0 -0
  133. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/callable_signature.py +0 -0
  134. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/callable_signature_test.py +0 -0
  135. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/class_schema_test.py +0 -0
  136. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/custom_typing.py +0 -0
  137. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/inspect.py +0 -0
  138. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/inspect_test.py +0 -0
  139. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/key_specs.py +0 -0
  140. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/key_specs_test.py +0 -0
  141. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/pytype_support.py +0 -0
  142. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/type_conversion.py +0 -0
  143. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/type_conversion_test.py +0 -0
  144. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/typed_missing.py +0 -0
  145. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/typing/typed_missing_test.py +0 -0
  146. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/__init__.py +0 -0
  147. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/base.py +0 -0
  148. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/base_test.py +0 -0
  149. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/__init__.py +0 -0
  150. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/base.py +0 -0
  151. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/base_test.py +0 -0
  152. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/__init__.py +0 -0
  153. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/base.py +0 -0
  154. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/label.py +0 -0
  155. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/label_test.py +0 -0
  156. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/progress_bar.py +0 -0
  157. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/progress_bar_test.py +0 -0
  158. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/tab.py +0 -0
  159. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/tab_test.py +0 -0
  160. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/tooltip.py +0 -0
  161. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/controls/tooltip_test.py +0 -0
  162. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/tree_view.py +0 -0
  163. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/core/views/html/tree_view_test.py +0 -0
  164. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/__init__.py +0 -0
  165. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/early_stopping/__init__.py +0 -0
  166. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/early_stopping/base.py +0 -0
  167. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/early_stopping/base_test.py +0 -0
  168. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/early_stopping/step_wise.py +0 -0
  169. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/early_stopping/step_wise_test.py +0 -0
  170. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/__init__.py +0 -0
  171. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/base.py +0 -0
  172. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/base_test.py +0 -0
  173. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/hill_climb.py +0 -0
  174. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/hill_climb_test.py +0 -0
  175. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/mutators.py +0 -0
  176. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/mutators_test.py +0 -0
  177. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/neat.py +0 -0
  178. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/neat_test.py +0 -0
  179. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/nsga2.py +0 -0
  180. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/nsga2_test.py +0 -0
  181. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/recombinators.py +0 -0
  182. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/recombinators_test.py +0 -0
  183. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/regularized_evolution.py +0 -0
  184. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/regularized_evolution_test.py +0 -0
  185. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/selectors.py +0 -0
  186. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/selectors_test.py +0 -0
  187. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/where.py +0 -0
  188. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/evolution/where_test.py +0 -0
  189. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/mutfun/__init__.py +0 -0
  190. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/mutfun/base.py +0 -0
  191. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/mutfun/base_test.py +0 -0
  192. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/mutfun/basic_ops.py +0 -0
  193. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/mutfun/basic_ops_test.py +0 -0
  194. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/__init__.py +0 -0
  195. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/base.py +0 -0
  196. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/base_test.py +0 -0
  197. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/maths.py +0 -0
  198. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/maths_test.py +0 -0
  199. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/randoms.py +0 -0
  200. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/randoms_test.py +0 -0
  201. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/step_wise.py +0 -0
  202. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove/ext/scalars/step_wise_test.py +0 -0
  203. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove.egg-info/SOURCES.txt +0 -0
  204. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove.egg-info/dependency_links.txt +0 -0
  205. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove.egg-info/requires.txt +0 -0
  206. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/pyglove.egg-info/top_level.txt +0 -0
  207. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/setup.cfg +0 -0
  208. {pyglove-0.4.5.dev202412140808 → pyglove-0.4.5.dev202412160810}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pyglove
3
- Version: 0.4.5.dev202412140808
3
+ Version: 0.4.5.dev202412160810
4
4
  Summary: PyGlove: A library for manipulating Python objects.
5
5
  Home-page: https://github.com/google/pyglove
6
6
  Author: PyGlove Authors
@@ -164,11 +164,22 @@ class ObjectMeta(abc.ABCMeta):
164
164
  if key is None:
165
165
  continue
166
166
 
167
+ # Skip class-level attributes that are not symbolic fields.
168
+ if typing.get_origin(attr_annotation) is typing.ClassVar:
169
+ continue
170
+
167
171
  field = pg_typing.Field.from_annotation(key, attr_annotation)
168
172
  if isinstance(key, pg_typing.ConstStrKey):
169
173
  attr_value = cls.__dict__.get(attr_name, pg_typing.MISSING_VALUE)
170
174
  if attr_value != pg_typing.MISSING_VALUE:
171
175
  field.value.set_default(attr_value)
176
+
177
+ if (field.value.frozen and
178
+ field.value.default is
179
+ pg_typing.value_specs._FROZEN_VALUE_PLACEHOLDER): # pylint: disable=protected-access
180
+ raise TypeError(
181
+ f'Field {field.key!r} is marked as final but has no default value.'
182
+ )
172
183
  fields.append(field)
173
184
 
174
185
  # Trigger event so subclass could modify the fields.
@@ -324,6 +324,26 @@ class ObjectTest(unittest.TestCase):
324
324
  self.assertEqual(e.x, 1)
325
325
  self.assertEqual(e.y, 3)
326
326
 
327
+ class F(Object):
328
+ x: typing.Literal[1, 'a']
329
+
330
+ class G(F):
331
+ x: typing.Final[int] = 1
332
+ y: typing.ClassVar[int] = 2
333
+
334
+ self.assertEqual(G().x, 1)
335
+ self.assertEqual(G.y, 2)
336
+
337
+ with self.assertRaisesRegex(
338
+ ValueError, 'Frozen field is not assignable'):
339
+ G(x=2)
340
+
341
+ with self.assertRaisesRegex(
342
+ TypeError, 'Field x is marked as final but has no default value'):
343
+
344
+ class H(Object): # pylint: disable=unused-variable
345
+ x: typing.Final[int] # pylint: disable=invalid-name
346
+
327
347
  def test_init_arg_list(self):
328
348
 
329
349
  def _update_init_arg_list(cls, init_arg_list):
@@ -14,16 +14,30 @@
14
14
  """Symbolic reference."""
15
15
 
16
16
  import functools
17
- import numbers
18
- from typing import Any, Callable, List, Optional, Tuple
17
+ import typing
18
+ from typing import Any, Callable, List, Optional, Tuple, Type
19
19
  from pyglove.core import object_utils
20
20
  from pyglove.core import typing as pg_typing
21
21
  from pyglove.core.symbolic import base
22
- from pyglove.core.symbolic.object import Object
22
+ from pyglove.core.symbolic import object as pg_object
23
23
  from pyglove.core.views.html import tree_view
24
24
 
25
25
 
26
- class Ref(Object, base.Inferential, tree_view.HtmlTreeView.Extension):
26
+ class RefMeta(pg_object.ObjectMeta):
27
+ """Metaclass for Ref."""
28
+
29
+ def __getitem__(cls, type_arg: Type[Any]) -> Any: # pylint: disable=no-self-argument
30
+ if typing.TYPE_CHECKING:
31
+ return type_arg
32
+ return pg_typing.Object(type_arg, transform=Ref)
33
+
34
+
35
+ class Ref(
36
+ pg_object.Object,
37
+ base.Inferential,
38
+ tree_view.HtmlTreeView.Extension,
39
+ metaclass=RefMeta
40
+ ):
27
41
  """Symbolic reference.
28
42
 
29
43
  When adding a symbolic node to a symbolic tree, it undergoes a copy operation
@@ -82,9 +96,9 @@ class Ref(Object, base.Inferential, tree_view.HtmlTreeView.Extension):
82
96
 
83
97
  def __new__(cls, value: Any, **kwargs):
84
98
  del kwargs
85
- if isinstance(value, (bool, numbers.Number, str)):
86
- return value
87
- return object.__new__(cls)
99
+ if isinstance(value, (base.Symbolic, list, dict)):
100
+ return object.__new__(cls)
101
+ return value
88
102
 
89
103
  @object_utils.explicit_method_override
90
104
  def __init__(self, value: Any, **kwargs) -> None:
@@ -241,4 +255,3 @@ def deref(value: base.Symbolic, recursive: bool = False) -> Any:
241
255
  return v
242
256
  return value.rebind(_deref, raise_on_no_change=False)
243
257
  return value
244
-
@@ -16,6 +16,7 @@
16
16
  import copy
17
17
  import inspect
18
18
  import pickle
19
+ import typing
19
20
  from typing import Any
20
21
  import unittest
21
22
 
@@ -202,6 +203,22 @@ class RefTest(unittest.TestCase):
202
203
  """
203
204
  )
204
205
 
206
+ def test_annotation(self):
207
+ typing.TYPE_CHECKING = True
208
+ assert ref.Ref[ValueError] is ValueError
209
+ typing.TYPE_CHECKING = False
210
+
211
+ class Bar(Object):
212
+ x: int
213
+
214
+ class Foo(Object):
215
+ y: ref.Ref[Bar]
216
+
217
+ f = Foo(Bar(1))
218
+ self.assertIsInstance(f.sym_getattr('y'), ref.Ref)
219
+ self.assertEqual(f.y.sym_path, '')
220
+ self.assertIsInstance(ref.Ref[Bar](1), ref.Ref)
221
+
205
222
 
206
223
  if __name__ == '__main__':
207
224
  unittest.main()
@@ -177,6 +177,11 @@ def _value_spec_from_type_annotation(
177
177
  if optional:
178
178
  spec = spec.noneable()
179
179
  return spec
180
+ elif origin is typing.Final:
181
+ return _value_spec_from_type_annotation(
182
+ args[0],
183
+ accept_value_as_annotation=False
184
+ ).freeze(vs._FROZEN_VALUE_PLACEHOLDER) # pylint: disable=protected-access
180
185
  elif isinstance(annotation, typing.ForwardRef):
181
186
  annotation = annotation.__forward_arg__
182
187
  if parent_module is not None:
@@ -306,6 +306,14 @@ class ValueSpecFromAnnotationTest(unittest.TestCase):
306
306
  ValueSpec.from_annotation(int | str, True),
307
307
  vs.Union([vs.Int(), vs.Str()]))
308
308
 
309
+ def test_final(self):
310
+ self.assertEqual(
311
+ ValueSpec.from_annotation(
312
+ typing.Final[int], True
313
+ ).set_default(1),
314
+ vs.Int().freeze(1)
315
+ )
316
+
309
317
 
310
318
  if __name__ == '__main__':
311
319
  unittest.main()
@@ -344,6 +344,10 @@ class ValueSpec(object_utils.Formattable, object_utils.JSONConvertible):
344
344
  Tuple[Type[Any], ...]]: # pyformat: disable
345
345
  """Returns acceptable (resolved) value type(s)."""
346
346
 
347
+ @abc.abstractmethod
348
+ def __call__(self, *args, **kwargs) -> Any:
349
+ """Instantiates a value based on the spec.."""
350
+
347
351
  @property
348
352
  @abc.abstractmethod
349
353
  def forward_refs(self) -> Set[ForwardRef]:
@@ -37,6 +37,17 @@ from pyglove.core.typing.custom_typing import CustomTyping
37
37
 
38
38
  MISSING_VALUE = object_utils.MISSING_VALUE
39
39
 
40
+
41
+ class _FrozenValuePlaceholder(CustomTyping):
42
+ """Placeholder for to-be-assigned frozen value."""
43
+
44
+ def custom_apply(self, *args, **kwargs) -> typing.Tuple[bool, typing.Any]:
45
+ return (False, self)
46
+
47
+
48
+ _FROZEN_VALUE_PLACEHOLDER = _FrozenValuePlaceholder()
49
+
50
+
40
51
  # Type alias for ValueSpec object or Python annotation that could be converted
41
52
  # to ValueSpec via `pg.typing.ValueSpec.from_annotation()`. This type alias is
42
53
  # just for better readability.
@@ -194,8 +205,18 @@ class ValueSpecBase(ValueSpec):
194
205
 
195
206
  def extend(self, base: ValueSpec) -> ValueSpec:
196
207
  """Extend current value spec on top of a base spec."""
197
- if base.frozen:
198
- raise TypeError(f'Cannot extend a frozen value spec: {base!r}')
208
+ if base.frozen and (not self.frozen or self.default != base.default):
209
+ raise TypeError(f'{self!r} cannot extend a frozen value spec: {base!r}')
210
+
211
+ # Special handling for extending enum.
212
+ if self.frozen and isinstance(base, Enum):
213
+ if self.default in base.values:
214
+ return Enum(MISSING_VALUE, base.values).freeze(self.default)
215
+ else:
216
+ raise TypeError(
217
+ f'{self!r} cannot extend {base!r} with incompatible '
218
+ f'frozen value: {self.default!r} '
219
+ )
199
220
 
200
221
  if self._transform is None:
201
222
  self._transform = base.transform
@@ -232,7 +253,7 @@ class ValueSpecBase(ValueSpec):
232
253
  root_path: typing.Optional[object_utils.KeyPath] = None) -> typing.Any: # pyformat: disable pylint: disable=line-too-long
233
254
  """Apply spec to validate and complete value."""
234
255
  root_path = root_path or object_utils.KeyPath()
235
- if self.frozen:
256
+ if self.frozen and self.default is not _FROZEN_VALUE_PLACEHOLDER:
236
257
  # Always return the default value if a field is frozen.
237
258
  if MISSING_VALUE != value and self.default != value:
238
259
  raise ValueError(
@@ -270,7 +291,8 @@ class ValueSpecBase(ValueSpec):
270
291
  value = self._transform(value)
271
292
  except Exception as e: # pylint: disable=broad-except
272
293
  raise e.__class__(
273
- object_utils.message_on_path(str(e), root_path)
294
+ object_utils.message_on_path(
295
+ str(e), root_path)
274
296
  ).with_traceback(sys.exc_info()[2])
275
297
 
276
298
  return self.skip_user_transform.apply(
@@ -319,7 +341,7 @@ class ValueSpecBase(ValueSpec):
319
341
  return value
320
342
 
321
343
  def is_compatible(self, other: ValueSpec) -> bool:
322
- """Returns if current spec is compatible with the other value spec."""
344
+ """Returns if current spec can receive all values from the other spec."""
323
345
  if self is other:
324
346
  return True
325
347
  if not isinstance(other, self.__class__):
@@ -417,6 +439,12 @@ class PrimitiveType(ValueSpecBase):
417
439
  value_type, default, is_noneable=is_noneable, frozen=frozen
418
440
  )
419
441
 
442
+ def __call__(self, *args, **kwargs) -> typing.Any:
443
+ del kwargs
444
+ if (not args and self.has_default) or self.frozen:
445
+ return self.default
446
+ return self.apply(self.value_type(*args))
447
+
420
448
 
421
449
  class Bool(PrimitiveType):
422
450
  """Value spec for boolean type.
@@ -898,6 +926,12 @@ class Enum(Generic, PrimitiveType):
898
926
  value_type, default, is_noneable=is_noneable, frozen=frozen
899
927
  )
900
928
 
929
+ def __call__(self, *args, **kwargs) -> typing.Any:
930
+ del kwargs
931
+ if (not args and self.has_default) or self.frozen:
932
+ return self.default
933
+ return self.apply(*args)
934
+
901
935
  def noneable(self) -> 'Enum':
902
936
  """Noneable is specially treated for Enum."""
903
937
  if None not in self._values:
@@ -929,6 +963,12 @@ class Enum(Generic, PrimitiveType):
929
963
  f'{repr(v)} is not an acceptable value.'
930
964
  ) from e
931
965
 
966
+ def is_compatible(self, other: ValueSpec) -> bool:
967
+ """Enum specific compatibility check."""
968
+ if other.frozen and other.default in self.values:
969
+ return True
970
+ return super().is_compatible(other)
971
+
932
972
  def _is_compatible(self, other: 'Enum') -> bool:
933
973
  """Enum specific compatibility check."""
934
974
  for v in other.values:
@@ -1067,6 +1107,12 @@ class List(Generic, ValueSpecBase):
1067
1107
  list, default, transform, is_noneable=is_noneable, frozen=frozen
1068
1108
  )
1069
1109
 
1110
+ def __call__(self, *args, **kwargs) -> typing.Any:
1111
+ del kwargs
1112
+ if (not args and self.has_default) or self.frozen:
1113
+ return self.default
1114
+ return self.apply(list(*args))
1115
+
1070
1116
  @property
1071
1117
  def element(self) -> Field:
1072
1118
  """Returns Field specification of list element."""
@@ -1316,6 +1362,12 @@ class Tuple(Generic, ValueSpecBase):
1316
1362
  tuple, default, transform, is_noneable=is_noneable, frozen=frozen
1317
1363
  )
1318
1364
 
1365
+ def __call__(self, *args, **kwargs) -> typing.Any:
1366
+ del kwargs
1367
+ if (not args and self.has_default) or self.frozen:
1368
+ return self.default
1369
+ return self.apply(tuple(*args))
1370
+
1319
1371
  @property
1320
1372
  def fixed_length(self) -> bool:
1321
1373
  """Returns True if current Tuple spec is fixed length."""
@@ -1617,6 +1669,9 @@ class Dict(Generic, ValueSpecBase):
1617
1669
  if MISSING_VALUE == default:
1618
1670
  self.set_default(default)
1619
1671
 
1672
+ def __call__(self, *args, **kwargs) -> typing.Any:
1673
+ return self.apply(dict(*args, **kwargs))
1674
+
1620
1675
  @property
1621
1676
  def schema(self) -> typing.Optional[Schema]:
1622
1677
  """Returns the schema of this dict spec."""
@@ -1816,6 +1871,9 @@ class Object(Generic, ValueSpecBase):
1816
1871
  t, default, transform, is_noneable=is_noneable, frozen=frozen
1817
1872
  )
1818
1873
 
1874
+ def __call__(self, *args, **kwargs) -> typing.Any:
1875
+ return self.apply(self.cls(*args, **kwargs))
1876
+
1819
1877
  @property
1820
1878
  def forward_refs(self) -> typing.Set[class_schema.ForwardRef]:
1821
1879
  """Returns forward references used in this spec."""
@@ -2014,6 +2072,10 @@ class Callable(Generic, ValueSpecBase):
2014
2072
  frozen=frozen,
2015
2073
  )
2016
2074
 
2075
+ def __call__(self, *args, **kwargs) -> typing.Any:
2076
+ del args, kwargs
2077
+ raise TypeError(f'{self!r} cannot be instantiated.')
2078
+
2017
2079
  @functools.cached_property
2018
2080
  def forward_refs(self) -> typing.Set[class_schema.ForwardRef]:
2019
2081
  """Returns forward references used in this spec."""
@@ -2351,6 +2413,10 @@ class Type(Generic, ValueSpecBase):
2351
2413
  self._forward_ref = forward_ref
2352
2414
  super().__init__(type, default, is_noneable=is_noneable, frozen=frozen)
2353
2415
 
2416
+ def __call__(self, *args, **kwargs) -> typing.Any:
2417
+ del args, kwargs
2418
+ return self.type
2419
+
2354
2420
  @property
2355
2421
  def type(self) -> typing.Type[typing.Any]:
2356
2422
  """Returns desired type."""
@@ -2539,6 +2605,10 @@ class Union(Generic, ValueSpecBase):
2539
2605
  frozen=frozen,
2540
2606
  )
2541
2607
 
2608
+ def __call__(self, *args, **kwargs) -> typing.Any:
2609
+ del args, kwargs
2610
+ raise TypeError(f'{self!r} cannot be instantiated.')
2611
+
2542
2612
  @functools.cached_property
2543
2613
  def forward_refs(self) -> typing.Set[class_schema.ForwardRef]:
2544
2614
  """Returns forward references used in this spec."""
@@ -2856,6 +2926,10 @@ class Any(ValueSpecBase):
2856
2926
  )
2857
2927
  self._annotation = annotation
2858
2928
 
2929
+ def __call__(self, *args, **kwargs) -> typing.Any:
2930
+ del args, kwargs
2931
+ raise TypeError(f'{self!r} cannot be instantiated.')
2932
+
2859
2933
  def is_compatible(self, other: ValueSpec) -> bool:
2860
2934
  """Any is compatible with any ValueSpec."""
2861
2935
  return True