[pytango] 299/483: preparing ipython >= 1.0; clean up HLAPI
Sandor Bodo-Merle
sbodomerle-guest at moszumanska.debian.org
Thu Sep 28 19:14:52 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 fb6c042d709186ba2aef7d93f1360d485492982a
Author: tiagocoutinho <tiagocoutinho at 4e9c00fd-8f2e-0410-aa12-93ce3db5e235>
Date: Fri Nov 15 16:29:44 2013 +0000
preparing ipython >= 1.0; clean up HLAPI
git-svn-id: http://svn.code.sf.net/p/tango-cs/code/bindings/PyTango/trunk@24227 4e9c00fd-8f2e-0410-aa12-93ce3db5e235
---
doc/WINDOWS-COMPILATION-EXAMPLE.TXT | 38 --
doc/_templates/index.html | 95 ++++-
doc/_templates/indexsidebar.html | 4 +-
doc/client/miscellaneous.rst | 8 +-
doc/quicktour.rst | 3 +-
doc/server/hlapi.rst | 112 ++++-
doc/start.rst | 394 +++--------------
doc/utilities.rst | 5 -
doc/windows_notes.txt | 156 +++++++
setup.py | 1 +
src/boost/python/__init__.py | 2 +-
src/boost/python/attr_data.py | 29 +-
src/boost/python/attribute_proxy.py | 10 +-
src/boost/python/device_proxy.py | 28 +-
src/boost/python/hlapi.py | 473 ++++++++++++++++-----
src/boost/python/ipython/__init__.py | 30 +-
src/boost/python/ipython/common.py | 91 +---
.../python/ipython/ipython_00_10/ipython_00_10.py | 8 +-
.../python/ipython/ipython_00_11/ipython_00_11.py | 13 +-
src/boost/python/tango_green.py | 41 +-
src/boost/python/utils.py | 62 +--
21 files changed, 910 insertions(+), 693 deletions(-)
diff --git a/doc/WINDOWS-COMPILATION-EXAMPLE.TXT b/doc/WINDOWS-COMPILATION-EXAMPLE.TXT
deleted file mode 100644
index 877ac65..0000000
--- a/doc/WINDOWS-COMPILATION-EXAMPLE.TXT
+++ /dev/null
@@ -1,38 +0,0 @@
-
-REM Set environment variables needed to compile
-
-set TANGO_ROOT=C:\Program Files\tango\win32_vc8\win32_dll
-set BOOST_ROOT=C:\Program Files\boost\boost_1_38
-set OMNI_ROOT=%TANGO_ROOT%
-set NUMPY_ROOT=C:\sicilia\Python25\Lib\site-packages\numpy\core\
-
-dir "%OMNI_ROOT%"\lib
-dir "%BOOST_ROOT%\lib"
-
-
-
-REM For some reason distutils is trying to locate Vs9 tools...
-REM And obviously it fails. We will fool him with this:
-
-set VS90COMNTOOLS=%VS80COMNTOOLS%
-
-REM compile :)
-setup.py -v build
-
-
-
-
-
-
-
-REM ------------------------------------
-
-REM to compile:
-setup.py -v build
-
-REM to create a MSI windows installer:
-setup.py bdist_msi
-
-REM to create a EXE windows installer:
-setup.py bdist_wininst
-
diff --git a/doc/_templates/index.html b/doc/_templates/index.html
index 9e5d7db..35d2404 100644
--- a/doc/_templates/index.html
+++ b/doc/_templates/index.html
@@ -5,16 +5,11 @@
<h1>Welcome to PyTango documentation!</h1>
<p>
- PyTango is a python module that exposes to <a class="reference external" href="http://www.python.org/">Python</a>
- the complete <a class="reference external" href="http://www.tango-controls.org/">Tango</a> C++ API
- (including both client and server).
-
-</p>
-
-<p>
- This means that you can write not only tango applications (scripts, CLIs, GUIs)
- that access tango device servers but also tango device servers themselves, all
- of this in pure python.
+ PyTango is a python module that exposes to <a class="reference external" href="http://www.python.org/">Python</a>
+ the complete <a class="reference external" href="http://www.tango-controls.org/">Tango</a> C++ API.
+ This means that you can write not only tango applications (scripts, CLIs, GUIs)
+ that access tango device servers but also tango device servers themselves, all
+ of this in pure python.
</p>
<div class="figure align-center">
@@ -25,8 +20,86 @@
Check out the <a class="reference internal" href="start.html#getting-started"><em>getting started guide</em></a>
to learn how to build and/or install PyTango and after that the <a class="reference internal" href="quicktour.html#quick-tour"><em>quick tour</em></a>
can help you with the first steps in the PyTango world.
+ In the meantime here is a preview:
</p>
+<table><tbody>
+<tr>
+ <td rowspan="2" style="width:50%; vertical-align:top;">
+
+<div class="highlight-python"><div class="highlight"><pre>
+<span class="c"># --------------- Server -------------------</span>
+
+<span class="kn">import</span> <span class="nn">time</span>
+
+<span class="kn">from</span> <span class="nn">PyTango</span> <span class="kn">import</span> <span class="n">server_run</span>
+<span class="kn">from</span> <span class="nn">PyTango.hlapi</span> <span class="kn">import</span> <span class="n">Device</span><span class="p">,</span> <span class="n">DeviceMeta</span>
+<span class="kn">from</span> <span class="nn">PyTango.hlapi</span> <span class="kn">import</span> <span class="n">attribute</span><span class="p">,</span> <span class="n">command</span>
+
+<span class="k">class</span> <span class="nc">Clock</span><span class="p">(</span><span class="n">Device</span><span class="p">):</span>
+ <span class="n">__metaclass__</span> <span class="o">=</span> <span class="n">DeviceMeta</span>
+
+ <span class="n">time</span> <span class="o">=</span> <span class="n">attribute</span><span class="p">()</span>
+
+ <span class="k">def</span> <span class="nf">read_time</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
+
+ <span class="nd">@command</span><span class="p">(</span><span class="n">din_type</span><span class="o">=</span><span class="nb">str</span><span class="p">,</span> <span class="n">dout_type</span><span class="o">=</span><span class="nb">str</span><span class="p">)</span>
+ <span class="k">def</span> <span class="nf">strftime</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">format</span><span class="p">):</span>
+ <span class="k">return</span> <span class="n">time</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="n">format</span><span class="p">)</span>
+
+<span class="k">if</span> <span class="n">__name__</span> <span class="o">==</span> <span class="s">"__main__"</span><span class="p">:</span>
+ <span class="n">server_run</span><span class="p">((</span><span class="n">Clock</span><span class="p">,))</span>
+
+
+
+
+</pre></div></div>
+
+ </td>
+ <td style="width:50%; vertical-align:top;">
+
+<div class="highlight-python"><div class="highlight"><pre>
+<span class="n">$</span><span class="c"> # ---------- Python Client --------------</span>
+
+<span class="n">$ python</span>
+
+<span class="gp">>>> </span><span class="kn">from</span> <span class="nn">PyTango</span> <span class="kn">import</span> <span class="n">DeviceProxy</span>
+
+<span class="gp">>>> </span><span class="n">clock</span> <span class="o">=</span> <span class="n">DeviceProxy</span><span class="p">(</span><span class="s">"my/first/clock"</span><span class="p">)</span>
+
+<span class="gp">>>> </span><span class="n">clock</span><span class="o">.</span><span class="n">time</span>
+<span class="go">1384447223.774121</span>
+
+<span class="gp">>>> </span><span class="n">clock</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s">"%H:%M:%S"</span><span class="p">)</span>
+<span class="go">'17:41:50'</span>
+</pre></div></div>
+ </td>
+
+</tr>
+<tr><td>
+
+ <div class="highlight-python">
+ <div class="highlight">
+<pre>
+<span class="n">$</span><span class="c"> # -------- ITango Client ----------------</span>
+
+<span class="n">$ itango</span>
+
+<span class="gp">ITango [1]: </span><span class="n">clock</span> <span class="o">=</span> <span class="n">Clock</span><span class="p">(</span><span class="s">"my/first/clock"</span><span class="p">)</span>
+
+<span class="gp">ITango [2]: </span><span class="n">clock</span><span class="o">.</span><span class="n">time</span>
+<span class="go">1384447223.774121</span>
+
+<span class="gp">ITango [3]: </span><span class="n">clock</span><span class="o">.</span><span class="n">strftime</span><span class="p">(</span><span class="s">"%H:%M:%S"</span><span class="p">)</span>
+<span class="go">'17:41:50'</span>
+</pre>
+ </div>
+ </div>
+
+</td></tr>
+</tbody></table>
+
<p>
If you need help understanding what Tango itself really is, you can check the
<a class="reference external" href="http://www.tango-controls.org/">Tango</a>
@@ -34,7 +107,7 @@
</p>
<p>
- A PDF version can be downloaded from <a href="PyTango.pdf">here</a>.
+ A PDF version of this documentation can be downloaded from <a href="PyTango.pdf">here</a>.
</p>
<p>
For convenience here are the links to other versions:<br/>
diff --git a/doc/_templates/indexsidebar.html b/doc/_templates/indexsidebar.html
index 5a9747d..7bf049c 100644
--- a/doc/_templates/indexsidebar.html
+++ b/doc/_templates/indexsidebar.html
@@ -1,8 +1,8 @@
<h3>Download</h3>
<p>Current version: <b>{{ version }}</b></p>
-<p>Get PyTango from the <a href="http://pypi.python.org/pypi/PyTango">PyPi</a>,
+<p>Get PyTango from <a href="http://pypi.python.org/pypi/PyTango">PyPi</a>,
or install it with:</p>
-<pre>easy_install -U PyTango</pre>
+<pre>pip install PyTango</pre>
<h3>PDF</h3>
<p>A PDF version <a href="PyTango.pdf">here</a>.
diff --git a/doc/client/miscellaneous.rst b/doc/client/miscellaneous.rst
index 4ab6deb..599f635 100644
--- a/doc/client/miscellaneous.rst
+++ b/doc/client/miscellaneous.rst
@@ -265,14 +265,14 @@ Green API
~~~~~~~~~
Summary:
- * :func:`get_green_mode`
- * :func:`set_green_mode`
+ * :func:`PyTango.get_green_mode`
+ * :func:`PyTango.set_green_mode`
* :func:`PyTango.gevent.DeviceProxy`
* :func:`PyTango.futures.DeviceProxy`
-.. autofunction:: get_green_mode
+.. autofunction:: PyTango.get_green_mode
-.. autofunction:: set_green_mode
+.. autofunction:: PyTango.set_green_mode
.. autofunction:: PyTango.gevent.DeviceProxy
diff --git a/doc/quicktour.rst b/doc/quicktour.rst
index a881b76..5b7432c 100644
--- a/doc/quicktour.rst
+++ b/doc/quicktour.rst
@@ -500,4 +500,5 @@ The following code is the complete device server code::
Quick tour (original) <quicktour_old>
-.. _IPython: http://ipython.scipy.org/
+.. _IPython: http://ipython.org/
+.. _numpy: http://www.numpy.org/
diff --git a/doc/server/hlapi.rst b/doc/server/hlapi.rst
index de3cb92..ddabf83 100644
--- a/doc/server/hlapi.rst
+++ b/doc/server/hlapi.rst
@@ -6,15 +6,113 @@
HLAPI
=====
-The High Level API for writting Tango device servers.
-
-Introduction
-------------
-
This module provides a high level device server API. It implements
:ref:`TEP1 <pytango-TEP1>`. It exposes an easier API for developing a Tango
device server.
+Here is an example on how to write a *Clock* device server using the
+high level API::
+
+ import time
+ from PyTango import server_run
+ from PyTango.hlapi import Device, DeviceMeta
+ from PyTango.hlapi import attribute, command
+
+ class Clock(Device):
+ __metaclass__ = DeviceMeta
+
+ time = attribute()
+
+ def read_time(self):
+ return time.time()
+
+ @command(din_type=str, dout_type=str)
+ def strftime(self, format):
+ return time.strftime(format)
+
+ if __name__ == "__main__":
+ server_run((Clock,))
+
+Here is an example on how to write a *PowerSupply* device server using the
+high level API. The example contains:
+
+#. a read-only double scalar attribute called *voltage*
+#. a read/write double scalar expert attribute *current*
+#. a read-only double image attribute called *noise*
+#. a *ramp* command
+#. a *host* device property
+#. a *port* class property
+
+.. code-block:: python
+ :linenos:
+
+ from time import time
+
+ from PyTango import AttrQuality, AttrWriteType, DispLevel, server_run
+ from PyTango.hlapi import Device, DeviceMeta, attribute, command
+ from PyTango.hlapi import class_property, device_property
+
+ class PowerSupply(Device):
+ __metaclass__ = DeviceMeta
+
+ voltage = attribute()
+
+ current = attribute(label="Current",
+ dtype=float,
+ display_level=DispLevel.EXPERT,
+ access=AttrWriteType.READ_WRITE,
+ unit="A",
+ format="8.4f",
+ min_value=0.0, max_value=8.5,
+ min_alarm=0.001, max_alarm=8.4,
+ min_warning=0.1, max_warning=8.0,
+ fget="get_current",
+ fset="set_current",
+ doc="the power supply current")
+
+ noise = attribute(label="Noise",
+ dtype=((float,),),
+ max_dim_x=1024, max_dim_y=1024,
+ fget="get_noise")
+
+ host = device_property(dtype=str)
+ port = class_property(dtype=int, default_value=9788)
+
+ def read_voltage(self):
+ self.info_stream("get voltage(%s, %d)" %(self.host, self.port))
+ return 10.0
+
+ def get_current(self):
+ return 2.3456, time(), AttrQuality.ATTR_WARNING
+
+ def set_current(self, value):
+ new_current = self.current.get_write_value()
+ print new_current
+
+ def get_noise(self):
+ import numpy.random
+ return numpy.random.random_sample((1024, 1024))
+
+ @command(din_type=(float,))
+ def go(self, array):
+ self.info_stream("Going..." + str(array))
+
+ @command(din_type=float, din_doc="initial current",
+ dout_type=bool, dout_doc="number of ramps")
+ def ramp(self, value):
+ self.info_stream("Ramping on %f..." % value)
+ return True
+
+ def main():
+ server_run((PowerSupply,))
+
+ if __name__ == "__main__":
+ main()
+
+
+Appendix
+--------
+
Here is the summary of features which this module exposes and are not available
on the low level :mod:`PyTango` server API:
@@ -105,7 +203,7 @@ Here is an example of a PowerSupply device with:
def write_current(self):
new_current = self.current.get_write_value()
- @command()
+ @command
def ramp(self):
self.info_stream("Ramping on " + self.host + "...")
@@ -138,7 +236,7 @@ And here is the equivalent code using the low-level API:
def read_voltage(self, attr):
attr.set_value(10.0)
- def read_current(self):
+ def read_current(self, attr):
attr.set_value_date_quality(2.5, time.time(), PyTango.AttrQuality.ON)
@PyTango.DebugIt()
diff --git a/doc/start.rst b/doc/start.rst
index 9feb492..359b919 100644
--- a/doc/start.rst
+++ b/doc/start.rst
@@ -6,106 +6,54 @@
Getting started
===============
-Quick installation
-------------------
+Quick installation: Linux
+-------------------------
-If you have all :ref:`dependencies <dependencies>` installed on your system,
-building and installing / updating PyTango can be as simple as::
+PyTango is available on linux as an official debian/ubuntu package::
- easy_install -U PyTango
+ $ sudo apt-get install python-pytango
-.. _dependencies:
-
-If you managed to run this line, the :ref:`quick tour <quick-tour>` can guide
-you through the first steps on using PyTango.
-
-Dependencies on other libraries
--------------------------------
-
-.. graphviz::
+RPM packages are also available for RHEL & CentOS:
- digraph dependencies {
- size="6,3";
- PyTango [shape=box, label="PyTango 8.0"];
- Python [shape=box, label="Python >=2.6"];
- boostpython [shape=box, label="boost python"];
- Tango [shape=box, label="Tango >=8.0.5"];
- omniORB [shape=box, label="omniORB >=4"];
- numpy [shape=box, label="numpy >=1.1.0"];
- IPython [shape=box, label="IPython >=0.10"];
- PyTango -> Python;
- PyTango -> Tango;
- PyTango -> numpy [style=dotted, label="mandatory in windows"];
- Tango -> omniORB;
- PyTango -> boostpython
- PyTango -> IPython [style=dotted, label="optional"];
- }
+.. hlist::
+ :columns: 2
-Don't be scared by the graph. Probably most of the packages are already installed.
-The current PyTango version has three major dependencies:
+ * `RHEL 5/CentOS 5 32bits <ftp://ftp.maxlab.lu.se/pub/maxlab/packages/el5/i386/repoview/index.html>`_
+ * `RHEL 5/CentOS 5 64bits <ftp://ftp.maxlab.lu.se/pub/maxlab/packages/el5/x86_64/repoview/index.html>`_
+ * `RHEL 6/CentOS 6 32bits <ftp://ftp.maxlab.lu.se/pub/maxlab/packages/el6/i386/repoview/index.html>`_
+ * `RHEL 6/CentOS 6 64bits <ftp://ftp.maxlab.lu.se/pub/maxlab/packages/el6/x86_64/repoview/index.html>`_
-- python (>= 2.6) (http://www.python.org/)
-- Tango (>= 8.0.5) (http://www.tango-controls.org/)
-- boost python (http://www.boost.org):
- We **strongly** recommend always using boost python >= 1.41
-
-plus two optional dependencies (activated by default) on:
+From PyPi
+~~~~~~~~~
-- IPython (>=0.10) (http://www.ipython.org/) (necessary for :ref:`itango`)
-- numpy (>= 1.1.0) (http://numpy.scipy.org/)
+You can also install the latest version from `PyPi`_.
-.. note::
- For the provided windows binary, numpy is MANDATORY!
+First, make sure you have the following packages already installed (all of them
+are available from the major official distribution repositories):
-Installing precompiled binaries
--------------------------------
+* `boost-python`_ (including boost-python-dev)
+* `numpy`_
+* `IPython`_ (optional, highly recommended)
-Linux
-~~~~~
+Then install PyTango either from through pip::
-PyTango is available on linux as an official debian/ubuntu package (python-pytango).
+ $ pip install PyTango
-RPM packages are also available for RHEL & CentOS:
+or easy_install::
- * `RHEL5/CentOS5 5 32bits <ftp://ftp.maxlab.lu.se/pub/maxlab/packages/el5/i386/repoview/index.html>`_
- * `RHEL5/CentOS5 5 64bits <ftp://ftp.maxlab.lu.se/pub/maxlab/packages/el5/x86_64/repoview/index.html>`_
- * `RHEL6/CentOS6 5 32bits <ftp://ftp.maxlab.lu.se/pub/maxlab/packages/el6/i386/repoview/index.html>`_
- * `RHEL6/CentOS6 5 64bits <ftp://ftp.maxlab.lu.se/pub/maxlab/packages/el6/x86_64/repoview/index.html>`_
+ $ easy_install -U PyTango
-.. _pytango-windows-bin:
+Quick installation: Windows
+---------------------------
-Windows
-~~~~~~~
+First, make sure `Python`_ and `numpy`_ are installed.
PyTango team provides a limited set of binary PyTango distributables for
-Windows XP/Vista/7. The complete list of binaries can be downloaded from
-`PyTango PyPI website <http://pypi.python.org/pypi/PyTango/>`_.
-
-Steps:
-
-* Install `Tango C++ 32 bits <http://ftp.esrf.fr/pub/cs/tango/TangoSetup-8.0.5_win32.exe>`_
-* For `Python 2.6 32 bits <http://www.python.org/ftp/python/2.6.6/python-2.6.6.msi>`_
- * `Numpy for python 2.6 <http://pypi.python.org/packages/2.6/n/numpy/numpy-1.6.2.win32-py2.6.exe>`_
- * `PyTango 8 for python 2.6 <http://pypi.python.org/packages/2.6/P/PyTango/PyTango-8.0.2.win32-py2.6.msi>`_
-* For `Python 2.7 32 bits <http://www.python.org/ftp/python/2.7.3/python-2.7.3.msi>`_
- * `Numpy for python 2.7 <http://pypi.python.org/packages/2.7/n/numpy/numpy-1.6.2.win32-py2.7.exe>`_
- * `PyTango 8 for python 2.7 <http://pypi.python.org/packages/2.7/P/PyTango/PyTango-8.0.2.win32-py2.7.msi>`_
-* For `Python 3.1 32 bits <http://www.python.org/ftp/python/3.1.4/python-3.1.4.msi>`_
- * `Numpy for python 3.1 <http://pypi.python.org/packages/3.1/n/numpy/numpy-1.6.2.win32-py3.1.exe>`_
- * `PyTango 8 for python 3.1 <http://pypi.python.org/packages/3.1/P/PyTango/PyTango-8.0.2.win32-py3.1.msi>`_
-* For `Python 3.2 32 bits <http://www.python.org/ftp/python/3.2.3/python-3.2.3.msi>`_
- * `Numpy for python 3.2 <http://pypi.python.org/packages/3.2/n/numpy/numpy-1.6.2.win32-py3.2.exe>`_
- * `PyTango 8 for python 3.2 <http://pypi.python.org/packages/3.2/P/PyTango/PyTango-8.0.2.win32-py3.2.msi>`_
-
-..
-.. _PyTango-8.0.2.win32-py2.6.msi: http://pypi.python.org/packages/2.6/P/PyTango/PyTango-8.0.2.win32-py2.6.msi
-.. _PyTango-8.0.2.win32-py2.6.exe: http://pypi.python.org/packages/2.6/P/PyTango/PyTango-8.0.2.win32-py2.6.exe
-.. _PyTango-8.0.2.win32-py2.7.msi: http://pypi.python.org/packages/2.7/P/PyTango/PyTango-8.0.2.win32-py2.7.msi
-.. _PyTango-8.0.2.win32-py2.7.exe: http://pypi.python.org/packages/2.7/P/PyTango/PyTango-8.0.2.win32-py2.7.exe
-.. _PyTango-8.0.2.win32-py3.1.msi: http://pypi.python.org/packages/3.1/P/PyTango/PyTango-8.0.2.win32-py3.1.msi
-.. _PyTango-8.0.2.win32-py3.1.exe: http://pypi.python.org/packages/3.1/P/PyTango/PyTango-8.0.2.win32-py3.1.exe
-.. _PyTango-8.0.2.win32-py3.2.msi: http://pypi.python.org/packages/3.2/P/PyTango/PyTango-8.0.2.win32-py3.2.msi
-.. _PyTango-8.0.2.win32-py3.2.exe: http://pypi.python.org/packages/3.2/P/PyTango/PyTango-8.0.2.win32-py3.2.exe
+Windows XP/Vista/7/8. The complete list of binaries can be downloaded from
+`PyPI`_.
+
+Select the proper windows package, download it and finally execute the
+installion wizard.
Compiling & installing
@@ -120,109 +68,35 @@ distutils.
Besides the binaries for the three dependencies mentioned above, you also need
the development files for the respective libraries.
-boost python dependency
-#######################
-
-PyTango has a dependency on the boost python library (>= 1.33). This means that
-the shared library file **libboost-python.so** must be accessible to the
-compilation command.
-
-.. note::
+You can get the latest ``.tar.gz`` from `PyPI`_ or directly
+the latest SVN checkout::
- If you use python >= 2.6.3 you MUST install boost python >= 1.41
+ $ svn co http://svn.code.sf.net/p/tango-cs/code/bindings/PyTango/trunk PyTango
+ $ cd PyTango
+ $ python setup.py build
+ $ sudo python setup.py install
-Most linux distributions today provide a boost python package.
-
-Furthermore, in order to be able to build PyTango, you also need the include
-headers of boost python. They are normaly provided by a package called
-boost_python-dev.
-
-If, for some reason, you need to compile and install boost python, here is a
-quick recipie:
-
- #. Download latest boost tar.gz file and extract it
- #. Download latest bjam (most linux distributions have a bjam package. If
- not, sourceforge provides a binary for many platforms)
- #. build and/or install:
-
- #. Simple build: in the root directory where you extracted boost type:
-
- ``bjam --with-python toolset=gcc variant=release threading=multi link=shared``
-
- this will produce in :file:`bin.v2/libs/python/build/gcc-<gcc_ver>/release/threading-multi` a file called :file:`libboost_python-gcc<gcc_ver>-mt-<boost_ver>.so.<boost_python_ver>`
-
- #. Install (you may need administrator permissions to do so):
-
- ``bjam --with-python toolset=gcc variant=release threading=multi link=shared install``
-
- #. Install in a different directory (<install_dir>):
-
- ``bjam --with-python toolset=gcc variant=release threading=multi link=shared install --prefix=<install_dir>``
-
-
-boost, omniORB and TangoC++ configuration
-#########################################
-
-The second step is to make sure the three/four libraries (omniORB, tango,
-boost python and/or numpy) are accessible to the compilation command. So, for
-example, if you installed:
-
- ``boost python under /home/homer/local``
-
- ``omniORB under /home/homer/local1``
-
- ``tango under /home/homer/local2``
-
- ``numpy under /usr/lib/python2.6/site-packages/numpy``
-
-you must export the three environment variables::
-
- export BOOST_ROOT=/home/homer/local
- export OMNI_ROOT=/home/homer/local1
- export TANGO_ROOT=/home/homer/local2
-
- # in openSUSE 11.1 this is the default base location for the include files
- export NUMPY_ROOT=/usr/lib/python2.6/site-packages/numpy/core
-
-(for numpy this is the default base location for the include files. This is
-distribution dependent. For example, ubuntu places a numpy directory under /usr/include,
-so exporting NUMPY_ROOT is not necessary for this distribution)
-
-For the libraries that were installed in the default system directory (/usr or /usr/local)
-the above lines are not necessary.
-
-.. _build-install:
-
-build & install
-###############
-
-Finally::
-
- python setup.py build
- sudo python setup.py install
-
This will install PyTango in the system python installation directory and, since
version 8.0.0, it will also install :ref:`itango` as an IPython_ extension.
-
-Or if you whish to install in a different directory::
-
- python setup.py build
- python setup.py install --prefix=/home/homer/local --ipython-local
-(This will try to install :ref:`itango` as an IPython profile to the local
-user, since probably there is no permission to write into the IPython_ extension
-directory)
+If whish to install in a different directory, replace the last line with::
+
+ $ # private installation to your user (usually ~/.local/lib/python<X>.<Y>/site-packages
+ $ python setup.py install --user
-Or if you wish to use your own private python distribution::
+ $ # or specific installation directory
+ $ python setup.py install --prefix=/home/homer/local
- /home/homer/bin/python setup.py build
- /home/homer/bin/python setup.py install
+Windows
+~~~~~~~
-For the last case above don't forget that boost python should have also been
-previously compiled with this private python distribution.
+On windows, PyTango must be built using MS VC++.
+Since it is rarely needed and the instructions are so complicated, I have
+choosen to place the how-to in a separate text file. You can find it in the
+source package under :file:`doc/windows_notes.txt`.
-test
-####
+Testing your installation
+-------------------------
If you have IPython_ installed, the best way to test your PyTango installation
is by starting the new PyTango CLI called :ref:`itango` by typing on the command
@@ -237,167 +111,19 @@ then, in ITango type:
ITango [1]: PyTango.Release.version
Result [1]: '8.0.2'
-(if you are wondering, :ref:`itango` automaticaly does ``import PyTango`` for you!)
+(if you are wondering, :ref:`itango` automaticaly does ``import PyTango``
+for you!)
-If you don't have IPython_ installed, to test the installation start a python console
-and type:
+If you don't have IPython_ installed, to test the installation start a
+python console and type:
>>> import PyTango
>>> PyTango.Release.version
'8.0.2'
-Windows
-~~~~~~~
-
-On windows, PyTango must be built using MS VC++.
-
-... which is good fun specially if you only have express edition and multiple python versions to build with!
-
-Pre-requisites
-##############
-
-**Python**
-
-Python must be installed in the following directory structure:
-
- <PythonBaseDir>\\<PlatformName>\\<PythonVersion>
-
-Where:
-
- - <PythonBaseDir> is a directory that can be choosen by the you (ex: C:\\Python)
- - <PlatformName> **must** be either *win32* or *x64*
- - <PythonVersion> **must** be *26*, *27*, *31*, *32*, *33*
-
-Example: Assuming you choose *C:\\Python* as PythonBaseDir, if you want to build
-PyTango for python 2.7 on 64 bits you must install python in:
-
- c:\\python\\x64\\27
-
-**Visual C++**
-
-Python recommends compiling any python libraries using the same compiler
-version. So, depending on the python version(s) you want PyTango to be
-build, you need VC++ 9.0 (2008) or/and VC++ 10.0 (2010).
-
-Here is the table of compilers and corresponding Visual C++ version used by CPython:
-
-+----------------------+--------------+
-| Visual C++ version | Compiler |
-+======================+==============+
-| Visual C++ 4.x | MSC_VER=1000 |
-+----------------------+--------------+
-| Visual C++ 5 | MSC_VER=1100 |
-+----------------------+--------------+
-| Visual C++ 6 | MSC_VER=1200 |
-+----------------------+--------------+
-| Visual C++ .NET | MSC_VER=1300 |
-+----------------------+--------------+
-| Visual C++ .NET 2003 | MSC_VER=1310 |
-+----------------------+--------------+
-| Visual C++ 2005 | MSC_VER=1400 |
-+----------------------+--------------+
-| Visual C++ 2008 | MSC_VER=1500 |
-+----------------------+--------------+
-| Visual C++ 2010 | MSC_VER=1600 |
-+----------------------+--------------+
-| Visual C++ 2011 | MSC_VER=1700 |
-+----------------------+--------------+
-
-+----------+--------------+-----------------------------+
-| version | architecture | VC++ |
-+==========+==============+=============================+
-| 2.6.6 | 32 bits | MSC 1500 (Visual C++ 2008) |
-+----------+--------------+-----------------------------+
-| 2.6.6 | 64 bits | MSC 1500 (Visual C++ 2008) |
-+----------+--------------+-----------------------------+
-| 2.7.3 | 32 bits | MSC 1500 (Visual C++ 2008) |
-+----------+--------------+-----------------------------+
-| 2.7.3 | 64 bits | MSC 1500 (Visual C++ 2008) |
-+----------+--------------+-----------------------------+
-| 3.1.4 | 32 bits | MSC 1500 (Visual C++ 2008) |
-+----------+--------------+-----------------------------+
-| 3.1.4 | 64 bits | MSC 1500 (Visual C++ 2008) |
-+----------+--------------+-----------------------------+
-| 3.2.3 | 32 bits | MSC 1500 (Visual C++ 2008) |
-+----------+--------------+-----------------------------+
-| 3.2.3 | 64 bits | MSC 1500 (Visual C++ 2008) |
-+----------+--------------+-----------------------------+
-| 3.3.0 | 32 bits | MSC 1600 (Visual C++ 2010) |
-+----------+--------------+-----------------------------+
-| 3.3.0 | 64 bits | MSC 1600 (Visual C++ 2010) |
-+----------+--------------+-----------------------------+
-
-**Visual C++ 9.0 (2008) express quick install guide**
-
-1. Download and install VC++ 9.0 (2008) Express Edition
-2. If you need to compile in 64 bits platform
- 2.1. Download and install Windows 7 SDK for .NET Framework 3.5 SP1 [a.k.a. Windows SDK 7.0]
- (**not** Windows SDK 7.1!)
-
- 2.2. The vcvarsall.bat in VC++ 2008 Express looks for the x86_amd64 vcvarsx86_amd64.bat
- in all the wrong places. The easiest way to work around that is to navigate to the
- VC\\bin directory of your VC++ 2008 installation (in my case
- C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\bin). Copy vcvarsx86_amd64.bat,
- and paste into the VC\\bin\\x86_amd64 subdirectory.
-
-**Visual C++ 10.0 (2010) express quick install guide**
-
-1. Download and install VC++ 10.0 (2010) Express Edition
-2. If you need to compile in 64 bits platform follow the instructions
- **in the order they appear** (not doing so may lead to
- `KB2519277 <http://support.microsoft.com/kb/2519277>`_ problem)
-
- 2.1. Visual Studio 2010 SP1
-
- 2.2. Download and install Windows 7 SDK for .NET Framework 4.0 [a.k.a. Windows SDK 7.1]
-
- 2.3. VC++ 2010 doesn't come with vcvarsx86_amd64.bat. But in this case, since the
- environment setting tool is different than in VC++ 2008, all you have to do is
- create a file called vcvarsx86_amd64.bat in VC\\bin\\x86_amd64 directory of your
- VC++ 2010 installation (in my case
- C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\bin\\x86_amd64) with the
- following content:
-
- @CALL "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Bin\\SetEnv.Cmd" /Release /x64
-
- (adapt to your Windows SDK installation directory)
-
-**Boost python**
-
-Boost python DLL, lib and header files must be installed for the specific platform(s)
-and python version(s) you which to build PyTango on. The directory structure for
-the boost headers:
-
- <BoostDir>\\include
-
-The directory structure for the boost libraries:
-
- <BoostDir>\\multi\\release\\<MSVCVersion>\\<PlatformName>\\<Link>\\<RuntimeLink>\\<PythonVersion>
-
-Where:
-
- - <BoostDir> the boost base directory (ex: C:\Boost-1.53.0)
- - <MSVCVersion> may be either *msvc-9.0* or *msvc-10.0*
- - <PlatformName> **must** be either *win32* or *x64*
- - <Link> **must** be either *static* or *shared*
- - <RuntimeLink> **must** be either *static* or *shared*
- (if Link==static, RuntimeLink can only be *static*)
- - <PythonVersion> **must** be *26*, *27*, *31*, *32*, *33*
-
-**Boost python multi platform compilation quick build guide**
-
- - Download boost source code from http://wwww.boost.org
- - Extract boost to a directory (ex: c:\\workspace\\boost-1.53.0)
- - Download and place `boost_python_install.py <>` in your boost extract directory (ex: c:\\workspace\\boost-1.53.0\\boost_python_install.py)
- (adapt python versions you which to build)
- - Place the user-config.jam file in %HOMEPATH%%HOMEDIR% (adapt paths and python versions to your system)
- - Open a console
- - Switch to the boost directory
- - Execute this script using python (ex: C:\\Python\\win32\\26\\python.exe boost_python_install.py)
-
-**Tango**
-
-
-
-.. _IPython: http://ipython.scipy.org/
+.. _Python: http://python.org/
+.. _IPython: http://ipython.org/
+.. _numpy: http://www.numpy.org/
+.. _boost-python: http://www.boost.org/libs/python/
+.. _PyPi: https://pypi.python.org/pypi/PyTango/
diff --git a/doc/utilities.rst b/doc/utilities.rst
index 5412ca9..27caf33 100644
--- a/doc/utilities.rst
+++ b/doc/utilities.rst
@@ -5,17 +5,12 @@ The Utilities API
.. autofunction:: PyTango.server_run
-
.. currentmodule:: PyTango.utils
.. autoclass:: PyTango.utils.EventCallBack
:members:
:undoc-members:
-.. autofunction:: PyTango.utils.get_green_mode
-
-.. autofunction:: PyTango.utils.set_green_mode
-
.. autofunction:: PyTango.utils.is_scalar_type
.. autofunction:: PyTango.utils.is_array_type
diff --git a/doc/windows_notes.txt b/doc/windows_notes.txt
new file mode 100644
index 0000000..8df6a95
--- /dev/null
+++ b/doc/windows_notes.txt
@@ -0,0 +1,156 @@
+Windows
+~~~~~~~
+
+On windows, PyTango must be built using MS VC++.
+
+... which is good fun specially if you only have express edition and multiple python versions to build with!
+
+.. warning::
+ The next chapters are internal notes I have gathered along the years to
+ overcome windows limitations/problems in order to be able to compile PyTango.
+ They are not for the weak of heart, seriously!
+
+Pre-requisites
+##############
+
+**Python**
+
+Python must be installed in the following directory structure:
+
+ <PythonBaseDir>\\<PlatformName>\\<PythonVersion>
+
+Where:
+
+ - <PythonBaseDir> is a python base directory choosen by you (ex: :file:`C:\\Python`)
+ - <PlatformName> **must** be either *win32* or *x64*
+ - <PythonVersion> **must** be *26*, *27*, *31*, *32*, *33*
+
+Example: Assuming you choose *C:\\Python* as PythonBaseDir, if you want to build
+PyTango for python 2.7 on 64 bits you must install python in
+:file:`C:\\python\\x64\\27`.
+
+**Visual C++**
+
+Python recommends compiling any python libraries using the same compiler
+version. So, depending on the python version(s) you want PyTango to be
+build, you need VC++ 9.0 (2008) or/and VC++ 10.0 (2010).
+
+Here is the table of compilers and corresponding Visual C++ version used by CPython:
+
++----------------------+--------------+
+| Visual C++ version | Compiler |
++======================+==============+
+| Visual C++ 4.x | MSC_VER=1000 |
++----------------------+--------------+
+| Visual C++ 5 | MSC_VER=1100 |
++----------------------+--------------+
+| Visual C++ 6 | MSC_VER=1200 |
++----------------------+--------------+
+| Visual C++ .NET | MSC_VER=1300 |
++----------------------+--------------+
+| Visual C++ .NET 2003 | MSC_VER=1310 |
++----------------------+--------------+
+| Visual C++ 2005 | MSC_VER=1400 |
++----------------------+--------------+
+| Visual C++ 2008 | MSC_VER=1500 |
++----------------------+--------------+
+| Visual C++ 2010 | MSC_VER=1600 |
++----------------------+--------------+
+| Visual C++ 2011 | MSC_VER=1700 |
++----------------------+--------------+
+
++----------+--------------+-----------------------------+
+| version | architecture | VC++ |
++==========+==============+=============================+
+| 2.6.6 | 32 bits | MSC 1500 (Visual C++ 2008) |
++----------+--------------+-----------------------------+
+| 2.6.6 | 64 bits | MSC 1500 (Visual C++ 2008) |
++----------+--------------+-----------------------------+
+| 2.7.3 | 32 bits | MSC 1500 (Visual C++ 2008) |
++----------+--------------+-----------------------------+
+| 2.7.3 | 64 bits | MSC 1500 (Visual C++ 2008) |
++----------+--------------+-----------------------------+
+| 3.1.4 | 32 bits | MSC 1500 (Visual C++ 2008) |
++----------+--------------+-----------------------------+
+| 3.1.4 | 64 bits | MSC 1500 (Visual C++ 2008) |
++----------+--------------+-----------------------------+
+| 3.2.3 | 32 bits | MSC 1500 (Visual C++ 2008) |
++----------+--------------+-----------------------------+
+| 3.2.3 | 64 bits | MSC 1500 (Visual C++ 2008) |
++----------+--------------+-----------------------------+
+| 3.3.0 | 32 bits | MSC 1600 (Visual C++ 2010) |
++----------+--------------+-----------------------------+
+| 3.3.0 | 64 bits | MSC 1600 (Visual C++ 2010) |
++----------+--------------+-----------------------------+
+
+**Visual C++ 9.0 (2008) express quick install guide**
+
+1. Download and install VC++ 9.0 (2008) Express Edition
+2. If you need to compile in 64 bits platform
+ 2.1. Download and install Windows 7 SDK for .NET Framework 3.5 SP1 [a.k.a. Windows SDK 7.0]
+ (**not** Windows SDK 7.1!)
+
+ 2.2. The vcvarsall.bat in VC++ 2008 Express looks for the x86_amd64 :file:`vcvarsx86_amd64.bat`
+ in all the wrong places. The easiest way to work around that is to navigate to the
+ :file:`VC\\bin` directory of your VC++ 2008 installation (in my case
+ :file:`C:\\Program Files (x86)\\Microsoft Visual Studio 9.0\\VC\\bin`). Copy :file:`vcvarsx86_amd64.bat`,
+ and paste into the :file:`VC\\bin\\x86_amd64 subdirectory`.
+
+**Visual C++ 10.0 (2010) express quick install guide**
+
+1. Download and install VC++ 10.0 (2010) Express Edition
+2. If you need to compile in 64 bits platform follow the instructions
+ **in the order they appear** (not doing so may lead to
+ `KB2519277 <http://support.microsoft.com/kb/2519277>`_ problem)
+
+ 2.1. Visual Studio 2010 SP1
+
+ 2.2. Download and install Windows 7 SDK for .NET Framework 4.0 [a.k.a. Windows SDK 7.1]
+
+ 2.3. VC++ 2010 doesn't come with vcvarsx86_amd64.bat. But in this case, since the
+ environment setting tool is different than in VC++ 2008, all you have to do is
+ create a file called vcvarsx86_amd64.bat in VC\\bin\\x86_amd64 directory of your
+ VC++ 2010 installation (in my case
+ C:\\Program Files (x86)\\Microsoft Visual Studio 10.0\\VC\\bin\\x86_amd64) with the
+ following content:
+
+ @CALL "C:\\Program Files\\Microsoft SDKs\\Windows\\v7.1\\Bin\\SetEnv.Cmd" /Release /x64
+
+ (adapt to your Windows SDK installation directory)
+
+**Boost python**
+
+Boost python DLL, lib and header files must be installed for the specific platform(s)
+and python version(s) you which to build PyTango on. The directory structure for
+the boost headers:
+
+ <BoostDir>\\include
+
+The directory structure for the boost libraries:
+
+ <BoostDir>\\multi\\release\\<MSVCVersion>\\<PlatformName>\\<Link>\\<RuntimeLink>\\<PythonVersion>
+
+Where:
+
+ - <BoostDir> the boost base directory (ex: C:\Boost-1.53.0)
+ - <MSVCVersion> may be either *msvc-9.0* or *msvc-10.0*
+ - <PlatformName> **must** be either *win32* or *x64*
+ - <Link> **must** be either *static* or *shared*
+ - <RuntimeLink> **must** be either *static* or *shared*
+ (if Link==static, RuntimeLink can only be *static*)
+ - <PythonVersion> **must** be *26*, *27*, *31*, *32*, *33*
+
+**Boost python multi platform compilation quick build guide**
+
+ - Download boost source code from http://wwww.boost.org
+ - Extract boost to a directory (ex: c:\\workspace\\boost-1.53.0)
+ - Download and place `boost_python_install.py <>` in your boost extract directory (ex: c:\\workspace\\boost-1.53.0\\boost_python_install.py)
+ (adapt python versions you which to build)
+ - Place the user-config.jam file in %HOMEPATH%%HOMEDIR% (adapt paths and python versions to your system)
+ - Open a console
+ - Switch to the boost directory
+ - Execute this script using python (ex: C:\\Python\\win32\\26\\python.exe boost_python_install.py)
+
+**Tango**
+
+TODO
diff --git a/setup.py b/setup.py
index fe904cb..0e3ecda 100644
--- a/setup.py
+++ b/setup.py
@@ -383,6 +383,7 @@ def main():
'PyTango.ipython',
'PyTango.ipython.ipython_00_10',
'PyTango.ipython.ipython_00_11',
+ 'PyTango.ipython.ipython_10_00',
]
py_modules = []
diff --git a/src/boost/python/__init__.py b/src/boost/python/__init__.py
index a050873..01a8088 100644
--- a/src/boost/python/__init__.py
+++ b/src/boost/python/__init__.py
@@ -174,7 +174,7 @@ from .globals import get_class, get_classes, get_cpp_class, get_cpp_classes, \
from .utils import is_scalar_type, is_array_type, is_numerical_type, \
is_int_type, is_float_type, obj_2_str, seqStr_2_obj
from .utils import server_run
-from .utils import set_green_mode, get_green_mode
+from .tango_green import set_green_mode, get_green_mode
from .device_proxy import get_device_proxy
from .tango_numpy import NumpyType, numpy_type, numpy_spectrum, numpy_image
diff --git a/src/boost/python/attr_data.py b/src/boost/python/attr_data.py
index 6dd7ed8..c75c6d6 100644
--- a/src/boost/python/attr_data.py
+++ b/src/boost/python/attr_data.py
@@ -22,8 +22,9 @@ __docformat__ = "restructuredtext"
import inspect
-from ._PyTango import Except, CmdArgType, AttrDataFormat, AttrWriteType, \
- DispLevel, UserDefaultAttrProp, Attr, SpectrumAttr, ImageAttr
+from ._PyTango import Except, CmdArgType, AttrDataFormat, AttrWriteType
+from ._PyTango import DispLevel, UserDefaultAttrProp
+from ._PyTango import Attr, SpectrumAttr, ImageAttr
from .utils import is_non_str_seq, is_pure_str
@@ -63,6 +64,10 @@ class AttrData(object):
name = attr_dict.pop('name', None)
class_name = attr_dict.pop('class_name', None)
self = cls(name, class_name)
+ self.build_from_dict(attr_dict)
+ return self
+
+ def build_from_dict(self, attr_dict):
self.attr_type = attr_dict.pop('dtype', CmdArgType.DevDouble)
self.attr_format = attr_dict.pop('dformat', AttrDataFormat.SCALAR)
self.dim_x = attr_dict.pop('max_dim_x', 1)
@@ -77,7 +82,8 @@ class AttrData(object):
self.attr_write = attr_dict.pop('access')
else:
# access is defined by which methods were defined
- r_explicit, w_explicit = "fread" in attr_dict, "fwrite" in attr_dict
+ r_explicit = "fread" in attr_dict or "fget" in attr_dict
+ w_explicit = "fwrite" in attr_dict or "fset" in attr_dict
if r_explicit and w_explicit:
self.attr_write = AttrWriteType.READ_WRITE
elif r_explicit:
@@ -87,13 +93,13 @@ class AttrData(object):
else:
self.attr_write = AttrWriteType.READ
- fread = attr_dict.pop('fread', None)
+ fread = attr_dict.pop('fget', attr_dict.pop('fread', None))
if fread is not None:
if is_pure_str(fread):
self.read_method_name = fread
elif inspect.isroutine(fread):
self.read_method_name = fread.__name__
- fwrite = attr_dict.pop('fwrite', None)
+ fwrite = attr_dict.pop('fset', attr_dict.pop('fwrite', None))
if fwrite is not None:
if is_pure_str(fwrite):
self.write_method_name = fwrite
@@ -112,7 +118,7 @@ class AttrData(object):
if not self.attr_format == AttrDataFormat.SPECTRUM:
self.attr_args.append(self.dim_y)
if len(attr_dict):
- self.att_prop = self.__create_user_default_attr_prop(self.attr_name, attr_dict)
+ self.att_prop = self.__create_user_default_attr_prop(attr_dict)
return self
def _set_name(self, name):
@@ -130,9 +136,14 @@ class AttrData(object):
def __throw_exception(self, msg, meth="create_attribute()"):
Except.throw_exception("PyDs_WrongAttributeDefinition", msg, meth)
- def __create_user_default_attr_prop(self, attr_name, extra_info):
+ def __create_user_default_attr_prop(self, extra_info):
"""for internal usage only"""
p = UserDefaultAttrProp()
+
+ doc = extra_info.pop('doc', None)
+ if 'doc' is not None:
+ extra_info['description'] = doc
+
for k, v in extra_info.items():
k_lower = k.lower()
method_name = "set_%s" % k_lower.replace(' ','_')
@@ -237,7 +248,7 @@ class AttrData(object):
self.dim_y = int(attr_info[4])
except:
throw_ex("Wrong data type in attribute argument for attribute "
- "%s in class %s\n5th element in sequence describing "
+ "%s in class %s\n5th element in sequence desribing "
"mandatory dim_y attribute parameter for image "
"attribute must be an integer" % (attr_name, name))
@@ -282,7 +293,7 @@ class AttrData(object):
att_prop = None
if extra_info:
- att_prop = self.__create_user_default_attr_prop(attr_name, extra_info)
+ att_prop = self.__create_user_default_attr_prop(extra_info)
self.att_prop = att_prop
def to_attr(self):
diff --git a/src/boost/python/attribute_proxy.py b/src/boost/python/attribute_proxy.py
index 89f9bed..f3d568e 100644
--- a/src/boost/python/attribute_proxy.py
+++ b/src/boost/python/attribute_proxy.py
@@ -25,9 +25,9 @@ import collections
from ._PyTango import StdStringVector, DbData, DbDatum, DeviceProxy
from ._PyTango import __AttributeProxy as _AttributeProxy
-from .utils import seq_2_StdStringVector, seq_2_DbData, DbData_2_dict, \
- is_pure_str, is_non_str_seq, get_green_mode
-from .tango_green import result, submit, green
+from .utils import seq_2_StdStringVector, seq_2_DbData, DbData_2_dict
+from .utils import is_pure_str, is_non_str_seq
+from .tango_green import result, submit, get_green_mode
def get_attribute_proxy(*args, **kwargs):
@@ -52,8 +52,8 @@ def get_attribute_proxy(*args, **kwargs):
:type attr_name: str
:param green_mode: determines the mode of execution of the device (including
the way it is created). Defaults to the current global
- green_mode (check :func:`~PyTango.utils.get_green_mode` and
- :func:`~PyTango.utils.set_green_mode`)
+ green_mode (check :func:`~PyTango.get_green_mode` and
+ :func:`~PyTango.set_green_mode`)
:type green_mode: :obj:`~PyTango.GreenMode`
:param wait: whether or not to wait for result. If green_mode
Ignored when green_mode is Synchronous (always waits).
diff --git a/src/boost/python/device_proxy.py b/src/boost/python/device_proxy.py
index ef03865..298112e 100644
--- a/src/boost/python/device_proxy.py
+++ b/src/boost/python/device_proxy.py
@@ -19,23 +19,19 @@ __all__ = ["device_proxy_init", "get_device_proxy"]
__docformat__ = "restructuredtext"
-
-import collections
-import numbers
import threading
+import collections
from ._PyTango import StdStringVector, DbData, DbDatum, AttributeInfo, \
AttributeInfoEx, AttributeInfoList, AttributeInfoListEx, DeviceProxy, \
__CallBackAutoDie, __CallBackPushEvent, EventType, DevFailed, Except, \
ExtractAs, GreenMode
-from .utils import is_pure_str, is_non_str_seq, is_integer, \
- seq_2_StdStringVector, StdStringVector_2_seq, seq_2_DbData, DbData_2_dict
-
+from .utils import is_pure_str, is_non_str_seq, is_integer
+from .utils import seq_2_StdStringVector, StdStringVector_2_seq
+from .utils import seq_2_DbData, DbData_2_dict
from .utils import document_method as __document_method
-from .utils import get_green_mode
-
-from .tango_green import result, submit, green
+from .tango_green import result, submit, green, get_green_mode
def get_device_proxy(*args, **kwargs):
@@ -64,8 +60,8 @@ def get_device_proxy(*args, **kwargs):
:type need_check_acc: bool
:param green_mode: determines the mode of execution of the device (including
the way it is created). Defaults to the current global
- green_mode (check :func:`~PyTango.utils.get_green_mode` and
- :func:`~PyTango.utils.set_green_mode`)
+ green_mode (check :func:`~PyTango.get_green_mode` and
+ :func:`~PyTango.set_green_mode`)
:type green_mode: :obj:`~PyTango.GreenMode`
:param wait: whether or not to wait for result. If green_mode
Ignored when green_mode is Synchronous (always waits).
@@ -136,8 +132,8 @@ def __DeviceProxy__get_green_mode(self):
:rtype: GreenMode
.. seealso::
- :func:`PyTango.utils.get_green_mode`
- :func:`PyTango.utils.set_green_mode`
+ :func:`PyTango.get_green_mode`
+ :func:`PyTango.set_green_mode`
New in PyTango 8.1.0
"""
@@ -149,7 +145,7 @@ def __DeviceProxy__get_green_mode(self):
def __DeviceProxy__set_green_mode(self, green_mode=None):
"""Sets the green mode to be used by this DeviceProxy
Setting it to None means use the global PyTango green mode
- (see :func:`PyTango.utils.get_green_mode`).
+ (see :func:`PyTango.get_green_mode`).
:param green_mode: the new green mode
:type green_mode: GreenMode
@@ -1119,8 +1115,8 @@ def __doc_DeviceProxy():
:type need_check_acc: bool
:param green_mode: determines the mode of execution of the device (including.
the way it is created). Defaults to the current global
- green_mode (check :func:`~PyTango.utils.get_green_mode` and
- :func:`~PyTango.utils.set_green_mode`)
+ green_mode (check :func:`~PyTango.get_green_mode` and
+ :func:`~PyTango.set_green_mode`)
:type green_mode: :obj:`~PyTango.GreenMode`
:param wait: whether or not to wait for result. If green_mode
Ignored when green_mode is Synchronous (always waits).
diff --git a/src/boost/python/hlapi.py b/src/boost/python/hlapi.py
index 7890d42..1fb02e9 100644
--- a/src/boost/python/hlapi.py
+++ b/src/boost/python/hlapi.py
@@ -9,7 +9,142 @@
# See LICENSE.txt for more info.
# ------------------------------------------------------------------------------
-"""High Level API for writting Tango device servers."""
+"""High Level API for writting Tango device servers.
+
+.. _pytango-hlapi-datatypes:
+
+.. rubric:: Data types
+
+When declaring attributes, properties or commands, one of the most important
+information is the data type. It is given by the keyword argument *dtype*.
+This argument is not retricted to the :obj:`~PyTango.CmdArgType` options.
+
+For example, to define a *SCALAR* :obj:`~PyTango.CmdArgType.DevLong`
+attribute you have several possibilities:
+
+#. :obj:`int`
+#. 'int'
+#. 'int32'
+#. 'integer'
+#. :obj:`PyTango.CmdArgType.DevLong`
+#. 'DevLong'
+#. :obj:`numpy.int32`
+
+To define a *SPECTRUM* attribute simply wrap the scalar data type in any
+python sequence:
+
+* (:obj:`int`,)
+* [:obj:`int`]
+
+To define an *IMAGE* attribute simply wrap the scalar data type in any
+python sequence of sequences:
+
+* ((:obj:`int`,),)
+* [[:obj:`int`]]
+
+Below is the complete table of equivalences.
+
+======================================== ========================================
+ type tango type
+======================================== ========================================
+ ``None`` ``DevVoid``
+ ``DevVoid`` ``DevVoid``
+ ``DevBoolean`` ``DevBoolean``
+ ``DevShort`` ``DevShort``
+ ``DevLong`` ``DevLong``
+ ``DevFloat`` ``DevFloat``
+ ``DevDouble`` ``DevDouble``
+ ``DevUShort`` ``DevUShort``
+ ``DevULong`` ``DevULong``
+ ``DevString`` ``DevString``
+ ``DevVarCharArray`` ``DevVarCharArray``
+ ``DevVarShortArray`` ``DevVarShortArray``
+ ``DevVarLongArray`` ``DevVarLongArray``
+ ``DevVarFloatArray`` ``DevVarFloatArray``
+ ``DevVarDoubleArray`` ``DevVarDoubleArray``
+ ``DevVarUShortArray`` ``DevVarUShortArray``
+ ``DevVarULongArray`` ``DevVarULongArray``
+ ``DevVarStringArray`` ``DevVarStringArray``
+ ``DevVarLongStringArray`` ``DevVarLongStringArray``
+ ``DevVarDoubleStringArray`` ``DevVarDoubleStringArray``
+ ``DevState`` ``DevState``
+ ``DevVarBooleanArray`` ``DevVarBooleanArray``
+ ``DevUChar`` ``DevUChar``
+ ``DevLong64`` ``DevLong64``
+ ``DevULong64`` ``DevULong64``
+ ``DevVarLong64Array`` ``DevVarLong64Array``
+ ``DevVarULong64Array`` ``DevVarULong64Array``
+ ``DevInt`` ``DevInt``
+ ``DevEncoded`` ``DevEncoded``
+ ``chr`` ``DevUChar``
+ ``'DevBoolean'`` ``DevBoolean``
+ ``'DevDouble'`` ``DevDouble``
+ ``'DevEncoded'`` ``DevEncoded``
+ ``'DevFloat'`` ``DevFloat``
+ ``'DevInt'`` ``DevInt``
+ ``'DevLong'`` ``DevLong``
+ ``'DevLong64'`` ``DevLong64``
+ ``'DevShort'`` ``DevShort``
+ ``'DevState'`` ``DevState``
+ ``'DevString'`` ``DevString``
+ ``'DevUChar'`` ``DevUChar``
+ ``'DevULong'`` ``DevULong``
+ ``'DevULong64'`` ``DevULong64``
+ ``'DevUShort'`` ``DevUShort``
+ ``'DevVarBooleanArray'`` ``DevVarBooleanArray``
+ ``'DevVarCharArray'`` ``DevVarCharArray``
+ ``'DevVarDoubleArray'`` ``DevVarDoubleArray``
+ ``'DevVarDoubleStringArray'`` ``DevVarDoubleStringArray``
+ ``'DevVarFloatArray'`` ``DevVarFloatArray``
+ ``'DevVarLong64Array'`` ``DevVarLong64Array``
+ ``'DevVarLongArray'`` ``DevVarLongArray``
+ ``'DevVarLongStringArray'`` ``DevVarLongStringArray``
+ ``'DevVarShortArray'`` ``DevVarShortArray``
+ ``'DevVarStringArray'`` ``DevVarStringArray``
+ ``'DevVarULong64Array'`` ``DevVarULong64Array``
+ ``'DevVarULongArray'`` ``DevVarULongArray``
+ ``'DevVarUShortArray'`` ``DevVarUShortArray``
+ ``'DevVoid'`` ``DevVoid``
+ ``'None'`` ``DevVoid``
+ ``'bool'`` ``DevBoolean``
+ ``'boolean'`` ``DevBoolean``
+ ``'byte'`` ``DevUChar``
+ ``'bytearray'`` ``DevEncoded``
+ ``'bytes'`` ``DevEncoded``
+ ``'char'`` ``DevUChar``
+ ``'chr'`` ``DevUChar``
+ ``'double'`` ``DevDouble``
+ ``'float'`` ``DevDouble``
+ ``'float32'`` ``DevFloat``
+ ``'float64'`` ``DevDouble``
+ ``'int'`` ``DevLong``
+ ``'int16'`` ``DevShort``
+ ``'int32'`` ``DevLong``
+ ``'int64'`` ``DevLong64``
+ ``'str'`` ``DevString``
+ ``'string'`` ``DevString``
+ ``'text'`` ``DevString``
+ ``'uint'`` ``DevULong``
+ ``'uint16'`` ``DevUShort``
+ ``'uint32'`` ``DevULong``
+ ``'uint64'`` ``DevULong64``
+ :py:obj:`float` ``DevDouble``
+ :py:obj:`int` ``DevLong``
+ :py:obj:`str` ``DevString``
+ :py:obj:`bool` ``DevBoolean``
+ :py:obj:`bytearray` ``DevEncoded``
+ :py:obj:`numpy.bool_` ``DevBoolean``
+ :py:obj:`numpy.int16` ``DevShort``
+ :py:obj:`numpy.int32` ``DevLong``
+ :py:obj:`numpy.int64` ``DevLong64``
+ :py:obj:`numpy.uint8` ``DevUChar``
+ :py:obj:`numpy.uint16` ``DevUShort``
+ :py:obj:`numpy.uint32` ``DevULong``
+ :py:obj:`numpy.uint64` ``DevULong64``
+ :py:obj:`numpy.float32` ``DevFloat``
+ :py:obj:`numpy.float64` ``DevDouble``
+======================================== ========================================
+"""
from __future__ import with_statement
from __future__ import print_function
@@ -17,15 +152,16 @@ from __future__ import print_function
__all__ = ["DeviceMeta", "Device", "LatestDeviceImpl", "attribute", "command",
"device_property", "class_property"]
-import functools
import __builtin__
+import inspect
+import functools
-from ._PyTango import DeviceImpl, Attribute, WAttribute, CmdArgType, \
- AttrDataFormat, AttrWriteType, DispLevel, constants
+from ._PyTango import DeviceImpl, Attribute, WAttribute, CmdArgType
+from ._PyTango import AttrDataFormat, AttrWriteType, DispLevel, constants
from .attr_data import AttrData
from .device_class import DeviceClass
-from .utils import get_tango_device_classes, is_non_str_seq, is_pure_str
-from .log4tango import DebugIt
+from .utils import get_tango_device_classes, is_seq, is_non_str_seq
+from .utils import scalar_to_array_type
API_VERSION = 2
@@ -90,38 +226,31 @@ def __build_to_tango_type():
for key,value in FROM_TANGO_TO_NUMPY_TYPE.items():
ret[value] = key
+ return ret
- head = "{0:40} {0:40}\n".format(40*"=")
- doc = "{0} {1:38} {2:38} \n{0}".format(head,'type','tango type')
- keys = sorted(ret)
- for key in keys:
- value = ret[key]
- if type(key) == type:
- key_name = key.__name__
- if key_name in __builtin__.__dict__:
- key = ":py:obj:`{0}`".format(key_name)
- elif key.__module__ == 'numpy':
- key = ":py:obj:`numpy.{0}`".format(key_name)
- else:
- key = "``{0}``".format(key_name)
- elif is_pure_str(key):
- key = "``'{0}'``".format(key)
- else:
- key = "``{0}``".format(key)
- value = "``{0}``".format(value)
- doc += " {0:38} {1:38} \n".format(key, str(value))
- doc += head
- return ret, doc
-
-TO_TANGO_TYPE, __type_doc = __build_to_tango_type()
+TO_TANGO_TYPE = __build_to_tango_type()
+def get_tango_type_format(dtype=None, dformat=None):
+ if dformat is None:
+ dformat = AttrDataFormat.SCALAR
+ if is_non_str_seq(dtype):
+ dtype = dtype[0]
+ dformat = AttrDataFormat.SPECTRUM
+ if is_non_str_seq(dtype):
+ dtype = dtype[0]
+ dformat = AttrDataFormat.IMAGE
+ return TO_TANGO_TYPE[dtype], dformat
-def get_tango_type(dtype):
- return TO_TANGO_TYPE[dtype]
-get_tango_type.__doc__ = __type_doc
+def from_typeformat_to_type(dtype, dformat):
+ if dformat == AttrDataFormat.SCALAR:
+ return dtype
+ elif dformat == AttrDataFormat.IMAGE:
+ raise TypeError("Cannot translate IMAGE to tango type")
+ return scalar_to_array_type(dtype)
+
def set_complex_value(attr, value):
is_tuple = isinstance(value, tuple)
dtype, fmt = attr.get_data_type(), attr.get_data_format()
@@ -182,7 +311,7 @@ def check_tango_device_klass_attribute_write_method(tango_device_klass, method_n
:type tango_device_klass: class
:param method_name: method to be cheched
:type attr_data: str"""
- write_method = real_f_obj = getattr(tango_device_klass, method_name)
+ write_method = getattr(tango_device_klass, method_name)
@functools.wraps(write_method)
def write_attr(self, attr):
@@ -207,21 +336,31 @@ def check_tango_device_klass_attribute_methods(tango_device_klass, attr_data):
def create_tango_deviceclass_klass(tango_device_klass, attrs=None):
klass_name = tango_device_klass.__name__
if not issubclass(tango_device_klass, (Device)):
- raise Exception("{0} device must inherit from PyTango.hlapi.Device".format(klass_name))
+ msg = "{0} device must inherit from PyTango.hlapi.Device".format(klass_name)
+ raise Exception(msg)
if attrs is None:
attrs = tango_device_klass.__dict__
attr_list = {}
+ class_property_list = {}
+ device_property_list = {}
+ cmd_list = {}
+
for attr_name, attr_obj in attrs.items():
- if isinstance(attr_obj, AttrData2):
+ if isinstance(attr_obj, attribute):
attr_obj._set_name(attr_name)
attr_list[attr_name] = attr_obj
check_tango_device_klass_attribute_methods(tango_device_klass, attr_obj)
+ elif isinstance(attr_obj, device_property):
+ device_property_list[attr_name] = [attr_obj.dtype, attr_obj.doc, attr_obj.default_value]
+ elif isinstance(attr_obj, class_property):
+ class_property_list[attr_name] = [attr_obj.dtype, attr_obj.doc, attr_obj.default_value]
+ elif inspect.isroutine(attr_obj):
+ if hasattr(attr_obj, "__tango_command__"):
+ cmd_name, cmd_info = attr_obj.__tango_command__
+ cmd_list[cmd_name] = cmd_info
- class_property_list = {}
- device_property_list = {}
- cmd_list = {}
devclass_name = klass_name + "Class"
def device_class_constructor(self, name):
@@ -293,12 +432,75 @@ class Device(LatestDeviceImpl):
pass
-class AttrData2(AttrData):
- """High level AttrData. To be used """
-
+class attribute(AttrData):
+ """declares a new tango attribute in a :class:`Device`. To be used like
+the python native :obj:`property` function. For example, to declare a
+scalar, `PyTango.DevDouble`, read-only attribute called *voltage* in a
+*PowerSupply* :class:`Device` do::
+
+ class PowerSupply(Device):
+
+ voltage = attribute()
+
+ def read_voltage(self):
+ self.voltage = 1.0
+
+It receives multiple keyword arguments.
+
+===================== ================================ ======================================= =======================================================================================
+parameter type default value description
+===================== ================================ ======================================= =======================================================================================
+name :obj:`str` class member name alternative attribute name
+dtype :obj:`object` :obj:`~PyTango.CmdArgType.DevDouble` data type (see :ref:`Data type equivalence <pytango-hlapi-datatypes>`)
+dformat :obj:`~PyTango.AttrDataFormat` :obj:`~PyTango.AttrDataFormat.SCALAR` data format
+max_dim_x :obj:`int` 1 maximum size for x dimension (ignored for SCALAR format)
+max_dim_y :obj:`int` 0 maximum size for y dimension (ignored for SCALAR and SPECTRUM formats)
+display_level :obj:`~PyTango.DispLevel` :obj:`~PyTango.DisLevel.OPERATOR` display level
+polling_period :obj:`int` -1 polling period
+memorized :obj:`bool` False attribute should or not be memorized
+hw_memorized :obj:`bool` False write method should be called at startup when restoring memorize value (dangerous!)
+access :obj:`~PyTango.AttrWriteType` :obj:`~PyTango.AttrWriteType.READ` read only/ read write / write only access
+fget (or fread) :obj:`str` or :obj:`callable` 'read_<attr_name>' read method name or method object
+fset (or fwrite) :obj:`str` or :obj:`callable` 'write_<attr_name>' write method name or method object
+is_allowed :obj:`str` or :obj:`callable` 'is_<attr_name>_allowed' is allowed method name or method object
+label :obj:`str` '<attr_name>' attribute label
+doc (or description) :obj:`str` '' attribute description
+unit :obj:`str` '' physical units the attribute value is in
+standard_unit :obj:`str` '' physical standard unit
+display_unit :obj:`str` '' physical display unit (hint for clients)
+format :obj:`str` '6.2f' attribute representation format
+min_value :obj:`str` None minimum allowed value
+max_value :obj:`str` None maximum allowed value
+min_alarm :obj:`str` None minimum value to trigger attribute alarm
+max_alarm :obj:`str` None maximum value to trigger attribute alarm
+min_warning :obj:`str` None minimum value to trigger attribute warning
+max_warning :obj:`str` None maximum value to trigger attribute warning
+delta_val :obj:`str` None
+delta_t :obj:`str` None
+abs_change :obj:`str` None minimum value change between events that causes event filter to send the event
+rel_change :obj:`str` None minimum relative change between events that causes event filter to send the event (%)
+period :obj:`str` None
+archive_abs_change :obj:`str` None
+archive_rel_change :obj:`str` None
+archive_period :obj:`str` None
+===================== ================================ ======================================= ======================================================================================="""
+
+ def __init__(self, **kwargs):
+ name = kwargs.pop("name", None)
+ class_name = kwargs.pop("class_name", None)
+ super(attribute, self).__init__(name, class_name)
+ if 'dtype' in kwargs:
+ kwargs['dtype'], kwargs['dformat'] = \
+ get_tango_type_format(kwargs['dtype'], kwargs.get('dformat'))
+ self.build_from_dict(kwargs)
+
def get_attribute(self, obj):
return obj.get_device_attr().get_attr_by_name(self.attr_name)
-
+
+ # --------------------
+ # descriptor interface
+ # --------------------
+
def __get__(self, obj, objtype):
return self.get_attribute(obj)
@@ -308,12 +510,13 @@ class AttrData2(AttrData):
def __delete__(self, obj):
obj.remove_attribute(self.attr_name)
-
-def attribute(**kwargs):
- """declares a new tango attribute in a :class:`Device`. To be used like the python
-native :obj:`property` function. For example, to declare a scalar,
-`PyTango.DevDouble`, read-only attribute called *voltage* in a *PowerSupply*
-:class:`Device` do::
+
+
+def _attribute(**kwargs):
+ """declares a new tango attribute in a :class:`Device`. To be used like
+the python native :obj:`property` function. For example, to declare a
+scalar, `PyTango.DevDouble`, read-only attribute called *voltage* in a
+*PowerSupply* :class:`Device` do::
class PowerSupply(Device):
@@ -324,81 +527,123 @@ native :obj:`property` function. For example, to declare a scalar,
It receives multiple keyword arguments.
-===================== ========================================== ============================================== =======================================================================================
-parameter type default value description
-===================== ========================================== ============================================== =======================================================================================
-name :obj:`str` class member name alternative attribute name
-dtype :obj:`object` :obj:`~PyTango.CmdArgType`\ ``.DevDouble`` data type (see :ref:`Data type equivalence <pytango-hlapi-datatypes>`)
-dformat :obj:`~PyTango.AttrDataFormat` :obj:`~PyTango.AttrDataFormat`\ ``.SCALAR`` data format
-max_dim_x :obj:`int` 1 maximum size for x dimension (ignored for SCALAR format)
-max_dim_y :obj:`int` 0 maximum size for y dimension (ignored for SCALAR and SPECTRUM formats)
-display_level :obj:`~PyTango.DispLevel` :obj:`~PyTango.DisLevel`\ ``.OPERATOR`` display level
-polling_period :obj:`int` -1 polling period
-memorized :obj:`bool` False attribute should or not be memorized
-hw_memorized :obj:`bool` False write method should be called at startup when restoring memorize value (dangerous!)
-access :obj:`~PyTango.AttrWriteType` :obj:`~PyTango.AttrWriteType`\ ``.READ`` read only/ read write / write only access
-fread :obj:`str` or :obj:`callable` 'read_<attr_name>' read method name or method object
-fwrite :obj:`str` or :obj:`callable` 'write_<attr_name>' write method name or method object
-is_allowed :obj:`str` or :obj:`callable` 'is_<attr_name>_allowed' is allowed method name or method object
-label :obj:`str` '<attr_name>' attribute label
-description :obj:`str` '' attribute description
-unit :obj:`str` '' physical units the attribute value is in
-standard_unit :obj:`str` '' physical standard unit
-display_unit :obj:`str` '' physical display unit (hint for clients)
-format :obj:`str` '6.2f' attribute representation format
-min_value :obj:`str` None minimum allowed value
-max_value :obj:`str` None maximum allowed value
-min_alarm :obj:`str` None minimum value to trigger attribute alarm
-max_alarm :obj:`str` None maximum value to trigger attribute alarm
-min_warning :obj:`str` None minimum value to trigger attribute warning
-max_warning :obj:`str` None maximum value to trigger attribute warning
-delta_val :obj:`str` None
-delta_t :obj:`str` None
-abs_change :obj:`str` None minimum value change between events that causes event filter to send the event
-rel_change :obj:`str` None minimum relative change between events that causes event filter to send the event (%)
-period :obj:`str` None
-archive_abs_change :obj:`str` None
-archive_rel_change :obj:`str` None
-archive_period :obj:`str` None
-===================== ========================================== ============================================== ======================================================================================="""
+===================== ================================ ======================================= =======================================================================================
+parameter type default value description
+===================== ================================ ======================================= =======================================================================================
+name :obj:`str` class member name alternative attribute name
+dtype :obj:`object` :obj:`~PyTango.CmdArgType.DevDouble` data type (see :ref:`Data type equivalence <pytango-hlapi-datatypes>`)
+dformat :obj:`~PyTango.AttrDataFormat` :obj:`~PyTango.AttrDataFormat.SCALAR` data format
+max_dim_x :obj:`int` 1 maximum size for x dimension (ignored for SCALAR format)
+max_dim_y :obj:`int` 0 maximum size for y dimension (ignored for SCALAR and SPECTRUM formats)
+display_level :obj:`~PyTango.DispLevel` :obj:`~PyTango.DisLevel.OPERATOR` display level
+polling_period :obj:`int` -1 polling period
+memorized :obj:`bool` False attribute should or not be memorized
+hw_memorized :obj:`bool` False write method should be called at startup when restoring memorize value (dangerous!)
+access :obj:`~PyTango.AttrWriteType` :obj:`~PyTango.AttrWriteType.READ` read only/ read write / write only access
+fget (or fread) :obj:`str` or :obj:`callable` 'read_<attr_name>' read method name or method object
+fset (or fwrite) :obj:`str` or :obj:`callable` 'write_<attr_name>' write method name or method object
+is_allowed :obj:`str` or :obj:`callable` 'is_<attr_name>_allowed' is allowed method name or method object
+label :obj:`str` '<attr_name>' attribute label
+doc (or description) :obj:`str` '' attribute description
+unit :obj:`str` '' physical units the attribute value is in
+standard_unit :obj:`str` '' physical standard unit
+display_unit :obj:`str` '' physical display unit (hint for clients)
+format :obj:`str` '6.2f' attribute representation format
+min_value :obj:`str` None minimum allowed value
+max_value :obj:`str` None maximum allowed value
+min_alarm :obj:`str` None minimum value to trigger attribute alarm
+max_alarm :obj:`str` None maximum value to trigger attribute alarm
+min_warning :obj:`str` None minimum value to trigger attribute warning
+max_warning :obj:`str` None maximum value to trigger attribute warning
+delta_val :obj:`str` None
+delta_t :obj:`str` None
+abs_change :obj:`str` None minimum value change between events that causes event filter to send the event
+rel_change :obj:`str` None minimum relative change between events that causes event filter to send the event (%)
+period :obj:`str` None
+archive_abs_change :obj:`str` None
+archive_rel_change :obj:`str` None
+archive_period :obj:`str` None
+===================== ================================ ======================================= ======================================================================================="""
if 'dtype' in kwargs:
- kwargs['dtype'] = get_tango_type(kwargs['dtype'])
- return AttrData2.from_dict(kwargs)
+ kwargs['dtype'], kwargs['dformat'] = \
+ get_tango_type_format(kwargs['dtype'], kwargs.get('dformat'))
+ return attribute.from_dict(kwargs)
+
+def command(f=None, dtype_in=None, dformat_in=None, doc_in="",
+ dtype_out=None, dformat_out=None, doc_out="",):
+ """declares a new tango command in a :class:`Device`.
+ To be used like a decorator in the methods you want to declare as tango
+ commands. For example, to declare a *ramp* command that receives a
+ `PyTango.DevDouble` parameter called *current*, do::
+
+ class PowerSupply(Device):
+
+ @command(dtype_in=float)
+ def ramp(self, current):
+ self.info_stream("Ramping on %f..." % current)
+
+ # Another more elaborate command
+
+ @command(dtype_in=float, doc_in="the pressure to be set",
+ dtype_out=(bool, doc_out="True if it worked, False otherwise")
+ def setPressure(self, pressure):
+ self.info_stream("Setting pressure on %f..." % pressure)
+
+ :param dtype_in: a :ref:`data type <pytango-hlapi-datatypes>`
+ describing the type of parameter. Default is None meaning
+ no parameter.
+ :param dformat_in: parameter data format. Default is None.
+ :type dformat_in: AttrDataFormat
+ :param doc_in: parameter documentation
+ :type doc_in: str
+
+ :param dtype_out: a :ref:`data type <pytango-hlapi-datatypes>`
+ describing the type of return value. Default is None
+ meaning no return value.
+ :param dformat_out: return value data format. Default is None.
+ :type dformat_out: AttrDataFormat
+ :param doc_out: return value documentation
+ :type doc_out: str
+
+ """
+ if f is None:
+ return functools.partial(command,
+ dtype_in=dtype_in, dformat_in=dformat_in, doc_in=doc_in,
+ dtype_out=dtype_out, dformat_out=dformat_out, doc_out=doc_out)
+ name = f.__name__
-def command():
- """TODO"""
- pass
-
-def device_property():
- """TODO"""
- pass
+ dtype_in, dformat_in = get_tango_type_format(dtype_in, dformat_in)
+ dtype_out, dformat_out = get_tango_type_format(dtype_out, dformat_out)
-def class_property():
- """TODO"""
- pass
+ din = [from_typeformat_to_type(dtype_in, dformat_in), doc_in]
+ dout = [from_typeformat_to_type(dtype_out, dformat_out), doc_out]
+ f.__tango_command__ = name, [din, dout]
+ return f
-__doc__ = """High Level API for writting Tango device servers.
-.. _pytango-hlapi-datatypes:
+class _property(object):
-.. rubric:: Data types
+ def __init__(self, dtype, doc='', default_value=None):
+ self.__value = None
+ dtype = from_typeformat_to_type(*get_tango_type_format(dtype))
+ self.dtype = dtype
+ self.doc = doc
+ self.default_value = default_value
+
+ def __get__(self, obj, objtype):
+ return self.__value
-When declaring attributes, properties or commands, one of the most important
-information is the data type. It is given by the keyword argument *dtype*.
-This argument is not retricted to the :obj:`~PyTango.CmdArgType` options.
+ def __set__(self, obj, value):
+ self.__value = value
+
+ def __delete__(self, obj):
+ del self.__value
-For example, to define a :obj:`~PyTango.CmdArgType.DevLong` attribute you
-have several possibilities:
- #. :obj:`int`
- #. 'int'
- #. 'int32'
- #. 'integer'
- #. :obj:`~PyTango.CmdArgType.DevLong`
- #. 'DevLong'
- #. :obj:`numpy.int32`
+class device_property(_property):
+ pass
-Below is the complete table of equivalences.
-""" + __type_doc
+class class_property(_property):
+ pass
diff --git a/src/boost/python/ipython/__init__.py b/src/boost/python/ipython/__init__.py
index ae7e657..94e27fb 100644
--- a/src/boost/python/ipython/__init__.py
+++ b/src/boost/python/ipython/__init__.py
@@ -12,18 +12,18 @@
__all__ = ["init_ipython", "install", "load_ipython_extension",
"unload_ipython_extension", "load_config"]
-from .common import get_python_version, get_python_version_number, \
- get_ipython_version, get_ipython_version_list, \
- get_ipython_version_number, get_pytango_version, get_pytango_version_number
+from .common import get_python_version
+from .common import get_ipython_version
+from .common import get_pytango_version
-def default_init_ipython(ip, store=True, pytango=True, colors=True,
- console=True, magic=True):
+
+def default_init_ipython(*args, **kwargs):
print("Unsupported IPython version (%s) for tango profile" \
% get_ipython_version())
print("Supported IPython versions are: >= 0.10")
print("Starting normal IPython console...")
-def default_install(ipydir=None, verbose=True):
+def default_install(*args, **kwargs):
print("Unsupported IPython version (%s) for tango profile" \
% get_ipython_version())
print("Supported IPython versions are: >= 0.10")
@@ -32,8 +32,9 @@ def default_install(ipydir=None, verbose=True):
init_ipython = default_init_ipython
install = default_install
-ipv = get_ipython_version_list()
-if ipv >= [0, 10] and ipv < [0, 11]:
+ipv = get_ipython_version()
+
+if ipv >= "0.10" and ipv < "0.11":
from . import ipython_00_10
init_ipython = ipython_00_10.init_ipython
install = ipython_00_10.install
@@ -42,7 +43,7 @@ if ipv >= [0, 10] and ipv < [0, 11]:
load_config = None
load_ipython_extension = None
unload_ipython_extension = None
-elif ipv >= [0, 11]:
+elif ipv >= "0.11" and ipv < "1.0":
from . import ipython_00_11
init_ipython = None
install = ipython_00_11.install
@@ -51,7 +52,16 @@ elif ipv >= [0, 11]:
load_config = ipython_00_11.load_config
load_ipython_extension = ipython_00_11.load_ipython_extension
unload_ipython_extension = ipython_00_11.unload_ipython_extension
-
+elif ipv >= "1.00":
+ from . import ipython_10_00
+ init_ipython = None
+ install = ipython_10_00.install
+ is_installed = ipython_10_00.is_installed
+ __run = ipython_10_00.run
+ load_config = ipython_10_00.load_config
+ load_ipython_extension = ipython_10_00.load_ipython_extension
+ unload_ipython_extension = ipython_10_00.unload_ipython_extension
+
def run():
if not is_installed():
install(verbose=False)
diff --git a/src/boost/python/ipython/common.py b/src/boost/python/ipython/common.py
index d20b5cf..1ae516f 100644
--- a/src/boost/python/ipython/common.py
+++ b/src/boost/python/ipython/common.py
@@ -13,78 +13,19 @@
"""functions common (hopefully) to all ipython versions"""
-__all__ = ["translate_version_str2int", "translate_version_str2list",
- "get_python_version", "get_python_version_number",
- "get_ipython_version", "get_ipython_version_list",
- "get_ipython_version_number",
- "get_pytango_version", "get_pytango_version_number"]
+__all__ = ["get_python_version",
+ "get_ipython_version",
+ "get_pytango_version"]
import sys
-import math
-
-def translate_version_str2int(version_str):
- """Translates a version string in format 'x[.y[.z[...]]]' into a 000000 number"""
-
- parts = version_str.split('.')
- i, v, l = 0, 0, len(parts)
- if not l:
- return v
- while i<3:
- try:
- v += int(parts[i])*int(math.pow(10,(2-i)*2))
- l -= 1
- i += 1
- except ValueError:
- return v
- if not l: return v
- return v
-
- try:
- v += 10000*int(parts[0])
- l -= 1
- except ValueError:
- return v
- if not l: return v
-
- try:
- v += 100*int(parts[1])
- l -= 1
- except ValueError:
- return v
- if not l: return v
-
- try:
- v += int(parts[0])
- l -= 1
- except ValueError:
- return v
- if not l: return v
-
-def translate_version_str2list(version_str):
- """Translates a version string in format 'x[.y[.z[...]]]' into a list of
- numbers"""
- if version_str is None:
- ver = [0, 0]
- else:
- ver = []
- for i in version_str.split(".")[:2]:
- try:
- i = int(i)
- except:
- i = 0
- ver.append(i)
- return ver
+from distutils.version import StrictVersion
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
# Python utilities
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
def get_python_version():
- return '.'.join(map(str, sys.version_info[:3]))
-
-def get_python_version_number():
- pyver_str = get_python_version()
- return translate_version_str2int(pyver_str)
+ return StrictVersion('.'.join(map(str, sys.version_info[:3])))
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
# IPython utilities
@@ -104,17 +45,7 @@ def get_ipython_version():
pass
except:
pass
- return v
-
-def get_ipython_version_list():
- ipv_str = get_ipython_version()
- return translate_version_str2list(ipv_str)
-
-def get_ipython_version_number():
- """Returns the current IPython version number"""
- ipyver_str = get_ipython_version()
- if ipyver_str is None: return None
- return translate_version_str2int(ipyver_str)
+ return StrictVersion(v)
#-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-
# PyTango utilities
@@ -126,11 +57,7 @@ def get_pytango_version():
except:
return
try:
- return PyTango.Release.version
+ v = PyTango.Release.version
except:
- return '0.0.0'
-
-def get_pytango_version_number():
- tgver_str = get_pytango_version()
- if tgver_str is None: return None
- return translate_version_str2int(tgver_str)
\ No newline at end of file
+ v = '0.0.0'
+ return StrictVersion(v)
diff --git a/src/boost/python/ipython/ipython_00_10/ipython_00_10.py b/src/boost/python/ipython/ipython_00_10/ipython_00_10.py
index 49ca3d2..9bc8a6c 100644
--- a/src/boost/python/ipython/ipython_00_10/ipython_00_10.py
+++ b/src/boost/python/ipython/ipython_00_10/ipython_00_10.py
@@ -865,10 +865,10 @@ def init_console(ip):
TermColors = IPython.ColorANSI.TermColors
- d = { "version" : PyTango.ipython.get_pytango_version(),
- "pyver" : PyTango.ipython.get_python_version(),
- "ipyver" : PyTango.ipython.get_ipython_version(),
- "pytangover" : PyTango.ipython.get_pytango_version() }
+ d = { "version" : str(PyTango.ipython.get_pytango_version()),
+ "pyver" : str(PyTango.ipython.get_python_version()),
+ "ipyver" : str(PyTango.ipython.get_ipython_version()),
+ "pytangover" : str(PyTango.ipython.get_pytango_version()) }
d.update(TermColors.__dict__)
o = ip.options
diff --git a/src/boost/python/ipython/ipython_00_11/ipython_00_11.py b/src/boost/python/ipython/ipython_00_11/ipython_00_11.py
index 7ac6fef..bbf5911 100644
--- a/src/boost/python/ipython/ipython_00_11/ipython_00_11.py
+++ b/src/boost/python/ipython/ipython_00_11/ipython_00_11.py
@@ -1129,10 +1129,10 @@ def load_config(config):
import PyTango.ipython
import IPython.utils.coloransi
- d = { "version" : PyTango.ipython.get_pytango_version(),
- "pyver" : PyTango.ipython.get_python_version(),
- "ipyver" : PyTango.ipython.get_ipython_version(),
- "pytangover" : PyTango.ipython.get_pytango_version(), }
+ d = { "version" : str(PyTango.ipython.get_pytango_version()),
+ "pyver" : str(PyTango.ipython.get_python_version()),
+ "ipyver" : str(PyTango.ipython.get_ipython_version()),
+ "pytangover" : str(PyTango.ipython.get_pytango_version()), }
d.update(IPython.utils.coloransi.TermColors.__dict__)
so = Struct(
@@ -1140,8 +1140,7 @@ def load_config(config):
so = config.get("tango_options", so)
- import PyTango.ipython
- ipy_ver = PyTango.ipython.get_ipython_version_list()
+ ipy_ver = PyTango.ipython.get_ipython_version()
# ------------------------------------
# Application
@@ -1155,7 +1154,7 @@ def load_config(config):
i_shell = config.InteractiveShell
i_shell.colors = 'Linux'
- if ipy_ver >= [0, 12]:
+ if ipy_ver >= "0.12":
# ------------------------------------
# PromptManager (ipython >= 0.12)
# ------------------------------------
diff --git a/src/boost/python/tango_green.py b/src/boost/python/tango_green.py
index d24e096..a5ea588 100644
--- a/src/boost/python/tango_green.py
+++ b/src/boost/python/tango_green.py
@@ -9,14 +9,16 @@
# See LICENSE.txt for more info.
# ------------------------------------------------------------------------------
-__all__ = ["get_executor", "submit", "spawn",
+__all__ = ["get_green_mode", "set_green_mode",
+ "get_executor", "submit", "spawn",
"get_synch_executor", "synch_submit",
"get_gevent_executor", "gevent_submit",
- "get_futures_executor", "futures_submit"
+ "get_futures_executor", "futures_submit",
"result", "submitable", "green"]
__docformat__ = "restructuredtext"
+import os
from functools import wraps
from ._PyTango import GreenMode
@@ -24,7 +26,40 @@ from .tango_gevent import get_global_executor as get_gevent_executor
from .tango_gevent import submit as gevent_submit
from .tango_futures import get_global_executor as get_futures_executor
from .tango_futures import submit as futures_submit
-from .utils import get_green_mode
+
+__default_green_mode = GreenMode.Synchronous
+try:
+ __current_green_mode = getattr(GreenMode,
+ os.environ.get("PYTANGO_GREEN_MODE",
+ "Synchronous").capitalize())
+except:
+ __current_green_mode = __default_green_mode
+
+
+def set_green_mode(green_mode=None):
+ """Sets the global default PyTango green mode.
+
+ Advice: Use only in your final application. Don't use this in a python library
+ in order not to interfere with the beavior of other libraries and/or
+ application where your library is being.
+
+ :param green_mode: the new global default PyTango green mode
+ :type green_mode: GreenMode
+ """
+ global __current_green_mode
+ if green_mode is None:
+ green_mode = GreenMode.Synchronous
+ __current_green_mode = green_mode
+
+
+def get_green_mode():
+ """Returns the current global default PyTango green mode.
+
+ :returns: the current global default PyTango green mode
+ :rtype: GreenMode
+ """
+ return __current_green_mode
+
class SynchExecutor(object):
def submit(self, fn, *args, **kwargs):
diff --git a/src/boost/python/utils.py b/src/boost/python/utils.py
index 32a8788..b834e6d 100644
--- a/src/boost/python/utils.py
+++ b/src/boost/python/utils.py
@@ -16,11 +16,11 @@ This is an internal PyTango module.
from __future__ import with_statement
from __future__ import print_function
-__all__ = [ "get_green_mode", "set_green_mode",
- "is_pure_str", "is_seq", "is_non_str_seq", "is_integer",
+__all__ = [ "is_pure_str", "is_seq", "is_non_str_seq", "is_integer",
"is_number", "is_scalar_type", "is_array_type", "is_numerical_type",
"is_int_type", "is_float_type", "is_bool_type", "is_bin_type",
"is_str_type", "obj_2_str", "seqStr_2_obj",
+ "scalar_to_array_type",
"document_method", "document_static_method", "document_enum",
"CaselessList", "CaselessDict", "EventCallBack", "get_home",
"from_version_str_to_hex_str", "from_version_str_to_int",
@@ -90,39 +90,6 @@ _scalar_to_array_type = {
CmdArgType.ConstDevString : CmdArgType.DevVarStringArray,
}
-__default_green_mode = GreenMode.Synchronous
-try:
- __current_green_mode = getattr(GreenMode,
- os.environ.get("PYTANGO_GREEN_MODE",
- "Synchronous").capitalize())
-except:
- __current_green_mode = __default_green_mode
-
-
-def set_green_mode(green_mode=None):
- """Sets the global default PyTango green mode.
-
- Advice: Use only in your final application. Don't use this in a python library
- in order not to interfere with the beavior of other libraries and/or
- application where your library is being.
-
- :param green_mode: the new global default PyTango green mode
- :type green_mode: GreenMode
- """
- global __current_green_mode
- if green_mode is None:
- green_mode = GreenMode.Synchronous
- __current_green_mode = green_mode
-
-
-def get_green_mode():
- """Returns the current global default PyTango green mode.
-
- :returns: the current global default PyTango green mode
- :rtype: GreenMode
- """
- return __current_green_mode
-
__device_classes = None
def get_tango_device_classes():
@@ -543,7 +510,7 @@ def _seqStr_2_obj_from_type_format(seq, tg_type, tg_format):
if tg_format == AttrDataFormat.SCALAR:
return _seqStr_2_obj_from_type(tg_type, seq)
elif tg_format == AttrDataFormat.SPECTRUM:
- return _seqStr_2_obj_from_type(_scalar_to_array_type(tg_type), seq)
+ return _seqStr_2_obj_from_type(_scalar_to_array_type[tg_type], seq)
elif tg_format == AttrDataFormat.IMAGE:
if tg_type == CmdArgType.DevString:
return seq
@@ -571,6 +538,9 @@ def _seqStr_2_obj_from_type_format(seq, tg_type, tg_format):
#UNKNOWN_FORMAT
return _seqStr_2_obj_from_type(tg_type, seq)
+def scalar_to_array_type(dtype):
+ return _scalar_to_array_type[dtype]
+
def obj_2_str(obj, tg_type):
"""Converts a python object into a string according to the given tango type
@@ -1141,7 +1111,8 @@ def from_version_str_to_hex_str(version_str):
def from_version_str_to_int(version_str):
return int(from_version_str_to_hex_str(version_str, 16))
-def __server_run(classes, args=None, msg_stream=sys.stderr, util=None):
+def __server_run(classes, args=None, msg_stream=sys.stdout, util=None,
+ event_loop=None):
import PyTango
if msg_stream is None:
import io
@@ -1173,12 +1144,15 @@ def __server_run(classes, args=None, msg_stream=sys.stderr, util=None):
klass = klass_info
util.add_class(klass_klass, klass, klass_name)
u_instance = PyTango.Util.instance()
+ if event_loop is not None:
+ u_instance.server_set_event_loop(event_loop)
u_instance.server_init()
msg_stream.write("Ready to accept request\n")
u_instance.server_run()
return util
-def server_run(classes, args=None, msg_stream=sys.stderr, verbose=False, util=None):
+def server_run(classes, args=None, msg_stream=sys.stdout,
+ verbose=False, util=None, event_loop=None):
"""Provides a simple way to run a tango server. It handles exceptions
by writting a message to the msg_stream.
@@ -1224,11 +1198,14 @@ def server_run(classes, args=None, msg_stream=sys.stderr, verbose=False, util=No
:type args: list
:param msg_stream:
- stream where to put messages [default: sys.stderr]
+ stream where to put messages [default: sys.stdout]
:param util:
PyTango Util object [default: None meaning create a Util instance]
:type util: :class:`~PyTango.Util`
+
+ :param event_loop: event_loop callable
+ :type event_loop: callable
:return: The Util singleton object
:rtype: :class:`~PyTango.Util`
@@ -1237,6 +1214,11 @@ def server_run(classes, args=None, msg_stream=sys.stderr, verbose=False, util=No
.. versionchanged:: 8.0.3
Added `util` keyword parameter.
+ Returns util object
+
+ .. versionchanged:: 8.1.1
+ Changed default msg_stream from *stderr* to *stdout*
+ Added `event_loop` keyword parameter.
Returns util object"""
if msg_stream is None:
@@ -1244,7 +1226,7 @@ def server_run(classes, args=None, msg_stream=sys.stderr, verbose=False, util=No
msg_stream = io.BytesIO()
write = msg_stream.write
try:
- return __server_run(classes, args=args, util=util)
+ return __server_run(classes, args=args, util=util, event_loop=event_loop)
write("Exiting:\n")
except KeyboardInterrupt:
write("Exiting: Keyboard interrupt\n")
--
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