@@ -308,7 +308,8 @@ def _apply_remove(self, resource: Resource[Any], operation: PatchOperation) -> b
308308
309309 return self ._remove_value_at_path (resource , operation .path )
310310
311- def _apply_root_attributes (self , resource : BaseModel , value : Any ) -> bool :
311+ @classmethod
312+ def _apply_root_attributes (cls , resource : BaseModel , value : Any ) -> bool :
312313 """Apply attributes to the resource root."""
313314 if not isinstance (value , dict ):
314315 return False
@@ -326,8 +327,9 @@ def _apply_root_attributes(self, resource: BaseModel, value: Any) -> bool:
326327
327328 return modified
328329
330+ @classmethod
329331 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
331333 ) -> bool :
332334 """Set a value at a specific path."""
333335 target , attr_path = _resolve_path_to_target (resource , path )
@@ -337,21 +339,22 @@ def _set_value_at_path(
337339
338340 path_parts = attr_path .split ("." )
339341 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 )
341343
342- return self ._set_complex_attribute (target , path_parts , value , is_add )
344+ return cls ._set_complex_attribute (target , path_parts , value , is_add )
343345
346+ @classmethod
344347 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
346349 ) -> bool :
347350 """Set a value on a simple (non-nested) attribute."""
348351 field_name = _find_field_name (type (resource ), attr_name )
349352 if not field_name :
350353 raise ValueError (Error .make_no_target_error ().detail )
351354
352355 # 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 )
355358
356359 old_value = getattr (resource , field_name )
357360 if old_value == value :
@@ -360,8 +363,9 @@ def _set_simple_attribute(
360363 setattr (resource , field_name , value )
361364 return True
362365
366+ @classmethod
363367 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
365369 ) -> bool :
366370 """Set a value on a complex (nested) attribute."""
367371 parent_attr = path_parts [0 ]
@@ -373,32 +377,35 @@ def _set_complex_attribute(
373377
374378 parent_obj = getattr (resource , parent_field_name )
375379 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 )
377381 if parent_obj is None :
378382 return False
379383
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 )
381385
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 :
383388 """Check if a field is multi-valued."""
384389 return hasattr (resource , field_name ) and type (resource ).get_field_multiplicity (
385390 field_name
386391 )
387392
393+ @classmethod
388394 def _handle_multivalued_add (
389- self , resource : BaseModel , field_name : str , value : Any
395+ cls , resource : BaseModel , field_name : str , value : Any
390396 ) -> bool :
391397 """Handle adding values to a multi-valued attribute."""
392398 current_list = getattr (resource , field_name ) or []
393399
394400 # RFC 7644 Section 3.5.2.1: "Add operation appends values to multi-valued attributes"
395401 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 )
397403
398- return self ._add_single_value (resource , field_name , current_list , value )
404+ return cls ._add_single_value (resource , field_name , current_list , value )
399405
406+ @classmethod
400407 def _add_multiple_values (
401- self ,
408+ cls ,
402409 resource : BaseModel ,
403410 field_name : str ,
404411 current_list : list [Any ],
@@ -408,7 +415,7 @@ def _add_multiple_values(
408415 new_values = []
409416 # RFC 7644 Section 3.5.2.1: "Do not add duplicate values"
410417 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 ):
412419 new_values .append (new_val )
413420
414421 if not new_values :
@@ -417,23 +424,26 @@ def _add_multiple_values(
417424 setattr (resource , field_name , current_list + new_values )
418425 return True
419426
427+ @classmethod
420428 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
422430 ) -> bool :
423431 """Add a single value to a multi-valued attribute."""
424432 # 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 ):
426434 return False
427435
428436 current_list .append (value )
429437 setattr (resource , field_name , current_list )
430438 return True
431439
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 :
433442 """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 )
435444
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 :
437447 """Create a parent object if it doesn't exist."""
438448 parent_class = type (resource ).get_field_root_type (parent_field_name )
439449 if not parent_class or not isclass (parent_class ):
@@ -443,7 +453,8 @@ def _create_parent_object(self, resource: BaseModel, parent_field_name: str) ->
443453 setattr (resource , parent_field_name , parent_obj )
444454 return parent_obj
445455
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 :
447458 """Remove a value at a specific path."""
448459 target , attr_path = _resolve_path_to_target (resource , path )
449460
@@ -466,10 +477,11 @@ def _remove_value_at_path(self, resource: Resource[Any], path: str) -> bool:
466477 return True
467478
468479 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 )
470481
482+ @classmethod
471483 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
473485 ) -> bool :
474486 """Remove a specific value from a multi-valued attribute."""
475487 target , attr_path = _resolve_path_to_target (resource , path )
@@ -490,7 +502,7 @@ def _remove_specific_value(
490502 modified = False
491503 # RFC 7644 Section 3.5.2.3: "Remove matching values from multi-valued attributes"
492504 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 ):
494506 new_list .append (item )
495507 else :
496508 modified = True
@@ -501,7 +513,8 @@ def _remove_specific_value(
501513
502514 return False
503515
504- def _values_match (self , value1 : Any , value2 : Any ) -> bool :
516+ @classmethod
517+ def _values_match (cls , value1 : Any , value2 : Any ) -> bool :
505518 """Check if two values match, converting BaseModel to dict for comparison."""
506519
507520 def to_dict (value : Any ) -> dict [str , Any ]:
0 commit comments