From facb43aad461f57ee282aaa80dac14f1e6849990 Mon Sep 17 00:00:00 2001 From: Tammo Jan Dijkema <dijkema@astron.nl> Date: Fri, 8 Jun 2018 11:15:07 +0000 Subject: [PATCH] Task #11556: python3 support for some LOFAR python-bindings --- .gitattributes | 2 + .../pystationresponse/CMakeLists.txt | 4 +- .../pystationresponse/src/__init__.py | 4 +- .../pystationresponse/test/CMakeLists.txt | 11 +- .../pystationresponse/test/tStationBeamNCP.py | 7 +- .../test/tpystationresponse.py | 5 + .../test/tpystationresponse.sh | 2 + CEP/DP3/PythonDPPP/src/PythonStep.cc | 4 + CEP/DP3/PythonDPPP/test/tPythonStep.py | 7 +- CEP/pyparmdb/CMakeLists.txt | 2 +- CEP/pyparmdb/src/__init__.py | 10 +- CEP/pyparmdb/test/CMakeLists.txt | 8 +- CEP/pyparmdb/test/tpyparmdb.py | 44 +++++-- CEP/pyparmdb/test/tpyparmdb.run | 15 --- CMake/FindBoost.cmake | 18 +++ CMake/FindCasacore.cmake | 17 +++ CMake/FindPython.cmake | 1 - CMake/FindPythonModule.cmake | 4 +- CMake/testscripts/assay | 3 +- CMake/testscripts/runctest.sh.in | 8 ++ LCS/pyparameterset/src/__init__.py | 4 +- LCS/pyparameterset/test/tpyparameterset.py | 120 +++++++++--------- .../test/tpyparameterset.stdout | 4 +- LCS/pytools/include/pytools/PycBasicData.h | 15 ++- LCS/pytools/test/tConvert.py | 44 ++++--- lofar_config.h.cmake | 3 + 26 files changed, 232 insertions(+), 134 deletions(-) create mode 100644 CEP/Calibration/pystationresponse/test/tpystationresponse.py create mode 100755 CEP/Calibration/pystationresponse/test/tpystationresponse.sh delete mode 100755 CEP/pyparmdb/test/tpyparmdb.run diff --git a/.gitattributes b/.gitattributes index 84d0d644ec7..a308317f463 100644 --- a/.gitattributes +++ b/.gitattributes @@ -295,6 +295,8 @@ CEP/Calibration/pystationresponse/test/tStationBeamNCP.in.MS/table.info -text CEP/Calibration/pystationresponse/test/tStationBeamNCP.in.MS/table.lock -text CEP/Calibration/pystationresponse/test/tStationBeamNCP.py -text CEP/Calibration/pystationresponse/test/tStationBeamNCP.sh -text +CEP/Calibration/pystationresponse/test/tpystationresponse.py -text +CEP/Calibration/pystationresponse/test/tpystationresponse.sh -text CEP/DP3/DPPP/etc/CMakeLists.txt -text CEP/DP3/DPPP/etc/DPPP.log_prop -text CEP/DP3/DPPP/include/DPPP/Apply.h -text diff --git a/CEP/Calibration/pystationresponse/CMakeLists.txt b/CEP/Calibration/pystationresponse/CMakeLists.txt index c2f387f96dd..3549dded7b5 100644 --- a/CEP/Calibration/pystationresponse/CMakeLists.txt +++ b/CEP/Calibration/pystationresponse/CMakeLists.txt @@ -3,9 +3,9 @@ lofar_package(pystationresponse 1.0 DEPENDS StationResponse) include(LofarFindPackage) -lofar_find_package(Boost REQUIRED COMPONENTS python) lofar_find_package(Python 2.6 REQUIRED) -lofar_find_package(Pyrap REQUIRED) +lofar_find_package(Boost REQUIRED COMPONENTS python) +lofar_find_package(Casacore REQUIRED COMPONENTS python) add_subdirectory(src) add_subdirectory(test) diff --git a/CEP/Calibration/pystationresponse/src/__init__.py b/CEP/Calibration/pystationresponse/src/__init__.py index a3e5a59bbd6..87961234ba1 100755 --- a/CEP/Calibration/pystationresponse/src/__init__.py +++ b/CEP/Calibration/pystationresponse/src/__init__.py @@ -19,7 +19,7 @@ # # $Id$ -import _stationresponse +from ._stationresponse import StationResponse class stationresponse(object): """ @@ -64,7 +64,7 @@ class stationresponse(object): time = subtable.getcell("TIME", 0) print time, response.evaluateChannel(time, 0, 0) """ - self._response = _stationresponse.StationResponse(msname, inverse, + self._response = StationResponse(msname, inverse, useElementResponse, useArrayFactor, useChanFreq) def version (self, type='other'): diff --git a/CEP/Calibration/pystationresponse/test/CMakeLists.txt b/CEP/Calibration/pystationresponse/test/CMakeLists.txt index d6da7e50cd0..48ba299ea0a 100644 --- a/CEP/Calibration/pystationresponse/test/CMakeLists.txt +++ b/CEP/Calibration/pystationresponse/test/CMakeLists.txt @@ -2,4 +2,13 @@ include(LofarCTest) -#lofar_add_test(tStationBeamNCP) # test not enabled because pyrap is not found +include(FindPythonModule) + +find_python_module(pyrap) +if(PYTHON_PYRAP_FOUND) + lofar_add_test(tStationBeamNCP) +else(PYTHON_PYRAP_FOUND) + message(WARNING "Python-casacore was not found, not installing test tStationBeamNCP") +endif(PYTHON_PYRAP_FOUND) + +lofar_add_test(tpystationresponse) diff --git a/CEP/Calibration/pystationresponse/test/tStationBeamNCP.py b/CEP/Calibration/pystationresponse/test/tStationBeamNCP.py index f16fbf80fa5..81e76b0c26a 100644 --- a/CEP/Calibration/pystationresponse/test/tStationBeamNCP.py +++ b/CEP/Calibration/pystationresponse/test/tStationBeamNCP.py @@ -1,4 +1,5 @@ "Test the Station Beam at the NCP. Rationale: when pointing at the NCP all stations should have (almost) the same beam" +from __future__ import print_function import sys @@ -17,8 +18,8 @@ a=[mys.evaluateStation(time=times[0],station=st) for st in range(20)] for a1 in a: for a2 in a: - if np.linalg.norm(a1-a2)>1.e-3: - print "a1=",a1,"\na2=",a2,"\nnorm=",np.linalg.norm(a1-a2) - sys.exit(1) + if np.linalg.norm(a1-a2)>1.e-3: + print("a1=",a1,"\na2=",a2,"\nnorm=",np.linalg.norm(a1-a2)) + sys.exit(1) sys.exit(0) diff --git a/CEP/Calibration/pystationresponse/test/tpystationresponse.py b/CEP/Calibration/pystationresponse/test/tpystationresponse.py new file mode 100644 index 00000000000..124019cde47 --- /dev/null +++ b/CEP/Calibration/pystationresponse/test/tpystationresponse.py @@ -0,0 +1,5 @@ +from __future__ import print_function + +import lofar.stationresponse + + diff --git a/CEP/Calibration/pystationresponse/test/tpystationresponse.sh b/CEP/Calibration/pystationresponse/test/tpystationresponse.sh new file mode 100755 index 00000000000..f967776d2c3 --- /dev/null +++ b/CEP/Calibration/pystationresponse/test/tpystationresponse.sh @@ -0,0 +1,2 @@ +#!/bin/sh +./runctest.sh tpystationresponse diff --git a/CEP/DP3/PythonDPPP/src/PythonStep.cc b/CEP/DP3/PythonDPPP/src/PythonStep.cc index ec36289830c..4cc265b2df3 100644 --- a/CEP/DP3/PythonDPPP/src/PythonStep.cc +++ b/CEP/DP3/PythonDPPP/src/PythonStep.cc @@ -72,7 +72,11 @@ namespace LOFAR { string workingDir = Path(".").absoluteName(); char path[] = "path"; // needed to avoid warning if "path" used below PyObject* sysPath = PySys_GetObject(path); +#if PYTHON_VERSION_MAJOR < 3 PyList_Insert (sysPath, 0, PyString_FromString(workingDir.c_str())); +#else + PyList_Insert (sysPath, 0, PyBytes_FromString(workingDir.c_str())); +#endif // Register converters for casa types from/to python types casa::pyrap::register_convert_excp(); casa::pyrap::register_convert_basicdata(); diff --git a/CEP/DP3/PythonDPPP/test/tPythonStep.py b/CEP/DP3/PythonDPPP/test/tPythonStep.py index 3b3ad8cfb48..33aaef591c4 100644 --- a/CEP/DP3/PythonDPPP/test/tPythonStep.py +++ b/CEP/DP3/PythonDPPP/test/tPythonStep.py @@ -19,6 +19,7 @@ # # $Id: __init__.py 23074 2012-12-03 07:51:29Z diepen $ +from __future__ import print_function from lofar.pythondppp import DPStep from lofar.parameterset import parameterset @@ -52,7 +53,7 @@ class tPythonStep(DPStep): self.getWeights (self.itsWeights); self.getUVW (self.itsUVW); # Process the data. - print "process tPythonStep", time-4.47203e9, exposure, self.itsData.sum(), self.itsFlags.sum(), self.itsWeights.sum(), self.itsUVW.sum() + print("process tPythonStep", time-4.47203e9, exposure, self.itsData.sum(), self.itsFlags.sum(), self.itsWeights.sum(), self.itsUVW.sum()) # Execute the next step in the DPPP pipeline. TIME,UVW are changed. return self.processNext ({'TIME': time+self.itsIncr, 'UVW': self.itsUVW+self.itsIncr}) @@ -60,7 +61,7 @@ class tPythonStep(DPStep): # Finish the step as needed. # This function does not need to be implemented. # Note: finish of the next step is called by the C++ layer. - print "finish tPythonStep" + print("finish tPythonStep") def showCounts(self): # Show the counts of this test. @@ -70,4 +71,4 @@ class tPythonStep(DPStep): def addToMS(self, msname): # Add some info the the output MeasurementSet. # This function does not need to be implemented. - print "addToMS tPythonStep", msname + print("addToMS tPythonStep", msname) diff --git a/CEP/pyparmdb/CMakeLists.txt b/CEP/pyparmdb/CMakeLists.txt index 6722696a794..c051e47709f 100644 --- a/CEP/pyparmdb/CMakeLists.txt +++ b/CEP/pyparmdb/CMakeLists.txt @@ -5,7 +5,7 @@ lofar_package(pyparmdb 1.0 DEPENDS Common ParmDB) include(LofarFindPackage) lofar_find_package(Boost REQUIRED COMPONENTS python) lofar_find_package(Python 2.6 REQUIRED) -lofar_find_package(Pyrap REQUIRED) +lofar_find_package(Casacore REQUIRED COMPONENTS python) add_subdirectory(src) add_subdirectory(test) diff --git a/CEP/pyparmdb/src/__init__.py b/CEP/pyparmdb/src/__init__.py index cd17f86050b..221af0ae377 100755 --- a/CEP/pyparmdb/src/__init__.py +++ b/CEP/pyparmdb/src/__init__.py @@ -19,7 +19,7 @@ # # $Id$ -from _parmdb import ParmDB +from ._parmdb import ParmDB class parmdb(ParmDB): """ @@ -41,7 +41,7 @@ class parmdb(ParmDB): import lofar.parmdb pdb = parmdb(dbname) # open existing - pdb = 0 # close + pdb = 0 # close Almost all functions work on a local as well as a distributed database. The exception is :func:`addValues`. For the time being it only works @@ -65,7 +65,7 @@ class parmdb(ParmDB): return self._getRange (parmnamepattern) def getNames (self, parmnamepattern='', includeDefaults=False): - """Return the list of matching parameter names with actual values. + """Return the list of matching parameter names with actual values. parmnamepattern Parameter name pattern given as a shell-like filename pattern. @@ -78,7 +78,7 @@ class parmdb(ParmDB): return self._getNames (parmnamepattern) def getDefNames (self, parmnamepattern=''): - """Return the list of matching parameter names with default values. + """Return the list of matching parameter names with default values. The pattern must be given as a shell-like filename pattern. An empty pattern (the default) means '*' (thus all names). @@ -87,7 +87,7 @@ class parmdb(ParmDB): return self._getDefNames (parmnamepattern) def getDefValues (self, parmnamepattern=''): - """Return the default values of matching parameter names as a dict. + """Return the default values of matching parameter names as a dict. The pattern must be given as a shell-like filename pattern. An empty pattern (the default) means '*' (thus all names). diff --git a/CEP/pyparmdb/test/CMakeLists.txt b/CEP/pyparmdb/test/CMakeLists.txt index 81a127052e6..0fd8973b287 100644 --- a/CEP/pyparmdb/test/CMakeLists.txt +++ b/CEP/pyparmdb/test/CMakeLists.txt @@ -1,6 +1,7 @@ # $Id$ include(LofarCTest) +include(FindPythonModule) # We need to create a symlink to the parmdbm executable in the current # binary directory, so that the test program(s) can find it. @@ -8,4 +9,9 @@ lofar_create_target_symlink( parmdbm ${CMAKE_CURRENT_BINARY_DIR}/parmdbm) -lofar_add_test(tpyparmdb DEPENDS parmdbm _parmdb) +find_python_module(numpy) +if(PYTHON_NUMPY_FOUND) + lofar_add_test(tpyparmdb DEPENDS parmdbm _parmdb) +else(PYTHON_NUMPY_FOUND) + message(WARNING "Numpy not found, disabling tpyparmdb test") +endif(PYTHON_NUMPY_FOUND) diff --git a/CEP/pyparmdb/test/tpyparmdb.py b/CEP/pyparmdb/test/tpyparmdb.py index 3728970b4ec..52abe973e70 100644 --- a/CEP/pyparmdb/test/tpyparmdb.py +++ b/CEP/pyparmdb/test/tpyparmdb.py @@ -1,28 +1,48 @@ +from __future__ import print_function + from lofar.parmdb import * +import os +import sys + + +def createTestFile(): + """Create a test parmdb using parmdbm""" + return os.system(""" +parmdbm <<EOF > tpyparmdb_tmp.pdbout + create tablename='tpyparmdb_tmp.pdb' + add parm1 domain=[1,5,4,10],values=2 + add parm2 type='polc', domain=[1,5,4,10], values=[2,0.1], nx=2 + adddef parmdef values=[3,1], nx=2 + quit +EOF""") + +### NOTE: parmdbm always returns exit code 0, so we cannot test if it worked +if createTestFile() != 0: + raise RuntimeError("Could not create parmdb for tpyparmdb") def showValues (pdb, pattern='*', nf=4, nt=2): # Get the names. - print pdb.getNames() + print(pdb.getNames()) # Get the range. rng = pdb.getRange() - print rng + print(rng) # Get the values. - print pdb.getValuesStep(pattern, rng[0], rng[2], nf, rng[1], rng[3], nt, True) + print(pdb.getValuesStep(pattern, rng[0], rng[2], nf, rng[1], rng[3], nt, True)) # Get values and grid. - print pdb.getValuesGrid(pattern, rng[0], rng[2], rng[1], rng[3]) + print(pdb.getValuesGrid(pattern, rng[0], rng[2], rng[1], rng[3])) # Print default names and values. - print pdb.getDefNames(pattern); - print pdb.getDefValues(pattern) + print(pdb.getDefNames(pattern)) + print(pdb.getDefValues(pattern)) # The test is the same as in tParmFacade.cc. # Open the parameterset (created in .run file). pdb=parmdb("tpyparmdb_tmp.pdb") -print ">>>" -print pdb.version("tree") -print pdb.version("full") -print pdb.version("top") -print pdb.version() -print "<<<" +print(">>>") +print(pdb.version("tree")) +print(pdb.version("full")) +print(pdb.version("top")) +print(pdb.version()) +print("<<<") showValues (pdb); showValues (pdb, '', 1); showValues (pdb, 'parm1', 1); diff --git a/CEP/pyparmdb/test/tpyparmdb.run b/CEP/pyparmdb/test/tpyparmdb.run deleted file mode 100755 index c64c4ee3360..00000000000 --- a/CEP/pyparmdb/test/tpyparmdb.run +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh - -parmdbm <<EOF > tpyparmdb_tmp.pdbout - create tablename='tpyparmdb_tmp.pdb' - add parm1 domain=[1,5,4,10],values=2 - add parm2 type='polc', domain=[1,5,4,10], values=[2,0.1], nx=2 - adddef parmdef values=[3,1], nx=2 - quit -EOF -if [ $? != 0 ]; then - cat tpyparmdb_tmp.pdbout - exit 1 -fi - -python tpyparmdb.py diff --git a/CMake/FindBoost.cmake b/CMake/FindBoost.cmake index 61dad5ba235..ec13e7ce786 100644 --- a/CMake/FindBoost.cmake +++ b/CMake/FindBoost.cmake @@ -58,6 +58,24 @@ foreach(_comp ${Boost_FIND_COMPONENTS}) endif(DEFINED USE_BOOST_${_COMP} AND NOT USE_BOOST_${_COMP}) endforeach(_comp ${Boost_FIND_COMPONENTS}) +# For python3, append the python component with a suffix +if("${Boost_FIND_COMPONENTS}" MATCHES "python") + find_package(Python) + if(PYTHON_FOUND) + if(PYTHON_VERSION_MAJOR GREATER 2) + if(APPLE) + # On apple (homebrew), boost-python for python 3 is called boost-python3 + string(REPLACE "python" "python3" Boost_FIND_COMPONENTS "${Boost_FIND_COMPONENTS}") + else(APPLE) + # On ubuntu, boost-python for python 3 is called e.g. boost-python-py35 + string(REPLACE "python" "python-py${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}" Boost_FIND_COMPONENTS "${Boost_FIND_COMPONENTS}") + endif(APPLE) + endif(PYTHON_VERSION_MAJOR GREATER 2) + else(PYTHON_FOUND) + message(SEND_ERROR "boost-python was requested but python was not found.") + endif(PYTHON_FOUND) +endif("${Boost_FIND_COMPONENTS}" MATCHES "python") + # Call the "real" FindBoost module. include(${CMAKE_ROOT}/Modules/FindBoost.cmake) diff --git a/CMake/FindCasacore.cmake b/CMake/FindCasacore.cmake index cf824314f79..8652068af55 100644 --- a/CMake/FindCasacore.cmake +++ b/CMake/FindCasacore.cmake @@ -5,6 +5,9 @@ # casa, coordinates, derivedmscal, fits, images, lattices, meas, # measures, mirlib, ms, msfits, python, scimath, scimath_f, tables # +# The component python will be replaced by python3 if the version of the +# python interpreter found is >= 3. +# # Note that most components are dependent on other (more basic) components. # In that case, it suffices to specify the "top-level" components; dependent # components will be searched for automatically. @@ -154,6 +157,7 @@ set(Casacore_components ms msfits python + python3 scimath scimath_f tables @@ -172,6 +176,7 @@ set(Casacore_mirlib_DEPENDENCIES) set(Casacore_ms_DEPENDENCIES measures scimath tables casa) set(Casacore_msfits_DEPENDENCIES ms fits measures tables casa) set(Casacore_python_DEPENDENCIES casa) +set(Casacore_python3_DEPENDENCIES casa) set(Casacore_scimath_DEPENDENCIES scimath_f casa) set(Casacore_scimath_f_DEPENDENCIES) set(Casacore_tables_DEPENDENCIES casa) @@ -220,6 +225,18 @@ else(NOT CASACORE_INCLUDE_DIR) # Get a list of all dependent Casacore libraries that need to be found. casacore_resolve_dependencies(_find_components ${Casacore_FIND_COMPONENTS}) + # For python3, change the python component to python3 + if("${_find_components}" MATCHES "python") + find_package(Python) + if(PYTHON_FOUND) + if(PYTHON_VERSION_MAJOR GREATER 2) + string(REPLACE "python" "python3" _find_components "${_find_components}") + endif(PYTHON_VERSION_MAJOR GREATER 2) + else(PYTHON_FOUND) + message(SEND_ERROR "casacore-python was requested but python was not found.") + endif(PYTHON_FOUND) + endif("${_find_components}" MATCHES "python") + # Find the library for each component, and handle external dependencies foreach(_comp ${_find_components}) casacore_find_library(casa_${_comp}) diff --git a/CMake/FindPython.cmake b/CMake/FindPython.cmake index b6e729e2781..ae5d0eecdc3 100644 --- a/CMake/FindPython.cmake +++ b/CMake/FindPython.cmake @@ -59,4 +59,3 @@ set(PYTHON_FOUND FALSE) if(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND) set(PYTHON_FOUND TRUE) endif(PYTHONINTERP_FOUND AND PYTHONLIBS_FOUND) - diff --git a/CMake/FindPythonModule.cmake b/CMake/FindPythonModule.cmake index 10185cda7af..190b85f210d 100644 --- a/CMake/FindPythonModule.cmake +++ b/CMake/FindPythonModule.cmake @@ -42,7 +42,7 @@ find_package(PythonInterp) # ----------------------------------------------------------------------------- include(CMakeParseArguments) -function(find_python_module _module) +macro(find_python_module _module) # Name of module in uppercase. string(TOUPPER "${_module}" _MODULE) @@ -103,4 +103,4 @@ function(find_python_module _module) endif(is_required GREATER -1) endif(NOT PYTHON_${_MODULE}_FOUND) -endfunction() +endmacro() diff --git a/CMake/testscripts/assay b/CMake/testscripts/assay index a2ceb3ee091..b9cd469c2e7 100755 --- a/CMake/testscripts/assay +++ b/CMake/testscripts/assay @@ -195,8 +195,9 @@ exit $STATUS' 0 1 2 3 15 # If there is a .py file then use it. +# Force unbuffered output to give the same behavior in python3 and python2 if [ -f "$PROG.py" ]; then - COMMAND="python $PROG.py" + COMMAND="${PYTHON_EXECUTABLE} -u $PROG.py" LOFAR_CHECKTOOL= fi diff --git a/CMake/testscripts/runctest.sh.in b/CMake/testscripts/runctest.sh.in index 052b94c0dc3..b6e935d9f20 100755 --- a/CMake/testscripts/runctest.sh.in +++ b/CMake/testscripts/runctest.sh.in @@ -42,6 +42,14 @@ export LD_LIBRARY_PATH # Add the Python build directory to PYTHONPATH. PYTHONPATH="@srcdir@:@PYTHON_BUILD_DIR@:${PYTHONPATH}"; export PYTHONPATH +# Set the Python interpreter to the one found by CMake +PYTHON_EXECUTABLE="@PYTHON_EXECUTABLE@" +# Fall back to just "python" +case $PYTHON_EXECUTABLE in + ("") PYTHON_EXECUTABLE="python" +esac +export PYTHON_EXECUTABLE + # Start CMake/testscripts/runtest.sh "@LOFAR_ROOT@/CMake/testscripts/runtest.sh" "$@" diff --git a/LCS/pyparameterset/src/__init__.py b/LCS/pyparameterset/src/__init__.py index bd37643c8fb..eb917c41b7b 100755 --- a/LCS/pyparameterset/src/__init__.py +++ b/LCS/pyparameterset/src/__init__.py @@ -19,8 +19,8 @@ # # $Id$ -from _pyparameterset import PyParameterValue -from _pyparameterset import PyParameterSet +from ._pyparameterset import PyParameterValue +from ._pyparameterset import PyParameterSet class parametervalue(PyParameterValue): """ diff --git a/LCS/pyparameterset/test/tpyparameterset.py b/LCS/pyparameterset/test/tpyparameterset.py index 92e61e32fcd..8b65375425c 100644 --- a/LCS/pyparameterset/test/tpyparameterset.py +++ b/LCS/pyparameterset/test/tpyparameterset.py @@ -1,71 +1,78 @@ +from __future__ import print_function + from lofar.parameterset import * +try: + import cPickle as pickle +except ImportError: + import pickle + def checkps (ps): - print ps.isDefined("key1") - print ps.isDefined("a.b") - print ps.get("a.b").get() - print ps.getString("a.b") - print ps.getString("a.b", "aa") - print ps.getString("aa.bb", "aa") + print(ps.isDefined("key1")) + print(ps.isDefined("a.b")) + print(ps.get("a.b").get()) + print(ps.getString("a.b")) + print(ps.getString("a.b", "aa")) + print(ps.getString("aa.bb", "aa")) - print ps.getString("a.b.lange_naam") + print(ps.getString("a.b.lange_naam")) - print ps.getBool(key="a.b.bool") - print ps.getBool("a.b.bool", False) - print ps.getBool("aa.bb", False) + print(ps.getBool(key="a.b.bool")) + print(ps.getBool("a.b.bool", False)) + print(ps.getBool("aa.bb", False)) - print ps.getInt("a.b") - print ps.getInt("a.b", 10) - print ps.getInt("aa.bb", 10) + print(ps.getInt("a.b")) + print(ps.getInt("a.b", 10)) + print(ps.getInt("aa.bb", 10)) - print ps.getFloat("a.b") - print ps.getFloat("a.b", 3.14) - print ps.getFloat("aa.bb", 3.14) - print ps.getDouble("a.b.double") + print("{:.1f}".format(ps.getFloat("a.b"))) + print("{:.1f}".format(ps.getFloat("a.b", 3.14))) + print("{:.10f}".format(ps.getFloat("aa.bb", 3.14))) + print("{:.7f}".format(ps.getDouble("a.b.double"))) - print ps.getBoolVector("vecbool") - print ps.getBoolVector("vecbool", (False,True)) - print ps.getBoolVector("aa.bb", [False,True]) + print(ps.getBoolVector("vecbool")) + print(ps.getBoolVector("vecbool", (False,True))) + print(ps.getBoolVector("aa.bb", [False,True])) - print ps.getIntVector("vec") - print ps.getIntVector("vec", (5,6)) - print ps.getIntVector("aa.bb", [5,6]) + print(ps.getIntVector("vec")) + print(ps.getIntVector("vec", (5,6))) + print(ps.getIntVector("aa.bb", [5,6])) - print ps.getFloatVector("vec") - print ps.getFloatVector("vec", (5,6)) - print ps.getFloatVector("aa.bb", [5,6]) + print(ps.getFloatVector("vec")) + print(ps.getFloatVector("vec", (5,6))) + print(ps.getFloatVector("aa.bb", [5,6])) - print ps.getDoubleVector("vec") - print ps.getDoubleVector("vec", (5,6)) - print ps.getDoubleVector("aa.bb", [5,6]) + print(ps.getDoubleVector("vec")) + print(ps.getDoubleVector("vec", (5,6))) + print(ps.getDoubleVector("aa.bb", [5,6])) - print ps.getStringVector("vec") - print ps.getStringVector("vec", ('5','6')) - print ps.getStringVector("aa.bb", ['5','6']) + print(ps.getStringVector("vec")) + print(ps.getStringVector("vec", ('5','6'))) + print(ps.getStringVector("aa.bb", ['5','6'])) - print ps.getIntVector("vecexp", True) - print ps.getIntVector("vecexp", [1,2], True) - print ps.getIntVector("aa.bb", [1,2], True) + print(ps.getIntVector("vecexp", True)) + print(ps.getIntVector("vecexp", [1,2], True)) + print(ps.getIntVector("aa.bb", [1,2], True)) pvs = ps["vecnest"] - print pvs.isVector() + print(pvs.isVector()) pvsvec = pvs.getVector() - print pvsvec[0].get() - print pvsvec[0].expand().getIntVector() - print pvsvec[1].expand().getIntVector() + print(pvsvec[0].get()) + print(pvsvec[0].expand().getIntVector()) + print(pvsvec[1].expand().getIntVector()) # Check using given parset file. checkps (parameterset("tpyparameterset.in")) -print "" +print("") # Create and check a new parset using same keys/values as in parset file. ps=parameterset() -print ">>>" -print ps.version("tree") -print ps.version("full") -print ps.version("top") -print ps.version() -print "<<<" +print(">>>") +print(ps.version("tree")) +print(ps.version("full")) +print(ps.version("top")) +print(ps.version()) +print("<<<") ps.add ("a.b", "7") ps.add ("a.b.lange_naam", "'dit \"is\" nu een andere naam geworden zonder extra spaties aan het einde want die gaan verloren bij wegschrijven + teruglezen'") ps.add ("a.b.c", "5") @@ -77,27 +84,26 @@ ps.add ("vecbool", "[true,false,true]") ps.add ("vec", "[1,2,3]") ps.add ("vecexp", "[1..3,5..10]") ps.add ("vecnest", "[[1..3,5*10],[5..10]]") -print ps.keys() +print(ps.keys()) checkps (ps) # Check if a subset can be made and its name can be read. pss = ps.makeSubset('a.') -print pss.keys() -print 'b.c =', pss.getString ('b.c') -print pss.makeSubset('b.', 'aa.bb.').keys() -print pss.makeSubset('b.').size() -print pss.makeSubset('cc').keys() # should be empty -print len(pss.makeSubset('cc')) +print(pss.keys()) +print('b.c =', pss.getString ('b.c')) +print(pss.makeSubset('b.', 'aa.bb.').keys()) +print(pss.makeSubset('b.').size()) +print(pss.makeSubset('cc').keys()) # should be empty +print(len(pss.makeSubset('cc'))) # Check the dict functionality. -print pss.dict() -print pss.dict(True) # remove quotes around strings +print(sorted(pss.dict().items())) +print(sorted(pss.dict(True).items())) # remove quotes around strings # Check str() -print str(ps) +print(str(ps)) # Check picking/unpickling -import cPickle as pickle s = pickle.dumps(ps) ps2 = pickle.loads(s) assert str(ps) == str(ps2) diff --git a/LCS/pyparameterset/test/tpyparameterset.stdout b/LCS/pyparameterset/test/tpyparameterset.stdout index 0fc009b824f..854ff79614f 100644 --- a/LCS/pyparameterset/test/tpyparameterset.stdout +++ b/LCS/pyparameterset/test/tpyparameterset.stdout @@ -128,8 +128,8 @@ b.c = 5 4 [] 0 -{'b.c': '5', 'b': '7', 'b.lange_naam': '\'dit "is" nu een andere naam geworden zonder extra spaties aan het einde want die gaan verloren bij wegschrijven + teruglezen\'', 'b.bool': 'true', 'b.double': '3.1415926'} -{'b.c': '5', 'b': '7', 'b.lange_naam': 'dit "is" nu een andere naam geworden zonder extra spaties aan het einde want die gaan verloren bij wegschrijven + teruglezen', 'b.bool': 'true', 'b.double': '3.1415926'} +[('b', '7'), ('b.bool', 'true'), ('b.c', '5'), ('b.double', '3.1415926'), ('b.lange_naam', '\'dit "is" nu een andere naam geworden zonder extra spaties aan het einde want die gaan verloren bij wegschrijven + teruglezen\'')] +[('b', '7'), ('b.bool', 'true'), ('b.c', '5'), ('b.double', '3.1415926'), ('b.lange_naam', 'dit "is" nu een andere naam geworden zonder extra spaties aan het einde want die gaan verloren bij wegschrijven + teruglezen')] a.b=7 a.b.bool=true a.b.c=5 diff --git a/LCS/pytools/include/pytools/PycBasicData.h b/LCS/pytools/include/pytools/PycBasicData.h index 85ecd8efc11..f2e12e55f72 100755 --- a/LCS/pytools/include/pytools/PycBasicData.h +++ b/LCS/pytools/include/pytools/PycBasicData.h @@ -231,11 +231,16 @@ namespace LOFAR { namespace pytools { incref(obj_ptr); // incr refcount, because ~object decrements it // Accept single values. if (PyBool_Check(obj_ptr) +#if PYTHON_VERSION_MAJOR < 3 || PyInt_Check(obj_ptr) + || PyString_Check(obj_ptr) +#else + || PyUnicode_Check(obj_ptr) +#endif || PyLong_Check(obj_ptr) || PyFloat_Check(obj_ptr) || PyComplex_Check(obj_ptr) - || PyString_Check(obj_ptr)) { + ) { extract<container_element_type> elem_proxy(py_obj); if (!elem_proxy.check()) return 0; return obj_ptr; @@ -277,12 +282,16 @@ namespace LOFAR { namespace pytools { data->convertible = storage; ContainerType& result = *((ContainerType*)storage); if (PyBool_Check(obj_ptr) +#if PYTHON_VERSION_MAJOR < 3 || PyInt_Check(obj_ptr) + || PyString_Check(obj_ptr) +#else + || PyUnicode_Check(obj_ptr) +#endif || PyLong_Check(obj_ptr) || PyFloat_Check(obj_ptr) || PyComplex_Check(obj_ptr) - || PyString_Check(obj_ptr)) { - /// || PyString_Check(obj_ptr) + ) { /// || PycArrayScalarCheck(obj_ptr)) { extract<container_element_type> elem_proxy(obj_ptr); ConversionPolicy::reserve(result, 1); diff --git a/LCS/pytools/test/tConvert.py b/LCS/pytools/test/tConvert.py index 551ebbe1738..3b245086108 100755 --- a/LCS/pytools/test/tConvert.py +++ b/LCS/pytools/test/tConvert.py @@ -1,30 +1,32 @@ #!/usr/bin/env python +from __future__ import print_function + from _tConvert import * def dotest(t): - print '' - print 'begin dotest' - print t.testbool (True); - print t.testbool (False); - print t.testint (-1); - print t.testint (10L); - print t.testint64 (-123456789013L); - print t.testint64 (123456789014L); - print t.testssize (-2); - print t.testssize (11); - print t.testfloat (3.14); - print t.testfloat (12); - print t.teststring ("this is a string"); + print('') + print('begin dotest') + print(t.testbool (True)) + print(t.testbool (False)) + print(t.testint (-1)) + print(t.testint (10)) + print(t.testint64 (-123456789013)) + print(t.testint64 (123456789014)) + print(t.testssize (-2)) + print(t.testssize (11)) + print(t.testfloat (3.14)) + print(t.testfloat (12)) + print(t.teststring ("this is a string")) - print t.testvecint ([1,2,3,4]); - print t.testvecint ([]); - print t.testvecint ((-1,-2,-3,-4)); - print t.testvecint (-10); - print t.testveccomplex ([1+2j, -1-3j, -1.5+2.5j]); - print t.testvecstr (["a1","a2","b1","b2"]) - print t.testvecstr (()) - print t.testvecstr ("sc1") + print(t.testvecint ([1,2,3,4])) + print(t.testvecint ([])) + print(t.testvecint ((-1,-2,-3,-4))) + print(t.testvecint (-10)) + print(t.testveccomplex ([1+2j, -1-3j, -1.5+2.5j])) + print(t.testvecstr (["a1","a2","b1","b2"])) + print(t.testvecstr (())) + print(t.testvecstr ("sc1")) t = tConvert(); diff --git a/lofar_config.h.cmake b/lofar_config.h.cmake index 6ff3b27b943..80ce0102abe 100644 --- a/lofar_config.h.cmake +++ b/lofar_config.h.cmake @@ -174,6 +174,9 @@ /* Define if WCSLIB is installed */ #cmakedefine HAVE_WCSLIB 1 +/* Define if python3 is installed */ +#cmakedefine PYTHON_VERSION_MAJOR ${PYTHON_VERSION_MAJOR} + /*-------------------------------------------------------------------------*\ | Defines for the presence or absence of (system) functions | -- GitLab