diff --git a/GaudiKernel/include/GaudiKernel/SerializeSTL.h b/GaudiKernel/include/GaudiKernel/SerializeSTL.h
index f8471fc227a1ddf6cf3f512bffd53eef75c363c6..b6db6913e1049426d9421241230dde90fbeb56a7 100644
--- a/GaudiKernel/include/GaudiKernel/SerializeSTL.h
+++ b/GaudiKernel/include/GaudiKernel/SerializeSTL.h
@@ -1,5 +1,5 @@
 /***********************************************************************************\
-* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
+* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
 *                                                                                   *
 * This software is distributed under the terms of the Apache version 2 licence,     *
 * copied verbatim in the file "LICENSE".                                            *
@@ -38,6 +38,10 @@ namespace GaudiUtils {
   template <class T1, class T2>
   std::ostream& operator<<( std::ostream& s, const std::pair<T1, T2>& p );
 
+  /// Serialize an std::tuple in a python like format. E.g. "(1, 2)".
+  template <typename... Args>
+  std::ostream& operator<<( std::ostream& s, const std::tuple<Args...>& tuple );
+
   /// Serialize an std::vector in a python like format. E.g. "[1, 2, 3]".
   template <class T, class ALLOC>
   std::ostream& operator<<( std::ostream& s, const std::vector<T, ALLOC>& v );
@@ -50,6 +54,14 @@ namespace GaudiUtils {
   template <class T, class ALLOC>
   std::ostream& operator<<( std::ostream& s, const std::list<T, ALLOC>& l );
 
+  /// Serialize an std::set in a python like format. E.g. "[1, 2, 3]".
+  template <class T, class ALLOC>
+  std::ostream& operator<<( std::ostream& s, const std::set<T, ALLOC>& l );
+
+  /// Serialize an std::unordered_set in a python like format. E.g. "{1, 2, 3}".
+  template <class T, class ALLOC>
+  std::ostream& operator<<( std::ostream& s, const std::unordered_set<T, ALLOC>& l );
+
   /// Serialize an std::map in a python like format. E.g. "{a: 1, b: 2}".
   template <class T1, class T2, class COMP, class ALLOC>
   std::ostream& operator<<( std::ostream& s, const std::map<T1, T2, COMP, ALLOC>& m );
@@ -91,6 +103,19 @@ namespace GaudiUtils {
     return s << '(' << p.first << ", " << p.second << ')';
   }
 
+  template <typename... Args>
+  std::ostream& operator<<( std::ostream& s, const std::tuple<Args...>& tup ) {
+    return std::apply(
+        [&s]( const auto&... a ) -> decltype( auto ) {
+          unsigned n = sizeof...( a );
+          if ( n == 1 ) n = 2; // special case in python...
+          s << " (";
+          ( ( s << " " << a << ( --n == 0 ? "" : "," ) ), ... );
+          return s << " )";
+        },
+        tup );
+  }
+
   template <class T, class ALLOC>
   std::ostream& operator<<( std::ostream& s, const std::vector<T, ALLOC>& v ) {
     return details::ostream_joiner( s << '[', v, ", " ) << ']';
diff --git a/GaudiKernel/include/GaudiKernel/ToStream.h b/GaudiKernel/include/GaudiKernel/ToStream.h
index 49a4873b4de39780922fea310bfde37a90420204..e09df340cac6f2221ade05f501230e11d2676d1d 100644
--- a/GaudiKernel/include/GaudiKernel/ToStream.h
+++ b/GaudiKernel/include/GaudiKernel/ToStream.h
@@ -1,5 +1,5 @@
 /***********************************************************************************\
-* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
+* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
 *                                                                                   *
 * This software is distributed under the terms of the Apache version 2 licence,     *
 * copied verbatim in the file "LICENSE".                                            *
@@ -123,6 +123,10 @@ namespace Gaudi {
     inline std::ostream& toStream( const std::pair<KTYPE, VTYPE>& obj, std::ostream& s ) {
       return toStream( obj.second, toStream( obj.first, s << "( " ) << " , " ) << " )";
     }
+
+    template <typename... Args>
+    inline std::ostream& toStream( const std::tuple<Args...>& tuple, std::ostream& s );
+
     // ========================================================================
     /** the partial template specialization of <c>std::vector<TYPE,ALLOCATOR></c>
      *  printout. The vector is printed a'la Python list: "[ a, b, c ]"
@@ -284,32 +288,6 @@ namespace Gaudi {
       return s << obj;
     }
     // ========================================================================
-    /** the helper function to print the sequence
-     *  @param first (INPUT)  begin-iterator for the sequence
-     *  @param last  (INPUT)  end-iterator for the sequence
-     *  @param s     (UPDATE) the stream itself
-     *  @param open  (INPUT)  "open"-symbol
-     *  @param close (INPUT)  "close"-symbol
-     *  @param delim (INPUT)  "delimiter"-symbol
-     *  @return the stream
-     *  @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
-     *  @date 2009-09-15
-     */
-    template <class ITERATOR>
-    inline std::ostream& toStream( ITERATOR           first,  // begin of the sequence
-                                   ITERATOR           last,   //   end of the sequence
-                                   std::ostream&      s,      //            the stream
-                                   const std::string& open,   //               opening
-                                   const std::string& close,  //               closing
-                                   const std::string& delim ) //             delimiter
-    {
-      using ref_t = typename std::iterator_traits<ITERATOR>::reference;
-      using GaudiUtils::details::ostream_joiner;
-      return ostream_joiner( s << open, first, last, delim,
-                             []( std::ostream& os, ref_t i ) -> std::ostream& { return toStream( i, os ); } )
-             << close;
-    }
-    // ========================================================================
     // helper function to print a tuple of any size
     template <class Tuple, std::size_t N>
     struct TuplePrinter {
@@ -340,6 +318,32 @@ namespace Gaudi {
       }
       return out << " ) ";
     }
+    // ========================================================================
+    /** the helper function to print the sequence
+     *  @param first (INPUT)  begin-iterator for the sequence
+     *  @param last  (INPUT)  end-iterator for the sequence
+     *  @param s     (UPDATE) the stream itself
+     *  @param open  (INPUT)  "open"-symbol
+     *  @param close (INPUT)  "close"-symbol
+     *  @param delim (INPUT)  "delimiter"-symbol
+     *  @return the stream
+     *  @author Vanya BELYAEV Ivan.BElyaev@nikhef.nl
+     *  @date 2009-09-15
+     */
+    template <class ITERATOR>
+    inline std::ostream& toStream( ITERATOR           first,  // begin of the sequence
+                                   ITERATOR           last,   //   end of the sequence
+                                   std::ostream&      s,      //            the stream
+                                   const std::string& open,   //               opening
+                                   const std::string& close,  //               closing
+                                   const std::string& delim ) //             delimiter
+    {
+      using ref_t = typename std::iterator_traits<ITERATOR>::reference;
+      using GaudiUtils::details::ostream_joiner;
+      return ostream_joiner( s << open, first, last, delim,
+                             []( std::ostream& os, ref_t i ) -> std::ostream& { return toStream( i, os ); } )
+             << close;
+    }
 
     // ========================================================================
     /** the generic implementation of the type conversion to the string
diff --git a/GaudiTestSuite/options/ExtendedProperties.opts b/GaudiTestSuite/options/ExtendedProperties.opts
index 5c4b35d100f8be69d13b0f3b5530f20269ffd2fb..4e714a7920313ffd47be4b490ef099c7f6a560a9 100644
--- a/GaudiTestSuite/options/ExtendedProperties.opts
+++ b/GaudiTestSuite/options/ExtendedProperties.opts
@@ -123,6 +123,13 @@ xProps.StdArrayInt1 = (42);
 
 xProps.GaudiMapSS = {"a": "1", "b": "2"};
 
+xProps.PTupleVector = [("one", "two", "three"), ("a", "b", "c")];
+xProps.PIntVectorTuple = (42, ["one", "two", "three"]);
+xProps.PTupleSet = [("one", "two", "three"), ("a", "b", "c")];
+xProps.PIntSetTuple = (42, ["one", "two", "three"]);
+xProps.PTupleUnSet = {("one", "two", "three"), ("a", "b", "c")};
+xProps.PIntUnSetTuple = (42, {"one", "two", "three"});
+
 // ============================================================================
 
 // ============================================================================
diff --git a/GaudiTestSuite/options/ExtendedProperties.py b/GaudiTestSuite/options/ExtendedProperties.py
index 84a0377e80b61709f0185deb251964665b360d09..66aa787f80e65e00ee249ea815099f34a9d32091 100644
--- a/GaudiTestSuite/options/ExtendedProperties.py
+++ b/GaudiTestSuite/options/ExtendedProperties.py
@@ -1,5 +1,5 @@
 #####################################################################################
-# (c) Copyright 1998-2023 CERN for the benefit of the LHCb and ATLAS collaborations #
+# (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations #
 #                                                                                   #
 # This software is distributed under the terms of the Apache version 2 licence,     #
 # copied verbatim in the file "LICENSE".                                            #
@@ -96,6 +96,13 @@ xProps.GaudiMapSS = {"a": "1", "b": "2"}
 xProps.ExtraInputs = set()
 xProps.ExtraOutputs = {"a", ("a", "b"), (1, "a")}
 
+xProps.PTupleVector = [("one", "two", "three"), ("a", "b", "c")]
+xProps.PIntVectorTuple = (42, ["one", "two", "three"])
+xProps.PTupleSet = [("one", "two", "three"), ("a", "b", "c")]
+xProps.PIntSetTuple = (42, ["one", "two", "three"])
+xProps.PTupleUnSet = {("one", "two", "three"), ("a", "b", "c")}
+xProps.PIntUnSetTuple = (42, {"one", "two", "three"})
+
 # END of xProp configuration
 
 app = ApplicationMgr(
diff --git a/GaudiTestSuite/src/ExtendedProperties/ExtendedProperties.cpp b/GaudiTestSuite/src/ExtendedProperties/ExtendedProperties.cpp
index 7bfe394b123db35177e3e891bb4893e2ca6c1f5d..89256fea476462904cdec118ef03be65df3fbc18 100644
--- a/GaudiTestSuite/src/ExtendedProperties/ExtendedProperties.cpp
+++ b/GaudiTestSuite/src/ExtendedProperties/ExtendedProperties.cpp
@@ -1,5 +1,5 @@
 /***********************************************************************************\
-* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
+* (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations *
 *                                                                                   *
 * This software is distributed under the terms of the Apache version 2 licence,     *
 * copied verbatim in the file "LICENSE".                                            *
@@ -101,72 +101,30 @@ private:
   Gaudi::Property<std::array<int, 1>>    m_26{ this, "StdArrayInt1", { 0 } };
 
   Gaudi::Property<GaudiUtils::Map<std::string, std::string>> m_24{ this, "GaudiMapSS" };
+
+  using Triplet = std::tuple<std::string, std::string, std::string>;
+  static std::hash<std::string> hasher;
+  struct HashFunction {
+    std::size_t operator()( Triplet const& entry ) const {
+      return hasher( std::get<0>( entry ) ) ^ hasher( std::get<1>( entry ) ) ^ hasher( std::get<2>( entry ) );
+    }
+  };
+
+  Gaudi::Property<std::vector<Triplet>>                      m_tuplevector{ this, "PTupleVector" };
+  Gaudi::Property<std::set<Triplet>>                         m_tupleset{ this, "PTupleSet" };
+  Gaudi::Property<std::unordered_set<Triplet, HashFunction>> m_tupleunset{ this, "PTupleUnSet" };
+  using VS = std::vector<std::string>;
+  Gaudi::Property<std::tuple<int, VS>> m_intvectortuple{ this, "PIntVectorTuple" };
+  using SS = std::set<std::string>;
+  Gaudi::Property<std::tuple<int, SS>> m_intsettuple{ this, "PIntSetTuple" };
+  using USS = std::unordered_set<std::string>;
+  Gaudi::Property<std::tuple<int, USS>> m_intunsettuple{ this, "PIntUnSetTuple" };
 };
 // ============================================================================
 /// factory
 // ============================================================================
 DECLARE_COMPONENT( ExtendedProperties )
 // ============================================================================
-namespace {
-  template <class TYPE>
-  inline SimplePropertyRef<TYPE> _prop( TYPE& value ) {
-    // construct a readable name
-    std::string            name = System::typeinfoName( typeid( value ) );
-    std::string::size_type ipos = name.find( "std::" );
-    while ( std::string::npos != ipos ) {
-      name.erase( ipos, 5 );
-      ipos = name.find( "std::" );
-    }
-    ipos = name.find( "__cxx11::" );
-    while ( std::string::npos != ipos ) {
-      name.erase( ipos, 9 );
-      ipos = name.find( "__cxx11::" );
-    }
-    ipos = name.find( " " );
-    while ( std::string::npos != ipos ) {
-      name.erase( ipos, 1 );
-      ipos = name.find( " " );
-    }
-    ipos = name.find( "const" );
-    while ( std::string::npos != ipos ) {
-      name.erase( ipos, 5 );
-      ipos = name.find( "const" );
-    }
-    ipos = name.find( ",allocator<" );
-    while ( std::string::npos != ipos ) {
-      std::string::size_type ip2 = ipos + 11;
-      int                    ip3 = 1;
-      for ( ; ip2 < name.size(); ++ip2 ) {
-        if ( '<' == name[ip2] ) { ip3 += 1; }
-        if ( '>' == name[ip2] ) { ip3 -= 1; }
-        if ( 0 == ip3 ) { break; }
-      }
-      name.erase( ipos, ip2 + 1 - ipos );
-      ipos = name.find( ",allocator<" );
-    }
-    if ( std::string::npos != name.find( "map<" ) ) {
-      ipos = name.find( ",less<" );
-      while ( std::string::npos != ipos ) {
-        std::string::size_type ip2 = ipos + 6;
-        int                    ip3 = 1;
-        for ( ; ip2 < name.size(); ++ip2 ) {
-          if ( '<' == name[ip2] ) { ip3 += 1; }
-          if ( '>' == name[ip2] ) { ip3 -= 1; }
-          if ( 0 == ip3 ) { break; }
-        }
-        name.erase( ipos, ip2 + 1 - ipos );
-        ipos = name.find( ",less<" );
-      }
-    }
-    ipos = name.find( ">>" );
-    while ( std::string::npos != ipos ) {
-      name.replace( ipos, 2, "> >" );
-      ipos = name.find( ">>" );
-    }
-    return SimplePropertyRef<TYPE>( name, value );
-  }
-} // namespace
-// ============================================================================
 StatusCode ExtendedProperties::execute() {
   always() << " My Properties : " << endmsg;
 
@@ -201,6 +159,13 @@ StatusCode ExtendedProperties::execute() {
   always() << " \t" << m_30 << endmsg;
   always() << " \t" << m_31 << endmsg;
 
+  always() << " \t" << m_tuplevector << endmsg;
+  always() << " \t" << m_intvectortuple << endmsg;
+  always() << " \t" << m_tupleset << endmsg;
+  always() << " \t" << m_intsettuple << endmsg;
+  always() << " \t" << m_tupleunset << endmsg;
+  always() << " \t" << m_intunsettuple << endmsg;
+
   // some properties could be created from other (convertible) types:
   Gaudi::Property<short>  m1( "a", 0 );
   Gaudi::Property<double> m2( "b", m1 );
diff --git a/GaudiTestSuite/tests/pytest/properties/ExtPropValidator.py b/GaudiTestSuite/tests/pytest/properties/ExtPropValidator.py
index 447fe86a6d4ad101133ef3c7940c4bfd8cd37355..43e1f55904337e4c24d1c2e138708b184f2eb361 100644
--- a/GaudiTestSuite/tests/pytest/properties/ExtPropValidator.py
+++ b/GaudiTestSuite/tests/pytest/properties/ExtPropValidator.py
@@ -1,5 +1,5 @@
 #####################################################################################
-# (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations #
+# (c) Copyright 1998-2025 CERN for the benefit of the LHCb and ATLAS collaborations #
 #                                                                                   #
 # This software is distributed under the terms of the Apache version 2 licence,     #
 # copied verbatim in the file "LICENSE".                                            #
@@ -59,6 +59,12 @@ def validate(stdout):
         "StdArrayDouble3": (3.3, 2.2, 1.1),
         "StdArrayInt1": (42,),
         "GaudiMapSS": {"a": "1", "b": "2"},
+        "PTupleVector": [("one", "two", "three"), ("a", "b", "c")],
+        "PIntVectorTuple": (42, ["one", "two", "three"]),
+        "PTupleSet": [("a", "b", "c"), ("one", "two", "three")],
+        "PIntSetTuple": (42, ["one", "three", "two"]),
+        "PTupleUnSet": {("a", "b", "c"), ("one", "two", "three")},
+        "PIntUnSetTuple": (42, {"one", "two", "three"}),
     }
 
     import re