value-object-pattern 1.30.0__tar.gz → 1.31.0__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.
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/.gitignore +1 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/PKG-INFO +4 -4
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/README.md +3 -3
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/__init__.py +1 -1
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/collections/dict_value_object.py +186 -18
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/collections/list_value_object.py +141 -10
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/union_value_object.py +141 -10
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/LICENSE.md +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/pyproject.toml +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/decorators/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/decorators/classproperty.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/decorators/value_object_process.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/decorators/value_object_validation.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/base_model.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/collections/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/enumeration_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/primitive_conversion.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/type_matching.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/py.typed +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/date/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/date/date_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/date/string_date_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/datetime/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/datetime/datetime_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/datetime/string_datetime_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/timezone/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/timezone/string_timezone_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/dates/timezone/timezone_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_v1_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_v3_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_v4_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_v5_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_v6_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_v7_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_v8_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/string_uuid_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/uuid_v1_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/uuid_v3_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/uuid_v4_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/uuid_v5_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/uuid_v6_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/uuid_v7_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/uuid_v8_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/uuid/uuid_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/country_tld_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/dni_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/nie_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/nif_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/nuss_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/passport_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/phone_number_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/administrative_technician_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/air_force_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/army_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/canarias_police_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/catalan_police_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/civil_guard_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/consular_corps_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/diplomatic_corps_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/especial_plate_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/historical_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/international_organization_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/ministry_development_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/ministry_environment_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/national_police_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/navy_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/ordinary_truck_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/ordinary_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/provincial_system_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/state_motor_pool_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_company_not_registered_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_company_registered_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/temporal_private_individual_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/two_wheels_vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/utils/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/plates/utils/provincial_plate_codes.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/utils/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/utils/provincial_codes.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/europe/spain/vehicle_plate_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/iso3166_alpha2_code_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/iso3166_alpha3_code_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/iso3166_numeric_code_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/phone_code_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/utils/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_codes.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_alpha3_mapping.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_numeric_mapping.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_phone_code_mapping.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha2_to_tld_mapping.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_alpha3_codes.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/utils/iso3166_numeric_codes.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/identifiers/world/vin_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/aws_cloud_region_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/domain_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/email_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/host_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/ip_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/ipv4_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/ipv4_network_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/ipv6_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/ipv6_network_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/keys/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/keys/kebab_case_key_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/keys/snake_case_key_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mac_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mac_addresses/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mac_addresses/cisco_mac_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mac_addresses/raw_mac_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mac_addresses/space_mac_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mac_addresses/universal_mac_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mac_addresses/windows_mac_address_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mobile/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/mobile/imei_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/port_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/slug_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/uri/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/uri/http_https_url_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/uri/http_url_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/uri/https_url_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/uri/url_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/user_agent_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/utils/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/utils/aws_regions.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/internet/utils/tld_domains.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/credit_card_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/credit_cards/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/credit_cards/amex_credit_card_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/credit_cards/discover_credit_card_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/credit_cards/mastercard_credit_card_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/credit_cards/visa_credit_card_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/iban_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/utils/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/money/utils/iban_lengths.txt +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/boolean/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/boolean/boolean_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/boolean/false_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/boolean/true_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/bytes/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/bytes/bytes_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/float/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/float/float_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/float/negative_float_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/float/negative_or_zero_float_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/float/positive_float_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/float/positive_or_zero_float_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/integer/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/integer/even_integer_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/integer/integer_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/integer/negative_integer_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/integer/negative_or_zero_integer_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/integer/odd_integer_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/integer/positive_integer_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/integer/positive_or_zero_integer_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/none/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/none/none_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/none/not_none_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/alpha_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/alphanumeric_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/camel_case_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/digit_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/kebab_case_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/lowercase_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/non_empty_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/pascal_case_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/printable_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/screaming_snake_case_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/secret_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/snake_case_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/trimmed_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/primitives/string/uppercase_string_value_object.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/utils/__init__.py +0 -0
- {value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/usables/utils/luhn_validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: value-object-pattern
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.31.0
|
|
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
|
|
268
|
-
| `DictValueObject[K, V]` | Immutable typed dictionary wrapper
|
|
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
|
|
243
|
-
| `DictValueObject[K, V]` | Immutable typed dictionary wrapper
|
|
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
|
|
|
@@ -14,7 +14,20 @@ else:
|
|
|
14
14
|
from collections.abc import Iterator
|
|
15
15
|
from inspect import isclass
|
|
16
16
|
from types import UnionType
|
|
17
|
-
from typing import
|
|
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
|
+
get_args,
|
|
29
|
+
get_origin,
|
|
30
|
+
)
|
|
18
31
|
|
|
19
32
|
from value_object_pattern.decorators import validation
|
|
20
33
|
from value_object_pattern.models import ValueObject
|
|
@@ -25,6 +38,154 @@ K = TypeVar('K', bound=Any)
|
|
|
25
38
|
V = TypeVar('V', bound=Any)
|
|
26
39
|
|
|
27
40
|
|
|
41
|
+
def _validate_dict_type_argument(*, type_argument: Any) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Validate a type argument used by DictValueObject.
|
|
44
|
+
|
|
45
|
+
Args:
|
|
46
|
+
type_argument: The type argument to validate.
|
|
47
|
+
|
|
48
|
+
Raises:
|
|
49
|
+
TypeError: If the type argument is not a type-like annotation.
|
|
50
|
+
"""
|
|
51
|
+
if isinstance(type_argument, TypeVar):
|
|
52
|
+
return
|
|
53
|
+
|
|
54
|
+
if type(type_argument) is not type and not isclass(object=type_argument) and get_origin(tp=type_argument) is None:
|
|
55
|
+
raise TypeError(f'DictValueObject[...] <<<{type_argument}>>> must be a type. Got <<<{type(type_argument).__name__}>>> type.') # noqa: E501 # fmt: skip
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _parse_dict_type_arguments(*, type_arguments: Any) -> tuple[Any, Any]:
|
|
59
|
+
"""
|
|
60
|
+
Return key and value type arguments from `DictValueObject[K, V]` input.
|
|
61
|
+
|
|
62
|
+
Args:
|
|
63
|
+
type_arguments: The raw type arguments passed to `DictValueObject[...]`.
|
|
64
|
+
|
|
65
|
+
Raises:
|
|
66
|
+
TypeError: If exactly two type arguments are not provided.
|
|
67
|
+
|
|
68
|
+
Returns:
|
|
69
|
+
tuple[Any, Any]: The key and value type arguments.
|
|
70
|
+
"""
|
|
71
|
+
if not isinstance(type_arguments, tuple):
|
|
72
|
+
raise TypeError('DictValueObject must be parameterised, e.g. `class StrIntDict(DictValueObject[str, int])`.')
|
|
73
|
+
|
|
74
|
+
if len(type_arguments) != 2:
|
|
75
|
+
raise TypeError('DictValueObject must be parameterised, e.g. `class StrIntDict(DictValueObject[str, int])`.')
|
|
76
|
+
|
|
77
|
+
key_type, value_type = type_arguments
|
|
78
|
+
|
|
79
|
+
return key_type, value_type
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class _DictValueObjectAlias:
|
|
83
|
+
"""
|
|
84
|
+
Runtime alias returned by `DictValueObject[K, V]`.
|
|
85
|
+
|
|
86
|
+
Key and value types must be available before `ValueObject.__init__` validates the dictionary. This alias keeps
|
|
87
|
+
subclass declarations working through `__mro_entries__` and supports direct inline construction by creating a
|
|
88
|
+
parameterized runtime subclass before validation starts.
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
_runtime_classes: ClassVar[dict[Any, type[DictValueObject[Any, Any]]]] = {}
|
|
92
|
+
|
|
93
|
+
def __init__(self, *, origin: type[DictValueObject[Any, Any]], key_type: Any, value_type: Any) -> None:
|
|
94
|
+
"""
|
|
95
|
+
Create a runtime alias for a parameterized DictValueObject.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
origin: The original DictValueObject class.
|
|
99
|
+
key_type: The key type argument used in `DictValueObject[K, V]`.
|
|
100
|
+
value_type: The value type argument used in `DictValueObject[K, V]`.
|
|
101
|
+
"""
|
|
102
|
+
self.__origin__ = origin
|
|
103
|
+
self.__args__ = (key_type, value_type)
|
|
104
|
+
|
|
105
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
|
106
|
+
"""
|
|
107
|
+
Construct an inline parameterized DictValueObject instance.
|
|
108
|
+
|
|
109
|
+
Args:
|
|
110
|
+
*args: Positional arguments passed to the generated value object subclass.
|
|
111
|
+
**kwargs: Keyword arguments passed to the generated value object subclass.
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
Any: The constructed value object.
|
|
115
|
+
"""
|
|
116
|
+
return self._runtime_class()(*args, **kwargs)
|
|
117
|
+
|
|
118
|
+
def __getattr__(self, name: str) -> Any:
|
|
119
|
+
"""
|
|
120
|
+
Delegate class attribute access to the generated runtime subclass.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
name: The attribute name to retrieve.
|
|
124
|
+
|
|
125
|
+
Returns:
|
|
126
|
+
Any: The resolved attribute.
|
|
127
|
+
"""
|
|
128
|
+
return getattr(self._runtime_class(), name)
|
|
129
|
+
|
|
130
|
+
def __mro_entries__(self, bases: tuple[type, ...]) -> tuple[type[DictValueObject[Any, Any]], ...]:
|
|
131
|
+
"""
|
|
132
|
+
Return the origin class when the alias is used as a base class.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
bases: The original class bases supplied by Python.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
tuple[type[DictValueObject[Any, Any]], ...]: The base classes to use for MRO construction.
|
|
139
|
+
"""
|
|
140
|
+
_ = bases
|
|
141
|
+
|
|
142
|
+
return (self.__origin__,)
|
|
143
|
+
|
|
144
|
+
def _runtime_class(self) -> type[DictValueObject[Any, Any]]:
|
|
145
|
+
"""
|
|
146
|
+
Return the generated runtime subclass for this alias.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
type[DictValueObject[Any, Any]]: The runtime subclass.
|
|
150
|
+
"""
|
|
151
|
+
key_type, value_type = self.__args__
|
|
152
|
+
_validate_dict_type_argument(type_argument=key_type)
|
|
153
|
+
_validate_dict_type_argument(type_argument=value_type)
|
|
154
|
+
key = (self.__origin__, key_type, value_type)
|
|
155
|
+
if key not in self._runtime_classes:
|
|
156
|
+
self._runtime_classes[key] = type(
|
|
157
|
+
f'{self.__origin__.__name__}[{self._format_type_argument(type=key_type)}, {self._format_type_argument(type=value_type)}]', # noqa: E501
|
|
158
|
+
(self.__origin__,),
|
|
159
|
+
{
|
|
160
|
+
'_is_inline_parameterized_dict_value_object': True,
|
|
161
|
+
'_key_type': key_type,
|
|
162
|
+
'_value_type': value_type,
|
|
163
|
+
},
|
|
164
|
+
)
|
|
165
|
+
|
|
166
|
+
return self._runtime_classes[key]
|
|
167
|
+
|
|
168
|
+
@staticmethod
|
|
169
|
+
def _format_type_argument(*, type: Any) -> str:
|
|
170
|
+
"""
|
|
171
|
+
Return a compact type-argument label for generated runtime class names.
|
|
172
|
+
|
|
173
|
+
Args:
|
|
174
|
+
type: The type argument to format.
|
|
175
|
+
|
|
176
|
+
Returns:
|
|
177
|
+
str: A readable type label.
|
|
178
|
+
"""
|
|
179
|
+
origin = get_origin(tp=type)
|
|
180
|
+
if origin in (Union, UnionType):
|
|
181
|
+
return ' | '.join(_DictValueObjectAlias._format_type_argument(type=allowed) for allowed in get_args(type))
|
|
182
|
+
|
|
183
|
+
if hasattr(type, '__name__'):
|
|
184
|
+
return type.__name__ # type: ignore[no-any-return]
|
|
185
|
+
|
|
186
|
+
return str(type).replace('typing.', '')
|
|
187
|
+
|
|
188
|
+
|
|
28
189
|
class DictValueObject(ValueObject[dict[K, V]], Generic[K, V]): # noqa: UP046
|
|
29
190
|
"""
|
|
30
191
|
Validate dictionary values, keys, and items against declared key and value types.
|
|
@@ -54,6 +215,21 @@ class DictValueObject(ValueObject[dict[K, V]], Generic[K, V]): # noqa: UP046
|
|
|
54
215
|
_key_type: K
|
|
55
216
|
_value_type: V
|
|
56
217
|
|
|
218
|
+
@classmethod
|
|
219
|
+
def __class_getitem__(cls, item: Any) -> Any:
|
|
220
|
+
"""
|
|
221
|
+
Return a runtime alias that supports subclassing and inline construction.
|
|
222
|
+
|
|
223
|
+
Args:
|
|
224
|
+
item: The type arguments used in `DictValueObject[item]`.
|
|
225
|
+
|
|
226
|
+
Returns:
|
|
227
|
+
Any: A runtime alias for the parameterized DictValueObject.
|
|
228
|
+
"""
|
|
229
|
+
key_type, value_type = _parse_dict_type_arguments(type_arguments=item)
|
|
230
|
+
|
|
231
|
+
return _DictValueObjectAlias(origin=cls, key_type=key_type, value_type=value_type)
|
|
232
|
+
|
|
57
233
|
@override
|
|
58
234
|
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
59
235
|
"""
|
|
@@ -69,25 +245,17 @@ class DictValueObject(ValueObject[dict[K, V]], Generic[K, V]): # noqa: UP046
|
|
|
69
245
|
"""
|
|
70
246
|
super().__init_subclass__(**kwargs)
|
|
71
247
|
|
|
72
|
-
|
|
73
|
-
|
|
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
|
|
248
|
+
if getattr(cls, '_is_inline_parameterized_dict_value_object', False):
|
|
249
|
+
return
|
|
83
250
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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
|
|
251
|
+
for base in getattr(cls, '__orig_bases__', ()):
|
|
252
|
+
if get_origin(base) is DictValueObject or getattr(base, '__origin__', None) is DictValueObject:
|
|
253
|
+
key_type, val_type = get_args(base) or base.__args__
|
|
89
254
|
|
|
90
|
-
|
|
255
|
+
_validate_dict_type_argument(type_argument=key_type)
|
|
256
|
+
cls._key_type = key_type
|
|
257
|
+
_validate_dict_type_argument(type_argument=val_type)
|
|
258
|
+
cls._value_type = val_type
|
|
91
259
|
|
|
92
260
|
return
|
|
93
261
|
|
|
@@ -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, 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
|
-
|
|
68
|
-
|
|
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
|
-
|
|
76
|
-
|
|
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
|
|
|
@@ -14,7 +14,7 @@ else:
|
|
|
14
14
|
from enum import Enum
|
|
15
15
|
from inspect import isclass
|
|
16
16
|
from types import UnionType
|
|
17
|
-
from typing import Any, Generic, NoReturn, Self, TypeVar, Union, get_args, get_origin
|
|
17
|
+
from typing import Any, ClassVar, Generic, NoReturn, Self, TypeVar, Union, get_args, get_origin
|
|
18
18
|
|
|
19
19
|
from value_object_pattern.decorators import process, validation
|
|
20
20
|
|
|
@@ -26,6 +26,127 @@ from .value_object import ValueObject
|
|
|
26
26
|
T = TypeVar('T', bound=Any)
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
def _validate_union_type_argument(*, type_argument: Any) -> None:
|
|
30
|
+
"""
|
|
31
|
+
Validate a type argument used by UnionValueObject.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
type_argument: The type argument to validate.
|
|
35
|
+
|
|
36
|
+
Raises:
|
|
37
|
+
TypeError: If the type argument is not a type-like annotation.
|
|
38
|
+
"""
|
|
39
|
+
if isinstance(type_argument, TypeVar):
|
|
40
|
+
return
|
|
41
|
+
|
|
42
|
+
if type(type_argument) is not type and not isclass(object=type_argument) and get_origin(tp=type_argument) is None:
|
|
43
|
+
raise TypeError(f'UnionValueObject[...] <<<{type_argument}>>> must be a type. Got <<<{type(type_argument).__name__}>>> type.') # noqa: E501 # fmt: skip
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class _UnionValueObjectAlias:
|
|
47
|
+
"""
|
|
48
|
+
Runtime alias returned by `UnionValueObject[T]`.
|
|
49
|
+
|
|
50
|
+
Python assigns `__orig_class__` only after `__init__` completes, but union conversion needs the type parameter
|
|
51
|
+
during `ValueObject.__init__`. This alias keeps subclass declarations working through `__mro_entries__` and supports
|
|
52
|
+
direct inline construction by creating a parameterized runtime subclass before validation starts.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
_runtime_classes: ClassVar[dict[Any, type[UnionValueObject[Any]]]] = {}
|
|
56
|
+
|
|
57
|
+
def __init__(self, *, origin: type[UnionValueObject[Any]], type_argument: Any) -> None:
|
|
58
|
+
"""
|
|
59
|
+
Create a runtime alias for a parameterized UnionValueObject.
|
|
60
|
+
|
|
61
|
+
Args:
|
|
62
|
+
origin: The original UnionValueObject class.
|
|
63
|
+
type_argument: The type argument used in `UnionValueObject[T]`.
|
|
64
|
+
"""
|
|
65
|
+
self.__origin__ = origin
|
|
66
|
+
self.__args__ = (type_argument,)
|
|
67
|
+
|
|
68
|
+
def __call__(self, *args: Any, **kwargs: Any) -> Any:
|
|
69
|
+
"""
|
|
70
|
+
Construct an inline parameterized UnionValueObject instance.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
*args: Positional arguments passed to the generated value object subclass.
|
|
74
|
+
**kwargs: Keyword arguments passed to the generated value object subclass.
|
|
75
|
+
|
|
76
|
+
Returns:
|
|
77
|
+
Any: The constructed value object.
|
|
78
|
+
"""
|
|
79
|
+
return self._runtime_class()(*args, **kwargs)
|
|
80
|
+
|
|
81
|
+
def __getattr__(self, name: str) -> Any:
|
|
82
|
+
"""
|
|
83
|
+
Delegate class attribute access to the generated runtime subclass.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
name: The attribute name to retrieve.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
Any: The resolved attribute.
|
|
90
|
+
"""
|
|
91
|
+
return getattr(self._runtime_class(), name)
|
|
92
|
+
|
|
93
|
+
def __mro_entries__(self, bases: tuple[type, ...]) -> tuple[type[UnionValueObject[Any]], ...]:
|
|
94
|
+
"""
|
|
95
|
+
Return the origin class when the alias is used as a base class.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
bases: The original class bases supplied by Python.
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
tuple[type[UnionValueObject[Any]], ...]: The base classes to use for MRO construction.
|
|
102
|
+
"""
|
|
103
|
+
_ = bases
|
|
104
|
+
|
|
105
|
+
return (self.__origin__,)
|
|
106
|
+
|
|
107
|
+
def _runtime_class(self) -> type[UnionValueObject[Any]]:
|
|
108
|
+
"""
|
|
109
|
+
Return the generated runtime subclass for this alias.
|
|
110
|
+
|
|
111
|
+
Returns:
|
|
112
|
+
type[UnionValueObject[Any]]: The runtime subclass.
|
|
113
|
+
"""
|
|
114
|
+
type_argument, *_ = self.__args__
|
|
115
|
+
_validate_union_type_argument(type_argument=type_argument)
|
|
116
|
+
key = (self.__origin__, type_argument)
|
|
117
|
+
if key not in self._runtime_classes:
|
|
118
|
+
self._runtime_classes[key] = type(
|
|
119
|
+
f'{self.__origin__.__name__}[{self._format_type_argument(type=type_argument)}]',
|
|
120
|
+
(self.__origin__,),
|
|
121
|
+
{
|
|
122
|
+
'_is_inline_parameterized_union_value_object': True,
|
|
123
|
+
'_type': type_argument,
|
|
124
|
+
},
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
return self._runtime_classes[key]
|
|
128
|
+
|
|
129
|
+
@staticmethod
|
|
130
|
+
def _format_type_argument(*, type: Any) -> str:
|
|
131
|
+
"""
|
|
132
|
+
Return a compact type-argument label for generated runtime class names.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
type: The type argument to format.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
str: A readable type label.
|
|
139
|
+
"""
|
|
140
|
+
origin = get_origin(tp=type)
|
|
141
|
+
if origin in (Union, UnionType):
|
|
142
|
+
return ' | '.join(_UnionValueObjectAlias._format_type_argument(type=allowed) for allowed in get_args(type))
|
|
143
|
+
|
|
144
|
+
if hasattr(type, '__name__'):
|
|
145
|
+
return type.__name__ # type: ignore[no-any-return]
|
|
146
|
+
|
|
147
|
+
return str(type).replace('typing.', '')
|
|
148
|
+
|
|
149
|
+
|
|
29
150
|
class UnionValueObject(ValueObject[T], Generic[T]): # noqa: UP046
|
|
30
151
|
"""
|
|
31
152
|
Validate and store a value as one of the allowed union candidates.
|
|
@@ -66,6 +187,19 @@ class UnionValueObject(ValueObject[T], Generic[T]): # noqa: UP046
|
|
|
66
187
|
|
|
67
188
|
_type: T
|
|
68
189
|
|
|
190
|
+
@classmethod
|
|
191
|
+
def __class_getitem__(cls, item: Any) -> Any:
|
|
192
|
+
"""
|
|
193
|
+
Return a runtime alias that supports subclassing and inline construction.
|
|
194
|
+
|
|
195
|
+
Args:
|
|
196
|
+
item: The type argument used in `UnionValueObject[item]`.
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
Any: A runtime alias for the parameterized UnionValueObject.
|
|
200
|
+
"""
|
|
201
|
+
return _UnionValueObjectAlias(origin=cls, type_argument=item)
|
|
202
|
+
|
|
69
203
|
@override
|
|
70
204
|
def __init_subclass__(cls, **kwargs: Any) -> None:
|
|
71
205
|
"""
|
|
@@ -80,17 +214,14 @@ class UnionValueObject(ValueObject[T], Generic[T]): # noqa: UP046
|
|
|
80
214
|
"""
|
|
81
215
|
super().__init_subclass__(**kwargs)
|
|
82
216
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
_type, *_ = get_args(tp=base)
|
|
86
|
-
|
|
87
|
-
if isinstance(_type, TypeVar):
|
|
88
|
-
cls._type = _type # type: ignore[assignment]
|
|
89
|
-
return
|
|
217
|
+
if getattr(cls, '_is_inline_parameterized_union_value_object', False):
|
|
218
|
+
return
|
|
90
219
|
|
|
91
|
-
|
|
92
|
-
|
|
220
|
+
for base in getattr(cls, '__orig_bases__', ()):
|
|
221
|
+
if get_origin(tp=base) is UnionValueObject or getattr(base, '__origin__', None) is UnionValueObject:
|
|
222
|
+
_type, *_ = get_args(tp=base) or base.__args__
|
|
93
223
|
|
|
224
|
+
_validate_union_type_argument(type_argument=_type)
|
|
94
225
|
cls._type = _type
|
|
95
226
|
return
|
|
96
227
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{value_object_pattern-1.30.0 → value_object_pattern-1.31.0}/value_object_pattern/models/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|