From 540ca689fbd90bdafea8143632adaf821a2e37d9 Mon Sep 17 00:00:00 2001
From: Charles Leggett <charles.g.leggett@gmail.com>
Date: Tue, 20 Dec 2016 20:56:39 +0100
Subject: [PATCH] Property modernization w/ Gaudi v28 (AthenaPython-00-07-00)

	* updates for Property modernization. see gaudi/Gaudi!182
	* requires Gaudi v28
	* tag AthenaPython-00-07-00

M       AthenaPython/PyProperty.h
M       src/PyJobOptionsCatalogue.cxx
M       src/PyProperty.cxx
M       src/PyJobOptionsSvc.h
M       src/PyJobOptionsCatalogue.h
M       src/PyJobOptionsSvc.cxx

2016-09-13  Wim Lavrijsen <WLavrijsen@lbl.gov>

	* implement GIL acquisition and release
---
 .../AthenaPython/AthenaPython/PyProperty.h    | 14 ++--
 Control/AthenaPython/src/PyAthenaAlg.cxx      | 11 ++-
 Control/AthenaPython/src/PyAthenaAud.cxx      | 12 +++-
 .../AthenaPython/src/PyAthenaGILStateEnsure.h | 47 +++++++++++++
 Control/AthenaPython/src/PyAthenaSvc.cxx      |  7 +-
 Control/AthenaPython/src/PyAthenaTool.cxx     | 12 +++-
 Control/AthenaPython/src/PyAthenaUtils.cxx    | 10 +++
 Control/AthenaPython/src/PyComponentMgr.cxx   | 29 +++++---
 .../src/PyJobOptionsCatalogue.cxx             | 17 +++++
 .../AthenaPython/src/PyJobOptionsCatalogue.h  |  6 +-
 Control/AthenaPython/src/PyJobOptionsSvc.cxx  | 67 +++++++++++--------
 Control/AthenaPython/src/PyJobOptionsSvc.h    | 43 +++++++-----
 Control/AthenaPython/src/PyProperty.cxx       | 10 +--
 13 files changed, 209 insertions(+), 76 deletions(-)
 create mode 100644 Control/AthenaPython/src/PyAthenaGILStateEnsure.h

diff --git a/Control/AthenaPython/AthenaPython/PyProperty.h b/Control/AthenaPython/AthenaPython/PyProperty.h
index 53719a6ce01..0f28e13a7e6 100644
--- a/Control/AthenaPython/AthenaPython/PyProperty.h
+++ b/Control/AthenaPython/AthenaPython/PyProperty.h
@@ -26,7 +26,7 @@ typedef _object PyObject;
 
 
 class PyProperty
-  : public Property
+  : public PropertyWithHandlers
 { 
 
   /////////////////////////////////////////////////////////////////// 
@@ -49,22 +49,22 @@ class PyProperty
   /// @c Property implementation
   ///@{
   /// export the property value to the destination
-  virtual bool load (Property& dest) const;
+  bool load (Property& dest) const override;
 
   /// import the property value from source
-  virtual bool assign (const Property& src);
+  bool assign (const Property& src) override;
 
   /// export the property value as a @c std::string
-  virtual std::string toString() const;
+  std::string toString() const override;
 
   /// export the property value into a std::stream
-  virtual void toStream(std::ostream& out) const;
+  void toStream(std::ostream& out) const override;
 
   /// import the property value from a @c std::string
-  virtual StatusCode fromString (const std::string& value);
+  StatusCode fromString (const std::string& value) override;
 
   /// clone: the usual "virtual constructor" pattern
-  virtual Property* clone() const;
+  PyProperty* clone() const override;
 
   /// access underlying wrapped object
   virtual void* object() const;
diff --git a/Control/AthenaPython/src/PyAthenaAlg.cxx b/Control/AthenaPython/src/PyAthenaAlg.cxx
index 8bcc6d6da6c..c32e505fa85 100644
--- a/Control/AthenaPython/src/PyAthenaAlg.cxx
+++ b/Control/AthenaPython/src/PyAthenaAlg.cxx
@@ -7,6 +7,7 @@
 // PyAthenaAlg.cxx 
 // Implementation file for class PyAthena::Alg
 // Author: S.Binet<binet@cern.ch>
+// Modified: Wim Lavrijsen <WLavrijsen@lbl.gov>
 /////////////////////////////////////////////////////////////////// 
 
 // Python includes
@@ -18,6 +19,7 @@
 // AthenaPython includes
 #include "AthenaPython/PyAthenaUtils.h"
 #include "AthenaPython/PyAthenaAlg.h"
+#include "PyAthenaGILStateEnsure.h"
 
 // STL includes
 
@@ -37,7 +39,7 @@ namespace PyAthena {
 ////////////////
 Alg::Alg( const std::string& name, ISvcLocator* svcLocator ) :
   AlgBase_t( name, svcLocator ),
-  m_self   ( 0 )
+  m_self   ( nullptr )
 {}
 
 // Destructor
@@ -45,7 +47,11 @@ Alg::Alg( const std::string& name, ISvcLocator* svcLocator ) :
 Alg::~Alg()
 { 
   ATH_MSG_DEBUG("Calling destructor");
-  Py_XDECREF( m_self );
+  if ( m_self ) {
+    PyGILStateEnsure ensure;
+    Py_DECREF( m_self );
+    m_self = nullptr;
+  }
 }
 
 // Framework's Hooks
@@ -138,6 +144,7 @@ bool
 Alg::setPyAttr( PyObject* o )
 {
   // now we tell the PyObject which C++ object it is the cousin of.
+  PyGILStateEnsure ensure;
   PyObject* pyobj = TPython::ObjectProxy_FromVoidPtr
     ( (void*)this, this->typeName() );
   if ( !pyobj ) {
diff --git a/Control/AthenaPython/src/PyAthenaAud.cxx b/Control/AthenaPython/src/PyAthenaAud.cxx
index 3729afce717..0ba85803711 100644
--- a/Control/AthenaPython/src/PyAthenaAud.cxx
+++ b/Control/AthenaPython/src/PyAthenaAud.cxx
@@ -7,6 +7,7 @@
 // PyAthenaAud.cxx 
 // Implementation file for class PyAthena::Aud
 // Author: S.Binet<binet@cern.ch>
+// Modified: Wim Lavrijsen <WLavrijsen@lbl.gov>
 /////////////////////////////////////////////////////////////////// 
 
 // Python includes
@@ -18,6 +19,7 @@
 // AthenaPython includes
 #include "AthenaPython/PyAthenaUtils.h"
 #include "AthenaPython/PyAthenaAud.h"
+#include "PyAthenaGILStateEnsure.h"
 
 // STL includes
 
@@ -38,14 +40,18 @@ namespace PyAthena {
 
 Aud::Aud( const std::string& name, ISvcLocator* svcLocator ) :
   ::Auditor( name, svcLocator ),
-  m_self   ( 0 )
+  m_self   ( nullptr )
 {}
 
 // Destructor
 ///////////////
 Aud::~Aud()
 { 
-  Py_XDECREF( m_self );
+  if ( m_self ) {
+    PyGILStateEnsure ensure;
+    Py_DECREF( m_self );
+    m_self = nullptr;
+  }
 }
 
 // Athena Auditor's Hooks
@@ -289,6 +295,7 @@ bool
 Aud::setPyAttr( PyObject* o )
 {
   // now we tell the PyObject which C++ object it is the cousin of.
+  PyGILStateEnsure ensure;
   PyObject* pyobj = TPython::ObjectProxy_FromVoidPtr
     ( (void*)this, this->typeName() );
   if ( !pyobj ) {
@@ -333,4 +340,3 @@ Aud::setPyAttr( PyObject* o )
 }
 
 } //> end namespace PyAthena
-
diff --git a/Control/AthenaPython/src/PyAthenaGILStateEnsure.h b/Control/AthenaPython/src/PyAthenaGILStateEnsure.h
new file mode 100644
index 00000000000..f0ed996b390
--- /dev/null
+++ b/Control/AthenaPython/src/PyAthenaGILStateEnsure.h
@@ -0,0 +1,47 @@
+///////////////////////// -*- C++ -*- /////////////////////////////
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// PyAthenaGILStateEnsure.h 
+// Header file for convenience class to ensure GIL
+// Author: Wim Lavrijsen <WLavrijsen@lbl.gov>
+/////////////////////////////////////////////////////////////////// 
+#ifndef ATHENAPYTHON_PYGILSTATEENSURE_H
+#define ATHENAPYTHON_PYGILSTATEENSURE_H 
+
+// Python includes
+#include "Python.h"
+
+namespace PyAthena {
+
+class PyGILStateEnsure
+{ 
+ public: 
+  PyGILStateEnsure();
+  PyGILStateEnsure( const PyGILStateEnsure& ) = delete;
+  PyGILStateEnsure& operator=( const PyGILStateEnsure& ) = delete;
+  ~PyGILStateEnsure(); 
+
+ private: 
+  PyGILState_STATE m_gstate;
+}; 
+
+/////////////////////////////////////////////////////////////////// 
+/// Inline methods: 
+/////////////////////////////////////////////////////////////////// 
+
+inline PyGILStateEnsure::PyGILStateEnsure()
+{ 
+   m_gstate = PyGILState_Ensure();
+}
+
+inline PyGILStateEnsure::~PyGILStateEnsure()
+{ 
+   PyGILState_Release( m_gstate );
+}
+
+} //> namespace PyAthena
+
+#endif //> ATHENAPYTHON_PYATHENA_PYGILSTATEENSURE_H
diff --git a/Control/AthenaPython/src/PyAthenaSvc.cxx b/Control/AthenaPython/src/PyAthenaSvc.cxx
index d09bdcfe908..0fb25e008ff 100644
--- a/Control/AthenaPython/src/PyAthenaSvc.cxx
+++ b/Control/AthenaPython/src/PyAthenaSvc.cxx
@@ -7,6 +7,7 @@
 // PyAthenaSvc.cxx 
 // Implementation file for class PyAthena::Svc
 // Author: S.Binet<binet@cern.ch>
+// Modified: Wim Lavrijsen <WLavrijsen@lbl.gov>
 /////////////////////////////////////////////////////////////////// 
 
 // Python includes
@@ -18,6 +19,7 @@
 // AthenaPython includes
 #include "AthenaPython/PyAthenaUtils.h"
 #include "AthenaPython/PyAthenaSvc.h"
+#include "PyAthenaGILStateEnsure.h"
 
 // STL includes
 
@@ -38,7 +40,7 @@ namespace PyAthena {
 ////////////////
 Svc::Svc( const std::string& name, ISvcLocator* svcLocator ) :
   SvcBase_t( name, svcLocator ),
-  m_self   ( 0 )
+  m_self   ( nullptr )
 {}
 
 // Destructor
@@ -151,6 +153,7 @@ Svc::typeName() const
 void
 Svc::handle (const Incident& inc)
 {
+  PyGILStateEnsure ensure;
   if (0 == PyObject_HasAttrString (m_self, (char*)"handle")) {
     // python side does not implement 'handle'. Fair enough.
     // XXX FIXME: could say something though: we have been registered as 
@@ -186,6 +189,7 @@ bool
 Svc::setPyAttr( PyObject* o )
 {
   // now we tell the PyObject which C++ object it is the cousin of.
+  PyGILStateEnsure ensure;
   PyObject* pyobj = TPython::ObjectProxy_FromVoidPtr
     ( (void*)this, this->typeName() );
   if ( !pyobj ) {
@@ -231,4 +235,3 @@ Svc::setPyAttr( PyObject* o )
 /////////////////////////////////////////////////////////////////// 
 
 } //> end namespace AthenaPython
-
diff --git a/Control/AthenaPython/src/PyAthenaTool.cxx b/Control/AthenaPython/src/PyAthenaTool.cxx
index d66a3875286..afb3a69cd91 100644
--- a/Control/AthenaPython/src/PyAthenaTool.cxx
+++ b/Control/AthenaPython/src/PyAthenaTool.cxx
@@ -7,6 +7,7 @@
 // Tool.cxx 
 // Implementation file for class Tool
 // Author: S.Binet<binet@cern.ch>
+// Modified: Wim Lavrijsen <WLavrijsen@lbl.gov>
 /////////////////////////////////////////////////////////////////// 
 
 // Python includes
@@ -18,6 +19,7 @@
 // AthenaPython includes
 #include "AthenaPython/PyAthenaTool.h"
 #include "AthenaPython/PyAthenaUtils.h"
+#include "PyAthenaGILStateEnsure.h"
 
 // STL includes
 
@@ -38,7 +40,7 @@ Tool::Tool( const std::string& type,
 	    const std::string& name, 
 	    const IInterface* parent ) : 
   ToolBase_t( type, name, parent ),
-  m_self    ( 0 )
+  m_self    ( nullptr )
 {
   //
   // Property declaration
@@ -52,8 +54,11 @@ Tool::Tool( const std::string& type,
 Tool::~Tool()
 { 
   ATH_MSG_DEBUG("Calling destructor");
-
-  Py_XDECREF( m_self );
+  if ( m_self ) {
+    PyGILStateEnsure ensure;
+    Py_DECREF( m_self );
+    m_self = nullptr;
+  }
 }
 
 // Athena AlgTool's Hooks
@@ -130,6 +135,7 @@ bool
 Tool::setPyAttr( PyObject* o )
 {
   // now we tell the PyObject which C++ object it is the cousin of.
+  PyGILStateEnsure ensure;
   PyObject* pyobj = TPython::ObjectProxy_FromVoidPtr
     ( (void*)this, this->typeName() );
   if ( !pyobj ) {
diff --git a/Control/AthenaPython/src/PyAthenaUtils.cxx b/Control/AthenaPython/src/PyAthenaUtils.cxx
index 3ca823fc286..d20a8486997 100644
--- a/Control/AthenaPython/src/PyAthenaUtils.cxx
+++ b/Control/AthenaPython/src/PyAthenaUtils.cxx
@@ -7,6 +7,7 @@
 // PyAthenaUtils.cxx 
 // Implementation file for various PyAthena helpers
 // Author: S.Binet<binet@cern.ch>
+// Modified: Wim Lavrijsen <WLavrijsen@lbl.gov>
 /////////////////////////////////////////////////////////////////// 
 
 // Python includes
@@ -14,6 +15,7 @@
 
 // AthenaPython includes
 #include "AthenaPython/PyAthenaUtils.h"
+#include "PyAthenaGILStateEnsure.h"
 
 // Framework includes
 #include "GaudiKernel/IInterface.h"
@@ -51,6 +53,7 @@ fetchInterfaceId( PyObject* klass,
 {
   Py_INCREF( klass );
 
+  PyAthena::PyGILStateEnsure ensure;
   PyObject* idObj = PyObject_CallMethod( klass, 
 					 const_cast<char*>("interfaceID"), 
 					 const_cast<char*>("") );
@@ -102,6 +105,7 @@ std::string
 PyAthena::repr( PyObject* o )
 {
   // PyObject_Repr returns a new ref.
+  PyGILStateEnsure ensure;
   PyObject* py_repr = PyObject_Repr( o );
   if ( !py_repr || !PyString_Check(py_repr) ) {
     Py_XDECREF( py_repr );
@@ -117,6 +121,7 @@ std::string
 PyAthena::str( PyObject* o )
 {
   // PyObject_Str returns a new ref.
+  PyGILStateEnsure ensure;
   PyObject* py_str = PyObject_Str( o );
   if ( !py_str || !PyString_Check(py_str) ) {
     Py_XDECREF( py_str );
@@ -131,6 +136,7 @@ PyAthena::str( PyObject* o )
 void PyAthena::throw_py_exception (bool display)
 {
   if (display) {
+    PyGILStateEnsure ensure;
     // fetch error
     PyObject* pytype = 0, *pyvalue = 0, *pytrace = 0;
     PyErr_Fetch (&pytype, &pyvalue, &pytrace);
@@ -155,6 +161,7 @@ PyAthena::callPyMethod( PyObject* self, const char* methodName )
   if ( 0 == self || 0 == method ) { return StatusCode::FAILURE; }
   
   // call Python 
+  PyGILStateEnsure ensure;
   PyObject* r = PyObject_CallMethod( self, method, const_cast<char*>("") );
   
   if ( 0 == r ) { 
@@ -224,6 +231,7 @@ StatusCode PyAthena::queryInterface( PyObject* self,
       << std::endl;
   }
 
+  PyGILStateEnsure ensure;
   PyObject* type = PyObject_GetAttrString( self, 
 					   const_cast<char*>("__class__") );
   if ( !type ) {
@@ -332,6 +340,7 @@ void PyAthena::pyAudit( PyObject* self,
 			const char* evt, 
 			const char* component )
 {
+  PyGILStateEnsure ensure;
   PyObject* call = PyObject_CallMethod(self,
 				       (char*)method,
 				       (char*)"ss", evt, component);
@@ -349,6 +358,7 @@ void PyAthena::pyAudit( PyObject* self,
 			const char* evt,
 			const char* component, const StatusCode& sc )
 {
+  PyGILStateEnsure ensure;
   PyObject* pySc = TPython::ObjectProxy_FromVoidPtr((void*)&sc,
 						    "StatusCode");
   if ( !pySc ) {
diff --git a/Control/AthenaPython/src/PyComponentMgr.cxx b/Control/AthenaPython/src/PyComponentMgr.cxx
index 4ba34802fb4..57e0d3752ec 100755
--- a/Control/AthenaPython/src/PyComponentMgr.cxx
+++ b/Control/AthenaPython/src/PyComponentMgr.cxx
@@ -7,6 +7,7 @@
 // PyComponentMgr.cxx 
 // Implementation file for class PyComponentMgr
 // Author: S.Binet<binet@cern.ch>
+// Modified: Wim Lavrijsen <WLavrijsen@lbl.gov>
 /////////////////////////////////////////////////////////////////// 
 
 // Python includes
@@ -19,6 +20,7 @@ SG_BASES1(PyObject, SG::NoBase);
 
 // AthenaPython includes
 #include "PyComponentMgr.h"
+#include "PyAthenaGILStateEnsure.h"
 
 // STL includes
 
@@ -42,7 +44,7 @@ using namespace PyAthena;
 PyComponentMgr::PyComponentMgr( const std::string& name, 
 				ISvcLocator* pSvcLocator ) : 
   AthService  ( name,     pSvcLocator ),
-  m_dict      ( 0 ),
+  m_dict      ( nullptr ),
   m_components(   )
 {
   //
@@ -59,16 +61,23 @@ PyComponentMgr::~PyComponentMgr()
   ATH_MSG_DEBUG("Calling destructor");
 
   // we own the repository of instances' description
-  Py_XDECREF( m_dict );
+  if ( m_dict ) {
+    PyGILStateEnsure ensure;
+    Py_DECREF( m_dict );
+    m_dict = nullptr;
+  }
 
   // as well as the one of corresponding instances
-  for ( PyComponents_t::iterator 
-	  i    = m_components.begin(), 
-	  iEnd = m_components.end();
-	i != iEnd;
-	++i ) {
-    ATH_MSG_VERBOSE("__del__(" << i->first << ")...");
-    Py_XDECREF( i->second );
+  if ( m_components.size() ) {
+    PyGILStateEnsure ensure;
+    for ( PyComponents_t::iterator
+            i    = m_components.begin(),
+            iEnd = m_components.end();
+          i != iEnd;
+          ++i ) {
+      ATH_MSG_VERBOSE("__del__(" << i->first << ")...");
+      Py_XDECREF( i->second );
+    }
   }
 
 }
@@ -83,6 +92,7 @@ PyComponentMgr::initialize()
   const std::string pyModuleName = "AthenaPython.Configurables";
 
   // import the module holding the dictionary of component instances
+  PyGILStateEnsure ensure;
   ATH_MSG_DEBUG("Importing module [" << pyModuleName << "]...");
   PyObject* module = PyImport_ImportModule( const_cast<char*>(pyModuleName.c_str()) );
   if ( !module || !PyModule_Check( module ) ) {
@@ -194,6 +204,7 @@ PyComponentMgr::pyObject( IPyComponent* cppComp )
   const std::string& name = cppComp->name();
 
   // Check if we already have instantiated that component
+  PyGILStateEnsure ensure;
   PyComponents_t::iterator comp = m_components.find( name );
   if ( comp != m_components.end() && comp->second ) {
     Py_INCREF (comp->second);
diff --git a/Control/AthenaPython/src/PyJobOptionsCatalogue.cxx b/Control/AthenaPython/src/PyJobOptionsCatalogue.cxx
index 062fcb6deb3..6967e5cfa91 100644
--- a/Control/AthenaPython/src/PyJobOptionsCatalogue.cxx
+++ b/Control/AthenaPython/src/PyJobOptionsCatalogue.cxx
@@ -112,6 +112,23 @@ PyJobOptionsCatalogue::remove_property (const std::string& client,
   return StatusCode::SUCCESS;
 }
 
+/// find a particular property by  name
+const PyJobOptionsCatalogue::Property_t*
+PyJobOptionsCatalogue::getProperty (const std::string& client,
+                                    const std::string& prop_name) const {
+
+  Properties_t* props = find_properties (client);
+  if (!props) { return nullptr; }
+
+  Properties_t::const_iterator itr;
+  for (itr = props->begin(); itr!=props->end(); ++itr) {
+    if (prop_name == (*itr)->name()) {
+      return *itr;
+    }
+  }
+  return nullptr;
+}
+
 /////////////////////////////////////////////////////////////////// 
 // Protected methods: 
 /////////////////////////////////////////////////////////////////// 
diff --git a/Control/AthenaPython/src/PyJobOptionsCatalogue.h b/Control/AthenaPython/src/PyJobOptionsCatalogue.h
index b7d095deeda..9b2a00c9332 100644
--- a/Control/AthenaPython/src/PyJobOptionsCatalogue.h
+++ b/Control/AthenaPython/src/PyJobOptionsCatalogue.h
@@ -32,7 +32,8 @@ class PyJobOptionsCatalogue
   /////////////////////////////////////////////////////////////////// 
 public: 
   
-  typedef std::vector<const Property*> Properties_t;
+  typedef Gaudi::Details::PropertyBase Property_t;
+  typedef std::vector<const Property_t*> Properties_t;
   typedef SG::unordered_map<std::string, Properties_t> Objects_t;
   
   /////////////////////////////////////////////////////////////////// 
@@ -59,6 +60,9 @@ public:
   /// FIXME: slow and inefficient
   std::vector<std::string> clients() const;
 
+  const Property_t* getProperty(const std::string& client, 
+                                const std::string& prop_name) const;
+  
   /////////////////////////////////////////////////////////////////// 
   // Non-const methods: 
   /////////////////////////////////////////////////////////////////// 
diff --git a/Control/AthenaPython/src/PyJobOptionsSvc.cxx b/Control/AthenaPython/src/PyJobOptionsSvc.cxx
index 78ea7a0b16b..c2dc7f34da2 100644
--- a/Control/AthenaPython/src/PyJobOptionsSvc.cxx
+++ b/Control/AthenaPython/src/PyJobOptionsSvc.cxx
@@ -25,6 +25,7 @@
 // PyRoot
 #include "TPython.h"
 
+typedef PyJobOptionsCatalogue::Property_t   Property_t;
 typedef PyJobOptionsCatalogue::Properties_t Properties_t;
 typedef PyJobOptionsCatalogue::Objects_t    Objects_t;
 
@@ -37,10 +38,10 @@ typedef PyJobOptionsCatalogue::Objects_t    Objects_t;
 PyJobOptionsSvc::PyJobOptionsSvc (const std::string& name, 
 				  ISvcLocator* pSvcLocator) : 
   ::AthService (name, pSvcLocator),
-  m_pmgr       (),
-  m_source_path(),
-  m_source_type(),
-  m_dir_search_path(),
+  // m_pmgr       (),
+  // m_source_path(),
+  // m_source_type(),
+  // m_dir_search_path(),
   m_catalogue()
 {
   //
@@ -62,18 +63,18 @@ PyJobOptionsSvc::PyJobOptionsSvc (const std::string& name,
     }
   }
 
-  m_pmgr.declareProperty ("TYPE", 
-			  m_source_type = "NONE",
-			  "type of the joboptions to parse (txt,py,pickle)");
-  m_pmgr.declareProperty ("PATH", 
-			  m_source_path,
-			  "path to the joboptions to parse");
-  m_pmgr.declareProperty ("SEARCHPATH", 
-			  m_dir_search_path,
-			  "list of directory-paths to look for joboptions");
-  m_pmgr.declareProperty ("DUMPFILE", 
-			  m_dump,
-			  "name of a file where to dump the list of options");
+  // m_pmgr.declareProperty ("TYPE", 
+  //       		  m_source_type = "NONE",
+  //       		  "type of the joboptions to parse (txt,py,pickle)");
+  // m_pmgr.declareProperty ("PATH", 
+  //       		  m_source_path,
+  //       		  "path to the joboptions to parse");
+  // m_pmgr.declareProperty ("SEARCHPATH", 
+  //       		  m_dir_search_path,
+  //       		  "list of directory-paths to look for joboptions");
+  // m_pmgr.declareProperty ("DUMPFILE", 
+  //       		  m_dump,
+  //       		  "name of a file where to dump the list of options");
 
 }
 
@@ -202,6 +203,14 @@ PyJobOptionsSvc::getProperties (const std::string& client) const
   return m_catalogue.properties (client);
 }
 
+const Property_t*
+PyJobOptionsSvc::getClientProperty( const std::string& client,
+                                    const std::string& name ) const 
+  {
+    return m_catalogue.getProperty( client, name );
+  }
+
+
 /// Get the list of clients
 std::vector<std::string> 
 PyJobOptionsSvc::getClients() const
@@ -237,19 +246,19 @@ PyJobOptionsSvc::readOptions (const std::string& file,
   return StatusCode::SUCCESS;
 }
 
-/// IProperty implementation (needed for initialisation)
-StatusCode 
-PyJobOptionsSvc::setProperty(const Property& p)
-{
-  return m_pmgr.setProperty (p);
-}
-
-/// IProperty implementation (needed for initialisation)
-StatusCode
-PyJobOptionsSvc::getProperty(Property *p) const
-{
-  return m_pmgr.getProperty (p);
-}
+// /// IProperty implementation (needed for initialisation)
+// StatusCode 
+// PyJobOptionsSvc::setProperty(const Property& p)
+// {
+//   return m_pmgr.setProperty (p);
+// }
+
+// /// IProperty implementation (needed for initialisation)
+// StatusCode
+// PyJobOptionsSvc::getProperty(Property *p) const
+// {
+//   return m_pmgr.getProperty (p);
+// }
 
 /////////////////////////////////////////////////////////////////// 
 // Const methods: 
diff --git a/Control/AthenaPython/src/PyJobOptionsSvc.h b/Control/AthenaPython/src/PyJobOptionsSvc.h
index 4d9683bba7f..f90b9f1c14f 100644
--- a/Control/AthenaPython/src/PyJobOptionsSvc.h
+++ b/Control/AthenaPython/src/PyJobOptionsSvc.h
@@ -22,7 +22,9 @@
 // GaudiKernel
 #include "GaudiKernel/IJobOptionsSvc.h"
 #include "GaudiKernel/IProperty.h"
-#include "GaudiKernel/PropertyMgr.h"
+#include "GaudiKernel/Property.h"
+#include "GaudiKernel/PropertyHolder.h"
+//#include "GaudiKernel/PropertyMgr.h"
 
 // AthenaPython includes
 #include "PyJobOptionsCatalogue.h"
@@ -31,7 +33,7 @@
 class ISvcLocator;
 template <class TYPE> class SvcFactory;
 class IProperty;
-class  Property;
+//class  Property;
 struct _object; 
 typedef _object PyObject;
 
@@ -91,9 +93,15 @@ class PyJobOptionsSvc
 
   /// Get the properties associated to a given client
   virtual 
-  const std::vector<const Property*>* 
+  //  const std::vector<const Property*>* 
+  const std::vector<const Gaudi::Details::PropertyBase*>* 
   getProperties (const std::string& client) const;
 
+  /// Get a property for a client
+  const Gaudi::Details::PropertyBase* 
+  getClientProperty( const std::string& client,
+                     const std::string& name ) const override;
+
   /// Get the list of clients
   virtual 
   std::vector<std::string> getClients() const;
@@ -111,8 +119,8 @@ class PyJobOptionsSvc
   ///@}
 
   /// IProperty implementation (needed for initialisation)
-  StatusCode setProperty(const Property& p);
-  StatusCode getProperty(Property *p) const;
+  // StatusCode setProperty(const Property& p);
+  // StatusCode getProperty(Property *p) const;
 
   /////////////////////////////////////////////////////////////////// 
   // Const methods: 
@@ -132,18 +140,23 @@ class PyJobOptionsSvc
   /// Default constructor: 
   PyJobOptionsSvc();
 
-  /// Property manager (where we store our properties - chicken/egg pb)
-  PropertyMgr m_pmgr;
+  // PropertyMgr m_pmgr;
+
+  // /// path to joboption file
+  // std::string m_source_path;
+  // /// source type (old-txt, py, pickle?)
+  // std::string m_source_type;
+  // /// list of paths to directories to look for joboptions
+  // std::string m_dir_search_path;
+
+  // /// optional output file to dump all properties 
+  // std::string m_dump;
 
-  /// path to joboption file
-  std::string m_source_path;
-  /// source type (old-txt, py, pickle?)
-  std::string m_source_type;
-  /// list of paths to directories to look for joboptions
-  std::string m_dir_search_path;
+  Gaudi::Property<std::string> m_source_type{this, "TYPE"};
+  Gaudi::Property<std::string> m_source_path{this, "PATH"};
+  Gaudi::Property<std::string> m_dir_search_path{this, "SEARCHPATH"};
+  Gaudi::Property<std::string> m_dump{this, "DUMPFILE"};
 
-  /// optional output file to dump all properties 
-  std::string m_dump;
 
   /// catalogue holding the properties
   PyJobOptionsCatalogue m_catalogue;
diff --git a/Control/AthenaPython/src/PyProperty.cxx b/Control/AthenaPython/src/PyProperty.cxx
index 473ff36eb63..87e67b83038 100644
--- a/Control/AthenaPython/src/PyProperty.cxx
+++ b/Control/AthenaPython/src/PyProperty.cxx
@@ -108,7 +108,7 @@ namespace {
 
 /// Copy constructor: 
 PyProperty::PyProperty( const PyProperty& rhs ) :
-  Property (rhs),
+  PropertyWithHandlers (rhs),
   m_pyobj  (::DeepCopier::instance()->copy (rhs.m_pyobj))
 {}
 
@@ -117,7 +117,7 @@ PyProperty&
 PyProperty::operator=( const PyProperty& rhs )
 {
   if ( this != &rhs ) {
-    Property::operator= (rhs);
+    PropertyWithHandlers::operator= (rhs);
     m_pyobj = ::DeepCopier::instance()->copy (rhs.m_pyobj);
   }
   return *this;
@@ -127,7 +127,7 @@ PyProperty::operator=( const PyProperty& rhs )
 PyProperty::PyProperty(const std::string& name,
 		       const std::type_info& type,
 		       void* obj) :
-  Property (name, type),
+  PropertyWithHandlers (name, type),
   m_pyobj  (Py_None)
 {
   if (type == typeid(PyObject) ||
@@ -142,7 +142,7 @@ PyProperty::PyProperty(const std::string& name,
 
 PyProperty::PyProperty (const std::string& name,
 			PyObject* obj) :
-  Property (name, typeid(obj)),
+  PropertyWithHandlers (name, typeid(obj)),
   m_pyobj  (::DeepCopier::instance()->copy (obj))
 {}
 
@@ -234,7 +234,7 @@ PyProperty::fromString (const std::string& value)
 }
 
 /// clone: the usual "virtual constructor" pattern
-Property* 
+PyProperty* 
 PyProperty::clone() const
 {
   return new PyProperty(*this);
-- 
GitLab