@@ -750,6 +750,99 @@ def _combine_property(self, other, name, allow_duplicates=True):
750
750
new_prop .update (getattr (other , name ))
751
751
return new_prop
752
752
753
+ def _combine_property_2 (self , other , name , allow_duplicates = True ):
754
+ """
755
+ Combine a property from two components during component addition.
756
+
757
+ This method handles the merging of component properties when two structural
758
+ components are combined using the `+` operator. It handles different data types
759
+ appropriately and provides control over duplicate handling for list properties.
760
+
761
+ Parameters
762
+ ----------
763
+ other : Component
764
+ The other component whose property is being combined with this one.
765
+ name : str
766
+ The name of the property to combine (e.g., 'state_names', 'param_names').
767
+ allow_duplicates : bool, default True
768
+ Controls duplicate handling for list properties:
769
+ - True: Concatenates lists directly, preserving duplicates
770
+ - False: Adds only items from `other` that aren't already in `self`
771
+
772
+ Returns
773
+ -------
774
+ Any
775
+ Combined property value with type depending on the property type:
776
+ - list: Concatenated lists (with or without deduplication)
777
+ - dict: Merged dictionaries (other overwrites self for same keys)
778
+ - scalar/array: Single value (if identical) or error (if different)
779
+
780
+ Raises
781
+ ------
782
+ ValueError
783
+ When scalar properties have different non-None values that cannot be
784
+ automatically combined, indicating unclear user intent.
785
+ """
786
+ self_prop = getattr (self , name )
787
+ other_prop = getattr (other , name )
788
+
789
+ if isinstance (self_prop , list ) and allow_duplicates :
790
+ return self_prop + other_prop
791
+ elif isinstance (self_prop , list ) and not allow_duplicates :
792
+ return self_prop + [x for x in other_prop if x not in self_prop ]
793
+ elif isinstance (self_prop , dict ):
794
+ new_prop = self_prop .copy ()
795
+ new_prop .update (other_prop )
796
+ return new_prop
797
+ else :
798
+ # NEW: Handle cases where self_prop is not a list or dict
799
+ import numpy as np
800
+
801
+ # Handle numpy arrays specially
802
+ if isinstance (self_prop , np .ndarray ) and isinstance (other_prop , np .ndarray ):
803
+ if np .array_equal (self_prop , other_prop ):
804
+ return self_prop
805
+ else :
806
+ # Convert to list for combination when arrays are different
807
+ return (
808
+ list (self_prop ) + [x for x in other_prop if x not in self_prop ]
809
+ if not allow_duplicates
810
+ else list (self_prop ) + list (other_prop )
811
+ )
812
+ elif isinstance (self_prop , np .ndarray ) or isinstance (other_prop , np .ndarray ):
813
+ # One is array, one is not - convert to list
814
+ self_list = (
815
+ list (self_prop )
816
+ if isinstance (self_prop , np .ndarray )
817
+ else [self_prop ]
818
+ if self_prop is not None
819
+ else []
820
+ )
821
+ other_list = (
822
+ list (other_prop )
823
+ if isinstance (other_prop , np .ndarray )
824
+ else [other_prop ]
825
+ if other_prop is not None
826
+ else []
827
+ )
828
+ return (
829
+ self_list + [x for x in other_list if x not in self_list ]
830
+ if not allow_duplicates
831
+ else self_list + other_list
832
+ )
833
+ elif self_prop == other_prop :
834
+ return self_prop
835
+ elif self_prop is None and other_prop is not None :
836
+ return other_prop
837
+ elif self_prop is not None and other_prop is None :
838
+ return self_prop
839
+ else :
840
+ # Different non-None values - this might indicate a problem
841
+ raise ValueError (
842
+ f"Cannot combine property '{ name } ': component values are different "
843
+ f"({ self_prop } vs { other_prop } ) and cannot be automatically combined"
844
+ )
845
+
753
846
def _combine_component_info (self , other ):
754
847
combined_info = {}
755
848
for key , value in self ._component_info .items ():
0 commit comments