[pytango] 436/483: Fix SF bug #698: PyTango.Util discrepancy
Sandor Bodo-Merle
sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:15:09 UTC 2017
This is an automated email from the git hooks/post-receive script.
sbodomerle-guest pushed a commit to annotated tag bliss_8.10
in repository pytango.
commit 3618411bfc5ff25e0d8b871c975b842fd71bc2b3
Author: coutinho <coutinho at esrf.fr>
Date: Wed Dec 17 10:35:43 2014 +0100
Fix SF bug #698: PyTango.Util discrepancy
---
src/boost/cpp/server/tango_util.cpp | 47 ++++---
src/boost/python/pyutil.py | 251 ++++++++++++++++++------------------
2 files changed, 152 insertions(+), 146 deletions(-)
diff --git a/src/boost/cpp/server/tango_util.cpp b/src/boost/cpp/server/tango_util.cpp
index b8a0aa1..157afc2 100644
--- a/src/boost/cpp/server/tango_util.cpp
+++ b/src/boost/cpp/server/tango_util.cpp
@@ -67,7 +67,7 @@ namespace PyUtil
AutoPythonAllowThreads guard;
instance.server_run();
}
-
+
inline Tango::Util* init(boost::python::object &obj)
{
PyObject *obj_ptr = obj.ptr();
@@ -87,12 +87,18 @@ namespace PyUtil
str item = str(handle<>(item_ptr));
argv[i] = extract<char *>(item);
}
- res = Tango::Util::init(argc, argv);
+ res = Tango::Util::init(argc, argv);
} catch (...) {
delete [] argv;
throw;
}
delete [] argv;
+
+ if (PyEval_ThreadsInitialized() == 0)
+ {
+ PyEval_InitThreads();
+ }
+
return res;
}
@@ -117,7 +123,7 @@ namespace PyUtil
to_python_indirect<
Tango::DeviceImpl*,
detail::make_reference_holder>()(*it)));
-
+
py_dev_list.append(py_value);
}
return py_dev_list;
@@ -134,7 +140,7 @@ namespace PyUtil
return py_value;
}
-
+
inline object get_device_list(Tango::Util &self, const string &name)
{
boost::python::list py_dev_list;
@@ -150,7 +156,7 @@ namespace PyUtil
}
return py_dev_list;
}
-
+
inline bool event_loop()
{
AutoPythonGIL guard;
@@ -160,7 +166,7 @@ namespace PyUtil
bool ret = boost::python::extract<bool>(py_ret);
return ret;
}
-
+
inline void server_set_event_loop(Tango::Util& self,
boost::python::object& py_event_loop)
{
@@ -176,12 +182,12 @@ namespace PyUtil
self.server_set_event_loop(event_loop);
}
}
-
+
void set_use_db(bool use_db)
{
Tango::Util::_UseDb = use_db;
}
-
+
boost::python::str get_dserver_ior(Tango::Util& self, Tango::DServer* dserver)
{
Tango::Device_var d = dserver->_this();
@@ -199,7 +205,7 @@ namespace PyUtil
delete [] ior;
return ret;
}
-
+
void orb_run(Tango::Util& self)
{
AutoPythonAllowThreads guard;
@@ -217,16 +223,16 @@ namespace PyUtil
boost::python::str ret = self.get_version_str().c_str();
return ret;
}
-}
-void init_python()
-{
- if (PyEval_ThreadsInitialized() == 0)
+ static boost::shared_ptr<Tango::Util>
+ makeUtil(boost::python::object& args)
{
- PyEval_InitThreads();
+ Tango::Util* util = PyUtil::init(args);
+ return boost::shared_ptr<Tango::Util>(util);
}
}
+
BOOST_PYTHON_FUNCTION_OVERLOADS (server_init_overload, PyUtil::server_init, 1, 2)
void export_util()
@@ -235,8 +241,9 @@ void export_util()
.def("create_thread", &Tango::Interceptors::create_thread)
.def("delete_thread", &Tango::Interceptors::delete_thread)
;
-
- class_<Tango::Util, boost::noncopyable>("_Util", no_init)
+
+ class_<Tango::Util, boost::noncopyable>("Util", no_init)
+ .def("__init__", boost::python::make_constructor(PyUtil::makeUtil))
.def("init", PyUtil::init,
return_value_policy<reference_existing_object>())
.staticmethod("init")
@@ -279,13 +286,13 @@ void export_util()
.def("set_polling_threads_pool_size", &Tango::Util::set_polling_threads_pool_size)
.def("get_polling_threads_pool_size", &Tango::Util::get_polling_threads_pool_size)
.def("is_svr_starting", &Tango::Util::is_svr_starting)
- .def("is_svr_shutting_down", &Tango::Util::is_svr_shutting_down)
- .def("is_device_restarting", &Tango::Util::is_device_restarting)
+ .def("is_svr_shutting_down", &Tango::Util::is_svr_shutting_down)
+ .def("is_device_restarting", &Tango::Util::is_device_restarting)
.def("get_sub_dev_diag", &Tango::Util::get_sub_dev_diag,
return_internal_reference<>())
.def("connect_db", &Tango::Util::connect_db)
.def("reset_filedatabase", &Tango::Util::reset_filedatabase)
- .def("get_database", &Tango::Util::get_database,
+ .def("get_database", &Tango::Util::get_database,
return_internal_reference<>())
.def("unregister_server", &Tango::Util::unregister_server)
.def("get_device_list_by_class", &PyUtil::get_device_list_by_class)
@@ -295,8 +302,6 @@ void export_util()
.def("set_interceptors", &Tango::Util::set_interceptors)
.def_readonly("_UseDb", &Tango::Util::_UseDb)
.def_readonly("_FileDb", &Tango::Util::_FileDb)
- .def("init_python", init_python)
- .staticmethod("init_python")
.def("set_use_db", &PyUtil::set_use_db)
.staticmethod("set_use_db")
.def("get_dserver_ior", &PyUtil::get_dserver_ior)
diff --git a/src/boost/python/pyutil.py b/src/boost/python/pyutil.py
index 23ac8a8..0a8415a 100644
--- a/src/boost/python/pyutil.py
+++ b/src/boost/python/pyutil.py
@@ -20,7 +20,7 @@ __docformat__ = "restructuredtext"
import os
import copy
-from ._PyTango import _Util, Except, DevFailed, DbDevInfo
+from ._PyTango import Util, Except, DevFailed, DbDevInfo
from .utils import document_method as __document_method
#from utils import document_static_method as __document_static_method
from .globals import class_list, cpp_class_list, get_constructed_classes
@@ -52,22 +52,22 @@ def __Util__get_class_list(self):
def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
"""
create_device(self, klass_name, device_name, alias=None, cb=None) -> None
-
+
Creates a new device of the given class in the database, creates a new
DeviceImpl for it and calls init_device (just like it is done for
existing devices when the DS starts up)
-
- An optional parameter callback is called AFTER the device is
+
+ An optional parameter callback is called AFTER the device is
registered in the database and BEFORE the init_device for the
newly created device is called
-
+
Throws PyTango.DevFailed:
- the device name exists already or
- the given class is not registered for this DS.
- the cb is not a callable
-
+
New in PyTango 7.1.2
-
+
Parameters :
- klass_name : (str) the device class name
- device_name : (str) the device name
@@ -77,17 +77,17 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
device is called. Typically you may want to put device and/or attribute
properties in the database here. The callback must receive a parameter:
device name (str). Default value is None meaning no callback
-
+
Return : None"""
if cb is not None and not isinstance(cb, collections.Callable):
Except.throw_exception("PyAPI_InvalidParameter",
"The optional cb parameter must be a python callable",
"Util.create_device")
-
+
db = self.get_database()
device_name = __simplify_device_name(device_name)
-
+
device_exists = True
try:
db.import_device(device_name)
@@ -96,7 +96,7 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
# 1 - Make sure device name doesn't exist already in the database
if device_exists:
- Except.throw_exception("PyAPI_DeviceAlreadyDefined",
+ Except.throw_exception("PyAPI_DeviceAlreadyDefined",
"The device %s is already defined in the database" % device_name,
"Util.create_device")
@@ -109,28 +109,28 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
klass = k
break
if klass is None:
- Except.throw_exception("PyAPI_UnknownDeviceClass",
+ Except.throw_exception("PyAPI_UnknownDeviceClass",
"The device class %s could not be found" % klass_name,
"Util.create_device")
-
+
# 3 - Create entry in the database (with alias if necessary)
dev_info = DbDevInfo()
dev_info.name = device_name
dev_info._class = klass_name
dev_info.server = self.get_ds_name()
-
+
db.add_device(dev_info)
-
+
if alias is not None:
db.put_device_alias(device_name, alias)
# from this point on, if anything wrong happens we need to clean the database
try:
- # 4 - run the callback which tipically is used to initialize
+ # 4 - run the callback which tipically is used to initialize
# device and/or attribute properties in the database
if cb is not None:
cb(device_name)
-
+
# 5 - Initialize device object on this server
k.device_factory([device_name])
except:
@@ -144,22 +144,22 @@ def __Util__create_device(self, klass_name, device_name, alias=None, cb=None):
def __Util__delete_device(self, klass_name, device_name):
"""
delete_device(self, klass_name, device_name) -> None
-
+
Deletes an existing device from the database and from this running
server
-
+
Throws PyTango.DevFailed:
- the device name doesn't exist in the database
- the device name doesn't exist in this DS.
-
+
New in PyTango 7.1.2
-
+
Parameters :
- klass_name : (str) the device class name
- device_name : (str) the device name
-
+
Return : None"""
-
+
db = self.get_database()
device_name = __simplify_device_name(device_name)
device_exists = True
@@ -170,10 +170,10 @@ def __Util__delete_device(self, klass_name, device_name):
# 1 - Make sure device name exists in the database
if not device_exists:
- Except.throw_exception("PyAPI_DeviceNotDefined",
+ Except.throw_exception("PyAPI_DeviceNotDefined",
"The device %s is not defined in the database" % device_name,
"Util.delete_device")
-
+
# 2 - Make sure device name is defined in this server
class_device_name = "%s::%s" % (klass_name, device_name)
ds = self.get_dserver_device()
@@ -186,94 +186,95 @@ def __Util__delete_device(self, klass_name, device_name):
device_exists =True
break
if not device_exists:
- Except.throw_exception("PyAPI_DeviceNotDefinedInServer",
+ Except.throw_exception("PyAPI_DeviceNotDefinedInServer",
"The device %s is not defined in this server" % class_device_name,
"Util.delete_device")
-
+
db.delete_device(device_name)
-
+
dimpl = self.get_device_by_name(device_name)
-
+
dc = dimpl.get_device_class()
dc.device_destroyer(device_name)
-def __Util__server_set_event_loop(self, event_loop):
- self._server_event_loop = event_loop
- self._server_set_event_loop()
+def __Util__init__(self, args):
+ args = copy.copy(args)
+ args[0] = os.path.splitext(args[0])[0]
+ Util.__init_orig__(self, args)
+
+def __Util__add_TgClass(self, klass_device_class, klass_device,
+ device_class_name=None):
+ """Register a new python tango class. Example::
+
+ util.add_TgClass(MotorClass, Motor)
+ util.add_TgClass(MotorClass, Motor, 'Motor') # equivalent to previous line
-class Util(_Util):
+ .. deprecated:: 7.1.2
+ Use :meth:`PyTango.Util.add_class` instead."""
+ if device_class_name is None:
+ device_class_name = klass_device.__name__
+ class_list.append((klass_device_class, klass_device, device_class_name))
+
+
+def __Util__add_Cpp_TgClass(self, device_class_name, tango_device_class_name):
+ """Register a new C++ tango class.
+
+ If there is a shared library file called MotorClass.so which
+ contains a MotorClass class and a _create_MotorClass_class method. Example::
+
+ util.add_Cpp_TgClass('MotorClass', 'Motor')
+
+ .. note:: the parameter 'device_class_name' must match the shared
+ library name.
+
+ .. deprecated:: 7.1.2
+ Use :meth:`PyTango.Util.add_class` instead."""
+ cpp_class_list.append((device_class_name, tango_device_class_name))
+
+def __Util__add_class(self, *args, **kwargs):
"""
- This class is a used to store TANGO device server process data and to
- provide the user with a set of utilities method.
-
- This class is implemented using the singleton design pattern.
- Therefore a device server process can have only one instance of this
- class and its constructor is not public. Example::
-
- util = PyTango.Util.instance()
- print(util.get_host_name())"""
-
- def __init__(self, args):
- args = copy.copy(args)
- args[0] = os.path.splitext(args[0])[0]
- _Util.init(args)
- _Util.init_python()
-
- def add_TgClass(self, klass_device_class, klass_device, device_class_name=None):
- """Register a new python tango class. Example::
-
- util.add_TgClass(MotorClass, Motor)
- util.add_TgClass(MotorClass, Motor, 'Motor') # equivalent to previous line
-
- .. deprecated:: 7.1.2
- Use :meth:`PyTango.Util.add_class` instead."""
-
- if device_class_name is None:
- device_class_name = klass_device.__name__
- class_list.append((klass_device_class, klass_device, device_class_name))
-
-
- def add_Cpp_TgClass(self, device_class_name, tango_device_class_name):
- """Register a new C++ tango class.
-
- If there is a shared library file called MotorClass.so which
- contains a MotorClass class and a _create_MotorClass_class method. Example::
-
- util.add_Cpp_TgClass('MotorClass', 'Motor')
-
- .. note:: the parameter 'device_class_name' must match the shared
- library name.
-
- .. deprecated:: 7.1.2
- Use :meth:`PyTango.Util.add_class` instead."""
- cpp_class_list.append((device_class_name, tango_device_class_name))
-
- def add_class(self, *args, **kwargs):
- """
- add_class(self, args, language="python") -> None
-
- Register a new tango class ('python' or 'c++').
-
- If language is 'python' then args must be the same as
- :meth:`PyTango.Util.add_TgClass`. Otherwise, args should be the ones
- in :meth:`PyTango.Util.add_Cpp_TgClass`. Example::
-
- util.add_class(MotorClass, Motor)
- util.add_class('CounterClass', 'Counter', language='c++')
-
- New in PyTango 7.1.2"""
- language = kwargs.get("language", "python")
- f = self.add_TgClass
- if language != "python":
- f = f = self.add_Cpp_TgClass
- return f(*args)
+ add_class(self, class<DeviceClass>, class<DeviceImpl>, language="python") -> None
+
+ Register a new tango class ('python' or 'c++').
+
+ If language is 'python' then args must be the same as
+ :meth:`PyTango.Util.add_TgClass`. Otherwise, args should be the ones
+ in :meth:`PyTango.Util.add_Cpp_TgClass`. Example::
+
+ util.add_class(MotorClass, Motor)
+ util.add_class('CounterClass', 'Counter', language='c++')
+
+ New in PyTango 7.1.2"""
+ language = kwargs.get("language", "python")
+ f = self.add_TgClass
+ if language != "python":
+ f = f = self.add_Cpp_TgClass
+ return f(*args)
def __init_Util():
- _Util.get_class_list = __Util__get_class_list
- _Util.create_device = __Util__create_device
- _Util.delete_device = __Util__delete_device
+ Util.__init_orig__ = Util.__init__
+ Util.__init__ = __Util__init__
+ Util.add_TgClass = __Util__add_TgClass
+ Util.add_Cpp_TgClass = __Util__add_Cpp_TgClass
+ Util.add_class = __Util__add_class
+ Util.get_class_list = __Util__get_class_list
+ Util.create_device = __Util__create_device
+ Util.delete_device = __Util__delete_device
def __doc_Util():
+
+ Util.__doc__ = """\
+ This class is a used to store TANGO device server process data and to
+ provide the user with a set of utilities method.
+
+ This class is implemented using the singleton design pattern.
+ Therefore a device server process can have only one instance of this
+ class and its constructor is not public. Example::
+
+ util = PyTango.Util.instance()
+ print(util.get_host_name())
+ """
+
def document_method(method_name, desc, append=True):
return __document_method(Util, method_name, desc, append)
@@ -584,7 +585,7 @@ def __doc_Util():
New in PyTango 8.0.0
""" )
-
+
document_method("get_sub_dev_diag", """
get_sub_dev_diag(self) -> SubDevDiag
@@ -592,7 +593,7 @@ def __doc_Util():
Parameters : None
Return : (SubDevDiag) the sub device manager
-
+
New in PyTango 7.0.0
""" )
@@ -603,7 +604,7 @@ def __doc_Util():
Parameters : None
Return : None
-
+
New in PyTango 7.0.0
""" )
@@ -614,7 +615,7 @@ def __doc_Util():
Parameters : None
Return : (Database) the database
-
+
New in PyTango 7.0.0
""" )
@@ -622,30 +623,30 @@ def __doc_Util():
unregister_server(self) -> None
Unregister a device server process from the TANGO database.
- If the database call fails, a message is displayed on the screen
+ If the database call fails, a message is displayed on the screen
and the process is aborted
Parameters : None
Return : None
-
+
New in PyTango 7.0.0
""" )
-
+
document_method("get_device_list_by_class", """
get_device_list_by_class(self, class_name) -> sequence<DeviceImpl>
Get the list of device references for a given TANGO class.
Return the list of references for all devices served by one implementation
of the TANGO device pattern implemented in the process.
-
+
Parameters :
- class_name : (str) The TANGO device class name
-
+
Return : (sequence<DeviceImpl>) The device reference list
-
+
New in PyTango 7.0.0
""" )
-
+
document_method("get_device_by_name", """
get_device_by_name(self, dev_name) -> DeviceImpl
@@ -654,10 +655,10 @@ def __doc_Util():
Parameters :
- dev_name : (str) The TANGO device name
Return : (DeviceImpl) The device reference
-
+
New in PyTango 7.0.0
""" )
-
+
document_method("get_dserver_device", """
get_dserver_device(self) -> DServer
@@ -665,33 +666,33 @@ def __doc_Util():
Parameters : None
Return : (DServer) A reference to the dserver device
-
+
New in PyTango 7.0.0
""" )
-
+
document_method("get_device_list", """
get_device_list(self) -> sequence<DeviceImpl>
Get device list from name.
It is possible to use a wild card ('*') in the name parameter
(e.g. "*", "/tango/tangotest/n*", ...)
-
+
Parameters : None
Return : (sequence<DeviceImpl>) the list of device objects
-
+
New in PyTango 7.0.0
""" )
-
+
document_method("server_set_event_loop", """
server_set_event_loop(self, event_loop) -> None
-
+
This method registers an event loop function in a Tango server.
This function will be called by the process main thread in an infinite loop
The process will not use the classical ORB blocking event loop.
It is the user responsability to code this function in a way that it implements
- some kind of blocking in order not to load the computer CPU. The following
+ some kind of blocking in order not to load the computer CPU. The following
piece of code is an example of how you can use this feature::
-
+
_LOOP_NB = 1
def looping():
global _LOOP_NB
@@ -699,10 +700,10 @@ def __doc_Util():
time.sleep(0.1)
_LOOP_NB += 1
return _LOOP_NB > 100
-
+
def main():
py = PyTango.Util(sys.argv)
-
+
# ...
U = PyTango.Util.instance()
@@ -712,11 +713,11 @@ def __doc_Util():
Parameters : None
Return : None
-
+
New in PyTango 8.1.0
""" )
-
+
# document_static_method("init_python", """
# init_python() -> None
#
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/pytango.git
More information about the debian-science-commits
mailing list