value-object-pattern 1.30.0__tar.gz → 1.31.1__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 (187) hide show
  1. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/.gitignore +1 -0
  2. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/PKG-INFO +4 -4
  3. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/README.md +3 -3
  4. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/__init__.py +1 -1
  5. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/collections/dict_value_object.py +193 -18
  6. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/collections/list_value_object.py +144 -10
  7. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/union_value_object.py +145 -13
  8. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/LICENSE.md +0 -0
  9. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/pyproject.toml +0 -0
  10. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/decorators/__init__.py +0 -0
  11. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/decorators/classproperty.py +0 -0
  12. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/decorators/value_object_process.py +0 -0
  13. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/decorators/value_object_validation.py +0 -0
  14. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/__init__.py +0 -0
  15. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/base_model.py +0 -0
  16. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/collections/__init__.py +0 -0
  17. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/enumeration_value_object.py +0 -0
  18. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/primitive_conversion.py +0 -0
  19. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/type_matching.py +0 -0
  20. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/models/value_object.py +0 -0
  21. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/py.typed +0 -0
  22. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/__init__.py +0 -0
  23. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/__init__.py +0 -0
  24. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/date/__init__.py +0 -0
  25. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/date/date_value_object.py +0 -0
  26. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/date/string_date_value_object.py +0 -0
  27. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/datetime/__init__.py +0 -0
  28. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/datetime/datetime_value_object.py +0 -0
  29. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/datetime/string_datetime_value_object.py +0 -0
  30. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/timezone/__init__.py +0 -0
  31. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/timezone/string_timezone_value_object.py +0 -0
  32. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/dates/timezone/timezone_value_object.py +0 -0
  33. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/__init__.py +0 -0
  34. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/__init__.py +0 -0
  35. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/string_uuid_v1_value_object.py +0 -0
  36. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/string_uuid_v3_value_object.py +0 -0
  37. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/string_uuid_v4_value_object.py +0 -0
  38. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/string_uuid_v5_value_object.py +0 -0
  39. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/string_uuid_v6_value_object.py +0 -0
  40. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/string_uuid_v7_value_object.py +0 -0
  41. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/string_uuid_v8_value_object.py +0 -0
  42. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/string_uuid_value_object.py +0 -0
  43. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/uuid_v1_value_object.py +0 -0
  44. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/uuid_v3_value_object.py +0 -0
  45. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/uuid_v4_value_object.py +0 -0
  46. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/uuid_v5_value_object.py +0 -0
  47. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/uuid_v6_value_object.py +0 -0
  48. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/uuid_v7_value_object.py +0 -0
  49. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/uuid_v8_value_object.py +0 -0
  50. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/uuid/uuid_value_object.py +0 -0
  51. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/__init__.py +0 -0
  52. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/country_tld_value_object.py +0 -0
  53. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/__init__.py +0 -0
  54. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/__init__.py +0 -0
  55. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/dni_value_object.py +0 -0
  56. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/nie_value_object.py +0 -0
  57. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/nif_value_object.py +0 -0
  58. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/nuss_value_object.py +0 -0
  59. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/passport_value_object.py +0 -0
  60. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/phone_number_value_object.py +0 -0
  61. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/__init__.py +0 -0
  62. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/administrative_technician_vehicle_plate_value_object.py +0 -0
  63. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/air_force_vehicle_plate_value_object.py +0 -0
  64. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/army_vehicle_plate_value_object.py +0 -0
  65. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/canarias_police_vehicle_plate_value_object.py +0 -0
  66. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/catalan_police_vehicle_plate_value_object.py +0 -0
  67. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/civil_guard_vehicle_plate_value_object.py +0 -0
  68. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/consular_corps_vehicle_plate_value_object.py +0 -0
  69. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/diplomatic_corps_vehicle_plate_value_object.py +0 -0
  70. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/especial_plate_vehicle_plate_value_object.py +0 -0
  71. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/historical_vehicle_plate_value_object.py +0 -0
  72. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/international_organization_vehicle_plate_value_object.py +0 -0
  73. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/ministry_development_vehicle_plate_value_object.py +0 -0
  74. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/ministry_environment_vehicle_plate_value_object.py +0 -0
  75. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/national_police_vehicle_plate_value_object.py +0 -0
  76. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/navy_vehicle_plate_value_object.py +0 -0
  77. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/ordinary_truck_vehicle_plate_value_object.py +0 -0
  78. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/ordinary_vehicle_plate_value_object.py +0 -0
  79. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/provincial_system_vehicle_plate_value_object.py +0 -0
  80. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/state_motor_pool_vehicle_plate_value_object.py +0 -0
  81. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_company_not_registered_vehicle_plate_value_object.py +0 -0
  82. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_company_registered_vehicle_plate_value_object.py +0 -0
  83. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_private_individual_vehicle_plate_value_object.py +0 -0
  84. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/two_wheels_vehicle_plate_value_object.py +0 -0
  85. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/utils/__init__.py +0 -0
  86. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/plates/utils/provincial_plate_codes.txt +0 -0
  87. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/utils/__init__.py +0 -0
  88. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/utils/provincial_codes.txt +0 -0
  89. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/europe/spain/vehicle_plate_value_object.py +0 -0
  90. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/iso3166_alpha2_code_value_object.py +0 -0
  91. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/iso3166_alpha3_code_value_object.py +0 -0
  92. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/iso3166_numeric_code_value_object.py +0 -0
  93. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/phone_code_value_object.py +0 -0
  94. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/utils/__init__.py +0 -0
  95. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_codes.txt +0 -0
  96. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_alpha3_mapping.txt +0 -0
  97. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_numeric_mapping.txt +0 -0
  98. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_phone_code_mapping.txt +0 -0
  99. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_tld_mapping.txt +0 -0
  100. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha3_codes.txt +0 -0
  101. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/utils/iso3166_numeric_codes.txt +0 -0
  102. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/identifiers/world/vin_value_object.py +0 -0
  103. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/__init__.py +0 -0
  104. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/aws_cloud_region_value_object.py +0 -0
  105. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/domain_value_object.py +0 -0
  106. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/email_address_value_object.py +0 -0
  107. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/host_value_object.py +0 -0
  108. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/ip_address_value_object.py +0 -0
  109. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/ipv4_address_value_object.py +0 -0
  110. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/ipv4_network_value_object.py +0 -0
  111. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/ipv6_address_value_object.py +0 -0
  112. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/ipv6_network_value_object.py +0 -0
  113. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/keys/__init__.py +0 -0
  114. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/keys/kebab_case_key_value_object.py +0 -0
  115. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/keys/snake_case_key_value_object.py +0 -0
  116. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mac_address_value_object.py +0 -0
  117. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mac_addresses/__init__.py +0 -0
  118. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mac_addresses/cisco_mac_address_value_object.py +0 -0
  119. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mac_addresses/raw_mac_address_value_object.py +0 -0
  120. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mac_addresses/space_mac_address_value_object.py +0 -0
  121. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mac_addresses/universal_mac_address_value_object.py +0 -0
  122. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mac_addresses/windows_mac_address_value_object.py +0 -0
  123. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mobile/__init__.py +0 -0
  124. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/mobile/imei_value_object.py +0 -0
  125. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/port_value_object.py +0 -0
  126. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/slug_value_object.py +0 -0
  127. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/uri/__init__.py +0 -0
  128. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/uri/http_https_url_value_object.py +0 -0
  129. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/uri/http_url_value_object.py +0 -0
  130. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/uri/https_url_value_object.py +0 -0
  131. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/uri/url_value_object.py +0 -0
  132. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/user_agent_value_object.py +0 -0
  133. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/utils/__init__.py +0 -0
  134. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/utils/aws_regions.txt +0 -0
  135. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/internet/utils/tld_domains.txt +0 -0
  136. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/__init__.py +0 -0
  137. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/credit_card_value_object.py +0 -0
  138. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/credit_cards/__init__.py +0 -0
  139. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/credit_cards/amex_credit_card_value_object.py +0 -0
  140. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/credit_cards/discover_credit_card_value_object.py +0 -0
  141. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/credit_cards/mastercard_credit_card_value_object.py +0 -0
  142. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/credit_cards/visa_credit_card_value_object.py +0 -0
  143. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/iban_value_object.py +0 -0
  144. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/utils/__init__.py +0 -0
  145. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/money/utils/iban_lengths.txt +0 -0
  146. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/__init__.py +0 -0
  147. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/boolean/__init__.py +0 -0
  148. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/boolean/boolean_value_object.py +0 -0
  149. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/boolean/false_value_object.py +0 -0
  150. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/boolean/true_value_object.py +0 -0
  151. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/bytes/__init__.py +0 -0
  152. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/bytes/bytes_value_object.py +0 -0
  153. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/float/__init__.py +0 -0
  154. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/float/float_value_object.py +0 -0
  155. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/float/negative_float_value_object.py +0 -0
  156. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/float/negative_or_zero_float_value_object.py +0 -0
  157. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/float/positive_float_value_object.py +0 -0
  158. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/float/positive_or_zero_float_value_object.py +0 -0
  159. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/integer/__init__.py +0 -0
  160. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/integer/even_integer_value_object.py +0 -0
  161. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/integer/integer_value_object.py +0 -0
  162. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/integer/negative_integer_value_object.py +0 -0
  163. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/integer/negative_or_zero_integer_value_object.py +0 -0
  164. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/integer/odd_integer_value_object.py +0 -0
  165. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/integer/positive_integer_value_object.py +0 -0
  166. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/integer/positive_or_zero_integer_value_object.py +0 -0
  167. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/none/__init__.py +0 -0
  168. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/none/none_value_object.py +0 -0
  169. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/none/not_none_value_object.py +0 -0
  170. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/__init__.py +0 -0
  171. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/alpha_value_object.py +0 -0
  172. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/alphanumeric_value_object.py +0 -0
  173. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/camel_case_string_value_object.py +0 -0
  174. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/digit_value_object.py +0 -0
  175. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/kebab_case_string_value_object.py +0 -0
  176. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/lowercase_string_value_object.py +0 -0
  177. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/non_empty_string_value_object.py +0 -0
  178. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/pascal_case_string_value_object.py +0 -0
  179. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/printable_string_value_object.py +0 -0
  180. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/screaming_snake_case_string_value_object.py +0 -0
  181. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/secret_string_value_object.py +0 -0
  182. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/snake_case_string_value_object.py +0 -0
  183. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/string_value_object.py +0 -0
  184. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/trimmed_string_value_object.py +0 -0
  185. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/primitives/string/uppercase_string_value_object.py +0 -0
  186. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/utils/__init__.py +0 -0
  187. {value_object_pattern-1.30.0 → value_object_pattern-1.31.1}/value_object_pattern/usables/utils/luhn_validation.py +0 -0
@@ -12,3 +12,4 @@ htmlcov/
12
12
 
13
13
  # environment folders
14
14
  **.venv**
15
+ **.agents/skills**
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: value-object-pattern
3
- Version: 1.30.0
3
+ Version: 1.31.1
4
4
  Summary: The Value Object Pattern is a Python package that streamlines the creation and management of value objects in your projects.
5
5
  Project-URL: Homepage, https://github.com/adriamontoto/value-object-pattern
6
6
  Project-URL: Repository, https://github.com/adriamontoto/value-object-pattern
@@ -262,10 +262,10 @@ low-level operations, and boundary examples.
262
262
  | --- | --- |
263
263
  | `ValueObject[T]` | Base class for immutable validated single-value wrappers. |
264
264
  | `EnumerationValueObject[E]` | Stores enum members while accepting enum members or raw enum values. |
265
- | `UnionValueObject[T]` | Accepts and converts values that match a union annotation. |
265
+ | `UnionValueObject[T]` | Accepts and converts values that match a union annotation; supports subclass and inline construction. |
266
266
  | `BaseModel` | Adds representation, equality, copying, and primitive conversion for aggregate-like models. |
267
- | `ListValueObject[T]` | Immutable typed list wrapper with helper methods that return new instances. |
268
- | `DictValueObject[K, V]` | Immutable typed dictionary wrapper with helper methods that return new instances. |
267
+ | `ListValueObject[T]` | Immutable typed list wrapper; supports subclass and inline construction. |
268
+ | `DictValueObject[K, V]` | Immutable typed dictionary wrapper; supports subclass and inline construction. |
269
269
 
270
270
  See [`docs/usage/README.md`](docs/usage/README.md) for examples of each model.
271
271
 
@@ -237,10 +237,10 @@ low-level operations, and boundary examples.
237
237
  | --- | --- |
238
238
  | `ValueObject[T]` | Base class for immutable validated single-value wrappers. |
239
239
  | `EnumerationValueObject[E]` | Stores enum members while accepting enum members or raw enum values. |
240
- | `UnionValueObject[T]` | Accepts and converts values that match a union annotation. |
240
+ | `UnionValueObject[T]` | Accepts and converts values that match a union annotation; supports subclass and inline construction. |
241
241
  | `BaseModel` | Adds representation, equality, copying, and primitive conversion for aggregate-like models. |
242
- | `ListValueObject[T]` | Immutable typed list wrapper with helper methods that return new instances. |
243
- | `DictValueObject[K, V]` | Immutable typed dictionary wrapper with helper methods that return new instances. |
242
+ | `ListValueObject[T]` | Immutable typed list wrapper; supports subclass and inline construction. |
243
+ | `DictValueObject[K, V]` | Immutable typed dictionary wrapper; supports subclass and inline construction. |
244
244
 
245
245
  See [`docs/usage/README.md`](docs/usage/README.md) for examples of each model.
246
246
 
@@ -1,4 +1,4 @@
1
- __version__ = '1.30.0'
1
+ __version__ = '1.31.1'
2
2
 
3
3
  from .decorators import process, validation
4
4
  from .models import BaseModel, EnumerationValueObject, UnionValueObject, ValueObject
@@ -14,7 +14,21 @@ else:
14
14
  from collections.abc import Iterator
15
15
  from inspect import isclass
16
16
  from types import UnionType
17
- from typing import Any, Generic, ItemsView, KeysView, NoReturn, Self, TypeVar, Union, ValuesView, get_args, get_origin
17
+ from typing import (
18
+ Any,
19
+ ClassVar,
20
+ Generic,
21
+ ItemsView,
22
+ KeysView,
23
+ NoReturn,
24
+ Self,
25
+ TypeVar,
26
+ Union,
27
+ ValuesView,
28
+ cast,
29
+ get_args,
30
+ get_origin,
31
+ )
18
32
 
19
33
  from value_object_pattern.decorators import validation
20
34
  from value_object_pattern.models import ValueObject
@@ -25,6 +39,154 @@ K = TypeVar('K', bound=Any)
25
39
  V = TypeVar('V', bound=Any)
26
40
 
27
41
 
42
+ def _validate_dict_type_argument(*, type_argument: Any) -> None:
43
+ """
44
+ Validate a type argument used by DictValueObject.
45
+
46
+ Args:
47
+ type_argument: The type argument to validate.
48
+
49
+ Raises:
50
+ TypeError: If the type argument is not a type-like annotation.
51
+ """
52
+ if isinstance(type_argument, TypeVar):
53
+ return
54
+
55
+ if type(type_argument) is not type and not isclass(object=type_argument) and get_origin(tp=type_argument) is None:
56
+ raise TypeError(f'DictValueObject[...] <<<{type_argument}>>> must be a type. Got <<<{type(type_argument).__name__}>>> type.') # noqa: E501 # fmt: skip
57
+
58
+
59
+ def _parse_dict_type_arguments(*, type_arguments: Any) -> tuple[Any, Any]:
60
+ """
61
+ Return key and value type arguments from `DictValueObject[K, V]` input.
62
+
63
+ Args:
64
+ type_arguments: The raw type arguments passed to `DictValueObject[...]`.
65
+
66
+ Raises:
67
+ TypeError: If exactly two type arguments are not provided.
68
+
69
+ Returns:
70
+ tuple[Any, Any]: The key and value type arguments.
71
+ """
72
+ if not isinstance(type_arguments, tuple):
73
+ raise TypeError('DictValueObject must be parameterised, e.g. `class StrIntDict(DictValueObject[str, int])`.')
74
+
75
+ if len(type_arguments) != 2:
76
+ raise TypeError('DictValueObject must be parameterised, e.g. `class StrIntDict(DictValueObject[str, int])`.')
77
+
78
+ key_type, value_type = type_arguments
79
+
80
+ return key_type, value_type
81
+
82
+
83
+ class _DictValueObjectAlias:
84
+ """
85
+ Runtime alias returned by `DictValueObject[K, V]`.
86
+
87
+ Key and value types must be available before `ValueObject.__init__` validates the dictionary. This alias keeps
88
+ subclass declarations working through `__mro_entries__` and supports direct inline construction by creating a
89
+ parameterized runtime subclass before validation starts.
90
+ """
91
+
92
+ _runtime_classes: ClassVar[dict[Any, type[DictValueObject[Any, Any]]]] = {}
93
+
94
+ def __init__(self, *, origin: type[DictValueObject[Any, Any]], key_type: Any, value_type: Any) -> None:
95
+ """
96
+ Create a runtime alias for a parameterized DictValueObject.
97
+
98
+ Args:
99
+ origin: The original DictValueObject class.
100
+ key_type: The key type argument used in `DictValueObject[K, V]`.
101
+ value_type: The value type argument used in `DictValueObject[K, V]`.
102
+ """
103
+ self.__origin__ = origin
104
+ self.__args__ = (key_type, value_type)
105
+
106
+ def __call__(self, *args: Any, **kwargs: Any) -> Any:
107
+ """
108
+ Construct an inline parameterized DictValueObject instance.
109
+
110
+ Args:
111
+ *args: Positional arguments passed to the generated value object subclass.
112
+ **kwargs: Keyword arguments passed to the generated value object subclass.
113
+
114
+ Returns:
115
+ Any: The constructed value object.
116
+ """
117
+ return self._runtime_class()(*args, **kwargs)
118
+
119
+ def __getattr__(self, name: str) -> Any:
120
+ """
121
+ Delegate class attribute access to the generated runtime subclass.
122
+
123
+ Args:
124
+ name: The attribute name to retrieve.
125
+
126
+ Returns:
127
+ Any: The resolved attribute.
128
+ """
129
+ return getattr(self._runtime_class(), name)
130
+
131
+ def __mro_entries__(self, bases: tuple[type, ...]) -> tuple[type[DictValueObject[Any, Any]], ...]:
132
+ """
133
+ Return the origin class when the alias is used as a base class.
134
+
135
+ Args:
136
+ bases: The original class bases supplied by Python.
137
+
138
+ Returns:
139
+ tuple[type[DictValueObject[Any, Any]], ...]: The base classes to use for MRO construction.
140
+ """
141
+ _ = bases
142
+
143
+ return (self.__origin__,)
144
+
145
+ def _runtime_class(self) -> type[DictValueObject[Any, Any]]:
146
+ """
147
+ Return the generated runtime subclass for this alias.
148
+
149
+ Returns:
150
+ type[DictValueObject[Any, Any]]: The runtime subclass.
151
+ """
152
+ key_type, value_type = self.__args__
153
+ _validate_dict_type_argument(type_argument=key_type)
154
+ _validate_dict_type_argument(type_argument=value_type)
155
+ key = (self.__origin__, key_type, value_type)
156
+ if key not in self._runtime_classes:
157
+ self._runtime_classes[key] = type(
158
+ f'{self.__origin__.__name__}[{self._format_type_argument(type=key_type)}, {self._format_type_argument(type=value_type)}]', # noqa: E501
159
+ (self.__origin__,),
160
+ {
161
+ '_is_inline_parameterized_dict_value_object': True,
162
+ '_key_type': key_type,
163
+ '_value_type': value_type,
164
+ },
165
+ )
166
+
167
+ return self._runtime_classes[key]
168
+
169
+ @staticmethod
170
+ def _format_type_argument(*, type: Any) -> str:
171
+ """
172
+ Return a compact type-argument label for generated runtime class names.
173
+
174
+ Args:
175
+ type: The type argument to format.
176
+
177
+ Returns:
178
+ str: A readable type label.
179
+ """
180
+ origin = get_origin(tp=type)
181
+ if origin in (Union, UnionType):
182
+ return ' | '.join(_DictValueObjectAlias._format_type_argument(type=allowed) for allowed in get_args(type))
183
+
184
+ if hasattr(type, '__name__'):
185
+ return type.__name__ # type: ignore[no-any-return]
186
+
187
+ return str(type).replace('typing.', '')
188
+
189
+
28
190
  class DictValueObject(ValueObject[dict[K, V]], Generic[K, V]): # noqa: UP046
29
191
  """
30
192
  Validate dictionary values, keys, and items against declared key and value types.
@@ -54,6 +216,21 @@ class DictValueObject(ValueObject[dict[K, V]], Generic[K, V]): # noqa: UP046
54
216
  _key_type: K
55
217
  _value_type: V
56
218
 
219
+ @classmethod
220
+ def __class_getitem__(cls, item: Any) -> Any:
221
+ """
222
+ Return a runtime alias that supports subclassing and inline construction.
223
+
224
+ Args:
225
+ item: The type arguments used in `DictValueObject[item]`.
226
+
227
+ Returns:
228
+ Any: A runtime alias for the parameterized DictValueObject.
229
+ """
230
+ key_type, value_type = _parse_dict_type_arguments(type_arguments=item)
231
+
232
+ return _DictValueObjectAlias(origin=cls, key_type=key_type, value_type=value_type)
233
+
57
234
  @override
58
235
  def __init_subclass__(cls, **kwargs: Any) -> None:
59
236
  """
@@ -69,25 +246,17 @@ class DictValueObject(ValueObject[dict[K, V]], Generic[K, V]): # noqa: UP046
69
246
  """
70
247
  super().__init_subclass__(**kwargs)
71
248
 
72
- for base in getattr(cls, '__orig_bases__', ()):
73
- if get_origin(base) is DictValueObject:
74
- key_type, val_type, *_ = get_args(base)
75
-
76
- if isinstance(key_type, TypeVar):
77
- cls._key_type = key_type # type: ignore[assignment]
78
- else:
79
- if type(key_type) is not type and not isclass(key_type) and get_origin(key_type) is None:
80
- raise TypeError(f'DictValueObject[...] <<<{key_type}>>> must be a type. Got <<<{type(key_type).__name__}>>> type.') # noqa: E501 # fmt: skip
81
-
82
- cls._key_type = key_type
249
+ if getattr(cls, '_is_inline_parameterized_dict_value_object', False):
250
+ return
83
251
 
84
- if isinstance(val_type, TypeVar):
85
- cls._value_type = val_type # type: ignore[assignment]
86
- else:
87
- if type(val_type) is not type and not isclass(val_type) and get_origin(val_type) is None:
88
- raise TypeError(f'DictValueObject[...] <<<{val_type}>>> must be a type. Got <<<{type(val_type).__name__}>>> type.') # noqa: E501 # fmt: skip
252
+ for base in getattr(cls, '__orig_bases__', ()):
253
+ if get_origin(base) is DictValueObject or getattr(base, '__origin__', None) is DictValueObject:
254
+ key_type, val_type = get_args(base) or base.__args__
89
255
 
90
- cls._value_type = val_type
256
+ _validate_dict_type_argument(type_argument=key_type)
257
+ cls._key_type = key_type
258
+ _validate_dict_type_argument(type_argument=val_type)
259
+ cls._value_type = val_type
91
260
 
92
261
  return
93
262
 
@@ -476,6 +645,9 @@ class DictValueObject(ValueObject[dict[K, V]], Generic[K, V]): # noqa: UP046
476
645
  Returns:
477
646
  Self: The created DictValueObject.
478
647
 
648
+ Raises:
649
+ TypeError: If the `value` is not a dict.
650
+
479
651
  Example:
480
652
  ```python
481
653
  from value_object_pattern.models import ValueObject
@@ -495,6 +667,9 @@ class DictValueObject(ValueObject[dict[K, V]], Generic[K, V]): # noqa: UP046
495
667
  # >>> {'john': 30, 'jane': 25}
496
668
  ```
497
669
  """
670
+ if not isinstance(cast(Any, value), dict):
671
+ return cls(value=value)
672
+
498
673
  dictionary: dict[Any, Any] = {}
499
674
 
500
675
  for key, item in value.items():
@@ -15,7 +15,7 @@ from collections.abc import Iterator
15
15
  from enum import Enum
16
16
  from inspect import isclass
17
17
  from types import UnionType
18
- from typing import Any, Generic, NoReturn, Self, TypeVar, Union, get_args, get_origin
18
+ from typing import Any, ClassVar, Generic, NoReturn, Self, TypeVar, Union, cast, get_args, get_origin
19
19
 
20
20
  from value_object_pattern.decorators import validation
21
21
  from value_object_pattern.models import BaseModel, ValueObject
@@ -25,6 +25,127 @@ from value_object_pattern.models.type_matching import matches_expected_type
25
25
  T = TypeVar('T', bound=Any)
26
26
 
27
27
 
28
+ def _validate_list_type_argument(*, type_argument: Any) -> None:
29
+ """
30
+ Validate a type argument used by ListValueObject.
31
+
32
+ Args:
33
+ type_argument: The type argument to validate.
34
+
35
+ Raises:
36
+ TypeError: If the type argument is not a type-like annotation.
37
+ """
38
+ if isinstance(type_argument, TypeVar):
39
+ return
40
+
41
+ if type(type_argument) is not type and not isclass(object=type_argument) and get_origin(tp=type_argument) is None:
42
+ raise TypeError(f'ListValueObject[...] <<<{type_argument}>>> must be a type. Got <<<{type(type_argument).__name__}>>> type.') # noqa: E501 # fmt: skip
43
+
44
+
45
+ class _ListValueObjectAlias:
46
+ """
47
+ Runtime alias returned by `ListValueObject[T]`.
48
+
49
+ The item type must be available before `ValueObject.__init__` validates the list. This alias keeps subclass
50
+ declarations working through `__mro_entries__` and supports direct inline construction by creating a parameterized
51
+ runtime subclass before validation starts.
52
+ """
53
+
54
+ _runtime_classes: ClassVar[dict[Any, type[ListValueObject[Any]]]] = {}
55
+
56
+ def __init__(self, *, origin: type[ListValueObject[Any]], type_argument: Any) -> None:
57
+ """
58
+ Create a runtime alias for a parameterized ListValueObject.
59
+
60
+ Args:
61
+ origin: The original ListValueObject class.
62
+ type_argument: The type argument used in `ListValueObject[T]`.
63
+ """
64
+ self.__origin__ = origin
65
+ self.__args__ = (type_argument,)
66
+
67
+ def __call__(self, *args: Any, **kwargs: Any) -> Any:
68
+ """
69
+ Construct an inline parameterized ListValueObject instance.
70
+
71
+ Args:
72
+ *args: Positional arguments passed to the generated value object subclass.
73
+ **kwargs: Keyword arguments passed to the generated value object subclass.
74
+
75
+ Returns:
76
+ Any: The constructed value object.
77
+ """
78
+ return self._runtime_class()(*args, **kwargs)
79
+
80
+ def __getattr__(self, name: str) -> Any:
81
+ """
82
+ Delegate class attribute access to the generated runtime subclass.
83
+
84
+ Args:
85
+ name: The attribute name to retrieve.
86
+
87
+ Returns:
88
+ Any: The resolved attribute.
89
+ """
90
+ return getattr(self._runtime_class(), name)
91
+
92
+ def __mro_entries__(self, bases: tuple[type, ...]) -> tuple[type[ListValueObject[Any]], ...]:
93
+ """
94
+ Return the origin class when the alias is used as a base class.
95
+
96
+ Args:
97
+ bases: The original class bases supplied by Python.
98
+
99
+ Returns:
100
+ tuple[type[ListValueObject[Any]], ...]: The base classes to use for MRO construction.
101
+ """
102
+ _ = bases
103
+
104
+ return (self.__origin__,)
105
+
106
+ def _runtime_class(self) -> type[ListValueObject[Any]]:
107
+ """
108
+ Return the generated runtime subclass for this alias.
109
+
110
+ Returns:
111
+ type[ListValueObject[Any]]: The runtime subclass.
112
+ """
113
+ type_argument, *_ = self.__args__
114
+ _validate_list_type_argument(type_argument=type_argument)
115
+ key = (self.__origin__, type_argument)
116
+ if key not in self._runtime_classes:
117
+ self._runtime_classes[key] = type(
118
+ f'{self.__origin__.__name__}[{self._format_type_argument(type=type_argument)}]',
119
+ (self.__origin__,),
120
+ {
121
+ '_is_inline_parameterized_list_value_object': True,
122
+ '_type': type_argument,
123
+ },
124
+ )
125
+
126
+ return self._runtime_classes[key]
127
+
128
+ @staticmethod
129
+ def _format_type_argument(*, type: Any) -> str:
130
+ """
131
+ Return a compact type-argument label for generated runtime class names.
132
+
133
+ Args:
134
+ type: The type argument to format.
135
+
136
+ Returns:
137
+ str: A readable type label.
138
+ """
139
+ origin = get_origin(tp=type)
140
+ if origin in (Union, UnionType):
141
+ return ' | '.join(_ListValueObjectAlias._format_type_argument(type=allowed) for allowed in get_args(type))
142
+
143
+ if hasattr(type, '__name__'):
144
+ return type.__name__ # type: ignore[no-any-return]
145
+
146
+ return str(type).replace('typing.', '')
147
+
148
+
28
149
  class ListValueObject(ValueObject[list[T]], Generic[T]): # noqa: UP046
29
150
  """
30
151
  Validate list values and every item against the declared item type.
@@ -50,6 +171,19 @@ class ListValueObject(ValueObject[list[T]], Generic[T]): # noqa: UP046
50
171
 
51
172
  _type: T
52
173
 
174
+ @classmethod
175
+ def __class_getitem__(cls, item: Any) -> Any:
176
+ """
177
+ Return a runtime alias that supports subclassing and inline construction.
178
+
179
+ Args:
180
+ item: The type argument used in `ListValueObject[item]`.
181
+
182
+ Returns:
183
+ Any: A runtime alias for the parameterized ListValueObject.
184
+ """
185
+ return _ListValueObjectAlias(origin=cls, type_argument=item)
186
+
53
187
  @override
54
188
  def __init_subclass__(cls, **kwargs: Any) -> None:
55
189
  """
@@ -64,17 +198,14 @@ class ListValueObject(ValueObject[list[T]], Generic[T]): # noqa: UP046
64
198
  """
65
199
  super().__init_subclass__(**kwargs)
66
200
 
67
- for base in getattr(cls, '__orig_bases__', ()):
68
- if get_origin(tp=base) is ListValueObject:
69
- _type, *_ = get_args(tp=base)
70
-
71
- if isinstance(_type, TypeVar):
72
- cls._type = _type # type: ignore[assignment]
73
- return
201
+ if getattr(cls, '_is_inline_parameterized_list_value_object', False):
202
+ return
74
203
 
75
- if type(_type) is not type and not isclass(object=_type) and get_origin(tp=_type) is None:
76
- raise TypeError(f'ListValueObject[...] <<<{_type}>>> must be a type. Got <<<{type(_type).__name__}>>> type.') # noqa: E501 # fmt: skip
204
+ for base in getattr(cls, '__orig_bases__', ()):
205
+ if get_origin(tp=base) is ListValueObject or getattr(base, '__origin__', None) is ListValueObject:
206
+ _type, *_ = get_args(tp=base) or base.__args__
77
207
 
208
+ _validate_list_type_argument(type_argument=_type)
78
209
  cls._type = _type
79
210
  return
80
211
 
@@ -747,6 +878,9 @@ class ListValueObject(ValueObject[list[T]], Generic[T]): # noqa: UP046
747
878
  # >>> [10, 20, 30]
748
879
  ```
749
880
  """
881
+ if not isinstance(cast(Any, value), list):
882
+ return cls(value=value)
883
+
750
884
  return cls(value=[from_primitive(value=item, expected_type=cls._type) for item in value])
751
885
 
752
886
  def to_primitives(self) -> list[Any]: