@@ -308,7 +308,8 @@ def _apply_remove(self, resource: Resource[Any], operation: PatchOperation) -> b
308
308
309
309
return self ._remove_value_at_path (resource , operation .path )
310
310
311
- def _apply_root_attributes (self , resource : BaseModel , value : Any ) -> bool :
311
+ @classmethod
312
+ def _apply_root_attributes (cls , resource : BaseModel , value : Any ) -> bool :
312
313
"""Apply attributes to the resource root."""
313
314
if not isinstance (value , dict ):
314
315
return False
@@ -326,8 +327,9 @@ def _apply_root_attributes(self, resource: BaseModel, value: Any) -> bool:
326
327
327
328
return modified
328
329
330
+ @classmethod
329
331
def _set_value_at_path (
330
- self , resource : Resource [Any ], path : str , value : Any , is_add : bool
332
+ cls , resource : Resource [Any ], path : str , value : Any , is_add : bool
331
333
) -> bool :
332
334
"""Set a value at a specific path."""
333
335
target , attr_path = _resolve_path_to_target (resource , path )
@@ -337,21 +339,22 @@ def _set_value_at_path(
337
339
338
340
path_parts = attr_path .split ("." )
339
341
if len (path_parts ) == 1 :
340
- return self ._set_simple_attribute (target , path_parts [0 ], value , is_add )
342
+ return cls ._set_simple_attribute (target , path_parts [0 ], value , is_add )
341
343
342
- return self ._set_complex_attribute (target , path_parts , value , is_add )
344
+ return cls ._set_complex_attribute (target , path_parts , value , is_add )
343
345
346
+ @classmethod
344
347
def _set_simple_attribute (
345
- self , resource : BaseModel , attr_name : str , value : Any , is_add : bool
348
+ cls , resource : BaseModel , attr_name : str , value : Any , is_add : bool
346
349
) -> bool :
347
350
"""Set a value on a simple (non-nested) attribute."""
348
351
field_name = _find_field_name (type (resource ), attr_name )
349
352
if not field_name :
350
353
raise ValueError (Error .make_no_target_error ().detail )
351
354
352
355
# RFC 7644 Section 3.5.2.1: "For multi-valued attributes, add operation appends values"
353
- if is_add and self ._is_multivalued_field (resource , field_name ):
354
- return self ._handle_multivalued_add (resource , field_name , value )
356
+ if is_add and cls ._is_multivalued_field (resource , field_name ):
357
+ return cls ._handle_multivalued_add (resource , field_name , value )
355
358
356
359
old_value = getattr (resource , field_name )
357
360
if old_value == value :
@@ -360,8 +363,9 @@ def _set_simple_attribute(
360
363
setattr (resource , field_name , value )
361
364
return True
362
365
366
+ @classmethod
363
367
def _set_complex_attribute (
364
- self , resource : BaseModel , path_parts : list [str ], value : Any , is_add : bool
368
+ cls , resource : BaseModel , path_parts : list [str ], value : Any , is_add : bool
365
369
) -> bool :
366
370
"""Set a value on a complex (nested) attribute."""
367
371
parent_attr = path_parts [0 ]
@@ -373,32 +377,35 @@ def _set_complex_attribute(
373
377
374
378
parent_obj = getattr (resource , parent_field_name )
375
379
if parent_obj is None :
376
- parent_obj = self ._create_parent_object (resource , parent_field_name )
380
+ parent_obj = cls ._create_parent_object (resource , parent_field_name )
377
381
if parent_obj is None :
378
382
return False
379
383
380
- return self ._set_value_at_path (parent_obj , sub_path , value , is_add )
384
+ return cls ._set_value_at_path (parent_obj , sub_path , value , is_add )
381
385
382
- def _is_multivalued_field (self , resource : BaseModel , field_name : str ) -> bool :
386
+ @classmethod
387
+ def _is_multivalued_field (cls , resource : BaseModel , field_name : str ) -> bool :
383
388
"""Check if a field is multi-valued."""
384
389
return hasattr (resource , field_name ) and type (resource ).get_field_multiplicity (
385
390
field_name
386
391
)
387
392
393
+ @classmethod
388
394
def _handle_multivalued_add (
389
- self , resource : BaseModel , field_name : str , value : Any
395
+ cls , resource : BaseModel , field_name : str , value : Any
390
396
) -> bool :
391
397
"""Handle adding values to a multi-valued attribute."""
392
398
current_list = getattr (resource , field_name ) or []
393
399
394
400
# RFC 7644 Section 3.5.2.1: "Add operation appends values to multi-valued attributes"
395
401
if isinstance (value , list ):
396
- return self ._add_multiple_values (resource , field_name , current_list , value )
402
+ return cls ._add_multiple_values (resource , field_name , current_list , value )
397
403
398
- return self ._add_single_value (resource , field_name , current_list , value )
404
+ return cls ._add_single_value (resource , field_name , current_list , value )
399
405
406
+ @classmethod
400
407
def _add_multiple_values (
401
- self ,
408
+ cls ,
402
409
resource : BaseModel ,
403
410
field_name : str ,
404
411
current_list : list [Any ],
@@ -408,7 +415,7 @@ def _add_multiple_values(
408
415
new_values = []
409
416
# RFC 7644 Section 3.5.2.1: "Do not add duplicate values"
410
417
for new_val in values :
411
- if not self ._value_exists_in_list (current_list , new_val ):
418
+ if not cls ._value_exists_in_list (current_list , new_val ):
412
419
new_values .append (new_val )
413
420
414
421
if not new_values :
@@ -417,23 +424,26 @@ def _add_multiple_values(
417
424
setattr (resource , field_name , current_list + new_values )
418
425
return True
419
426
427
+ @classmethod
420
428
def _add_single_value (
421
- self , resource : BaseModel , field_name : str , current_list : list [Any ], value : Any
429
+ cls , resource : BaseModel , field_name : str , current_list : list [Any ], value : Any
422
430
) -> bool :
423
431
"""Add a single value to a multi-valued attribute."""
424
432
# RFC 7644 Section 3.5.2.1: "Do not add duplicate values"
425
- if self ._value_exists_in_list (current_list , value ):
433
+ if cls ._value_exists_in_list (current_list , value ):
426
434
return False
427
435
428
436
current_list .append (value )
429
437
setattr (resource , field_name , current_list )
430
438
return True
431
439
432
- def _value_exists_in_list (self , current_list : list [Any ], new_value : Any ) -> bool :
440
+ @classmethod
441
+ def _value_exists_in_list (cls , current_list : list [Any ], new_value : Any ) -> bool :
433
442
"""Check if a value already exists in a list."""
434
- return any (self ._values_match (item , new_value ) for item in current_list )
443
+ return any (cls ._values_match (item , new_value ) for item in current_list )
435
444
436
- def _create_parent_object (self , resource : BaseModel , parent_field_name : str ) -> Any :
445
+ @classmethod
446
+ def _create_parent_object (cls , resource : BaseModel , parent_field_name : str ) -> Any :
437
447
"""Create a parent object if it doesn't exist."""
438
448
parent_class = type (resource ).get_field_root_type (parent_field_name )
439
449
if not parent_class or not isclass (parent_class ):
@@ -443,7 +453,8 @@ def _create_parent_object(self, resource: BaseModel, parent_field_name: str) ->
443
453
setattr (resource , parent_field_name , parent_obj )
444
454
return parent_obj
445
455
446
- def _remove_value_at_path (self , resource : Resource [Any ], path : str ) -> bool :
456
+ @classmethod
457
+ def _remove_value_at_path (cls , resource : Resource [Any ], path : str ) -> bool :
447
458
"""Remove a value at a specific path."""
448
459
target , attr_path = _resolve_path_to_target (resource , path )
449
460
@@ -466,10 +477,11 @@ def _remove_value_at_path(self, resource: Resource[Any], path: str) -> bool:
466
477
return True
467
478
468
479
sub_path = "." .join (path_parts )
469
- return self ._remove_value_at_path (parent_obj , sub_path )
480
+ return cls ._remove_value_at_path (parent_obj , sub_path )
470
481
482
+ @classmethod
471
483
def _remove_specific_value (
472
- self , resource : Resource [Any ], path : str , value_to_remove : Any
484
+ cls , resource : Resource [Any ], path : str , value_to_remove : Any
473
485
) -> bool :
474
486
"""Remove a specific value from a multi-valued attribute."""
475
487
target , attr_path = _resolve_path_to_target (resource , path )
@@ -490,7 +502,7 @@ def _remove_specific_value(
490
502
modified = False
491
503
# RFC 7644 Section 3.5.2.3: "Remove matching values from multi-valued attributes"
492
504
for item in current_list :
493
- if not self ._values_match (item , value_to_remove ):
505
+ if not cls ._values_match (item , value_to_remove ):
494
506
new_list .append (item )
495
507
else :
496
508
modified = True
@@ -501,7 +513,8 @@ def _remove_specific_value(
501
513
502
514
return False
503
515
504
- def _values_match (self , value1 : Any , value2 : Any ) -> bool :
516
+ @classmethod
517
+ def _values_match (cls , value1 : Any , value2 : Any ) -> bool :
505
518
"""Check if two values match, converting BaseModel to dict for comparison."""
506
519
507
520
def to_dict (value : Any ) -> dict [str , Any ]:
0 commit comments