0
# Other Specialized Types
1
2
Specialized comparison types for common data formats including JSON, UUIDs, URLs, hashes, IP addresses, dataclasses, enums, and custom function-based validation. These types enable validation of complex data formats and structures beyond basic Python types.
3
4
## Capabilities
5
6
### IsUUID
7
8
UUID (Universally Unique Identifier) validation with optional version constraints.
9
10
```python { .api }
11
class IsUUID(DirtyEquals):
12
"""
13
UUID validation with optional version checking.
14
15
Validates that a value is a properly formatted UUID,
16
optionally checking for a specific UUID version.
17
"""
18
19
def __init__(self, version: Optional[int] = None):
20
"""
21
Initialize UUID validator.
22
23
Args:
24
version: Specific UUID version to validate (1-5), None for any version
25
"""
26
27
def equals(self, other: Any) -> bool:
28
"""
29
Check if value is a valid UUID.
30
31
Args:
32
other: Value to validate (string or uuid.UUID object)
33
34
Returns:
35
bool: True if valid UUID (and correct version if specified)
36
"""
37
```
38
39
#### Usage Examples
40
41
```python
42
from dirty_equals import IsUUID
43
import uuid
44
45
# Basic UUID validation - any version
46
valid_uuid = str(uuid.uuid4())
47
assert valid_uuid == IsUUID
48
49
# UUID object validation
50
uuid_obj = uuid.uuid4()
51
assert uuid_obj == IsUUID
52
53
# Version-specific validation
54
uuid_v4 = str(uuid.uuid4()) # Version 4 UUID
55
assert uuid_v4 == IsUUID(version=4)
56
57
uuid_v1 = str(uuid.uuid1()) # Version 1 UUID
58
assert uuid_v1 == IsUUID(version=1)
59
60
# API response with UUIDs
61
api_response = {
62
'user_id': str(uuid.uuid4()),
63
'session_id': str(uuid.uuid4()),
64
'request_id': str(uuid.uuid4())
65
}
66
67
assert api_response == {
68
'user_id': IsUUID,
69
'session_id': IsUUID,
70
'request_id': IsUUID
71
}
72
73
# Database record validation
74
user_record = {
75
'id': '123e4567-e89b-12d3-a456-426614174000',
76
'external_id': uuid.uuid4(),
77
'tenant_id': str(uuid.uuid1())
78
}
79
80
assert user_record == {
81
'id': IsUUID,
82
'external_id': IsUUID,
83
'tenant_id': IsUUID(version=1) # Specific version requirement
84
}
85
```
86
87
### IsJson
88
89
JSON parsing and validation with support for expected value matching and generic type syntax.
90
91
```python { .api }
92
class IsJson(DirtyEquals):
93
"""
94
JSON parsing and validation.
95
96
Parses JSON strings and validates the resulting data structure
97
against expected values or patterns.
98
"""
99
100
def __init__(
101
self,
102
expected_value: Any = AnyJson,
103
**expected_kwargs: Any
104
):
105
"""
106
Initialize JSON validator (overloaded constructor).
107
108
Args:
109
expected_value: Expected value after JSON parsing
110
**expected_kwargs: Expected key-value pairs for JSON objects
111
"""
112
113
@classmethod
114
def __class_getitem__(cls, expected_value: Any) -> 'IsJson':
115
"""
116
Support generic syntax: IsJson[expected] equivalent to IsJson(expected).
117
118
Args:
119
expected_value: Expected value after parsing
120
121
Returns:
122
IsJson: New instance configured for the expected value
123
"""
124
125
def equals(self, other: Any) -> bool:
126
"""
127
Parse JSON and validate against expected value.
128
129
Args:
130
other: JSON string to parse and validate
131
132
Returns:
133
bool: True if JSON parses and matches expected structure
134
"""
135
```
136
137
#### Usage Examples
138
139
```python
140
from dirty_equals import IsJson, IsPositive, IsStr, AnyThing
141
142
# Basic JSON validation - any valid JSON
143
assert '{"key": "value"}' == IsJson
144
assert '[1, 2, 3]' == IsJson
145
assert '"hello"' == IsJson
146
assert 'true' == IsJson
147
148
# Specific value matching
149
assert '{"name": "John", "age": 25}' == IsJson({"name": "John", "age": 25})
150
151
# Generic syntax
152
assert '{"user_id": 123}' == IsJson[{"user_id": 123}]
153
154
# Keyword arguments for JSON objects
155
assert '{"name": "John", "age": 25}' == IsJson(name="John", age=25)
156
157
# With validators for JSON content
158
json_string = '{"user_id": 123, "username": "john_doe", "active": true}'
159
assert json_string == IsJson({
160
"user_id": IsPositive,
161
"username": IsStr,
162
"active": True
163
})
164
165
# API response validation
166
api_response = '{"status": "success", "data": [1, 2, 3], "count": 3}'
167
assert api_response == IsJson({
168
"status": "success",
169
"data": [1, 2, 3],
170
"count": IsPositive
171
})
172
173
# Configuration validation
174
config_json = '{"debug": true, "port": 8080, "features": ["auth", "logging"]}'
175
assert config_json == IsJson(
176
debug=True,
177
port=IsPositive,
178
features=["auth", "logging"]
179
)
180
181
# Nested JSON validation
182
nested_json = '''
183
{
184
"user": {
185
"id": 123,
186
"profile": {
187
"name": "John Doe",
188
"settings": {"theme": "dark"}
189
}
190
},
191
"metadata": {"version": 1}
192
}
193
'''
194
195
from dirty_equals import IsDict, IsPartialDict
196
197
assert nested_json == IsJson({
198
"user": IsDict({
199
"id": IsPositive,
200
"profile": IsPartialDict({"name": IsStr})
201
}),
202
"metadata": AnyThing # Accept any metadata
203
})
204
205
# Database field validation (JSON column)
206
user_preferences = '{"notifications": true, "theme": "light", "language": "en"}'
207
assert user_preferences == IsJson[IsDict({
208
"notifications": bool,
209
"theme": IsStr,
210
"language": IsStr
211
})]
212
```
213
214
### FunctionCheck
215
216
Custom function-based validation that allows arbitrary validation logic through user-provided functions.
217
218
```python { .api }
219
class FunctionCheck(DirtyEquals):
220
"""
221
Custom function-based validation.
222
223
Validates values using a user-provided function that returns
224
True for valid values and False for invalid ones.
225
"""
226
227
def __init__(self, func: Callable[[Any], bool]):
228
"""
229
Initialize function-based validator.
230
231
Args:
232
func: Function that takes a value and returns bool
233
"""
234
235
def equals(self, other: Any) -> bool:
236
"""
237
Validate using the provided function.
238
239
Args:
240
other: Value to validate
241
242
Returns:
243
bool: Result of calling func(other)
244
"""
245
```
246
247
#### Usage Examples
248
249
```python
250
from dirty_equals import FunctionCheck
251
252
# Simple validation functions
253
def is_even(x):
254
return isinstance(x, int) and x % 2 == 0
255
256
def is_valid_email(email):
257
return isinstance(email, str) and '@' in email and '.' in email
258
259
# Basic function validation
260
assert 42 == FunctionCheck(is_even)
261
assert 21 != FunctionCheck(is_even) # Odd number fails
262
263
assert "user@example.com" == FunctionCheck(is_valid_email)
264
assert "invalid-email" != FunctionCheck(is_valid_email)
265
266
# Lambda functions for inline validation
267
assert "HELLO" == FunctionCheck(lambda x: x.isupper())
268
assert "hello" != FunctionCheck(lambda x: x.isupper())
269
270
# Complex business logic validation
271
def is_valid_user_id(user_id):
272
"""Custom business rule: user IDs must be 6-digit integers starting with 1 or 2"""
273
if not isinstance(user_id, (int, str)):
274
return False
275
str_id = str(user_id)
276
return (len(str_id) == 6 and
277
str_id.isdigit() and
278
str_id[0] in ['1', '2'])
279
280
assert 123456 == FunctionCheck(is_valid_user_id)
281
assert 234567 == FunctionCheck(is_valid_user_id)
282
assert 345678 != FunctionCheck(is_valid_user_id) # Doesn't start with 1 or 2
283
284
# Data structure validation
285
user_data = {
286
'user_id': 123456,
287
'email': 'user@company.com',
288
'score': 88
289
}
290
291
assert user_data == {
292
'user_id': FunctionCheck(is_valid_user_id),
293
'email': FunctionCheck(is_valid_email),
294
'score': FunctionCheck(lambda x: 0 <= x <= 100) # Score range validation
295
}
296
297
# Advanced validation with external dependencies
298
def is_valid_credit_card(card_num):
299
"""Luhn algorithm check (simplified example)"""
300
if not isinstance(card_num, str) or not card_num.isdigit():
301
return False
302
# Simplified Luhn check
303
digits = [int(d) for d in card_num]
304
for i in range(len(digits) - 2, -1, -2):
305
digits[i] *= 2
306
if digits[i] > 9:
307
digits[i] -= 9
308
return sum(digits) % 10 == 0
309
310
# Validate credit card number
311
card_number = "4532015112830366" # Valid test card number
312
assert card_number == FunctionCheck(is_valid_credit_card)
313
314
# API response validation with custom rules
315
api_response = {
316
'transaction_id': 'TXN123456789',
317
'amount': 299.99,
318
'currency': 'USD'
319
}
320
321
def is_valid_transaction_id(txn_id):
322
return (isinstance(txn_id, str) and
323
txn_id.startswith('TXN') and
324
len(txn_id) == 12)
325
326
def is_valid_currency(currency):
327
valid_currencies = ['USD', 'EUR', 'GBP', 'JPY', 'CAD']
328
return currency in valid_currencies
329
330
assert api_response == {
331
'transaction_id': FunctionCheck(is_valid_transaction_id),
332
'amount': FunctionCheck(lambda x: isinstance(x, (int, float)) and x > 0),
333
'currency': FunctionCheck(is_valid_currency)
334
}
335
```
336
337
### IsUrl
338
339
URL validation with support for different URL types (requires Pydantic for full functionality).
340
341
```python { .api }
342
class IsUrl(DirtyEquals):
343
"""
344
URL validation using Pydantic (requires Pydantic dependency).
345
346
Validates URLs with support for different URL schemes and
347
additional attribute validation.
348
"""
349
350
def __init__(
351
self,
352
any_url: bool = False,
353
any_http_url: bool = False,
354
http_url: bool = False,
355
file_url: bool = False,
356
postgres_dsn: bool = False,
357
ampqp_dsn: bool = False,
358
redis_dsn: bool = False,
359
**expected_attributes: Any
360
):
361
"""
362
Initialize URL validator.
363
364
Args:
365
any_url: Accept any valid URL scheme
366
any_http_url: Accept HTTP/HTTPS URLs
367
http_url: Accept only HTTP URLs
368
file_url: Accept only file:// URLs
369
postgres_dsn: Accept PostgreSQL connection strings
370
ampqp_dsn: Accept AMQP connection strings
371
redis_dsn: Accept Redis connection strings
372
**expected_attributes: Expected URL component values
373
"""
374
375
def equals(self, other: Any) -> bool:
376
"""
377
Validate URL format and attributes.
378
379
Args:
380
other: URL string to validate
381
382
Returns:
383
bool: True if valid URL matching constraints
384
"""
385
```
386
387
#### Usage Examples
388
389
```python
390
from dirty_equals import IsUrl
391
392
# Basic URL validation (requires Pydantic)
393
assert "https://example.com" == IsUrl(any_url=True)
394
assert "http://localhost:8080" == IsUrl(any_http_url=True)
395
assert "file:///path/to/file" == IsUrl(file_url=True)
396
397
# Database connection strings
398
assert "postgresql://user:pass@localhost/db" == IsUrl(postgres_dsn=True)
399
assert "redis://localhost:6379/0" == IsUrl(redis_dsn=True)
400
401
# With attribute validation
402
assert "https://api.example.com/v1" == IsUrl(
403
any_url=True,
404
host="api.example.com"
405
)
406
```
407
408
### IsHash
409
410
Hash string validation for common hash algorithms.
411
412
```python { .api }
413
class IsHash(DirtyEquals):
414
"""
415
Hash string validation for common hash types.
416
417
Validates that a string matches the expected format
418
for common cryptographic hash algorithms.
419
"""
420
421
def __init__(self, hash_type: str):
422
"""
423
Initialize hash validator.
424
425
Args:
426
hash_type: Type of hash to validate ('md5', 'sha-1', 'sha-256')
427
"""
428
429
def equals(self, other: Any) -> bool:
430
"""
431
Validate hash string format.
432
433
Args:
434
other: String to validate as hash
435
436
Returns:
437
bool: True if matches expected hash format
438
"""
439
```
440
441
#### Usage Examples
442
443
```python
444
from dirty_equals import IsHash
445
import hashlib
446
447
# Generate test hashes
448
test_data = b"hello world"
449
md5_hash = hashlib.md5(test_data).hexdigest()
450
sha1_hash = hashlib.sha1(test_data).hexdigest()
451
sha256_hash = hashlib.sha256(test_data).hexdigest()
452
453
# Validate different hash types
454
assert md5_hash == IsHash('md5')
455
assert sha1_hash == IsHash('sha-1')
456
assert sha256_hash == IsHash('sha-256')
457
458
# API response with file hashes
459
file_info = {
460
'filename': 'document.pdf',
461
'size': 1024,
462
'md5': md5_hash,
463
'sha256': sha256_hash
464
}
465
466
assert file_info == {
467
'filename': 'document.pdf',
468
'size': 1024,
469
'md5': IsHash('md5'),
470
'sha256': IsHash('sha-256')
471
}
472
```
473
474
### IsIP
475
476
IP address validation with version and netmask support.
477
478
```python { .api }
479
class IsIP(DirtyEquals):
480
"""
481
IP address validation with version and netmask support.
482
483
Validates IPv4 and IPv6 addresses with optional
484
version constraints and netmask validation.
485
"""
486
487
def __init__(
488
self,
489
*,
490
version: Optional[int] = None,
491
netmask: Optional[str] = None
492
):
493
"""
494
Initialize IP address validator.
495
496
Args:
497
version: IP version constraint (4 or 6), None for any
498
netmask: Expected netmask/CIDR notation
499
"""
500
501
def equals(self, other: Any) -> bool:
502
"""
503
Validate IP address format and constraints.
504
505
Args:
506
other: IP address string to validate
507
508
Returns:
509
bool: True if valid IP address matching constraints
510
"""
511
```
512
513
#### Usage Examples
514
515
```python
516
from dirty_equals import IsIP
517
518
# Basic IP validation
519
assert "192.168.1.1" == IsIP
520
assert "::1" == IsIP # IPv6 localhost
521
522
# Version-specific validation
523
assert "192.168.1.1" == IsIP(version=4)
524
assert "2001:db8::1" == IsIP(version=6)
525
526
# With CIDR/netmask
527
assert "192.168.1.0/24" == IsIP(version=4, netmask="255.255.255.0")
528
529
# Network configuration validation
530
network_config = {
531
'gateway': '192.168.1.1',
532
'dns_primary': '8.8.8.8',
533
'dns_secondary': '2001:4860:4860::8888',
534
'subnet': '192.168.1.0/24'
535
}
536
537
assert network_config == {
538
'gateway': IsIP(version=4),
539
'dns_primary': IsIP(version=4),
540
'dns_secondary': IsIP(version=6),
541
'subnet': IsIP(version=4)
542
}
543
```
544
545
### Dataclass Types
546
547
Validation types for Python dataclasses with field validation and matching strategies.
548
549
```python { .api }
550
class IsDataclassType(DirtyEquals):
551
"""Checks if value is a dataclass type (class, not instance)."""
552
553
class IsDataclass(DirtyEquals):
554
"""
555
Dataclass instance validation with field checking.
556
557
Validates dataclass instances and optionally checks
558
specific field values.
559
"""
560
561
def __init__(self, **fields: Any):
562
"""
563
Initialize dataclass validator.
564
565
Args:
566
**fields: Expected field names and values
567
"""
568
569
def settings(
570
self,
571
*,
572
strict: bool = False,
573
partial: bool = False
574
) -> 'IsDataclass':
575
"""
576
Configure dataclass matching behavior.
577
578
Args:
579
strict: Enforce field order and exact matching
580
partial: Allow subset matching (only check specified fields)
581
582
Returns:
583
IsDataclass: New instance with updated settings
584
"""
585
586
class IsPartialDataclass(IsDataclass):
587
"""Partial dataclass field matching."""
588
589
class IsStrictDataclass(IsDataclass):
590
"""Strict dataclass field matching with order enforcement."""
591
```
592
593
#### Usage Examples
594
595
```python
596
from dirty_equals import IsDataclass, IsDataclassType, IsPartialDataclass, IsStr, IsPositive
597
from dataclasses import dataclass
598
599
@dataclass
600
class User:
601
id: int
602
name: str
603
email: str
604
active: bool = True
605
606
# Check if something is a dataclass type
607
assert User == IsDataclassType
608
609
# Dataclass instance validation
610
user = User(123, "John Doe", "john@example.com")
611
assert user == IsDataclass() # Any dataclass instance
612
613
# Field validation
614
assert user == IsDataclass(
615
id=123,
616
name="John Doe",
617
email="john@example.com",
618
active=True
619
)
620
621
# With validators
622
assert user == IsDataclass(
623
id=IsPositive,
624
name=IsStr,
625
email=IsStr,
626
active=bool
627
)
628
629
# Partial matching - only check some fields
630
assert user == IsPartialDataclass(
631
id=IsPositive,
632
name=IsStr
633
)
634
```
635
636
### IsEnum
637
638
Enum instance and value validation.
639
640
```python { .api }
641
class IsEnum(DirtyEquals):
642
"""
643
Enum instance/value checking.
644
645
Validates enum instances or checks if a value
646
matches any enum member value.
647
"""
648
649
def __init__(self, enum_cls: type = Enum):
650
"""
651
Initialize enum validator.
652
653
Args:
654
enum_cls: Enum class to validate against (default: any Enum)
655
"""
656
657
def equals(self, other: Any) -> bool:
658
"""
659
Check if value is enum instance or matches enum value.
660
661
Args:
662
other: Value to validate
663
664
Returns:
665
bool: True if valid enum instance or matching value
666
"""
667
```
668
669
#### Usage Examples
670
671
```python
672
from dirty_equals import IsEnum
673
from enum import Enum
674
675
class Status(Enum):
676
ACTIVE = "active"
677
INACTIVE = "inactive"
678
PENDING = "pending"
679
680
class Priority(Enum):
681
LOW = 1
682
MEDIUM = 2
683
HIGH = 3
684
685
# Enum instance validation
686
assert Status.ACTIVE == IsEnum(Status)
687
assert Priority.HIGH == IsEnum(Priority)
688
689
# Any enum validation
690
assert Status.ACTIVE == IsEnum # Any enum type
691
692
# API response with enum values
693
task_data = {
694
'id': 123,
695
'status': Status.ACTIVE,
696
'priority': Priority.HIGH
697
}
698
699
assert task_data == {
700
'id': 123,
701
'status': IsEnum(Status),
702
'priority': IsEnum(Priority)
703
}
704
```
705
706
## Type Definitions
707
708
```python { .api }
709
from typing import Any, Callable, Optional, Union
710
from enum import Enum
711
import uuid
712
713
# Special constant for JSON validation
714
AnyJson = object() # Placeholder for any valid JSON value
715
716
# Hash type options
717
HashTypes = Union['md5', 'sha-1', 'sha-256']
718
719
# All specialized types inherit from DirtyEquals
720
# External dependencies: Pydantic (optional, for IsUrl)
721
```