From 01b83b74e29ffd048e3054b0baf66bd3069c8829 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:12:24 +0200 Subject: [PATCH 01/68] Add CMake files --- CMakeLists.txt | 52 ++++++++++++++++++++++++++++++++++++++ cmake/Anaconda.cmake | 11 ++++++++ cmake/CXX14.cmake | 25 ++++++++++++++++++ cmake/FindPlantGL.cmake | 33 ++++++++++++++++++++++++ cmake/FindPython.cmake | 11 ++++++++ src/cpp/CMakeLists.txt | 27 ++++++++++++++++++++ src/wrapper/CMakeLists.txt | 24 ++++++++++++++++++ 7 files changed, 183 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/Anaconda.cmake create mode 100644 cmake/CXX14.cmake create mode 100644 cmake/FindPlantGL.cmake create mode 100644 cmake/FindPython.cmake create mode 100644 src/cpp/CMakeLists.txt create mode 100644 src/wrapper/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..bf5b0aa3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,52 @@ +# --- L-Py Project + +cmake_minimum_required(VERSION 3.12) +project(lpy_project CXX) + +# --- CMake Modules + +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +include("Anaconda") +include("CXX14") + +# --- (Win32) Multithreaded Compilation + +if (MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W0") +endif() + +# --- Libraries + +find_package(Threads REQUIRED) +find_package(Python REQUIRED) +find_package(Qt5Core CONFIG REQUIRED) +find_package(Qt5Concurrent CONFIG REQUIRED) +find_package(PlantGL REQUIRED) + +# Boost +if (DEFINED CONDA_ENV) + set(BOOST_ROOT ${CONDA_ENV}) + set(BOOST_LIBRARYDIR "${BOOST_ROOT}/lib") +endif() + +set(Boost_NO_SYSTEM_PATHS ON) +set(Boost_USE_MULTITHREAD ON) +set(Boost_USE_STATIC_LIBS OFF) + +find_package(Boost 1.67 COMPONENTS ${BOOST_PYTHON_LIB} REQUIRED) + +# --- Include Directories + +include_directories("src/cpp") + +include_directories(${Boost_INCLUDE_DIR}) + +# --- Library Directory + +link_directories("${CONDA_ENV}/lib") + +# --- Source Directories + +add_subdirectory("src/cpp") +add_subdirectory("src/wrapper") diff --git a/cmake/Anaconda.cmake b/cmake/Anaconda.cmake new file mode 100644 index 00000000..f03509ea --- /dev/null +++ b/cmake/Anaconda.cmake @@ -0,0 +1,11 @@ +# Anaconda Check +if (DEFINED ENV{CONDA_PREFIX}) + # Anaconda Environment + message(STATUS "Anaconda environment detected.") + + if (WIN32) + set(CONDA_ENV "$ENV{CONDA_PREFIX}/Library") + else() + set(CONDA_ENV "$ENV{CONDA_PREFIX}") + endif() +endif() diff --git a/cmake/CXX14.cmake b/cmake/CXX14.cmake new file mode 100644 index 00000000..268b9685 --- /dev/null +++ b/cmake/CXX14.cmake @@ -0,0 +1,25 @@ +# Compiler Check +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + # Clang (Min 3.4) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) + message(FATAL_ERROR "Clang 3.4 or greater is required.") + endif() +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + # GCC (Min 5.1) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1) + message(FATAL_ERROR "GCC 5.1 or greater is required.") + endif() +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + # Visual C++ (Min 14.0) + if (MSVC_VERSION LESS 1900) + message(FATAL_ERROR "Microsoft Visual C++ 14.0 (Visual Studio 2015) or greater is required.") + endif() +else() + # Other Compilers + message(WARNING "You are using an unknown compiler. It may not be supported.") +endif() + +# C++14 Standard +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/cmake/FindPlantGL.cmake b/cmake/FindPlantGL.cmake new file mode 100644 index 00000000..bbfcf55e --- /dev/null +++ b/cmake/FindPlantGL.cmake @@ -0,0 +1,33 @@ +# Include Directory +find_path(PLANTGL_INCLUDE_DIR "plantgl/plantgl.h" "libplantgl/plantgl.h" PATHS $ENV{PATH}) + +# Library Directory +find_library(PLANTGL_ALGO_LIBRARY NAMES "pglalgo" "libpglalgo" PATHS $ENV{PATH}) +find_library(PLANTGL_GUI_LIBRARY NAMES "pglgui" "libpglgui" PATHS $ENV{PATH}) +find_library(PLANTGL_MATH_LIBRARY NAMES "pglmath" "libpglmath" PATHS $ENV{PATH}) +find_library(PLANTGL_SG_LIBRARY NAMES "pglsg" "libpglsg" PATHS $ENV{PATH}) +find_library(PLANTGL_TOOL_LIBRARY NAMES "pgltool" "libpgltool" PATHS $ENV{PATH}) + +if (PLANTGL_INCLUDE_DIR AND PLANTGL_ALGO_LIBRARY AND PLANTGL_GUI_LIBRARY AND PLANTGL_MATH_LIBRARY AND PLANTGL_SG_LIBRARY AND PLANTGL_TOOL_LIBRARY) + set(PLANTGL_FOUND ON) + set(PLANTGL_INCLUDE_DIRS ${PLANTGL_INCLUDE_DIR}) + set(PLANTGL_LIBRARIES ${PLANTGL_ALGO_LIBRARY} ${PLANTGL_GUI_LIBRARY} ${PLANTGL_MATH_LIBRARY} ${PLANTGL_SG_LIBRARY} ${PLANTGL_TOOL_LIBRARY}) + + # PlantGL found + message(STATUS "Found PlantGL: TRUE") +else() + set(PLANTGL_FOUND OFF) + + if (PlantGL_FIND_REQUIRED) + # PlantGL not found + message(SEND_ERROR "Unable to find PlantGL library.") + endif() +endif() + +if (PLANTGL_FOUND) + # Build with PlantGL + include_directories(${PLANTGL_INCLUDE_DIRS}) + +elseif (NOT PlantGL_FIND_REQUIRED) + message(STATUS "Building without PlantGL - Library not found.") +endif() diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake new file mode 100644 index 00000000..60a6e1e3 --- /dev/null +++ b/cmake/FindPython.cmake @@ -0,0 +1,11 @@ +find_package(Python3 COMPONENTS Development REQUIRED) + +if (Python3_FOUND) + if (Python3_VERSION_MINOR LESS 6) + message(SEND_ERROR "Python 3.6 or greater is required.") + else() + include_directories(${Python3_INCLUDE_DIRS}) + endif() + + set(BOOST_PYTHON_LIB "python3${Python3_VERSION_MINOR}") +endif() diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt new file mode 100644 index 00000000..13621e94 --- /dev/null +++ b/src/cpp/CMakeLists.txt @@ -0,0 +1,27 @@ +# --- Source Files + +file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") + +add_library(lpy SHARED ${SRC_FILES}) + +# --- Linked Libraries + +target_link_libraries(lpy ${PLANTGL_LIBRARIES}) +target_link_libraries(lpy Qt5::Core Qt5::Concurrent) +target_link_libraries(lpy Python3::Python) + +# Disable Boost Auto-Link +target_compile_definitions(lpy PRIVATE BOOST_ALL_NO_LIB) + +target_link_libraries(lpy Boost::${BOOST_PYTHON_LIB}) + +# --- Preprocessor + +if (WIN32) + # Export DLL on Windows + target_compile_definitions(lpy PRIVATE LPY_MAKEDLL) +endif() + +# --- Output Library + +install(TARGETS lpy LIBRARY DESTINATION "lib") diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt new file mode 100644 index 00000000..97930af4 --- /dev/null +++ b/src/wrapper/CMakeLists.txt @@ -0,0 +1,24 @@ +# --- Source Files + +file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") + +add_library(_lpy SHARED ${SRC_FILES}) + +# --- Linked Library + +target_link_libraries(_lpy lpy) +target_link_libraries(_lpy ${PLANTGL_LIBRARIES}) +target_link_libraries(_lpy Python3::Python) + +# Disable Boost Auto-Link +target_compile_definitions(_lpy PRIVATE BOOST_ALL_NO_LIB) + +target_link_libraries(_lpy Boost::${BOOST_PYTHON_LIB}) + +# --- Dependencies + +add_dependencies(_lpy lpy) + +# --- Output Library + +install(TARGETS _lpy LIBRARY DESTINATION "lib") From 23632219613f54b1f439094957add1e91cd7000f Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:12:53 +0200 Subject: [PATCH 02/68] Remove Visual Studio-related files --- src/lpy.sln | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 src/lpy.sln diff --git a/src/lpy.sln b/src/lpy.sln deleted file mode 100644 index 0766b84b..00000000 --- a/src/lpy.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lpy", "cpp\lpy.vcxproj", "{CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wraplpy", "wrapper\wraplpy.vcxproj", "{432DE2EC-508C-4072-9400-1E16CBAB9C78}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}.Debug|Win32.ActiveCfg = Debug|Win32 - {CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}.Debug|Win32.Build.0 = Debug|Win32 - {CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}.Release|Win32.ActiveCfg = Release|Win32 - {CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}.Release|Win32.Build.0 = Release|Win32 - {432DE2EC-508C-4072-9400-1E16CBAB9C78}.Debug|Win32.ActiveCfg = Debug|Win32 - {432DE2EC-508C-4072-9400-1E16CBAB9C78}.Debug|Win32.Build.0 = Debug|Win32 - {432DE2EC-508C-4072-9400-1E16CBAB9C78}.Release|Win32.ActiveCfg = Release|Win32 - {432DE2EC-508C-4072-9400-1E16CBAB9C78}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal From 1921ab46f50d3b5ae90d285b3d44b191e4face82 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:13:09 +0200 Subject: [PATCH 03/68] Remove SConscruct files --- SConstruct | 51 ------------------------------------------ src/cpp/SConscript | 23 ------------------- src/wrapper/SConscript | 21 ----------------- 3 files changed, 95 deletions(-) delete mode 100644 SConstruct delete mode 100644 src/cpp/SConscript delete mode 100644 src/wrapper/SConscript diff --git a/SConstruct b/SConstruct deleted file mode 100644 index bc1d02b0..00000000 --- a/SConstruct +++ /dev/null @@ -1,51 +0,0 @@ -# -*-python-*- - -from openalea.sconsx import config, environ -from openalea.sconsx.util.buildprefix import fix_custom_buildprefix -from openalea.sconsx.util.qt_check import detect_installed_qt_version -try: - import openalea.plantgl.config as pglconf -except ImportError: - pglconf = None - -import os - -ALEASolution = config.ALEASolution -pj= os.path.join - -name='lpy' - -options = Variables(['../options.py', 'options.py'], ARGUMENTS ) -if pglconf : - qt_version = pglconf.PGL_QT_VERSION -else: - options.Add(EnumVariable('QT_VERSION','Qt major version to use',str(detect_installed_qt_version(4)),allowed_values=('4','5'))) - - # Create an environment to access qt option values - qt_env = Environment(options=options, tools=[]) - qt_version = eval(qt_env['QT_VERSION']) - - -tools = ['boost_python', 'openalea.plantgl','qt'+str(qt_version)] - -env = ALEASolution(options, tools) -env.Append( CPPPATH = pj( '$build_includedir','lpy' ) ) -env['QT_VERSION'] = str(qt_version) - -# Build stage -prefix= env['build_prefix'] - - -from versionmanager import deployconfig -# create config files -deployconfig(env) - - -SConscript( pj(prefix,"src/cpp/SConscript"), exports={"env":env} ) - -SConscript( pj(prefix,"src/wrapper/SConscript"), exports={"env":env} ) - -Default("build") - -fix_custom_buildprefix(env) - diff --git a/src/cpp/SConscript b/src/cpp/SConscript deleted file mode 100644 index 6322bab6..00000000 --- a/src/cpp/SConscript +++ /dev/null @@ -1,23 +0,0 @@ -# -*-python-*- -Import( "env" ) -lib_env= env.Clone() -qt_version = int(lib_env['QT_VERSION']) -if qt_version == 4: - lib_env.EnableQtModules( [ 'QtCore'])# 'QtSql', 'QtXml']) -else: - lib_env.EnableQtModules( [ 'QtCore', 'QtConcurrent'])# 'QtSql', 'QtXml']) - -includes= lib_env.ALEAGlob('*.h') -sources= lib_env.ALEAGlob('*.cpp') - -# Add defines to export symbols on Windows -DEFINES= list(lib_env['CPPDEFINES']) -DEFINES.append('LPY_MAKEDLL') - -lib_env.AppendUnique(LIBS= ['pgltool','pglmath','pglsg','pglalgo','pglgui']) - -inc= lib_env.ALEAIncludes( "lpy", includes ) - -lib = lib_env.ALEALibrary( "lpy", - sources, - CPPDEFINES = DEFINES ) diff --git a/src/wrapper/SConscript b/src/wrapper/SConscript deleted file mode 100644 index af81ce7b..00000000 --- a/src/wrapper/SConscript +++ /dev/null @@ -1,21 +0,0 @@ -# -*-python-*- - -Import( "env" ) - -import os.path -pj = os.path.join - -py_dir = pj(os.path.pardir,'openalea','lpy') - -# Build wrappers as shared libraries -lib_env=env.Clone() -#lib_env.EnableQt4Modules( [ 'QtCore', 'QtGui', 'QtOpenGL', 'QtNetwork',])# 'QtSql', 'QtXml']) -#lib_env.AppendUnique( CPPPATH = ['$QT4_CPPPATH/Qt'] ) - - -sources= lib_env.ALEAGlob( '*.cpp' ) -target= "__lpy_kernel__" - -lib_env.AppendUnique(LIBS= ['lpy','pgltool','pglmath','pglsg','pglalgo','pglgui']) -lib_env.ALEAWrapper( py_dir, target, sources ) - From 8f2446321bf4882e9399e4287cfc9c51b75ab06a Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:13:54 +0200 Subject: [PATCH 04/68] Upgrade to Python 3 API --- src/wrapper/export_axialtree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/export_axialtree.cpp b/src/wrapper/export_axialtree.cpp index 9fecb3b9..4c530b00 100644 --- a/src/wrapper/export_axialtree.cpp +++ b/src/wrapper/export_axialtree.cpp @@ -215,7 +215,7 @@ boost::python::object py_varnames(AxialTree * tree) struct axialtree_from_str { static void* convertible(PyObject* py_obj){ - if( !PyString_Check( py_obj ) ) return 0; + if( !PyUnicode_Check( py_obj ) ) return 0; return py_obj; } static void construct( PyObject* obj, boost::python::converter::rvalue_from_python_stage1_data* data){ From 526c831d72f541b093e0ff7a2e19c962a3ace872 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:14:10 +0200 Subject: [PATCH 05/68] Fix wrong namespaces --- src/cpp/lpy_parser.cpp | 2 +- src/cpp/lsystem.cpp | 2 +- src/cpp/lsystem.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpp/lpy_parser.cpp b/src/cpp/lpy_parser.cpp index f0d8b1fc..b4db31f4 100644 --- a/src/cpp/lpy_parser.cpp +++ b/src/cpp/lpy_parser.cpp @@ -1582,7 +1582,7 @@ LpyParsing::parse_moddeclist(std::string::const_iterator& beg, && *_it != '\n' && *_it != ':' && *_it != '=' && *_it != '(' && *_it != '#' && *_it != delim) ++_it; std::string name(bm,_it); - if(name.empty()) LsysSyntaxError("Invalid empty name in declaration of "+TOOLS::number(nb)+" module."); + if(name.empty()) LsysSyntaxError("Invalid empty name in declaration of "+ PGL_NAMESPACE_NAME::number(nb)+" module."); else { result.push_back(ModDeclaration(name)); } while (_it != endpos && (*_it == ' ' || *_it == '\t'))++_it; if(_it == endpos) break; diff --git a/src/cpp/lsystem.cpp b/src/cpp/lsystem.cpp index e5c966b5..68bb3ec2 100644 --- a/src/cpp/lsystem.cpp +++ b/src/cpp/lsystem.cpp @@ -1205,7 +1205,7 @@ Lsystem::__recursiveInterpretation(AxialTree& workingstring, PglTurtle& turtle; LsysContext& context; - TOOLS::Sequencer timer; + PGL_NAMESPACE_NAME::Sequencer timer; inline bool earlyReturn() { return context.isEarlyReturnEnabled(); } diff --git a/src/cpp/lsystem.h b/src/cpp/lsystem.h index a95718f3..b4fe7bc4 100644 --- a/src/cpp/lsystem.h +++ b/src/cpp/lsystem.h @@ -212,7 +212,7 @@ class LPY_API Lsystem { void addSubLsystem(const std::string& lfile); void addSubLsystem(const Lsystem& sublsystem); - class LPY_API Debugger : public TOOLS::RefCountObject { + class LPY_API Debugger : public PGL_NAMESPACE_NAME::RefCountObject { public: Debugger() : alwaysStop(true) { } virtual ~Debugger() ; From 90fbd124a5d8b014c0f77a3a8a2ee681090a72f0 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:14:17 +0200 Subject: [PATCH 06/68] Update Conda build --- conda/bld.bat | 12 +++++++++--- conda/build.sh | 11 +++++++---- conda/meta.yaml | 9 +-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/conda/bld.bat b/conda/bld.bat index b3d75134..84e5d368 100644 --- a/conda/bld.bat +++ b/conda/bld.bat @@ -1,5 +1,11 @@ -COPY options_conda_win.py options.py - -%PYTHON% setup.py install +:: Working Dir +mkdir build-cmake +cd build-cmake +:: Build +cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% -DCMAKE_BUILD_TYPE=Release .. +if errorlevel 1 exit 1 +nmake +if errorlevel 1 exit 1 +nmake install if errorlevel 1 exit 1 diff --git a/conda/build.sh b/conda/build.sh index 2664d705..524bbccd 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -1,7 +1,10 @@ #!/bin/bash -export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig +# Working Dir +mkdir build-cmake +cd build-cmake -cp options_conda_build.py options.py - -$PYTHON setup.py install --prefix=$PREFIX +# Build +cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} -DCMAKE_BUILD_TYPE=Release .. +make -j${CPU_COUNT} +make install diff --git a/conda/meta.yaml b/conda/meta.yaml index 0690f095..60002a26 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -8,7 +8,6 @@ package: source: path: .. - about: home: https://github.com/openalea/lpy license: Cecill-C @@ -20,22 +19,16 @@ build: requirements: build: - - python - - setuptools - - openalea.deploy - - scons - - openalea.sconsx + - python =3 - openalea.plantgl - boost - qt - pyqt - - openalea.vpltk run: - openalea.plantgl - boost - qt - pyqt - - openalea.vpltk - ipython - qtconsole - pyopengl From 405b08fdb05d4b59818075b4e7885433ea5a91ed Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Thu, 2 May 2019 15:28:56 +0200 Subject: [PATCH 07/68] CMake: Update Conda finder --- cmake/Anaconda.cmake | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cmake/Anaconda.cmake b/cmake/Anaconda.cmake index f03509ea..056ca7fe 100644 --- a/cmake/Anaconda.cmake +++ b/cmake/Anaconda.cmake @@ -3,9 +3,6 @@ if (DEFINED ENV{CONDA_PREFIX}) # Anaconda Environment message(STATUS "Anaconda environment detected.") - if (WIN32) - set(CONDA_ENV "$ENV{CONDA_PREFIX}/Library") - else() - set(CONDA_ENV "$ENV{CONDA_PREFIX}") - endif() + set(CONDA_ENV "$ENV{CONDA_PREFIX}/Library") + set(CONDA_PYTHON_ENV "$ENV{CONDA_PREFIX}") endif() From ddeb5ff43f47193df0015bff4f387b2cedd71678 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:22:05 +0200 Subject: [PATCH 08/68] Upgrade setup.py to Python 3 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 28f25e34..4ad462c5 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ from openalea.deploy.metainfo import read_metainfo metadata = read_metainfo('metainfo.ini', verbose=True) -for key,value in metadata.iteritems(): +for key,value in metadata.items(): exec("%s = '%s'" % (key, value)) ############## @@ -22,7 +22,7 @@ # check that meta version is updated f = pj(os.path.dirname(__file__),'src', 'openalea', 'lpy','__version__.py') d = {} -execfile(f,d,d) +exec(compile(open(f, "rb").read(), f, 'exec'),d,d) version= d['LPY_VERSION_STR'] if meta_version != version: print ('Warning:: Update the version in metainfo.ini !!') From 747dd845630db4d9cf3d693826267760235fc85a Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:22:14 +0200 Subject: [PATCH 09/68] Remove setup.cfg --- setup.cfg | 63 ------------------------------------------------------- 1 file changed, 63 deletions(-) delete mode 100644 setup.cfg diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 6b71aa77..00000000 --- a/setup.cfg +++ /dev/null @@ -1,63 +0,0 @@ -# Distutils parameters file -# Use this file to specify custom parameters to pass to setup.py script -# Uncomment necessary options - -[global] -# verbose=0 - -[egg_info] -#tag_build = .dev -#tag_svn_revision = 1 - -[build] -##### scons parameters (use options.py instead) -#scons-ext-param= - -#####scons exe path -#scons-path=C:\Python24 - -#####distutils build directory -#build-lib= - -[install] - -#####openalea data directory -#external-prefix= - -[bdist_rpm] -requires = python >= 2.6 - python-VPlants.PlantGL - PyOpenGL - libQGLViewer - boost - qt - readline -build_requires = python >= 2.6 - python-devel >= 2.6 - python-setuptools >= 0.6 - python-VPlants.PlantGL - python-OpenAlea.Deploy >= 0.9 - python-OpenAlea.SConsX >= 0.9 - qt-devel - boost-devel - boost-python - readline-devel - pkgconfig - freeglut-devel -provides = %{name} = %{version} -obsoletes = %{name} < %{version} -doc_files = AUTHORS.txt ChangeLog.txt README.txt LICENSE.txt -python = /usr/bin/python -packager = OpenAlea Consortium - -[build_sphinx] -source-dir = doc/ -build-dir = doc/_build -all_files = 1 - -[nosetests] -where=test - -[upload_sphinx] -package = lpy -project = vplants From 59ae4a496bd484769b156df7e5f5b39ab32ea5fe Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:22:32 +0200 Subject: [PATCH 10/68] Update wrappers CMakeLists --- src/wrapper/CMakeLists.txt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 97930af4..32e63ce4 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -2,23 +2,27 @@ file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") -add_library(_lpy SHARED ${SRC_FILES}) +add_library(__lpy_kernel__ SHARED ${SRC_FILES}) # --- Linked Library -target_link_libraries(_lpy lpy) -target_link_libraries(_lpy ${PLANTGL_LIBRARIES}) -target_link_libraries(_lpy Python3::Python) +target_link_libraries(__lpy_kernel__ lpy) +target_link_libraries(__lpy_kernel__ ${PLANTGL_LIBRARIES}) +target_link_libraries(__lpy_kernel__ Python3::Python) # Disable Boost Auto-Link -target_compile_definitions(_lpy PRIVATE BOOST_ALL_NO_LIB) +target_compile_definitions(__lpy_kernel__ PRIVATE BOOST_ALL_NO_LIB) -target_link_libraries(_lpy Boost::${BOOST_PYTHON_LIB}) +target_link_libraries(__lpy_kernel__ Boost::${BOOST_PYTHON_LIB}) # --- Dependencies -add_dependencies(_lpy lpy) +add_dependencies(__lpy_kernel__ lpy) # --- Output Library -install(TARGETS _lpy LIBRARY DESTINATION "lib") +set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") + +install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy") +install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy_d") +install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy_wralea") From 5c52515b98f53333bd2a1ad7f81c72407ab0cd6d Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:22:43 +0200 Subject: [PATCH 11/68] Add .lib files to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 796400fe..7b726e30 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ build-scons_qt5 *.so *.dll *.dblite +*.lib # Distribution / packaging .Python From 89dfb66e6dfe637d474ce79464709baf6ccf3165 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:25:43 +0200 Subject: [PATCH 12/68] Fix old Macintosh end-of-line characters --- .../lpy/gui/plugins/curve2dmanager.py | 159 +++++++++++++++++- .../lpy/gui/plugins/functionmanager.py | 60 ++++++- 2 files changed, 217 insertions(+), 2 deletions(-) diff --git a/src/openalea/lpy/gui/plugins/curve2dmanager.py b/src/openalea/lpy/gui/plugins/curve2dmanager.py index a028bfc1..6b845764 100644 --- a/src/openalea/lpy/gui/plugins/curve2dmanager.py +++ b/src/openalea/lpy/gui/plugins/curve2dmanager.py @@ -1 +1,158 @@ -try: from openalea.plantgl.gui.curve2deditor import Curve2DEditor,Curve2DConstraint except ImportError, e: Curve2DEditor = None from openalea.plantgl.scenegraph import Polyline2D, BezierCurve2D, NurbsCurve2D, Point2Array, Point3Array from openalea.lpy.gui.abstractobjectmanager import * from OpenGL.GL import * from openalea.vpltk.qt import QtGui, QtWidgets def displayLineAsThumbnail(manager, obj, i, objectthumbwidth, color = (1,1,0,0), linecolor = (0.5,0.5,0.5,1.0)): manager.discretizer.clear() b = manager.getBoundingBox(obj) lsize = b.getSize() msize = lsize[lsize.getMaxAbsCoord()] scaling = objectthumbwidth/(2*msize) x0c = -b.getCenter()[0]*scaling y0c = -b.getCenter()[1]*scaling #display lines if 2*abs(y0c) <= objectthumbwidth: glColor4fv(linecolor) glLineWidth(1) glBegin(GL_LINE_STRIP) glVertex2f(-objectthumbwidth/2.,-y0c) glVertex2f(objectthumbwidth/2.,-y0c) glEnd() if 2*abs(x0c) <= objectthumbwidth: glColor4fv(linecolor) glLineWidth(1) glBegin(GL_LINE_STRIP) glVertex2f(x0c,-objectthumbwidth/2.) glVertex2f(x0c,objectthumbwidth/2.) glEnd() # resize and translate pgl object glScalef(scaling,-scaling,1) glTranslatef(*-b.getCenter()) pw = obj.width obj.width = 1 glColor4f(*color) glLineWidth(2) # display curve with plantgl tools obj.apply(manager.renderer) obj.width = pw class TriggerParamFunc: def __init__(self,func,*value): self.func = func self.value= value def __call__(self): self.func(*self.value) class Curve2DManager(AbstractPglObjectManager): """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" def __init__(self): AbstractPglObjectManager.__init__(self,"Curve2D") self.focusCurveColor = (1,1,0,1) self.curveColor = (0.8,0.8,0,1) self.frameColor = (0.5,0.5,0.5,1.0) def getTheme(self): return { 'Curve2D' : [ int(self.curveColor[i] *255) for i in xrange(3)], 'FocusCurve2D' : [ int(self.focusCurveColor[i] *255) for i in xrange(3)], 'FrameColor' : [ int(self.frameColor[i] *255) for i in xrange(3)] } def setTheme(self,theme): if theme.has_key('FocusCurve2D'): self.focusCurveColor = [ theme['FocusCurve2D'][i] *255 for i in xrange(3)] + [1] if theme.has_key('Curve2D'): self.curveColor = [ theme['Curve2D'][i] *255 for i in xrange(3)] + [1] if theme.has_key('FrameColor'): self.frameColor = [ theme['FrameColor'][i] *255 for i in xrange(3)] + [1] def displayThumbnail(self, obj, i , focus, objectthumbwidth): if focus : color = self.focusCurveColor else : color = self.curveColor displayLineAsThumbnail(self,obj, i , objectthumbwidth, color, self.frameColor) def createDefaultObject(self,subtype = None): nbP = 4 if subtype == 'Polyline': return Polyline2D(Point2Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)]) ) if subtype == 'BezierCurve': return BezierCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) else: return NurbsCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) def reset(self,obj): subtype = 'NurbsCurve' if isinstance(obj,Polyline2D): subtype = 'Polyline' elif isinstance(obj,BezierCurve2D): subtype = 'BezierCurve' return self.createDefaultObject(subtype) def getEditor(self,parent): if Curve2DEditor: return Curve2DEditor(parent,Curve2DConstraint()) else : return None def setObjectToEditor(self,editor,obj): """ ask for edition of obj with editor """ from copy import deepcopy editor.setCurve(deepcopy(obj)) def retrieveObjectFromEditor(self,editor): """ ask for current value of object being edited """ return editor.getCurve() def canImportData(self,fname): from os.path import splitext return splitext(fname)[1] == '.cset' def importData(self,fname): from openalea.lpy.cpfg_compat.data_import import import_contours return import_contours(fname) def defaultObjectTypes(self): return ['Polyline','BezierCurve','NurbsCurve'] def fillEditorMenu(self,menubar,editor): """ Function call to fill the menu of the editor """ menu = QtWidgets.QMenu('Curve',menubar) menu.addAction('Flip Horizontally',TriggerParamFunc(self.flipHorizontallyEditor,editor)) menu.addAction('Flip Vertically',TriggerParamFunc(self.flipVerticallyEditor,editor)) menubar.addMenu(menu) menu = QtWidgets.QMenu('Theme',menubar) menu.addAction('Black',lambda : editor.applyTheme(editor.BLACK_THEME)) menu.addAction('White',lambda : editor.applyTheme(editor.WHITE_THEME)) menubar.addMenu(menu) menu = QtWidgets.QMenu('Image',menubar) menu.addAction('Open',lambda : editor.openImage()) menu.addAction('Close',lambda : editor.closeImage()) menubar.addMenu(menu) def completeContextMenu(self,menu,obj,widget): menu.addAction('Flip Horizontally',TriggerParamFunc(self.flipHorizontally,obj,widget)) menu.addAction('Flip Vertically',TriggerParamFunc(self.flipVertically,obj,widget)) def flipHorizontallyEditor(self,editor): self.flipHorizontally(editor.getCurve(),editor) def flipHorizontally(self,obj,widget): if isinstance(obj,Polyline2D): obj.pointList = [(i.x,-i.y) for i in obj.pointList] else: obj.ctrlPointList = [(i.x,-i.y,i.z) for i in obj.ctrlPointList] widget.updateGL() def flipVerticallyEditor(self,editor): self.flipVertically(editor.getCurve(),editor) def flipVertically(self,obj,widget): if isinstance(obj,Polyline2D): obj.pointList = [(-i.x,i.y) for i in obj.pointList] else: obj.ctrlPointList = [(-i.x,i.y,i.z) for i in obj.ctrlPointList] widget.updateGL() def get_managers(): return Curve2DManager() \ No newline at end of file +try: + from openalea.plantgl.gui.curve2deditor import Curve2DEditor,Curve2DConstraint +except ImportError, e: + Curve2DEditor = None +from openalea.plantgl.scenegraph import Polyline2D, BezierCurve2D, NurbsCurve2D, Point2Array, Point3Array +from openalea.lpy.gui.abstractobjectmanager import * +from OpenGL.GL import * +from openalea.vpltk.qt import QtGui, QtWidgets + +def displayLineAsThumbnail(manager, obj, i, objectthumbwidth, color = (1,1,0,0), linecolor = (0.5,0.5,0.5,1.0)): + manager.discretizer.clear() + b = manager.getBoundingBox(obj) + lsize = b.getSize() + msize = lsize[lsize.getMaxAbsCoord()] + scaling = objectthumbwidth/(2*msize) + x0c = -b.getCenter()[0]*scaling + y0c = -b.getCenter()[1]*scaling + #display lines + if 2*abs(y0c) <= objectthumbwidth: + glColor4fv(linecolor) + glLineWidth(1) + glBegin(GL_LINE_STRIP) + glVertex2f(-objectthumbwidth/2.,-y0c) + glVertex2f(objectthumbwidth/2.,-y0c) + glEnd() + if 2*abs(x0c) <= objectthumbwidth: + glColor4fv(linecolor) + glLineWidth(1) + glBegin(GL_LINE_STRIP) + glVertex2f(x0c,-objectthumbwidth/2.) + glVertex2f(x0c,objectthumbwidth/2.) + glEnd() + # resize and translate pgl object + glScalef(scaling,-scaling,1) + glTranslatef(*-b.getCenter()) + pw = obj.width + obj.width = 1 + glColor4f(*color) + glLineWidth(2) + # display curve with plantgl tools + obj.apply(manager.renderer) + obj.width = pw + +class TriggerParamFunc: + def __init__(self,func,*value): + self.func = func + self.value= value + def __call__(self): + self.func(*self.value) + +class Curve2DManager(AbstractPglObjectManager): + """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" + def __init__(self): + AbstractPglObjectManager.__init__(self,"Curve2D") + self.focusCurveColor = (1,1,0,1) + self.curveColor = (0.8,0.8,0,1) + self.frameColor = (0.5,0.5,0.5,1.0) + + def getTheme(self): + return { 'Curve2D' : [ int(self.curveColor[i] *255) for i in xrange(3)], + 'FocusCurve2D' : [ int(self.focusCurveColor[i] *255) for i in xrange(3)], + 'FrameColor' : [ int(self.frameColor[i] *255) for i in xrange(3)] } + + def setTheme(self,theme): + if theme.has_key('FocusCurve2D'): + self.focusCurveColor = [ theme['FocusCurve2D'][i] *255 for i in xrange(3)] + [1] + if theme.has_key('Curve2D'): + self.curveColor = [ theme['Curve2D'][i] *255 for i in xrange(3)] + [1] + if theme.has_key('FrameColor'): + self.frameColor = [ theme['FrameColor'][i] *255 for i in xrange(3)] + [1] + + def displayThumbnail(self, obj, i , focus, objectthumbwidth): + if focus : color = self.focusCurveColor + else : color = self.curveColor + displayLineAsThumbnail(self,obj, i , objectthumbwidth, color, self.frameColor) + + def createDefaultObject(self,subtype = None): + nbP = 4 + if subtype == 'Polyline': + return Polyline2D(Point2Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)]) ) + if subtype == 'BezierCurve': + return BezierCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + else: + return NurbsCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + + def reset(self,obj): + subtype = 'NurbsCurve' + if isinstance(obj,Polyline2D): + subtype = 'Polyline' + elif isinstance(obj,BezierCurve2D): + subtype = 'BezierCurve' + return self.createDefaultObject(subtype) + def getEditor(self,parent): + if Curve2DEditor: + return Curve2DEditor(parent,Curve2DConstraint()) + else : return None + + def setObjectToEditor(self,editor,obj): + """ ask for edition of obj with editor """ + from copy import deepcopy + editor.setCurve(deepcopy(obj)) + + def retrieveObjectFromEditor(self,editor): + """ ask for current value of object being edited """ + return editor.getCurve() + + def canImportData(self,fname): + from os.path import splitext + return splitext(fname)[1] == '.cset' + + def importData(self,fname): + from openalea.lpy.cpfg_compat.data_import import import_contours + return import_contours(fname) + + def defaultObjectTypes(self): + return ['Polyline','BezierCurve','NurbsCurve'] + + def fillEditorMenu(self,menubar,editor): + """ Function call to fill the menu of the editor """ + menu = QtWidgets.QMenu('Curve',menubar) + menu.addAction('Flip Horizontally',TriggerParamFunc(self.flipHorizontallyEditor,editor)) + menu.addAction('Flip Vertically',TriggerParamFunc(self.flipVerticallyEditor,editor)) + menubar.addMenu(menu) + menu = QtWidgets.QMenu('Theme',menubar) + menu.addAction('Black',lambda : editor.applyTheme(editor.BLACK_THEME)) + menu.addAction('White',lambda : editor.applyTheme(editor.WHITE_THEME)) + menubar.addMenu(menu) + menu = QtWidgets.QMenu('Image',menubar) + menu.addAction('Open',lambda : editor.openImage()) + menu.addAction('Close',lambda : editor.closeImage()) + menubar.addMenu(menu) + + def completeContextMenu(self,menu,obj,widget): + menu.addAction('Flip Horizontally',TriggerParamFunc(self.flipHorizontally,obj,widget)) + menu.addAction('Flip Vertically',TriggerParamFunc(self.flipVertically,obj,widget)) + + def flipHorizontallyEditor(self,editor): + self.flipHorizontally(editor.getCurve(),editor) + + def flipHorizontally(self,obj,widget): + if isinstance(obj,Polyline2D): + obj.pointList = [(i.x,-i.y) for i in obj.pointList] + else: + obj.ctrlPointList = [(i.x,-i.y,i.z) for i in obj.ctrlPointList] + widget.updateGL() + + def flipVerticallyEditor(self,editor): + self.flipVertically(editor.getCurve(),editor) + + def flipVertically(self,obj,widget): + if isinstance(obj,Polyline2D): + obj.pointList = [(-i.x,i.y) for i in obj.pointList] + else: + obj.ctrlPointList = [(-i.x,i.y,i.z) for i in obj.ctrlPointList] + widget.updateGL() + +def get_managers(): + return Curve2DManager() diff --git a/src/openalea/lpy/gui/plugins/functionmanager.py b/src/openalea/lpy/gui/plugins/functionmanager.py index 9c1cc07e..f20f61d2 100644 --- a/src/openalea/lpy/gui/plugins/functionmanager.py +++ b/src/openalea/lpy/gui/plugins/functionmanager.py @@ -1 +1,59 @@ -try: from openalea.plantgl.gui.curve2deditor import Curve2DEditor,FuncConstraint except ImportError, e: Curve2DEditor = None from openalea.lpy.gui.abstractobjectmanager import * from curve2dmanager import displayLineAsThumbnail from openalea.vpltk.qt import QtGui, QtWidgets class FunctionManager(AbstractPglObjectManager): """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" def __init__(self): AbstractPglObjectManager.__init__(self,"Function") def displayThumbnail(self,obj,i,focus,objectthumbwidth): displayLineAsThumbnail(self,obj,i,objectthumbwidth,(1,0,1,1)) def createDefaultObject(self,subtype=None): import openalea.plantgl.all as pgl nbP = 4 return pgl.NurbsCurve2D(pgl.Point3Array([(float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) def getEditor(self,parent): if Curve2DEditor: return Curve2DEditor(parent,FuncConstraint()) else: return None def setObjectToEditor(self,editor,obj): """ ask for edition of obj with editor """ from copy import deepcopy editor.setCurve(deepcopy(obj)) def retrieveObjectFromEditor(self,editor): """ ask for current value of object being edited """ return editor.getCurve() def writeObjectToLsysContext(self,obj): return 'pgl.QuantisedFunction('+obj.name+')' def canImportData(self,fname): from os.path import splitext ext = splitext(fname)[1] return ext == '.fset' or ext == '.func' def importData(self,fname): from openalea.lpy.gui.lpfg_data_import import import_functions, import_function from os.path import splitext ext = splitext(fname)[1] if ext == '.fset': return import_functions(fname) else: return import_function(fname) def fillEditorMenu(self,menubar,editor): """ Function call to fill the menu of the editor """ menu = QtWidgets.QMenu('Theme',menubar) menu.addAction('Black',lambda : editor.applyTheme(editor.BLACK_THEME)) menu.addAction('White',lambda : editor.applyTheme(editor.WHITE_THEME)) menubar.addMenu(menu) def get_managers(): return FunctionManager() \ No newline at end of file +try: + from openalea.plantgl.gui.curve2deditor import Curve2DEditor,FuncConstraint +except ImportError, e: + Curve2DEditor = None +from openalea.lpy.gui.abstractobjectmanager import * +from curve2dmanager import displayLineAsThumbnail +from openalea.vpltk.qt import QtGui, QtWidgets + +class FunctionManager(AbstractPglObjectManager): + """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" + def __init__(self): + AbstractPglObjectManager.__init__(self,"Function") + + def displayThumbnail(self,obj,i,focus,objectthumbwidth): + displayLineAsThumbnail(self,obj,i,objectthumbwidth,(1,0,1,1)) + + def createDefaultObject(self,subtype=None): + import openalea.plantgl.all as pgl + nbP = 4 + return pgl.NurbsCurve2D(pgl.Point3Array([(float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + + def getEditor(self,parent): + if Curve2DEditor: + return Curve2DEditor(parent,FuncConstraint()) + else: return None + + def setObjectToEditor(self,editor,obj): + """ ask for edition of obj with editor """ + from copy import deepcopy + editor.setCurve(deepcopy(obj)) + + def retrieveObjectFromEditor(self,editor): + """ ask for current value of object being edited """ + return editor.getCurve() + + def writeObjectToLsysContext(self,obj): + return 'pgl.QuantisedFunction('+obj.name+')' + + def canImportData(self,fname): + from os.path import splitext + ext = splitext(fname)[1] + return ext == '.fset' or ext == '.func' + + def importData(self,fname): + from openalea.lpy.gui.lpfg_data_import import import_functions, import_function + from os.path import splitext + ext = splitext(fname)[1] + if ext == '.fset': return import_functions(fname) + else: return import_function(fname) + + def fillEditorMenu(self,menubar,editor): + """ Function call to fill the menu of the editor """ + menu = QtWidgets.QMenu('Theme',menubar) + menu.addAction('Black',lambda : editor.applyTheme(editor.BLACK_THEME)) + menu.addAction('White',lambda : editor.applyTheme(editor.WHITE_THEME)) + menubar.addMenu(menu) + +def get_managers(): + return FunctionManager() From 8c4209505d6f13ad8495b92f15aaf5b0acf0d437 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 12:51:00 +0200 Subject: [PATCH 13/68] Upgrade to Python 3 --- src/openalea/lpy/__init__.py | 12 +-- src/openalea/lpy/__lpyfuture__.py | 6 +- src/openalea/lpy/composition.py | 2 +- src/openalea/lpy/cpfg_compat/cpfg2lpy.py | 36 ++++----- src/openalea/lpy/cpfg_compat/data_import.py | 58 +++++++------- src/openalea/lpy/cpfg_compat/vafile_import.py | 46 +++++------ src/openalea/lpy/defaultparameters.py | 4 +- src/openalea/lpy/gui/compile_ui.py | 18 ++--- src/openalea/lpy/gui/computationtask.py | 6 +- src/openalea/lpy/gui/documentation.py | 4 +- src/openalea/lpy/gui/killsimulationdialog.py | 2 +- src/openalea/lpy/gui/lpycodeeditor.py | 46 +++++------ src/openalea/lpy/gui/lpydock.py | 4 +- src/openalea/lpy/gui/lpypreferences.py | 4 +- src/openalea/lpy/gui/lpyprofiling.py | 14 ++-- src/openalea/lpy/gui/lpystudio.py | 77 ++++++++++--------- src/openalea/lpy/gui/lpystudiodebugger.py | 18 ++--- src/openalea/lpy/gui/lpytabbar.py | 2 +- src/openalea/lpy/gui/lpyview3d.py | 6 +- src/openalea/lpy/gui/objectmanagers.py | 12 +-- src/openalea/lpy/gui/objectpanel.py | 38 ++++----- src/openalea/lpy/gui/optioneditordelegate.py | 2 +- .../lpy/gui/plugins/curve2dmanager.py | 26 +++---- .../lpy/gui/plugins/functionmanager.py | 4 +- .../lpy/gui/plugins/nurbspatchmanager.py | 2 +- src/openalea/lpy/gui/pymodulemonitoring.py | 13 ++-- src/openalea/lpy/gui/reformatingcode.py | 10 +-- src/openalea/lpy/gui/scalareditor.py | 4 +- src/openalea/lpy/gui/settings.py | 10 +-- src/openalea/lpy/gui/simulation.py | 74 +++++++++--------- src/openalea/lpy/gui/svnmanip.py | 24 +++--- src/openalea/lpy/parameterset.py | 8 +- src/openalea/lpy/pytranslation.py | 4 +- src/openalea/lpy/simu_environ.py | 10 +-- src/openalea/lpy_d/__init__.py | 2 +- src/openalea/lpy_wralea/__wralea__.py | 2 +- src/openalea/lpy_wralea/lpy_nodes.py | 2 +- 37 files changed, 307 insertions(+), 305 deletions(-) diff --git a/src/openalea/lpy/__init__.py b/src/openalea/lpy/__init__.py index 335d302e..30aba78e 100644 --- a/src/openalea/lpy/__init__.py +++ b/src/openalea/lpy/__init__.py @@ -1,6 +1,6 @@ -from __version__ import * -from __lpy_kernel__ import * -from parameterset import * +from .__version__ import * +from .__lpy_kernel__ import * +from .parameterset import * def __mod_getattr__(self,name): if self.hasParameter(name): return self.getParameter(name) @@ -16,7 +16,7 @@ def __mod_setattr__(self,name,value): del __mod_getattr__ del __mod_setattr__ -from __lpy_kernel__ import __setCythonAvailable,__setPythonExec +from .__lpy_kernel__ import __setCythonAvailable,__setPythonExec try: import pyximport @@ -115,7 +115,7 @@ def __init__(self, lsystem): self.axiom = self.lsystem.axiom self.nbstep = self.lsystem.derivationLength self.currentstep = -1 - def next(self): + def __next__(self): if self.currentstep == -1: self.axiom = self.lsystem.axiom self.currentstep += 1 @@ -148,7 +148,7 @@ def Lsystem__call__(self,lstring,nbsteps=None): del Lsystem__call__ def __lsystem_getattribute__(self,name): - if self.context().has_key(name): return self.context()[name] + if name in self.context(): return self.context()[name] else: raise AttributeError(name) __original_lsystem_setattr__ = Lsystem.__setattr__ diff --git a/src/openalea/lpy/__lpyfuture__.py b/src/openalea/lpy/__lpyfuture__.py index 7a2c3a35..60341c9c 100644 --- a/src/openalea/lpy/__lpyfuture__.py +++ b/src/openalea/lpy/__lpyfuture__.py @@ -15,7 +15,7 @@ def __check_discard_string(lstring): __last_string = lpy.Lstring(lstring) def enable_string_discard(endeach): - endeach_arg_nb = endeach.func_code.co_argcount + endeach_arg_nb = endeach.__code__.co_argcount if endeach_arg_nb == 0: def wrapped(lstring): global __string_discarded, __last_string @@ -60,13 +60,13 @@ def pushString( stringname ): def popString( stringname ): global __pop_string - if not __string_stack.has_key(stringname): + if stringname not in __string_stack: raise ValueError('Stack of string has not string named '+repr(stringname)) __pop_string = stringname return __string_stack[stringname] def enable_string_pushpop(endeach): - endeach_arg_nb = endeach.func_code.co_argcount + endeach_arg_nb = endeach.__code__.co_argcount def check_push_pop(lstring, res): global __push_string, __pop_string, __string_stack if not __push_string is None: diff --git a/src/openalea/lpy/composition.py b/src/openalea/lpy/composition.py index ce64b247..7147c506 100644 --- a/src/openalea/lpy/composition.py +++ b/src/openalea/lpy/composition.py @@ -37,7 +37,7 @@ def animate(self,lstring = None, nbsteps = 1, dt = 0.1): from openalea.plantgl.all import Sequencer s = Sequencer(dt) clstring = lstring - for i in xrange(nbsteps): + for i in range(nbsteps): clstring = self.derive(clstring) self.plot(clstring) s.touch() diff --git a/src/openalea/lpy/cpfg_compat/cpfg2lpy.py b/src/openalea/lpy/cpfg_compat/cpfg2lpy.py index e68d234f..6829def8 100644 --- a/src/openalea/lpy/cpfg_compat/cpfg2lpy.py +++ b/src/openalea/lpy/cpfg_compat/cpfg2lpy.py @@ -1,5 +1,5 @@ import openalea.lpy as lpy -import vafile_import as vafile +from . import vafile_import as vafile @@ -12,7 +12,7 @@ def empty_line(line): def empty_end_line(txt,index): nbchar = len(txt) if nbchar >= index : return True - for i in xrange(index,nbchar) : + for i in range(index,nbchar) : c = txt[i] if c in '\n': return True if c not in ' \t': return False @@ -194,7 +194,7 @@ def process_rule(predecessor,conditions,precondition,defs,withlineno = True): else: result += indent+'from openalea.lpy.cpfg_compat import select_successor_from_prob\n' result += indent+'successor = select_successor_from_prob(['+','.join([pb for p,s,pb,l in defs])+'])\n' - for i in xrange(len(defs)) : + for i in range(len(defs)) : postcondition, successor, prob, lineno = defs[i] result += indent if i == 0: result += 'if successor == '+str(i)+' : # see line '+str(lineno)+'\n' @@ -338,8 +338,8 @@ def process_current_rule(result, allgvar): line += nline.strip() try: predecessor, successor = line.split('-->') - except Exception, e: - print line + except Exception as e: + print(line) raise e if not ':' in predecessor and not ':' in successor: # simplest rules result += convert_lstring(predecessor) + '-->' + convert_lstring(successor) + '\n' @@ -374,7 +374,7 @@ def process_current_rule(result, allgvar): current_rule.append_succ([postcond, successor, prob,lineno]) if len(allgvar) > 0: gvardec = '# declaration of global variables used in the model\n' - gvardec += ','.join(allgvar) + ' = ' + ','.join([str(None) for i in xrange(len(allgvar))])+'\n\n' + gvardec += ','.join(allgvar) + ' = ' + ','.join([str(None) for i in range(len(allgvar))])+'\n\n' result = result[:proddecposition]+gvardec+result[proddecposition:] return result @@ -417,18 +417,18 @@ def translate_obj(fname): for sfile in sfiles: sworkspace = splitext(basename(sfile))[0] surfaces = [] - for manager in managers.itervalues(): + for manager in managers.values(): fname = join(project,sfile) if manager.canImportData(fname): try: objects = manager.importData(fname) surfaces += [(manager,i) for i in objects] groupofpatches[sworkspace] = [i.name for i in objects] - except Exception, e: + except Exception as e: import sys, traceback exc_info = sys.exc_info() traceback.print_exception(*exc_info) - print 'Cannot import file '+repr(sfile) + print('Cannot import file '+repr(sfile)) break panels += [({'name':sworkspace},surfaces)] @@ -437,17 +437,17 @@ def translate_obj(fname): if funcfiles: functions = [] for funcfile in funcfiles: - for manager in managers.itervalues(): + for manager in managers.values(): fname = join(project,funcfile) if manager.canImportData(fname): try: objects = manager.importData(fname) functions += [(manager,i) for i in objects] - except Exception, e: + except Exception as e: import sys, traceback exc_info = sys.exc_info() traceback.print_exception(*exc_info) - print 'Cannot import file '+repr(funcfile) + print('Cannot import file '+repr(funcfile)) break panels += [({'name':'functions'},functions)] @@ -457,18 +457,18 @@ def translate_obj(fname): if fsetfiles is None: fsetfiles = [] if csetfiles is None: csetfiles = [] for fsetfile in fsetfiles+csetfiles: - for manager in managers.itervalues(): + for manager in managers.values(): fname = join(project,fsetfile) if manager.canImportData(fname): try: objects = manager.importData(fname) managedobjects = [(manager,i) for i in objects] panels += [({'name':basename(splitext(fn)[0])}, managedobjects)] - except Exception, e: + except Exception as e: import sys, traceback exc_info = sys.exc_info() traceback.print_exception(*exc_info) - print 'Cannot import file '+repr(fsetfile) + print('Cannot import file '+repr(fsetfile)) break @@ -493,7 +493,7 @@ def translate_obj(fname): l.turtle.setMaterial(i,mat) nbMaterials = l.turtle.getColorListSize() if nbMaterials > len(materials): - for i in xrange(nbMaterials-1,len(materials)-1,-1): + for i in range(nbMaterials-1,len(materials)-1,-1): l.turtle.removeColor(i) # read desciption @@ -522,7 +522,7 @@ def help(): def main(): import sys if len(sys.argv) < 2: - print help() + print(help()) return lpycode = translate_obj(sys.argv[1]) if len(sys.argv) == 3: @@ -530,7 +530,7 @@ def main(): output.write(lpycode) output.close() else: - print lpycode + print(lpycode) if __name__ == '__main__': diff --git a/src/openalea/lpy/cpfg_compat/data_import.py b/src/openalea/lpy/cpfg_compat/data_import.py index f4cc79c2..9eb74597 100644 --- a/src/openalea/lpy/cpfg_compat/data_import.py +++ b/src/openalea/lpy/cpfg_compat/data_import.py @@ -6,7 +6,7 @@ def import_contours(fn): f.readline() nbitems = int(f.readline().split()[1]) result = [] - for i in xrange(nbitems): + for i in range(nbitems): f.readline() name = f.readline().split()[1] nbpoints = int(f.readline().split()[1]) @@ -15,10 +15,10 @@ def import_contours(fn): if typecurve == 'or': samples = int(f.readline().split()[1]) points = [] - for j in xrange(nbpoints): - coord = map(float,f.readline().split()) + for j in range(nbpoints): + coord = list(map(float,f.readline().split())) point = Vector4(coord[:3]+[1]) - for k in xrange(int(coord[3])): + for k in range(int(coord[3])): points.append(point) if sum([p.z for p in points]) > 0: n = NurbsCurve(points) @@ -36,15 +36,15 @@ def import_functions(fn): f.readline() # funcgalleryver 1 1 nbitems = int(f.readline().split()[1]) # items: 10 result = [] - for i in xrange(nbitems): + for i in range(nbitems): f.readline() # fver 1 1 name = f.readline().split()[1] # name: BR_LEN_0 samples = int(f.readline().split()[1]) # samples: 5 f.readline() # flip: off nbpoints = int(f.readline().split()[1]) # points: 4 points = [] - for j in xrange(nbpoints): - coord = map(float,f.readline().split()) # 0.000000 0.577929 + for j in range(nbpoints): + coord = list(map(float,f.readline().split())) # 0.000000 0.577929 point = Vector3(coord+[1]) points.append(point) n = NurbsCurve2D(points) @@ -61,8 +61,8 @@ def import_function(fn): f.readline() # range 0, 1 nbpoints = int(f.readline().split()[1]) # points: 4 points = [] - for j in xrange(nbpoints): - coord = map(float,f.readline().split()) # 0.000000 0.577929 + for j in range(nbpoints): + coord = list(map(float,f.readline().split())) # 0.000000 0.577929 point = Vector3(coord+[1]) points.append(point) result = NurbsCurve2D(points) @@ -70,7 +70,7 @@ def import_function(fn): result.name = name return result -linetofloat = lambda l : map(float,l.split()) +linetofloat = lambda l : list(map(float,l.split())) def vec3inline(l,i,j,k): values = l.split() return Vector3(float(values[i]),float(values[j]),float(values[k])) @@ -80,34 +80,34 @@ def import_patch(fn): f = open(fn,'r') base = splitext(basename(fn))[0] # read header of the file - f.next() # bbox - nextline = f.next() + next(f) # bbox + nextline = next(f) # PRECISION S: s T: t if nextline.split()[0] == 'PRECISION': - nextline = f.next() + nextline = next(f) # CONTACT POINT X: x Y: y Z: z contact = vec3inline(nextline,3,5,7) # END POINT X: x Y: y Z: z - f.next() + next(f) # HEADING X: x Y: y Z: z - heading = vec3inline(f.next(),2,4,6) + heading = vec3inline(next(f),2,4,6) l = heading.normalize() # UP X: x Y: y Z: z - up = vec3inline(f.next(),2,4,6) + up = vec3inline(next(f),2,4,6) up.normalize() # SIZE: x size = float(f.next().split()[1]) patchlist = [] while True : try : - nextline = f.next() + nextline = next(f) except: break nextline = nextline.strip() dobreak = False while len(nextline) == 0 : try : - nextline = f.next() + nextline = next(f) nextline = nextline.strip() except: dobreak = True @@ -120,13 +120,13 @@ def import_patch(fn): # AL: patch1 A: patch2 AR: patch3 # L: patch4 R: patch5 # BL: patch6 B: patch7 BR: patch8 - for i in xrange(4): f.next() + for i in range(4): next(f) ctrlpoints = [] left = heading^up m = Matrix3(-up,-left,heading) #m = Matrix3(-left, -heading, up) m = m.inverse() - for i in xrange(4): + for i in range(4): v = f.next().split() row = [] for j in range(4): @@ -146,7 +146,7 @@ def import_colormap(fn): import array a = array.array('B') a.fromfile(open(fn,'rb'),256*3) - return [Material('Color_'+str(i),Color3(a[3*i],a[3*i+1],a[3*i+2]),diffuse=0) for i in xrange(256)] + return [Material('Color_'+str(i),Color3(a[3*i],a[3*i+1],a[3*i+2]),diffuse=0) for i in range(256)] def import_materialmap(fn): import array @@ -156,16 +156,16 @@ def import_materialmap(fn): a = array.array('B') try: a.fromfile(stream,15) - except Exception,e: + except Exception as e: break valiter = iter(a) - id = valiter.next() - transparency = valiter.next() - ambient = (valiter.next(),valiter.next(),valiter.next()) - diffuse = (valiter.next(),valiter.next(),valiter.next()) - emission = Color3(valiter.next(),valiter.next(),valiter.next()) - specular = Color3(valiter.next(),valiter.next(),valiter.next()) - shininess = valiter.next() + id = next(valiter) + transparency = next(valiter) + ambient = (next(valiter),next(valiter),next(valiter)) + diffuse = (next(valiter),next(valiter),next(valiter)) + emission = Color3(next(valiter),next(valiter),next(valiter)) + specular = Color3(next(valiter),next(valiter),next(valiter)) + shininess = next(valiter) sdiffuse = sum(diffuse) sambient = sum(ambient) if sdiffuse > 0 and sambient > 0: diff --git a/src/openalea/lpy/cpfg_compat/vafile_import.py b/src/openalea/lpy/cpfg_compat/vafile_import.py index 10f98c7f..c3a63ce6 100644 --- a/src/openalea/lpy/cpfg_compat/vafile_import.py +++ b/src/openalea/lpy/cpfg_compat/vafile_import.py @@ -4,7 +4,7 @@ def parse_config_file(ctext): cline = cline.strip() if len(cline) > 1 and cline[:2] != '/*': key, value = cline.split(':',1) - if config.has_key(key): + if key in config: nvalue = config[key] if type(nvalue) != list: nvalue = [nvalue] nvalue.append(value) @@ -17,48 +17,48 @@ def get_view_info(vconfig): vlpyinitconfig = {} angle_increment = None - if vconfig.has_key('angle factor'): + if 'angle factor' in vconfig: angle_increment = 360 / float(vconfig['angle factor']) - if vconfig.has_key('angle increment'): + if 'angle increment' in vconfig: angle_increment = float(vconfig['angle increment']) if angle_increment: vlpyconfig['AngleIncrement'] = angle_increment - if vconfig.has_key('initial color'): + if 'initial color' in vconfig: vlpyinitconfig['initial_color'] = int(vconfig['initial color'].split()[0]) - if vconfig.has_key('color increment'): + if 'color increment' in vconfig: vlpyconfig['ColorIncrement'] = int(vconfig['color increment'].split()[0]) unit = None - if vconfig.has_key('initial line width'): + if 'initial line width' in vconfig: val,unit = vconfig['initial line width'].split() vlpyinitconfig['initial_line_width'] = float(val) if unit == 'p' or unit == 'pixels': vlpyinitconfig['initial_line_width'] /= 10 - if vconfig.has_key('line width increment'): + if 'line width increment' in vconfig: vlpyconfig['WidthIncrement'] = float(vconfig['line width increment']) if unit == 'p' or unit == 'pixels': vlpyconfig['WidthIncrement'] /= 10 - if vconfig.has_key('initial scale'): + if 'initial scale' in vconfig: vlpyinitconfig['initial_scale'] = float(vconfig['initial scale']) - if vconfig.has_key('scale multiplier'): + if 'scale multiplier' in vconfig: vlpyconfig['ScaleMultiplier'] = float(vconfig['scale multiplier']) - if vconfig.has_key('tropism direction'): - vlpyconfig['tropism_direction'] = map(float,vconfig['tropism direction'].split(',')) + if 'tropism direction' in vconfig: + vlpyconfig['tropism_direction'] = list(map(float,vconfig['tropism direction'].split(','))) - if vconfig.has_key('initial elasticity'): + if 'initial elasticity' in vconfig: vlpyinitconfig['initial_elasticity'] = float(vconfig['initial elasticity']) - if vconfig.has_key('elasticity increment'): + if 'elasticity increment' in vconfig: vlpyconfig['ElasticityIncrement'] = float(vconfig['elasticity increment']) surfaces = None - if vconfig.has_key('surface'): + if 'surface' in vconfig: values = vconfig['surface'] if type(values) != list: values = [values] surfaces = dict() @@ -71,13 +71,13 @@ def get_view_info(vconfig): def translate_view_init(vlpyinitconfig): res = '' - if vlpyinitconfig.has_key('initial_color'): + if 'initial_color' in vlpyinitconfig: res += ',('+str(vlpyinitconfig['initial_color'])+')' - if vlpyinitconfig.has_key('initial_line_width'): + if 'initial_line_width' in vlpyinitconfig: res += '_('+str(vlpyinitconfig['initial_line_width'])+')' - if vlpyinitconfig.has_key('initial_scale'): + if 'initial_scale' in vlpyinitconfig: res += '@D('+str(vlpyinitconfig['initial_scale'])+')' - if vlpyinitconfig.has_key('initial_elasticity'): + if 'initial_elasticity' in vlpyinitconfig: res += '@Ts('+str(vlpyinitconfig['initial_elasticity'])+')' return res @@ -85,21 +85,21 @@ def generate_view_code(vlpyconfig,groupofpatches = None): import os.path code = '# Turtle attributes \n' for att in ['AngleIncrement','ColorIncrement','WidthIncrement','ScaleMultiplier']: - if vlpyconfig.has_key(att): + if att in vlpyconfig: code += 'context().turtle.set'+att+'('+str(vlpyconfig[att])+')\n' - if vlpyconfig.has_key('tropism direction'): + if 'tropism direction' in vlpyconfig: val = vlpyconfig['tropism direction'] code += 'context().turtle.setTropism('+str((val[0],val[2],val[1]))+')\n' if groupofpatches and len(groupofpatches) > 0: code += '# Patch gathering \n' code += 'import openalea.plantgl.all as pgl\n' - for group,patches in groupofpatches.iteritems(): + for group,patches in groupofpatches.items(): code += group+' = pgl.Group(['+','.join(patches)+'])\n' code += group+'.name = '+repr(group)+'\n' - if vlpyconfig.has_key('surfaces'): + if 'surfaces' in vlpyconfig: code += '# Patch declaration in turtle \n' - for name, value in vlpyconfig['surfaces'].iteritems(): + for name, value in vlpyconfig['surfaces'].items(): fname,scale = value code += 'context().turtle.setSurface('+repr(name)+',pgl.Scaled('+str(scale)+','+os.path.splitext(fname)[0]+'))\n' return code diff --git a/src/openalea/lpy/defaultparameters.py b/src/openalea/lpy/defaultparameters.py index b367ea6d..92dcfc92 100644 --- a/src/openalea/lpy/defaultparameters.py +++ b/src/openalea/lpy/defaultparameters.py @@ -40,7 +40,7 @@ def default_parameters_wrapper(function): def wrapper(*args, **kwargs): l = LocalsRetriever(function) params, res = l(*args,**kwargs) - map(get_caller_frame().f_locals.setdefault, params.keys(), params.values()) + list(map(get_caller_frame().f_locals.setdefault, list(params.keys()), list(params.values()))) return res return wrapper @@ -74,7 +74,7 @@ def myparams(i): import inspect if len(inspect.getargspec(function).args) == 0: params, res = LocalsRetriever(function)() - map(get_caller_frame().f_locals.setdefault, params.keys(), params.values()) + list(map(get_caller_frame().f_locals.setdefault, list(params.keys()), list(params.values()))) return function else: return default_parameters_wrapper(function) diff --git a/src/openalea/lpy/gui/compile_ui.py b/src/openalea/lpy/gui/compile_ui.py index ea1f53bb..da998df5 100644 --- a/src/openalea/lpy/gui/compile_ui.py +++ b/src/openalea/lpy/gui/compile_ui.py @@ -1,10 +1,10 @@ -from openalea.vpltk.qt import qt -from openalea.vpltk.qt.uic import compileUi, compile_args +from openalea.plantgl.gui.qt import qt +from openalea.plantgl.gui.qt.uic import compileUi, compile_args import os import sys -from openalea.vpltk.qt import QT_API, PYQT5_API, PYQT4_API, PYSIDE_API +from openalea.plantgl.gui.qt import QT_API, PYQT5_API, PYQT4_API, PYSIDE_API def get_uifnames_from(fname): uiprefix = os.path.splitext(fname)[0] @@ -19,7 +19,7 @@ def get_rcfnames_from(fname): def compile_ui(uifname): """ compile a Ui """ pyfname = get_uifnames_from(uifname) - fstream = file(pyfname,'w') + fstream = open(pyfname,'w') compileUi(uifname, fstream, **compile_args) fstream.close() @@ -33,7 +33,7 @@ def def_exe(suffix = ''): exe = 'pyrcc4'+suffix return exe - if os.environ.has_key('CONDA_PREFIX'): + if 'CONDA_PREFIX' in os.environ: exe = def_exe() elif sys.platform == 'darwin': exe = def_exe('-2.7') @@ -48,8 +48,8 @@ def def_exe(suffix = ''): def detect_file_api(fname): patternapi = {'PyQt5':PYQT5_API, 'PyQt4':PYQT4_API, 'PySide':PYSIDE_API} - txt = file(fname,'r').read() - for pattern,api in patternapi.items(): + txt = open(fname,'r').read() + for pattern,api in list(patternapi.items()): if pattern in txt: return api return None @@ -61,7 +61,7 @@ def check_ui_generation(uifname): not os.path.exists(pyfname) or (os.access(pyfname,os.F_OK|os.W_OK) and os.stat(pyfname).st_mtime < os.stat(uifname).st_mtime or not api in detect_file_api(pyfname))) : - print 'Generate Ui', repr(uifname) + print('Generate Ui', repr(uifname)) compile_ui(uifname) def check_rc_generation(rcfname): @@ -72,5 +72,5 @@ def check_rc_generation(rcfname): not os.path.exists(pyfname) or (os.access(pyfname,os.F_OK|os.W_OK) and os.stat(pyfname).st_mtime < os.stat(rcfname).st_mtime or not api in detect_file_api(pyfname))) : - print 'Generate Rc', repr(rcfname) + print('Generate Rc', repr(rcfname)) compile_rc(rcfname) diff --git a/src/openalea/lpy/gui/computationtask.py b/src/openalea/lpy/gui/computationtask.py index fe786856..ae9a8343 100644 --- a/src/openalea/lpy/gui/computationtask.py +++ b/src/openalea/lpy/gui/computationtask.py @@ -38,7 +38,7 @@ def run(self): try: self.process(self) except : - self.exception = ThreadTransferException(sys.exc_type,sys.exc_value,sys.exc_traceback) + self.exception = ThreadTransferException(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]) else: self.process(self) def finalize(self): @@ -77,7 +77,7 @@ def finalizeTask(self): if not self.computationThread is None: try: self.computationThread.finalize() - except ThreadTransferException, e: + except ThreadTransferException as e: self.graberror((e.exc_type,e.exc_value,e.exc_traceback)) except: self.graberror() @@ -153,7 +153,7 @@ def graberror(self, exc_info = None, displayDialog = True): else: self.endErrorEvent(None) def getErrorMessage(self,exc_info): - print type(exc_info[1]), exc_info[1] + print(type(exc_info[1]), exc_info[1]) msg = str(exc_info[1]) if exc_info[0] == SyntaxError and len(msg) == 0: msg = exc_info[1].msg diff --git a/src/openalea/lpy/gui/documentation.py b/src/openalea/lpy/gui/documentation.py index 5b06aa40..23d849cb 100644 --- a/src/openalea/lpy/gui/documentation.py +++ b/src/openalea/lpy/gui/documentation.py @@ -157,8 +157,8 @@ def aboutVPlants(parent): def splashLPy(): try: return lpyDialog() - except Exception,e: - print e + except Exception as e: + print(e) pass def vplantsDialog(parent = None): diff --git a/src/openalea/lpy/gui/killsimulationdialog.py b/src/openalea/lpy/gui/killsimulationdialog.py index f8a8a598..91129c7d 100644 --- a/src/openalea/lpy/gui/killsimulationdialog.py +++ b/src/openalea/lpy/gui/killsimulationdialog.py @@ -5,7 +5,7 @@ py2exe_release = False from openalea.vpltk.qt import qt -from killsimulationwidget import Ui_KillSimulationDialog +from .killsimulationwidget import Ui_KillSimulationDialog from openalea.vpltk.qt.QtCore import QTimer from openalea.vpltk.qt.QtWidgets import QDialog diff --git a/src/openalea/lpy/gui/lpycodeeditor.py b/src/openalea/lpy/gui/lpycodeeditor.py index 551afc62..d66bad84 100644 --- a/src/openalea/lpy/gui/lpycodeeditor.py +++ b/src/openalea/lpy/gui/lpycodeeditor.py @@ -96,7 +96,7 @@ def setTabViewActivation(self,value): self.tabviewactivated = value self.rehighlight() def highlightBlock(self,text): - text = unicode(text) + text = str(text) if self.activated: lentxt = len(text) prevst = self.currentBlockState() @@ -183,7 +183,7 @@ def highlightBlock(self,text): index = self.tabRule.indexIn(text) if index >= 0: length = self.tabRule.matchedLength() - for i in xrange(index,index+length): + for i in range(index,index+length): if text[i] == '\t': self.setFormat(i, 1 , self.tabFormat) else: @@ -243,15 +243,15 @@ def hasMarker(self): return len(self.markers) != 0 def setMarkerAt(self,line,id): self.markers[line] = id - if self.markerStack.has_key(line): + if line in self.markerStack: del self.markerStack[line] self.update() def hasMarkerAt(self,line): - return self.markers.has_key(line) + return line in self.markers def hasMarkerTypeAt(self,line,id): - if self.markers.has_key(line) : + if line in self.markers : if self.markers[line] == id: return True - if self.markerStack.has_key(line): + if line in self.markerStack: if id in self.markerStack[line]: return True return False @@ -259,7 +259,7 @@ def getCurrentMarkerAt(self,line): return self.markers[line] def removeCurrentMarkerAt(self,line): del self.markers[line] - if self.markerStack.has_key(line): + if line in self.markerStack: self.markers[line] = self.markerStack[line].pop() if len(self.markerStack[line]) == 0: del self.markerStack[line] @@ -273,9 +273,9 @@ def removeMarkerTypeAt(self,line,id): del self.markerStack[line] self.update() def removeAllMarkersAt(self,line): - if self.marker.has_key(line): + if line in self.marker: del self.markers[line] - if self.markerStack.has_key(line): + if line in self.markerStack: del self.markerStack[line] self.update() def removeAllMarkers(self): @@ -285,7 +285,7 @@ def removeAllMarkers(self): def addMarkerAt(self,line,id): val = self.markers.get(line,None) if not val is None: - if not self.markerStack.has_key(line): + if line not in self.markerStack: self.markerStack[line] = [] self.markerStack[line].append(val) self.markers[line] = id @@ -293,7 +293,7 @@ def addMarkerAt(self,line,id): def appendMarkerAt(self,line,id): val = self.markers.get(line,None) if not val is None: - if not self.markerStack.has_key(line): + if line not in self.markerStack: self.markerStack[line] = [] self.markerStack[line].append(id) else: @@ -302,28 +302,28 @@ def appendMarkerAt(self,line,id): def defineMarker(self,id,pixmap): self.markerType[id] = pixmap def getAllMarkers(self,id): - return set([l for l,lid in self.markers.iteritems() if id == lid]).union(set([l for l,lids in self.markerStack.iteritems() if id in lids])) + return set([l for l,lid in self.markers.items() if id == lid]).union(set([l for l,lids in self.markerStack.items() if id in lids])) def decalMarkers(self,line,decal = 1): markers = {} markerStack = {} if decal < 0: - for l,v in self.markers.iteritems(): + for l,v in self.markers.items(): if l <= line+decal: markers[l] = v elif l > line: markers[l+decal] = v - for l,v in self.markerStack.iteritems(): + for l,v in self.markerStack.items(): if l <= line+decal: markerStack[l] = v elif l > line: markerStack[l+decal] = v if decal > 0: - for l,v in self.markers.iteritems(): + for l,v in self.markers.items(): if l < line: markers[l] = v else: markers[l+decal] = v - for l,v in self.markerStack.iteritems(): + for l,v in self.markerStack.items(): if l < line: markerStack[l] = v else: @@ -340,7 +340,7 @@ def restoreState(self,obj): else: self.removeAllMarkers() -ErrorMarker,BreakPointMarker,CodePointMarker = range(3) +ErrorMarker,BreakPointMarker,CodePointMarker = list(range(3)) class LpyCodeEditor(QTextEdit): def __init__(self,parent): @@ -501,7 +501,7 @@ def returnEvent(self): while txtok: ok = cursor.movePosition(QTextCursor.NextCharacter,QTextCursor.KeepAnchor) if not ok: break - txt2 = unicode(cursor.selection().toPlainText()) + txt2 = str(cursor.selection().toPlainText()) txtok = (txt2[-1] in ' \t') if txtok: txt = txt2 @@ -514,7 +514,7 @@ def returnEvent(self): while txtok: ok = cursor.movePosition(QTextCursor.PreviousCharacter,QTextCursor.KeepAnchor) if not ok: break - txt2 = unicode(cursor.selection().toPlainText()) + txt2 = str(cursor.selection().toPlainText()) txtok = (txt2[0] in ' \t') if not txtok: if txt2[0] == ':': @@ -730,7 +730,7 @@ def untab(self): if cursor.selectedText() == '\t': cursor.deleteChar() else: - for i in xrange(len(self.indentation)-1): + for i in range(len(self.indentation)-1): b = cursor.movePosition(QTextCursor.NextCharacter,QTextCursor.KeepAnchor) if not b : break if cursor.selectedText() == self.indentation: @@ -786,7 +786,7 @@ def gotoLine(self,lineno): def gotoLineFromEdit(self): self.gotoLine(int(self.gotoEdit.text())) def setLineInEdit(self): - self.gotoEdit.setText(unicode(self.textCursor().blockNumber()+1)) + self.gotoEdit.setText(str(self.textCursor().blockNumber()+1)) self.gotoEdit.selectAll() def restoreSimuState(self,simu): if self.hasError: @@ -806,7 +806,7 @@ def restoreSimuState(self,simu): def saveSimuState(self,simu): simu.code = self.getCode() if simu.textdocument is None: - print 'custom document clone' + print('custom document clone') simu.textdocument = self.document().clone() simu.cursor = self.textCursor() simu.hvalue = self.horizontalScrollBar().value() @@ -814,7 +814,7 @@ def saveSimuState(self,simu): self.sidebar.saveState(simu) def getCode(self): - return unicode(self.toPlainText()).encode('iso-8859-1','replace') + return str(self.toPlainText()).encode('iso-8859-1','replace') def codeToExecute(self): cursor = self.textCursor() diff --git a/src/openalea/lpy/gui/lpydock.py b/src/openalea/lpy/gui/lpydock.py index 28ee2125..de223844 100644 --- a/src/openalea/lpy/gui/lpydock.py +++ b/src/openalea/lpy/gui/lpydock.py @@ -1,8 +1,8 @@ from openalea.vpltk.qt import qt import debugger_ui import debugger_right_ui -from objectpanel import LpyObjectPanelDock -from lpyshell import set_shell_widget +from .objectpanel import LpyObjectPanelDock +from .lpyshell import set_shell_widget from openalea.vpltk.qt.QtCore import Qt, QCoreApplication from openalea.vpltk.qt.QtGui import QIcon, QPixmap diff --git a/src/openalea/lpy/gui/lpypreferences.py b/src/openalea/lpy/gui/lpypreferences.py index ba785294..837a9e50 100644 --- a/src/openalea/lpy/gui/lpypreferences.py +++ b/src/openalea/lpy/gui/lpypreferences.py @@ -1,9 +1,9 @@ from openalea.vpltk.qt import qt import os -from lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot +from .lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot import generate_ui -import lpyprefwidget +from . import lpyprefwidget from openalea.vpltk.qt.QtCore import QObject, pyqtSignal diff --git a/src/openalea/lpy/gui/lpyprofiling.py b/src/openalea/lpy/gui/lpyprofiling.py index c983d257..322ff7ba 100644 --- a/src/openalea/lpy/gui/lpyprofiling.py +++ b/src/openalea/lpy/gui/lpyprofiling.py @@ -3,7 +3,7 @@ from openalea.vpltk.qt.QtGui import QStandardItem, QStandardItemModel import os -AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot = range(3) +AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot = list(range(3)) class MyItem(QStandardItem): @@ -22,8 +22,8 @@ def profileItem(st,rule_table=None,timing= None, gfname = None): si = MyItem(st.code) else: n = st.code.co_name - p = '('+','.join([st.code.co_varnames[i] for i in xrange(st.code.co_argcount)])+')' - if rule_table.has_key(n): + p = '('+','.join([st.code.co_varnames[i] for i in range(st.code.co_argcount)])+')' + if n in rule_table: n = rule_table[n] n += ':'+p else: @@ -53,7 +53,7 @@ class StEntry: def __init__(self,entry): self.entry = entry if hasattr(entry,'calls') and not entry.calls is None: - self.calls = map(StEntry,list(entry.calls)) + self.calls = list(map(StEntry,list(entry.calls))) else: self.calls = [] def __getattr__(self,name): @@ -63,13 +63,13 @@ def __getattr__(self,name): statdict = {} for s in stats: statdict[s.code] = StEntry(s) - v = statdict.values() + v = list(statdict.values()) for s in v: for subs in s.calls: - if statdict.has_key(subs.code) and subs.entry.callcount == statdict[subs.code].entry.callcount: + if subs.code in statdict and subs.entry.callcount == statdict[subs.code].entry.callcount: subs.calls = statdict[subs.code].calls del statdict[subs.code] - return statdict.values() + return list(statdict.values()) class ProfileItemModel (QStandardItemModel): def __init__(self,a,b,table,lpywidget,fname): diff --git a/src/openalea/lpy/gui/lpystudio.py b/src/openalea/lpy/gui/lpystudio.py index faea4845..ba4e15e3 100644 --- a/src/openalea/lpy/gui/lpystudio.py +++ b/src/openalea/lpy/gui/lpystudio.py @@ -12,21 +12,21 @@ except: py2exe_release = False -import qt_check +from . import qt_check import openalea.vpltk.qt.QtCore try: import PyQGLViewer -except ImportError, e: +except ImportError as e: PyQGLViewer = None import traceback as tb -import documentation as doc -import settings -import lpypreferences -from simulation import LpySimulation -from killsimulationdialog import KillSimulationDialog -from objectpanel import ObjectPanelManager +from . import documentation as doc +from . import settings +from . import lpypreferences +from .simulation import LpySimulation +from .kilsimulationdialog import KillSimulationDialog +from .objectpanel import ObjectPanelManager try: import matplotlib @@ -56,11 +56,11 @@ import generate_ui -import lpydock -import lpymainwindow as lsmw -from computationtask import * -from lpystudiodebugger import LpyVisualDebugger -from lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot +from . import lpydock +from . import lpymainwindow as lsmw +from .computationtask import * +from .lpystudiodebugger import LpyVisualDebugger +from .lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot class LpyPlotter: @@ -257,11 +257,11 @@ def check_lpy_update_available(self): return available def retrieve_official_lpy_version(self): - import urllib2 + import urllib.request, urllib.error, urllib.parse versionurl = 'https://raw.githubusercontent.com/VirtualPlants/lpy/master/src/openalea/lpy/__version__.py' try: - response = urllib2.urlopen(versionurl) - except urllib2.URLError, ue: + response = urllib.request.urlopen(versionurl) + except urllib.error.URLError as ue: import openalea.lpy.__version__ as lv return lv.__version_number__, lv.LPY_VERSION_STR else: @@ -361,7 +361,7 @@ def closeDocument(self,id = None): id = self.currentSimulationId if self.simulations[id].close(): self.documentNames.removeTab(id) - for i in xrange(id+1,len(self.simulations)): + for i in range(id+1,len(self.simulations)): self.simulations[i].index = i-1 self.textEditionWatch = False @@ -457,7 +457,7 @@ def cancelTask(self): self.killsimudialog.run(self.isRunning,self.killTask) else: if self.isRunning(): - print "Force release" + print("Force release") self.releaseCR() def customEvent(self,event): self.viewer_plot(event.scene) @@ -556,7 +556,7 @@ def newfile(self): self.releaseCR() self.currentSimulation().restoreState() def recoverPreviousFiles(self): - import lpytmpfile as tf + from . import lpytmpfile as tf import os torecover = tf.getPreviousTmpLpyFiles() nbrecoverfile = len(torecover) @@ -736,7 +736,7 @@ def nextIterate(self): self.releaseCR() def debug(self): if self.debugMode == True: - self.debugger.next() + next(self.debugger) else: self.debugMode = True self.acquireCR() @@ -811,8 +811,8 @@ def clear(self): self.releaseCR() def appendInHistory(self,fname): if fname is None: - print 'Wrong added file in history' - fname = unicode(fname) + print('Wrong added file in history') + fname = str(fname) if not fname in self.history: self.history.insert(0,fname) elif fname == self.history[0]: @@ -822,7 +822,7 @@ def appendInHistory(self,fname): del self.history[self.historymaxsize:] self.createRecentMenu() def removeInHistory(self,fname): - fname = unicode(fname) + fname = str(fname) if fname in self.history: self.history.remove(fname) self.createRecentMenu() @@ -866,7 +866,7 @@ def createTutorialMenu(self): action.setIcon(iconfile) cmenu.addAction(action) def recentMenuAction(self,action): - self.openfile(unicode(action.data())) + self.openfile(str(action.data())) def clearHistory(self): self.history = [] self.createRecentMenu() @@ -897,7 +897,7 @@ def onlinehelp(self): import webbrowser webbrowser.open("http://openalea.gforge.inria.fr/dokuwiki/doku.php?id=packages:vplants:lpy:main") def initSVNMenu(self): - import svnmanip + from . import svnmanip if not svnmanip.hasSvnSupport() : self.menuSVN.setEnabled(False) else: @@ -910,7 +910,8 @@ def initSVNMenu(self): self.actionSVNIsUpToDate.triggered.connect(self.svnIsUpToDate) # QObject.connect(self.actionSVNIsUpToDate, SIGNAL('triggered(bool)'),self.svnIsUpToDate) def updateSVNMenu(self): - import svnmanip, os + from . import svnmanip + import os if svnmanip.hasSvnSupport() : fname = self.currentSimulation().fname @@ -949,20 +950,20 @@ def svnCommit(self): def versionmessage(): import openalea.lpy.__version__ as lpyversion - print 'L-Py, version '+lpyversion.LPY_VERSION_STR + print('L-Py, version '+lpyversion.LPY_VERSION_STR) def help(): versionmessage() - print 'Frederic Boudon et al., Virtual Plants, CIRAD/INRIA/INRA' - print - print 'lpy [OPTIONS] [FILES]' - print 'OPTIONS:' - print '--help : print this help' - print '--version : print version of the software.' - print '--safe | --no-safe: load settings in a safe or no safe mode' - print '--run lpyfile: run an lpymodel' - print - print 'See http://openalea.gforge.inria.fr/wiki/doku.php?id=packages:vplants:lpy:main for more documentation' + print('Frederic Boudon et al., Virtual Plants, CIRAD/INRIA/INRA') + print() + print('lpy [OPTIONS] [FILES]') + print('OPTIONS:') + print('--help : print this help') + print('--version : print version of the software.') + print('--safe | --no-safe: load settings in a safe or no safe mode') + print('--run lpyfile: run an lpymodel') + print() + print('See http://openalea.gforge.inria.fr/wiki/doku.php?id=packages:vplants:lpy:main for more documentation') def runmodel(fname): from openalea.lpy import Lsystem @@ -996,7 +997,7 @@ def main(): return toopen = [] - if len(args) > 1: toopen = map(os.path.abspath,args[1:]) + if len(args) > 1: toopen = list(map(os.path.abspath,args[1:])) qapp = QApplication([]) splash = doc.splashLPy() diff --git a/src/openalea/lpy/gui/lpystudiodebugger.py b/src/openalea/lpy/gui/lpystudiodebugger.py index 20c5a7eb..ce89484a 100644 --- a/src/openalea/lpy/gui/lpystudiodebugger.py +++ b/src/openalea/lpy/gui/lpystudiodebugger.py @@ -1,7 +1,7 @@ import openalea.lpy as lpy from openalea.vpltk.qt import qt from time import clock -from lpycodeeditor import CodePointMarker, BreakPointMarker +from . lpycodeeditor import CodePointMarker, BreakPointMarker import sys import traceback as tb @@ -35,7 +35,7 @@ def __init__(self,lpywidget): self.srcView = self.debugWidget.right.srcView self.destView = self.debugWidget.right.destView self.ruleView = self.debugWidget.right.ruleView - self.debugWidget.right.nextDebugButton.clicked.connect(self.next) # QObject.connect(self.debugWidget.right.nextDebugButton,SIGNAL('clicked()'),self.next) + self.debugWidget.right.nextDebugButton.clicked.connect(self.__next__) # QObject.connect(self.debugWidget.right.nextDebugButton,SIGNAL('clicked()'),self.next) self.debugWidget.right.animateDebugButton.clicked.connect(self.animate) # QObject.connect(self.debugWidget.right.animateDebugButton,SIGNAL('clicked()'),self.animate) self.debugWidget.right.animationDebugSlider.valueChanged.connect(self.setAnimationTiming) # QObject.connect(self.debugWidget.right.animationDebugSlider,SIGNAL('valueChanged(int)'),self.setAnimationTiming) self.debugWidget.right.endDebugButton.clicked.connect(self.continueDebug) # QObject.connect(self.debugWidget.right.endDebugButton,SIGNAL('clicked()'),self.continueDebug) @@ -46,7 +46,7 @@ def startDebugger(self): if not self.lpywidget.debugDock.isWindow(): try: docks = self.lpywidget.tabifiedDockWidget(self.lpywidget.debugDock) - except AttributeError, e: + except AttributeError as e: docks = [] id = self.lpywidget.interpreterDock if id.isVisible and not id.isWindow(): @@ -138,7 +138,7 @@ def total_match(self,pos_beg,pos_end,dest,prod_length,rule,args): self.ruleView.setText(str(rule.lineno)+': '+rule.name()) self.addMarker(rule.lineno) self.setProgress(pos_end if self.direction == lpy.eForward else pos_beg) - self.updateArgs(dict(zip(rule.parameterNames(),args))) + self.updateArgs(dict(list(zip(rule.parameterNames(),args)))) self.wait() self.delMarker() def partial_match(self,pos_beg,pos_end,dest,rule,args): @@ -146,7 +146,7 @@ def partial_match(self,pos_beg,pos_end,dest,rule,args): self.print_dest(dest) self.ruleView.setText(str(rule.lineno)+': '+rule.name()+' --> nothing produce!') self.addMarker(rule.lineno) - self.updateArgs(dict(zip(rule.parameterNames(),args))) + self.updateArgs(dict(list(zip(rule.parameterNames(),args)))) self.wait() self.delMarker() def error_match(self,pos_beg,pos_end,dest,rule,args,exc_info): @@ -154,7 +154,7 @@ def error_match(self,pos_beg,pos_end,dest,rule,args,exc_info): self.print_dest(dest) self.ruleView.setText(str(rule.lineno)+': '+rule.name()+' --> raise exception!') self.addMarker(rule.lineno) - self.updateArgs(dict(zip(rule.parameterNames(),args))) + self.updateArgs(dict(list(zip(rule.parameterNames(),args)))) tb.print_exception(*exc_info) self.lpywidget.errorEvent(exc_info) errmsg = self.lpywidget.getErrorMessage(exc_info) @@ -196,7 +196,7 @@ def wait(self): raise AbortDebugger() if self.breakPointMonitor: self.retrieveBreakPoints() - def next(self): + def __next__(self): self.waitcond.unlock() def animate(self): self.animation = True @@ -228,13 +228,13 @@ def updateArgs(self,args=None): self.simu.lsystem.context().getNamespace(d) if not self.showHidden: lpyobjects = dir(lpy) - d = dict([ (n,v) for n,v in d.iteritems() if not n in lpyobjects and (len(n) < 2 or n[0:2] != '__')]) + d = dict([ (n,v) for n,v in d.items() if not n in lpyobjects and (len(n) < 2 or n[0:2] != '__')]) self.updateTable(self.debugWidget.left.globalTable,d) def updateTable(self,table,args): model = QStandardItemModel(len(args), 2) model.setHorizontalHeaderLabels(["Name", "Value", "Type" ]) indexitem = 0 - for name,val in args.iteritems(): + for name,val in args.items(): si = QStandardItem(name) si.setEditable(False) model.setItem(indexitem, 0, si) diff --git a/src/openalea/lpy/gui/lpytabbar.py b/src/openalea/lpy/gui/lpytabbar.py index e2b6e9dc..e8b6aa31 100644 --- a/src/openalea/lpy/gui/lpytabbar.py +++ b/src/openalea/lpy/gui/lpytabbar.py @@ -1,5 +1,5 @@ from openalea.vpltk.qt import qt -import svnmanip +from . import svnmanip import os from openalea.vpltk.qt.QtCore import QObject, Qt, pyqtSignal diff --git a/src/openalea/lpy/gui/lpyview3d.py b/src/openalea/lpy/gui/lpyview3d.py index cb041473..0b3bdefb 100644 --- a/src/openalea/lpy/gui/lpyview3d.py +++ b/src/openalea/lpy/gui/lpyview3d.py @@ -5,9 +5,9 @@ from openalea.plantgl.gui.pglnqgl import * ParentClass = QGLViewer hasPyQGLViewer = True -except ImportError, e: +except ImportError as e: ParentClass = qt.QtOpenGL.QGLWidget - print 'Missing PyQGLViewer !!!!!! Unstable Lpy !!!!!!!!!' + print('Missing PyQGLViewer !!!!!! Unstable Lpy !!!!!!!!!') hasPyQGLViewer = False class LpyView3D (ParentClass): @@ -37,7 +37,7 @@ def display(self,scene = None): self.camera().setSceneBoundingBox(*bbx2qgl(bbx)) self.showEntireScene() self.updateGL() - else: print 'error computing bbox' + else: print('error computing bbox') else : self.updateGL() def draw(self): diff --git a/src/openalea/lpy/gui/objectmanagers.py b/src/openalea/lpy/gui/objectmanagers.py index fd332721..da39afb0 100644 --- a/src/openalea/lpy/gui/objectmanagers.py +++ b/src/openalea/lpy/gui/objectmanagers.py @@ -22,9 +22,9 @@ def __read_manager_plugins(): listplugins = [ splitext(basename(i))[0] for i in listplugins] listplugins = [ i for i in listplugins if i[:2] != '__'] else: - import plugins.curve2dmanager as cm - import plugins.functionmanager as fm - import plugins.nurbspatchmanager as nm + from .plugins import curve2dmanager as cm + from .plugins import functionmanager as fm + from .plugins import nurbspatchmanager as nm listplugins = [cm,fm,nm] for plugin in listplugins: plugname = plugin @@ -33,7 +33,7 @@ def __read_manager_plugins(): mod = __import__(plugname) else: mod = plugin - except ImportError,e : + except ImportError as e : exc_info = sys.exc_info() traceback.print_exception(*exc_info) warnings.warn("Cannot import "+plugin+" : "+str(e)) @@ -48,10 +48,10 @@ def __read_manager_plugins(): except: managers.append(lmanagers) #print "import manager '"+lmanagers.typename+"' from plugin '"+plugin+"'" - except Exception, e: + except Exception as e: exc_info = sys.exc_info() traceback.print_exception(*exc_info) - print dir(mod) + print(dir(mod)) warnings.warn("Cannot import "+plugin+" : "+str(e)) sys.path = oldpathes return managers diff --git a/src/openalea/lpy/gui/objectpanel.py b/src/openalea/lpy/gui/objectpanel.py index 5946e035..5abe391d 100644 --- a/src/openalea/lpy/gui/objectpanel.py +++ b/src/openalea/lpy/gui/objectpanel.py @@ -5,7 +5,7 @@ import sys, traceback, os from math import sin, pi -from objectmanagers import get_managers +from .objectmanagers import get_managers from openalea.vpltk.qt.QtCore import QObject, QPoint, Qt, pyqtSignal from openalea.vpltk.qt.QtGui import QFont, QFontMetrics, QImageWriter, QColor, QPainter @@ -37,7 +37,7 @@ def renderText(self, x, y, text, font = QFont(), color = None): try: from openalea.vpltk.qt.QtGui import QOpenGLWidget QGLParentClass = QOpenGLWidget - print 'Use QOpenGLWidget' + print('Use QOpenGLWidget') QGLParentClass.mRenderText = renderText @@ -89,7 +89,7 @@ def __call__(self): self.func(*self.value) -from objectdialog import ObjectDialog +from .objectdialog import ObjectDialog class ManagerDialogContainer (QObject): def __init__(self,panel,manager): @@ -215,13 +215,13 @@ def __init__(self,parent, panelmanager = None): self.managerDialogs = {} # dialog for editor corresponding to manager # loading managers - for typename, manager in get_managers().items(): + for typename, manager in list(get_managers().items()): try: md = ManagerDialogContainer(self,manager) md.init() self.managers[typename] = manager self.managerDialogs[manager] = md - except Exception,e: + except Exception as e: exc_info = sys.exc_info() traceback.print_exception(*exc_info) continue @@ -262,17 +262,17 @@ def __init__(self,parent, panelmanager = None): def setTheme(self,theme): self.theme.values.update(theme) - for name,value in self.theme.values.items(): + for name,value in list(self.theme.values.items()): setattr(self.theme,name,[i/255. for i in value]+[0.5 if 'humbnailBackGround' in name else 1.0]) - for m in self.managers.values(): + for m in list(self.managers.values()): m.setTheme(theme) def getTheme(self): from copy import deepcopy theme = deepcopy(self.theme.values) - for m in self.managers.values(): + for m in list(self.managers.values()): theme.update(m.getTheme()) def applyTheme(self,theme): @@ -592,9 +592,9 @@ def heigth(i,nbpoint,maxheigth=self.bgheigth,midheigth=midheigth,bottomheigth=bo else: return midheigth + ((midheigth - bottomheigth) *sin(pi*2*i/float(nbpoint-1))) - points = ([ (self.bgwidth *i / float(nbpoint-1), heigth(i,nbpoint), 0) for i in xrange(nbpoint)]+ - [ (self.bgwidth *i / float(nbpoint-1), 0, 0) for i in xrange(nbpoint)]) - indices = [ (i,i+1,nbpoint+i+1,nbpoint+i) for i in xrange(nbpoint-1)] + points = ([ (self.bgwidth *i / float(nbpoint-1), heigth(i,nbpoint), 0) for i in range(nbpoint)]+ + [ (self.bgwidth *i / float(nbpoint-1), 0, 0) for i in range(nbpoint)]) + indices = [ (i,i+1,nbpoint+i+1,nbpoint+i) for i in range(nbpoint-1)] self.bgObject = QuadSet(points,indices) def drawBackGround(self,w,h): @@ -613,7 +613,7 @@ def drawBackGround(self,w,h): glTranslatef(0,h,-10) glScalef(1,-1,1) nb = w/(self.bgwidth) - for i in xrange(int(nb)+1): + for i in range(int(nb)+1): glColor4fv(c) self.bgObject.apply(self.renderer) glTranslatef(self.bgwidth,0,0) @@ -791,7 +791,7 @@ def createContextMenuActions(self): self.editAction.setFont(f) self.editAction.triggered.connect(self.editSelection) self.newItemMenu = QMenu("New item",self) - for mname, manager in self.managers.items(): + for mname, manager in list(self.managers.items()): subtypes = manager.defaultObjectTypes() if not subtypes is None and len(subtypes) == 1: mname = subtypes[0] @@ -1009,7 +1009,7 @@ def dropEvent(self,event): self.fileDropEvent(str(event.mimeData().urls()[0].toLocalFile())) def fileDropEvent(self,fname): - for manager in self.view.managers.itervalues(): + for manager in self.view.managers.values(): if manager.canImportData(fname): objects = manager.importData(fname) self.view.appendObjects([(manager,i) for i in objects]) @@ -1096,9 +1096,9 @@ def getInfo(self): def setInfo(self,info): self.setName(info['name']) - if info.has_key('active'): + if 'active' in info: self.view.setActive(info['active']) - if info.has_key('visible'): + if 'visible' in info: self.previousVisibility = info['visible'] self.setVisible(info['visible']) @@ -1138,14 +1138,14 @@ def setObjectPanelNb(self,nb, new_visible = True): nbunusedpanels = len(self.unusedpanels) nbreused = min(nbtoadd,nbunusedpanels) if nbreused > 0: - for i in xrange(nbreused): + for i in range(nbreused): npanel,visible = self.unusedpanels.pop(0) self.panels.append(npanel) if visible: npanel.show() self.vparameterView.addAction(npanel.toggleViewAction()) if nbtoadd-nbunusedpanels > 0: - for i in xrange(nbtoadd-nbunusedpanels): + for i in range(nbtoadd-nbunusedpanels): npanel = LpyObjectPanelDock(self.parent,"Panel "+str(i+nbpanel+nbunusedpanels),self) npanel.setStatusBar(self.parent.statusBar()) npanel.valueChanged.connect(self.parent.projectEdited) @@ -1179,7 +1179,7 @@ def completeMenu(self,menu,panel): subpanelmenu = QMenu("Theme",menu) panelmenu.addSeparator() panelmenu.addMenu(subpanelmenu) - for themename,value in ObjectListDisplay.THEMES.iteritems(): + for themename,value in ObjectListDisplay.THEMES.items(): panelAction = QAction(themename,subpanelmenu) panelAction.triggered.connect(TriggerParamFunc(panel.view.applyTheme,value)) diff --git a/src/openalea/lpy/gui/optioneditordelegate.py b/src/openalea/lpy/gui/optioneditordelegate.py index 64100526..81ac3dd3 100644 --- a/src/openalea/lpy/gui/optioneditordelegate.py +++ b/src/openalea/lpy/gui/optioneditordelegate.py @@ -11,7 +11,7 @@ def createEditor(self, parent, option, index): """ Create the editor """ editor = QComboBox(parent) option = index.model().itemFromIndex(index).option - editor.addItems([option[i].name for i in xrange(len(option))]) + editor.addItems([option[i].name for i in range(len(option))]) return editor def setEditorData(self, editor, index): diff --git a/src/openalea/lpy/gui/plugins/curve2dmanager.py b/src/openalea/lpy/gui/plugins/curve2dmanager.py index 6b845764..1ef7d27c 100644 --- a/src/openalea/lpy/gui/plugins/curve2dmanager.py +++ b/src/openalea/lpy/gui/plugins/curve2dmanager.py @@ -1,6 +1,6 @@ try: from openalea.plantgl.gui.curve2deditor import Curve2DEditor,Curve2DConstraint -except ImportError, e: +except ImportError as e: Curve2DEditor = None from openalea.plantgl.scenegraph import Polyline2D, BezierCurve2D, NurbsCurve2D, Point2Array, Point3Array from openalea.lpy.gui.abstractobjectmanager import * @@ -57,17 +57,17 @@ def __init__(self): self.frameColor = (0.5,0.5,0.5,1.0) def getTheme(self): - return { 'Curve2D' : [ int(self.curveColor[i] *255) for i in xrange(3)], - 'FocusCurve2D' : [ int(self.focusCurveColor[i] *255) for i in xrange(3)], - 'FrameColor' : [ int(self.frameColor[i] *255) for i in xrange(3)] } + return { 'Curve2D' : [ int(self.curveColor[i] *255) for i in range(3)], + 'FocusCurve2D' : [ int(self.focusCurveColor[i] *255) for i in range(3)], + 'FrameColor' : [ int(self.frameColor[i] *255) for i in range(3)] } def setTheme(self,theme): - if theme.has_key('FocusCurve2D'): - self.focusCurveColor = [ theme['FocusCurve2D'][i] *255 for i in xrange(3)] + [1] - if theme.has_key('Curve2D'): - self.curveColor = [ theme['Curve2D'][i] *255 for i in xrange(3)] + [1] - if theme.has_key('FrameColor'): - self.frameColor = [ theme['FrameColor'][i] *255 for i in xrange(3)] + [1] + if 'FocusCurve2D' in theme: + self.focusCurveColor = [ theme['FocusCurve2D'][i] *255 for i in range(3)] + [1] + if 'Curve2D' in theme: + self.curveColor = [ theme['Curve2D'][i] *255 for i in range(3)] + [1] + if 'FrameColor' in theme: + self.frameColor = [ theme['FrameColor'][i] *255 for i in range(3)] + [1] def displayThumbnail(self, obj, i , focus, objectthumbwidth): if focus : color = self.focusCurveColor @@ -77,11 +77,11 @@ def displayThumbnail(self, obj, i , focus, objectthumbwidth): def createDefaultObject(self,subtype = None): nbP = 4 if subtype == 'Polyline': - return Polyline2D(Point2Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)]) ) + return Polyline2D(Point2Array([(-0.5+float(i)/(nbP-1),0) for i in range(nbP)]) ) if subtype == 'BezierCurve': - return BezierCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + return BezierCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in range(nbP)],1) ) else: - return NurbsCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + return NurbsCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in range(nbP)],1) ) def reset(self,obj): subtype = 'NurbsCurve' diff --git a/src/openalea/lpy/gui/plugins/functionmanager.py b/src/openalea/lpy/gui/plugins/functionmanager.py index f20f61d2..08941d8a 100644 --- a/src/openalea/lpy/gui/plugins/functionmanager.py +++ b/src/openalea/lpy/gui/plugins/functionmanager.py @@ -1,6 +1,6 @@ try: from openalea.plantgl.gui.curve2deditor import Curve2DEditor,FuncConstraint -except ImportError, e: +except ImportError as e: Curve2DEditor = None from openalea.lpy.gui.abstractobjectmanager import * from curve2dmanager import displayLineAsThumbnail @@ -17,7 +17,7 @@ def displayThumbnail(self,obj,i,focus,objectthumbwidth): def createDefaultObject(self,subtype=None): import openalea.plantgl.all as pgl nbP = 4 - return pgl.NurbsCurve2D(pgl.Point3Array([(float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + return pgl.NurbsCurve2D(pgl.Point3Array([(float(i)/(nbP-1),0) for i in range(nbP)],1) ) def getEditor(self,parent): if Curve2DEditor: diff --git a/src/openalea/lpy/gui/plugins/nurbspatchmanager.py b/src/openalea/lpy/gui/plugins/nurbspatchmanager.py index eec890d2..9085d550 100644 --- a/src/openalea/lpy/gui/plugins/nurbspatchmanager.py +++ b/src/openalea/lpy/gui/plugins/nurbspatchmanager.py @@ -3,7 +3,7 @@ try: from openalea.plantgl.gui.nurbspatcheditor import NurbsPatchEditor from PyQGLViewer import Vec -except ImportError, e: +except ImportError as e: NurbsPatchEditor = None from OpenGL.GL import * from math import pi diff --git a/src/openalea/lpy/gui/pymodulemonitoring.py b/src/openalea/lpy/gui/pymodulemonitoring.py index 54f7271d..aa7da461 100644 --- a/src/openalea/lpy/gui/pymodulemonitoring.py +++ b/src/openalea/lpy/gui/pymodulemonitoring.py @@ -1,3 +1,4 @@ +import importlib class ModuleMonitor: def __init__(self): @@ -6,7 +7,7 @@ def __init__(self): self.sysmodules = sys.modules def _get_current_modules(self): - return set([k for k,m in self.sysmodules.items() if not m is None]) + return set([k for k,m in list(self.sysmodules.items()) if not m is None]) def start(self): self.modules = set() @@ -24,8 +25,8 @@ def reloadall(self, verbose = True): for m in self.modules: module = self.sysmodules[m] if module: - if verbose: print 'Reload',repr(m) - reload(module) + if verbose: print('Reload',repr(m)) + importlib.reload(module) class ModuleMonitorWatcher: def __init__(self, modulemonitor): @@ -72,7 +73,7 @@ def check_local_modules(dir = '.'): pylocalmodules = glob.glob('*.pyc') pylocalmodules = set([op.join(op.abspath(dir),f) for f in pylocalmodules]) result = [] - for modname, module in sys.modules.items(): + for modname, module in list(sys.modules.items()): if not module is None and ('__file__' in module.__dict__) and (op.abspath(module.__file__) in pylocalmodules): result.append(modname) return result @@ -80,5 +81,5 @@ def check_local_modules(dir = '.'): def reload_local_modules(dir = '.', verbose = False): import sys for mod in check_local_modules(dir): - if verbose: print 'Reload', mod - reload(sys.modules[mod]) + if verbose: print('Reload', mod) + importlib.reload(sys.modules[mod]) diff --git a/src/openalea/lpy/gui/reformatingcode.py b/src/openalea/lpy/gui/reformatingcode.py index 52a98c99..4d46d90f 100644 --- a/src/openalea/lpy/gui/reformatingcode.py +++ b/src/openalea/lpy/gui/reformatingcode.py @@ -41,7 +41,7 @@ def detect_signals(filetext): toinsert = {} for oline in filetext.splitlines(True): if oline.startswith('class'): - print oline, oline.split(' \t') + print(oline, oline.split(' \t')) cclass = re.split('[ \t:(]',oline)[1] cline = iline res += oline @@ -122,7 +122,7 @@ def generate_qt_header(qt_classmap): qw = set(qwmodule.__dict__.keys()) qp = set(qpmodule.__dict__.keys()) classmap = {} - for key, value in qt_classmap.items(): + for key, value in list(qt_classmap.items()): nvalue = value.split('.') if key == 'SIGNAL': key = 'pyqtSignal' @@ -135,17 +135,17 @@ def generate_qt_header(qt_classmap): if not nvalue[1] in classmap: classmap[nvalue[1]] = [] classmap[nvalue[1]].append(key) res = '' - for key, value in classmap.items(): + for key, value in list(classmap.items()): value.sort() res += 'from openalea.vpltk.qt.'+key+' import '+', '.join(value)+'\n' return res def qth(text): - print generate_qt_header(generate_qt_classmap(text)) + print(generate_qt_header(generate_qt_classmap(text))) def simmlify_code(filetext,qt_classmap): nfiletext = filetext - for nclass, oclass in qt_classmap.items(): + for nclass, oclass in list(qt_classmap.items()): nfiletext = nfiletext.replace(oclass, nclass) return nfiletext diff --git a/src/openalea/lpy/gui/scalareditor.py b/src/openalea/lpy/gui/scalareditor.py index 5be397c0..1dea0c88 100644 --- a/src/openalea/lpy/gui/scalareditor.py +++ b/src/openalea/lpy/gui/scalareditor.py @@ -1,9 +1,9 @@ from openalea.vpltk.qt import qt -from scalar import * +from .scalar import * import generate_ui import sys -import scalarmetaedit as sme +from . import scalarmetaedit as sme from openalea.vpltk.qt.QtCore import QDataStream, QIODevice, QObject, Qt, pyqtSignal from openalea.vpltk.qt.QtGui import QBrush, QColor, QStandardItem, QStandardItemModel diff --git a/src/openalea/lpy/gui/settings.py b/src/openalea/lpy/gui/settings.py index 7abd6bae..da94b212 100644 --- a/src/openalea/lpy/gui/settings.py +++ b/src/openalea/lpy/gui/settings.py @@ -15,9 +15,9 @@ def restoreState(lpywidget): settings = getSettings() settings.beginGroup('history') - lpywidget.history = [ unicode(i) for i in list(settings.value('RecentFiles')) if not i is None and len(i) > 0] + lpywidget.history = [ str(i) for i in list(settings.value('RecentFiles')) if not i is None and len(i) > 0] try: - openedfiles = [ unicode(i) for i in list(settings.value('OpenedFiles')) if not i is None and len(i) > 0] + openedfiles = [ str(i) for i in list(settings.value('OpenedFiles')) if not i is None and len(i) > 0] except: openedfiles = '' try: @@ -117,7 +117,7 @@ def restoreState(lpywidget): settings.endGroup() if settings.status() != QSettings.NoError: - raise 'settings error' + raise Exception('settings error') del settings if lpywidget.reloadAtStartup and len(openedfiles) > 0: @@ -129,8 +129,8 @@ def restoreState(lpywidget): lpywidget.openfile(openedfiles[lastfocus]) except: pass - except Exception, e: - print "cannot restore correctly state from ini file:", e + except Exception as e: + print("cannot restore correctly state from ini file:", e) def saveState(lpywidget): settings = getSettings() diff --git a/src/openalea/lpy/gui/simulation.py b/src/openalea/lpy/gui/simulation.py index ff75cde1..edd081c6 100644 --- a/src/openalea/lpy/gui/simulation.py +++ b/src/openalea/lpy/gui/simulation.py @@ -1,15 +1,15 @@ from openalea.vpltk.qt import qt from openalea.lpy import * from openalea.plantgl.all import PglTurtle, Viewer, Material, PyStrPrinter, eStatic, eAnimatedPrimitives, eAnimatedScene -import optioneditordelegate as oed +from . import optioneditordelegate as oed import os, shutil, sys, traceback from time import clock, time -from lpystudiodebugger import AbortDebugger -from scalar import * +from .lpystudiodebugger import AbortDebugger +from .scalar import * import cProfile as profiling -from lpyprofiling import * -from lpytmpfile import * -import pymodulemonitoring as pm +from .lpyprofiling import * +from .lpytmpfile import * +from . import pymodulemonitoring as pm from openalea.vpltk.qt.QtCore import QObject, pyqtSignal @@ -83,7 +83,7 @@ def isDefault(self): if self.code != defaultcode : return False if self.textedition == True : return False if self._edited == True: return False - for i in self.desc_items.itervalues(): + for i in self.desc_items.values(): if len(i) > 0: return False ini = self.getInitialisationCode() @@ -108,7 +108,7 @@ def getTabName(self): # t += '*' return t def generateIcon(self): - import svnmanip + from . import svnmanip if self.readonly is True: pixmap = QPixmap(":/images/icons/lock.png") elif self._edited: @@ -164,7 +164,7 @@ def restoreState(self): self.lpywidget.parametersTable.setModel(self.optionModel) self.lpywidget.parametersTable.setItemDelegateForColumn(1,self.optionDelegate) self.textedition, self._edited = te, tf - for key,editor in self.lpywidget.desc_items.iteritems(): + for key,editor in self.lpywidget.desc_items.items(): editor.setText(self.desc_items[key]) self.lpywidget.setTimeStep(self.lsystem.context().animation_timestep) self.lpywidget.materialed.setTurtle(self.lsystem.context().turtle) @@ -193,7 +193,7 @@ def restoreState(self): def saveState(self): #if self.lsystem.isCurrent() :self.lsystem.done() self.lpywidget.codeeditor.saveSimuState(self) - for key,editor in self.lpywidget.desc_items.iteritems(): + for key,editor in self.lpywidget.desc_items.items(): if type(editor) == QLineEdit: self.desc_items[key] = editor.text() else: @@ -211,7 +211,7 @@ def initializeParametersTable(self): category = None categoryItem = None indexitem = 0 - for i in xrange(len(options)): + for i in range(len(options)): option = options[i] if option.category != category: category = option.category @@ -264,9 +264,9 @@ def save(self): if os.path.exists(self.fname) and self.lpywidget.fileBackupEnabled : try: shutil.copy(self.fname,self.fname+'~') - except Exception,e: - print 'Cannot create backup file',repr(self.fname+'~') - print e + except Exception as e: + print('Cannot create backup file',repr(self.fname+'~')) + print(e) self.saveToFile(self.fname) self.mtime = os.stat(self.fname).st_mtime self.lpywidget.statusBar().showMessage("Save file '"+self.fname+"'",2000) @@ -441,35 +441,35 @@ def monitorfile(self): del self.monitoring def updateSvnStatus(self): - import svnmanip + from . import svnmanip if svnmanip.hasSvnSupport(): if (not hasattr(self,'svnstatus') and svnmanip.isSvnFile(self.fname)) or (hasattr(self,'svnstatus') and svnmanip.svnFileTextStatus(self.fname) != self.svnstatus): self.updateTabName(force=True) def svnUpdate(self): - import svnmanip + from . import svnmanip hasupdated = svnmanip.svnUpdate(self.fname,self.lpywidget) if hasupdated: self.reload() self.updateSvnStatus() def svnIsUpToDate(self): - import svnmanip + from . import svnmanip svnmanip.svnIsUpToDate(self.fname,self.lpywidget) self.updateSvnStatus() def svnAdd(self): - import svnmanip + from . import svnmanip svnmanip.svnFileAdd(self.fname) self.updateSvnStatus() def svnRevert(self): - import svnmanip + from . import svnmanip svnmanip.svnFileRevert(self.fname) self.reload() self.updateSvnStatus() def svnCommit(self): - import svnmanip + from . import svnmanip svnmanip.svnFileCommit(self.fname, None, self.lpywidget) self.updateSvnStatus() @@ -536,7 +536,7 @@ def updateLsystemCode(self): lpycode = self.code lpycode += '\n'+self.getInitialisationCode(False) res = self.lsystem.set(lpycode,{},self.lpywidget.showPyCode) - if not res is None: print res + if not res is None: print(res) def getInitialisationCode(self,withall=True): code = self.initialisationFunction(withall) @@ -563,7 +563,7 @@ def initialisationFunction(self, withall=True): if self.fname and len(self.fname) > 0: printer.reference_dir = os.path.abspath(os.path.dirname(self.getStrFname())) #print printer.reference_dir - for i in xrange(nbcurrent): + for i in range(nbcurrent): cmat = currentlist[i] if ( (i >= nbdefault) or (cmat.isTexture()) or @@ -581,7 +581,7 @@ def initialisationFunction(self, withall=True): if not self.lsystem.context().is_animation_timestep_to_default(): init_txt += '\tcontext.animation_timestep = '+str(self.getTimeStep())+'\n' options = self.lsystem.context().options - for i in xrange(len(options)): + for i in range(len(options)): if not options[i].isToDefault(): init_txt += '\tcontext.options.setSelection('+repr(options[i].name)+','+str(options[i].selection)+')\n' if len(self.scalars): @@ -598,7 +598,7 @@ def emptyparameterset(params): for panelinfo,objects in self.visualparameters: if panelinfo.get('active',True) or withall: for manager,obj in objects: - if not intialized_managers.has_key(manager): + if manager not in intialized_managers: intialized_managers[manager] = True init_txt += manager.initWriting('\t') init_txt += manager.writeObject(obj,'\t') @@ -639,7 +639,7 @@ def emptyparameterset(params): def creditsCode(self): txt = '' - for key,value in self.desc_items.iteritems(): + for key,value in self.desc_items.items(): if len(value) > 0: txt += key+' = '+repr(str(value))+'\n' return txt @@ -666,37 +666,37 @@ def opencode(self,txt): exc_info = sys.exc_info() traceback.print_exception(*exc_info) init = None - if context.has_key(context.InitialisationFunctionName): + if context.InitialisationFunctionName in context: del context[context.InitialisationFunctionName] - for key in self.desc_items.iterkeys(): - if context.has_key(key): + for key in self.desc_items.keys(): + if key in context: self.desc_items[key] = context[key] if init is None: init = True else: self.desc_items[key] = '' - from objectmanagers import get_managers + from .objectmanagers import get_managers managers = get_managers() self.visualparameters = [] lpy_code_version = 1.0 - if context.has_key('__lpy_code_version__'): + if '__lpy_code_version__' in context: lpy_code_version = ['__lpy_code_version__'] - if context.has_key('__functions__') and lpy_code_version <= 1.0 : + if '__functions__' in context and lpy_code_version <= 1.0 : functions = context['__functions__'] for n,c in functions: c.name = n # self.functions = [ c for n,c in functions ] funcmanager = managers['Function'] self.visualparameters += [ ({'name':'Functions'}, [(funcmanager,func) for n,func in functions]) ] - if context.has_key('__curves__') and lpy_code_version <= 1.0 : + if '__curves__' in context and lpy_code_version <= 1.0 : curves = context['__curves__'] for n,c in curves: c.name = n # self.curves = [ c for n,c in curves ] curvemanager = managers['Curve2D'] self.visualparameters += [ ({'name':'Curve2D'}, [(curvemanager,curve) for n,curve in curves]) ] - if context.has_key('__scalars__'): + if '__scalars__' in context: scalars = context['__scalars__'] self.scalars = [ ProduceScalar(v) for v in scalars ] - if context.has_key('__parameterset__'): + if '__parameterset__' in context: def checkinfo(info): if type(info) == str: return {'name':info} @@ -708,7 +708,7 @@ def checkinfo(info): import warnings warnings.warn('initialisation failed') else: - for key in self.desc_items.iterkeys(): + for key in self.desc_items.keys(): self.desc_items[key] = '' if self.textdocument: self.lpywidget.textEditionWatch = False @@ -730,7 +730,7 @@ def post_run(self,task): self.lsystem.plot(task.result,True) plottiming = time() - plottiming self.setTree(task.result,task.dl,task.timing,plottiming) - if self.lpywidget.displayMetaInfo and not self.autorun and self.lsystem.context().has_key('__description__'): + if self.lpywidget.displayMetaInfo and not self.autorun and '__description__' in self.lsystem.context(): self.lpywidget.viewer.showMessage(self.lsystem.context()['__description__'],5000) def animate(self,task): @@ -813,7 +813,7 @@ def debug(self): self.setTree(self.lsystem.derive(self.tree,self.nbiterations,1),self.nbiterations+1) else: self.setTree(self.lsystem.derive(self.lsystem.axiom,0,1),1) - except AbortDebugger,e : + except AbortDebugger as e : self.lsystem.clearDebugger() return except : diff --git a/src/openalea/lpy/gui/svnmanip.py b/src/openalea/lpy/gui/svnmanip.py index 14d6790f..d7c53b10 100644 --- a/src/openalea/lpy/gui/svnmanip.py +++ b/src/openalea/lpy/gui/svnmanip.py @@ -1,12 +1,12 @@ from openalea.vpltk.qt import qt from openalea.vpltk.qt.QtWidgets import QDialog, QMessageBox -from settings import getSettings +from .settings import getSettings try : import pysvn has_svn = True -except ImportError, e: +except ImportError as e: has_svn = False @@ -43,9 +43,9 @@ def create_svn_client(): def get_login( realm, username, may_save ): if svn_client_gui_parent is None : - print 'Login is None' + print('Login is None') return False, '', '', False - import logindialog + from . import logindialog dialog = QDialog(svn_client_gui_parent) widget = logindialog.Ui_LoginDialog() widget.setupUi(dialog) @@ -58,7 +58,7 @@ def get_login( realm, username, may_save ): def ssl_client_cert_password_prompt( realm, may_save ): if svn_client_gui_parent is None : return False, '', False - import logindialog + from . import logindialog dialog = QDialog(svn_client_gui_parent) widget = logindialog.Ui_LoginDialog() widget.setupUi(dialog) @@ -133,7 +133,7 @@ def svnUpdate(fname, parent = None): else: if parent : QMessageBox.question(parent,'Update', 'Updated at revision %s' % rev.number) return True - except pysvn.ClientError, ce: + except pysvn.ClientError as ce: QMessageBox.warning(parent,'Update', ce.message) return False @@ -148,7 +148,7 @@ def svnFileAdd(fname): return res def get_log( parent , title = 'SVN Commit'): - import logdialog + from . import logdialog dialog = QDialog(parent) widget = logdialog.Ui_LogDialog() widget.setupUi(dialog) @@ -221,7 +221,7 @@ def svnIsUpToDate( fname, parent = None, silent = False): msg += "Status : "+str(svnFileTextStatus(fname)) QMessageBox.question(parent,'Up-to-date', msg) return True - except pysvn.ClientError, ce: + except pysvn.ClientError as ce: if not silent and parent: QMessageBox.warning(parent,'Up-to-date', ce.message) return True @@ -271,28 +271,28 @@ def isSvnFile(fname): try: res = svnFileTextStatus(fname) return (res != pysvn.wc_status_kind.unversioned and res != pysvn.wc_status_kind.none and res != pysvn.wc_status_kind.ignored) - except pysvn.ClientError,e: + except pysvn.ClientError as e: return False def isSvnModifiedFile(fname): try: res = svnFileTextStatus(fname) return (res == pysvn.wc_status_kind.modified) - except pysvn.ClientError,e: + except pysvn.ClientError as e: return False def isSvnAddedFile(fname): try: res = svnFileTextStatus(fname) return (res == pysvn.wc_status_kind.added) - except pysvn.ClientError,e: + except pysvn.ClientError as e: return False def isSSHRepository(fname): try: res = svnFileInfo(fname) return ('+ssh' in res.url) - except pysvn.ClientError,e: + except pysvn.ClientError as e: return False for d in dir(pysvn.wc_status_kind): diff --git a/src/openalea/lpy/parameterset.py b/src/openalea/lpy/parameterset.py index 8d58be95..be92c2f7 100644 --- a/src/openalea/lpy/parameterset.py +++ b/src/openalea/lpy/parameterset.py @@ -16,13 +16,13 @@ def setdefault(self, *args, **kwd): assert len(args) == 0 or len(kwd) == 0 if len(args) > 0: if len(args) % 2 != 0 : raise ValueError("Should give a list of parameter name and values") - for i in xrange(len(args)/2): + for i in range(len(args)/2): attname = args[2*i] defaultvalue = args[2*i+1] if not hasattr(self,attname): setattr(self,attname,defaultvalue) elif len(kwd) > 0: - for attname, defaultvalue in kwd.items(): + for attname, defaultvalue in list(kwd.items()): if not hasattr(self,attname): setattr(self,attname,defaultvalue) @@ -42,7 +42,7 @@ def set(self, **kwd): def parameter_names(self): """ Gives the name of the parameters """ - return self.__dict__.keys() + return list(self.__dict__.keys()) def copy(self, deep = True): """ Return a deep copy of self """ @@ -51,7 +51,7 @@ def copy(self, deep = True): else: return copy(self) def __repr__(self): - return self.__class__.__name__+'('+','.join([k+'='+repr(v) for k,v in self.__dict__.items()])+')' + return self.__class__.__name__+'('+','.join([k+'='+repr(v) for k,v in list(self.__dict__.items())])+')' def __getitem__(self, attname): return getattr(self,attname) diff --git a/src/openalea/lpy/pytranslation.py b/src/openalea/lpy/pytranslation.py index 8f6c9b3f..db657940 100644 --- a/src/openalea/lpy/pytranslation.py +++ b/src/openalea/lpy/pytranslation.py @@ -7,7 +7,7 @@ def splitmodules(text): last = it while it < len(text): c = text[it] - print it, c + print(it, c) if c.isspace(): pot = it while c.isspace() and it < len(text): @@ -42,7 +42,7 @@ def splitmodules(text): last = it else: m = ModuleClass.get(text[last:it+1]) - print repr(text[last:it+1]), m + print(repr(text[last:it+1]), m) if m is None or m.name == '': it += 1 elif it < len(text)-1 and text[it+1] == '(': diff --git a/src/openalea/lpy/simu_environ.py b/src/openalea/lpy/simu_environ.py index b2ad3453..72757d2b 100644 --- a/src/openalea/lpy/simu_environ.py +++ b/src/openalea/lpy/simu_environ.py @@ -1,5 +1,5 @@ from openalea.plantgl.all import PglTurtle, PyStrPrinter, Material -from __lpy_kernel__ import LpyParsing, LsysContext +from .__lpy_kernel__ import LpyParsing, LsysContext def getInitialisationCode(context = None, scalars = None, visualparameters = None, credits = None, colorlist = None, simplified = False, keepCode_1_0_Compatibility = False, referencedir = None): @@ -42,7 +42,7 @@ def emptyparameterset(params): for panelinfo,objects in visualparameters: if panelinfo.get('active',True) or not simplified: for manager,obj in objects: - if not intialized_managers.has_key(manager): + if manager not in intialized_managers: intialized_managers[manager] = True init_txt += manager.initWriting('\t') init_txt += manager.writeObject(obj,'\t') @@ -93,7 +93,7 @@ def colorListCode(colorlist = None, referencedir = None, indentation = '\t'): printer.line_between_object = 0 if referencedir: printer.reference_dir = referencedir - for i in xrange(nbcurrent): + for i in range(nbcurrent): cmat = colorlist[i] if ( (i >= nbdefault) or (cmat.isTexture()) or @@ -116,7 +116,7 @@ def contextOptionCode(context,indentation = '\t'): if not context.is_animation_timestep_to_default(): init_txt += '\tcontext.animation_timestep = '+str(context.animation_timestep)+'\n' options = context.options - for i in xrange(len(options)): + for i in range(len(options)): if not options[i].isToDefault(): init_txt += '\tcontext.options.setSelection('+repr(options[i].name)+','+str(options[i].selection)+')\n' return init_txt @@ -131,7 +131,7 @@ def scalarCode(scalars = None, indentation = '\t'): def creditsCode(desc_items): txt = '' - for key,value in desc_items.iteritems(): + for key,value in desc_items.items(): if len(value) > 0: txt += key+' = '+repr(str(value))+'\n' return txt diff --git a/src/openalea/lpy_d/__init__.py b/src/openalea/lpy_d/__init__.py index 97a62462..0a7de47b 100644 --- a/src/openalea/lpy_d/__init__.py +++ b/src/openalea/lpy_d/__init__.py @@ -1 +1 @@ -from __lpy_kernel__ import * \ No newline at end of file +from .__lpy_kernel__ import * \ No newline at end of file diff --git a/src/openalea/lpy_wralea/__wralea__.py b/src/openalea/lpy_wralea/__wralea__.py index e56f7995..255875dc 100644 --- a/src/openalea/lpy_wralea/__wralea__.py +++ b/src/openalea/lpy_wralea/__wralea__.py @@ -1,5 +1,5 @@ from openalea.core import * -#from lpy_nodes import WithLpyGui +#from .lpy_nodes import WithLpyGui __name__ = "vplants.l-py" __version__ = '0.0.1' diff --git a/src/openalea/lpy_wralea/lpy_nodes.py b/src/openalea/lpy_wralea/lpy_nodes.py index c30dcd8b..a5f08bfa 100644 --- a/src/openalea/lpy_wralea/lpy_nodes.py +++ b/src/openalea/lpy_wralea/lpy_nodes.py @@ -154,7 +154,7 @@ def showEvent(self,e): except: - print "Import lpy.gui has failed" + print("Import lpy.gui has failed") WithLpyGui = False LSysWidget = None From aae4db5e07407e1ffb62b9baa023757627ee33d9 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 12:51:14 +0200 Subject: [PATCH 14/68] Upgrade tests to Python 3 --- test/cembedding/test_cembedding.py | 2 +- test/test_axialtree.py | 14 ++++++------- test/test_debugger.py | 20 +++++++++---------- test/test_endeach.py | 6 +++--- test/test_execcontext.py | 6 +++--- test/test_fibonacci.py | 2 +- test/test_genscene.py | 2 +- test/test_geometry.py | 6 +++--- test/test_lpytest.py | 10 +++++----- test/test_lsystem_as_module.py | 4 ++-- test/test_lsystemiterator.py | 2 +- test/test_matching.py | 18 ++++++++--------- test/test_memory.py | 10 +++++----- test/test_modnamespace.py | 8 ++++---- test/test_nproduce.py | 10 +++++----- test/test_parsing.py | 14 ++++++------- test/test_predecessor_at_scale.py | 16 +++++++-------- test/test_regexpmatching.py | 6 +++--- test/test_selection.py | 8 ++++---- test/test_shareexamples.py | 4 ++-- test/test_starmatching.py | 32 +++++++++++++++--------------- test/test_stringmatching.py | 4 ++-- test/test_successor_at_scale.py | 14 ++++++------- test/test_tree_matching.py | 20 +++++++++---------- test/test_ui.py | 6 +++--- 25 files changed, 122 insertions(+), 122 deletions(-) diff --git a/test/cembedding/test_cembedding.py b/test/cembedding/test_cembedding.py index 8484d1da..c8715038 100644 --- a/test/cembedding/test_cembedding.py +++ b/test/cembedding/test_cembedding.py @@ -6,7 +6,7 @@ def test_embeddedlpy(): proc = subprocess.Popen(["./embeddedlpy"], stdout=subprocess.PIPE) out, err = proc.communicate() out = out.strip() - print repr(out) + print(repr(out)) assert out == "'+(90);(3)I(6765)I(4181)I(2584)I(1597)I(987)I(610)I(377)I(233)I(144)I(89)I(55)I(34)I(21)I(13)I(8)I(5)I(3)I(2)I(1)I(1)'" if __name__ == '__main__': diff --git a/test/test_axialtree.py b/test/test_axialtree.py index 277ea035..d7edd6e4 100644 --- a/test/test_axialtree.py +++ b/test/test_axialtree.py @@ -9,7 +9,7 @@ def test_repr(): l.makeCurrent() m = ParamModule('B',A()) a = AxialTree([m]) - print a + print(a) def test_well_bracketed(): l = LsysContext() @@ -76,7 +76,7 @@ def test_successor_at_level(): a = AxialTree('BA[A[A][CA]][A]B[[[CA]CA]AA]') l.setModuleScale('B,C',1) l.setModuleScale('A',2) - print a.successor_at_level(0,1) + print(a.successor_at_level(0,1)) assert a.successor_at_level(0,1) == 15 @@ -89,7 +89,7 @@ def test_successor_at_scale(): assert a.successor_at_scale(0,1) == 15 assert a.successor_at_scale(15,1) == 29 a = AxialTree('BA[[A][CA][A]A]BA[[[CA]CA]AA]') - print a.directSon(1),a.directSon(15),a.successor_at_scale(1,2) + print(a.directSon(1),a.directSon(15),a.successor_at_scale(1,2)) assert a.successor_at_scale(1,2) == 16 def test_successor_at_scale2(): @@ -108,16 +108,16 @@ def test_predecessor_at_scale(): l.setModuleScale('B,C',1) l.setModuleScale('A',2) assert a.predecessor_at_scale(15,1) == 0 - print a.predecessor_at_scale(25,2) + print(a.predecessor_at_scale(25,2)) assert a.predecessor_at_scale(25,2) == 1 if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_debugger.py b/test/test_debugger.py index a5322f78..937027ec 100644 --- a/test/test_debugger.py +++ b/test/test_debugger.py @@ -6,27 +6,27 @@ def __init__(self): def begin(self,src,direction): self.direction = direction self.src = src - print 'Axiom:',src + print('Axiom:',src) def end(self,result): - print 'Result:',result + print('Result:',result) def total_match(self,pos_beg,pos_end,dest,prod_length,rule,args): - print pos_beg,pos_end,dest,prod_length,rule,args + print(pos_beg,pos_end,dest,prod_length,rule,args) assert self.src[pos_beg].name == 'B' if self.direction == eForward: - print '*', prod_length - print dest - print self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[-prod_length:] + print('*', prod_length) + print(dest) + print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[-prod_length:]) else: - print self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[:prod_length] + print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[:prod_length]) def partial_match(self,pos_beg,pos_end,dest,rule,args): assert self.src[pos_beg].name == 'C' - print self.src[pos_beg:pos_end],'--',rule.lineno-1,'--> failed' + print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'--> failed') def identity(self,pos,dest): assert self.src[pos].name in 'AC' if self.direction == eForward: - print self.src[pos],'-- ID ->',dest[-1] + print(self.src[pos],'-- ID ->',dest[-1]) else: - print self.src[pos],'-- ID ->',dest[0] + print(self.src[pos],'-- ID ->',dest[0]) lcode = """ Axiom: BAABAC diff --git a/test/test_endeach.py b/test/test_endeach.py index 07acdbe2..079b942e 100644 --- a/test/test_endeach.py +++ b/test/test_endeach.py @@ -204,10 +204,10 @@ def test_endeach_with_return_none(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_execcontext.py b/test/test_execcontext.py index 361cd3f6..391984b3 100644 --- a/test/test_execcontext.py +++ b/test/test_execcontext.py @@ -27,10 +27,10 @@ def ctx(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_fibonacci.py b/test/test_fibonacci.py index 14f18c9b..ec68a27f 100644 --- a/test/test_fibonacci.py +++ b/test/test_fibonacci.py @@ -6,7 +6,7 @@ def test_backward(): """ Computation of the fibonnacci series using fast transfer in backward direction """ l = Lsystem(get_filename('fibonacci.lpy')) a = l.iterate() - print a + print(a) assert a[2][0] == 6765, "Lpy failed to compute fibonacci test" assert a[3][0] == 4181, "Lpy failed to compute fibonacci test" assert a[21][0] == 1, "Lpy failed to compute fibonacci test" diff --git a/test/test_genscene.py b/test/test_genscene.py index 90fc7485..a6d89457 100644 --- a/test/test_genscene.py +++ b/test/test_genscene.py @@ -5,7 +5,7 @@ def sc2dict(s): d = {} for i in s: - if not d.has_key(i.id): + if i.id not in d: d[i.id] = [] d[i.id].append(i) return d diff --git a/test/test_geometry.py b/test/test_geometry.py index ceaf7b74..b99aea54 100644 --- a/test/test_geometry.py +++ b/test/test_geometry.py @@ -45,10 +45,10 @@ def test_surface(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_lpytest.py b/test/test_lpytest.py index 3b1c6bc6..f56299ff 100644 --- a/test/test_lpytest.py +++ b/test/test_lpytest.py @@ -12,8 +12,8 @@ def exec_lpy_tst(lfile): try: l = Lsystem(lfile) l.iterate() - except Exception,e : - print 'Test file :',lfile + except Exception as e : + print('Test file :',lfile) raise e toavoid = [] @@ -25,7 +25,7 @@ def test_lpy_tests(): for lfile in get_lpy_tst(): if os.path.basename(lfile) in toavoid: continue - print lfile + print(lfile) yield exec_lpy_tst,lfile @@ -34,8 +34,8 @@ def test_diese_bug(): try: exec_lpy_tst("diese_bug.lpy") ok = False - except Exception,e: - print e + except Exception as e: + print(e) ok = True assert ok diff --git a/test/test_lsystem_as_module.py b/test/test_lsystem_as_module.py index 001a73df..9d54f484 100644 --- a/test/test_lsystem_as_module.py +++ b/test/test_lsystem_as_module.py @@ -16,9 +16,9 @@ def test_lsystem_as_module(): l.test1 = 2 assert l.test1 == 2 assert l.context()['test1'] == 2 - print 'Axiom:',l.axiom + print('Axiom:',l.axiom) l.axiom = 'B' - print l.axiom, type(l.axiom) + print(l.axiom, type(l.axiom)) assert type(l.axiom) == AxialTree and l.axiom == Lstring('B') if __name__ == '__main__': diff --git a/test/test_lsystemiterator.py b/test/test_lsystemiterator.py index 3bb5171c..e71cbe58 100644 --- a/test/test_lsystemiterator.py +++ b/test/test_lsystemiterator.py @@ -11,7 +11,7 @@ def test_iterator(): """ ) for lstring in l: - print lstring + print(lstring) if __name__ == '__main__': diff --git a/test/test_matching.py b/test/test_matching.py index e1c0a11c..73b217fd 100644 --- a/test/test_matching.py +++ b/test/test_matching.py @@ -13,7 +13,7 @@ def test_matchingmode(): l = Lsystem() modes = { 0: PatternModule.eSimple, 1: PatternModule.eWithStar , 2: PatternModule.eWithStarNValueConstraint } l.set(lcode_matchingmode) - for key,val in modes.items(): + for key,val in list(modes.items()): l.context().options.setSelection('Module matching',key) l.context()['mode'] = val l.iterate() @@ -31,7 +31,7 @@ def EndEach(): """ -def runmatch(code,optionvalues = range(3)): +def runmatch(code,optionvalues = list(range(3))): if type(optionvalues) == int: optionvalues = [optionvalues] for i in range(3): @@ -44,7 +44,7 @@ def runmatch(code,optionvalues = range(3)): try: l.set(lcodebeg+code) l.iterate() - print "Test do not fail for unsupported module matching mode : %i." % i + print("Test do not fail for unsupported module matching mode : %i." % i) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass @@ -162,7 +162,7 @@ def test_match_mod_with_valueargs(): def test_match_mod_with_stararg(): """ Test matching of module with pattern with a star arg as argument """ - runmatch(lcodemodwithstararg,range(1,3)) + runmatch(lcodemodwithstararg,list(range(1,3))) ######################################################## @@ -179,7 +179,7 @@ def test_match_mod_with_stararg(): def test_match_mod_with_stararg_for_two(): """ Test matching of module with pattern with a star arg as argument """ - runmatch(lcodemodwithstararg_for_two,range(1,3)) + runmatch(lcodemodwithstararg_for_two,list(range(1,3))) ######################################################## @@ -194,7 +194,7 @@ def test_match_mod_with_stararg_for_two(): def test_match_mod_with_stararg_for_zero(): """ Test matching of module with pattern with a star arg as argument """ - runmatch(lcodemodwithstararg_for_zero,range(1,3)) + runmatch(lcodemodwithstararg_for_zero,list(range(1,3))) ######################################################## @@ -461,10 +461,10 @@ def test_simple_match() : if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_memory.py b/test/test_memory.py index 3c20177f..2d838612 100644 --- a/test/test_memory.py +++ b/test/test_memory.py @@ -14,15 +14,15 @@ def test_AT( nb = maxlength, size = maxsize): """ Test creation of AxialTree """ - for i in xrange(nb): + for i in range(nb): a = AxialTree('F'*size) del a def test_PAT( nb = maxlength, size = maxsize): """ Test creation of Parametric AxialTree """ - for i in xrange(nb): + for i in range(nb): a = AxialTree() - for j in xrange(size): + for j in range(size): a += 'F('+str(j)+')' del a @@ -31,7 +31,7 @@ def test_LsRuleWithGlobalContext(): l = LsysRule() try: l.set('F --> F') - except NameError,e : + except NameError as e : import warnings warnings.warn("GlobalContext has not lpy symbols") @@ -57,7 +57,7 @@ def lnLs(l = 8): else: res = 6 a = 5 - for i in xrange(l-2): + for i in range(l-2): res += a*6 a *= 5 res += a*11 diff --git a/test/test_modnamespace.py b/test/test_modnamespace.py index c0c12dfd..09775cfa 100644 --- a/test/test_modnamespace.py +++ b/test/test_modnamespace.py @@ -10,7 +10,7 @@ def test_modclasstable(): ids.sort() #cl.sort(lambda x,y : cmp(x.id,y.id)) #print cl - assert ids == range(len(ids)) and "All predefined modules are not registered or other modules are still registered" + assert ids == list(range(len(ids))) and "All predefined modules are not registered or other modules are still registered" lcode1 = """ module BABA @@ -122,10 +122,10 @@ def test_scale_declaration(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_nproduce.py b/test/test_nproduce.py index f1a451ec..cd464f8f 100644 --- a/test/test_nproduce.py +++ b/test/test_nproduce.py @@ -4,18 +4,18 @@ def test_nproduce(verbose = False): """ Test use of nproduce """ l=Lsystem(get_filename('test_nproduce.lpy')) - if verbose: print l.axiom + if verbose: print(l.axiom) res = l.derive(1) - if verbose: print res + if verbose: print(res) assert len(res) == 2 and res[1].name == 'B' res = l.derive(res,1,1) - if verbose: print res + if verbose: print(res) assert len(res) == 1 and res[0].name == 'C' res = l.derive(res,2,1) - if verbose: print res + if verbose: print(res) assert len(res) == 1 and res[0].name == 'D' res = l.derive(res,3,1) - if verbose: print res + if verbose: print(res) assert len(res) == 0 if __name__ == '__main__': diff --git a/test/test_parsing.py b/test/test_parsing.py index 64699ccb..4c719fe1 100644 --- a/test/test_parsing.py +++ b/test/test_parsing.py @@ -8,7 +8,7 @@ def test_lstring2py(): declare('tralala,toto') lstr = 'FF[+F]tralala(2)[toto]' l = eval(lstring2py(lstr)) - print l + print(l) assert len(l) == 10 ax = AxialTree(l) assert len(ax) == 10 @@ -72,9 +72,9 @@ def test_format_reading(verbose = False): version = 2.5 s = LpyParsing.VersionTag % version s+='\n' - print s + print(s) read_version = LpyParsing.getFormatVersion(s) - print read_version + print(read_version) assert read_version == version supported_versions = LpyParsing.formats for v in supported_versions: @@ -108,16 +108,16 @@ def test_multi_line_production(verbose = False): l.set(lmlcode) try: l.iterate() - except Exception,e: + except Exception as e: import sys lineno = tb.extract_tb(sys.exc_info()[2])[-1][1] assert lineno == 10 if __name__ == '__main__': - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_predecessor_at_scale.py b/test/test_predecessor_at_scale.py index aa355201..78ed31ff 100644 --- a/test/test_predecessor_at_scale.py +++ b/test/test_predecessor_at_scale.py @@ -33,17 +33,17 @@ def test_predecessor_at_scale(assertion = True): l.setCode(lsysbasecode) l.makeCurrent() lstring = l.axiom - print lstring + print(lstring) for i,m in enumerate(lstring): pred = lstring.predecessor_at_scale(i,1) pred2 = lstring.predecessor_at_scale(i,2) - print i,m, - print '\t',pred, - if not pred is None: print lstring[pred], - print '\t',pred == res_1[i], - print '\t',pred2, - if not pred2 is None: print lstring[pred2], - print '\t',pred2 == res_2[i] + print(i,m, end=' ') + print('\t',pred, end=' ') + if not pred is None: print(lstring[pred], end=' ') + print('\t',pred == res_1[i], end=' ') + print('\t',pred2, end=' ') + if not pred2 is None: print(lstring[pred2], end=' ') + print('\t',pred2 == res_2[i]) if assertion: assert pred == res_1[i] and pred2 == res_2[i] diff --git a/test/test_regexpmatching.py b/test/test_regexpmatching.py index d68573ae..b1fa7e37 100644 --- a/test/test_regexpmatching.py +++ b/test/test_regexpmatching.py @@ -13,12 +13,12 @@ def EndEach(): assert matched """ -def runmatch(code, lcodebeg = lcodebeg,optionvalues = range(3)): +def runmatch(code, lcodebeg = lcodebeg,optionvalues = list(range(3))): if type(optionvalues) == int: optionvalues = [optionvalues] for i in range(3): l = Lsystem() - print i + print(i) l.context().options.setSelection('Module matching',i) if i in optionvalues: l.set(lcodebeg+code) @@ -27,7 +27,7 @@ def runmatch(code, lcodebeg = lcodebeg,optionvalues = range(3)): try: l.set(lcodebeg+code) l.iterate() - print "Test do not fail for unsupported module matching mode : %i." % i + print("Test do not fail for unsupported module matching mode : %i." % i) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass diff --git a/test/test_selection.py b/test/test_selection.py index 84060154..c6e0c7d4 100644 --- a/test/test_selection.py +++ b/test/test_selection.py @@ -8,7 +8,7 @@ def display(self,sc): pass def selection(self): if not self.selectionAsked: - print 'selection' + print('selection') self.selectionAsked = True return [3] @@ -20,13 +20,13 @@ def test_selection(): ln = len(l.axiom) l.context().makeCurrent() assert l.axiom == AxialTree('N[+NN][-N]N') and 'Invalid axiom parsing' - print l.axiom + print(l.axiom) res = l.iterate(1) - print res + print(res) assert len(res) == ln+1 assert res[3].name == '%' res = l.derive(res,1,1) - print res + print(res) assert len(res) == ln-2 assert plot.selectionAsked and "Selection has not been asked" l.done() diff --git a/test/test_shareexamples.py b/test/test_shareexamples.py index 77249f20..3cdc9bfa 100644 --- a/test/test_shareexamples.py +++ b/test/test_shareexamples.py @@ -12,8 +12,8 @@ def exec_share_example(lfile): try: l = Lsystem(lfile) l.iterate() - except Exception,e : - print 'Example file :',lfile + except Exception as e : + print('Example file :',lfile) raise e diff --git a/test/test_starmatching.py b/test/test_starmatching.py index 19e526c2..02485e48 100644 --- a/test/test_starmatching.py +++ b/test/test_starmatching.py @@ -12,7 +12,7 @@ def test_matchingmode(): l = Lsystem() modes = { 0: PatternModule.eSimple, 1: PatternModule.eWithStar , 2: PatternModule.eWithStarNValueConstraint } l.set(lcode_matchingmode) - for key,val in modes.items(): + for key,val in list(modes.items()): l.context().options.setSelection('Module matching',key) l.context()['mode'] = val l.iterate() @@ -30,7 +30,7 @@ def EndEach(): """ -def runmatch(code,optionvalues = range(3)): +def runmatch(code,optionvalues = list(range(3))): if type(optionvalues) == int: optionvalues = [optionvalues] for i in range(3): @@ -43,7 +43,7 @@ def runmatch(code,optionvalues = range(3)): try: l.set(lcodebeg+code) l.iterate() - print "Test do not fail for unsupported module matching mode : %i." % i + print("Test do not fail for unsupported module matching mode : %i." % i) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass @@ -63,7 +63,7 @@ def runmatch(code,optionvalues = range(3)): def test_match_mod_with_starmod(): """ Test matching of module with pattern with a star module """ - runmatch(lcodemodwithstarmod,range(1,3)) + runmatch(lcodemodwithstarmod,list(range(1,3))) ######################################################## @@ -80,7 +80,7 @@ def test_match_mod_with_starmod(): def test_match_mod_with_starmod_withnamearg(): """ Test matching of module with pattern with a star module and name arg """ - runmatch(lcodemodwithstarmod_withnamearg,range(1,3)) + runmatch(lcodemodwithstarmod_withnamearg,list(range(1,3))) ######################################################## @@ -100,7 +100,7 @@ def test_match_mod_with_starmod_withnamearg(): def test_match_mod_with_starmod_onearg(): """ Test matching of module with one arg with pattern with a star module """ - runmatch(lcodemodwithstarmod_onearg,range(1,3)) + runmatch(lcodemodwithstarmod_onearg,list(range(1,3))) ######################################################## @@ -118,7 +118,7 @@ def test_match_mod_with_starmod_onearg(): def test_match_mod_with_starmod_onearg_staronly(): """ Test matching of module with one arg with pattern with a star module only """ - runmatch(lcodemodwithstarmod_onearg_staronly,range(1,3)) + runmatch(lcodemodwithstarmod_onearg_staronly,list(range(1,3))) ######################################################## @@ -139,7 +139,7 @@ def test_match_mod_with_starmod_onearg_staronly(): def test_match_mod_with_starmod_two(): """ Test matching of module with two arg with pattern with a star module """ - runmatch(lcodemodwithstarmod_two,range(1,3)) + runmatch(lcodemodwithstarmod_two,list(range(1,3))) ######################################################## @@ -159,7 +159,7 @@ def test_match_mod_with_starmod_two(): def test_match_mod_with_starmod_two_staronly(): """ Test matching of module with two arg with pattern with a star module only """ - runmatch(lcodemodwithstarmod_two_staronly,range(1,3)) + runmatch(lcodemodwithstarmod_two_staronly,list(range(1,3))) ######################################################## @@ -174,7 +174,7 @@ def test_match_mod_with_starmod_two_staronly(): def test_match_mod_with_starmod_stararg(): """ Test matching of module with two arg with pattern with a star module with star args""" - runmatch(lcodemodwithstarmod_stararg,range(1,3)) + runmatch(lcodemodwithstarmod_stararg,list(range(1,3))) ######################################################## @@ -189,7 +189,7 @@ def test_match_mod_with_starmod_stararg(): def test_match_mod_with_starmod_stararg_name(): """ Test matching of module with two arg with pattern with a star module with args name and star args """ - runmatch(lcodemodwithstarmod_stararg_name,range(1,3)) + runmatch(lcodemodwithstarmod_stararg_name,list(range(1,3))) ######################################################## @@ -204,7 +204,7 @@ def test_match_mod_with_starmod_stararg_name(): def test_match_mod_with_starmod_args_and_stararg(): """ Test matching of module with two arg with pattern with a star module with 2 args and star args """ - runmatch(lcodemodwithstarmod_args_and_stararg,range(1,3)) + runmatch(lcodemodwithstarmod_args_and_stararg,list(range(1,3))) ######################################################## @@ -221,7 +221,7 @@ def test_match_mod_with_starmod_args_and_stararg(): def test_match_mod_with_starmod_enoughargs_and_stararg(): """ Test matching of module with two arg with pattern with a star module with enough args and star args """ - runmatch(lcodemodwithstarmod_enoughargs_and_stararg,range(1,3)) + runmatch(lcodemodwithstarmod_enoughargs_and_stararg,list(range(1,3))) ######################################################## @@ -417,10 +417,10 @@ def Start(): backward() if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_stringmatching.py b/test/test_stringmatching.py index 40f43f8b..c5e39d4e 100644 --- a/test/test_stringmatching.py +++ b/test/test_stringmatching.py @@ -9,6 +9,6 @@ def test_stringmatching(): a.addIdentity(1) a.append(1,2) b = a.begin() - for i in xrange(15): + for i in range(15): b.nextValues() - assert b.values() == (10,15) \ No newline at end of file + assert list(b.values()) == (10,15) \ No newline at end of file diff --git a/test/test_successor_at_scale.py b/test/test_successor_at_scale.py index 4f9db4bd..c1d855fc 100644 --- a/test/test_successor_at_scale.py +++ b/test/test_successor_at_scale.py @@ -40,13 +40,13 @@ def test_successor_at_scale(assertion = True): if assertion: assert pred == res_1[i] and pred2 == res_2[i] else : - print i,m, - print '\t',pred, - if not pred is None: print lstring[pred], - print '\t',pred == res_1[i], - print '\t',pred2, - if not pred2 is None: print lstring[pred2], - print '\t',pred2 == res_2[i] + print(i,m, end=' ') + print('\t',pred, end=' ') + if not pred is None: print(lstring[pred], end=' ') + print('\t',pred == res_1[i], end=' ') + print('\t',pred2, end=' ') + if not pred2 is None: print(lstring[pred2], end=' ') + print('\t',pred2 == res_2[i]) if __name__ == '__main__': test_successor_at_scale(False) diff --git a/test/test_tree_matching.py b/test/test_tree_matching.py index 570a7902..da298f0e 100644 --- a/test/test_tree_matching.py +++ b/test/test_tree_matching.py @@ -15,12 +15,12 @@ def EndEach(): assert matched """ -def matching_run(code,optionvalues = range(4)): +def matching_run(code,optionvalues = list(range(4))): if type(optionvalues) == int: optionvalues = [optionvalues] for i in range(4): l = Lsystem() - print 'option =',i + print('option =',i) if i in optionvalues: l.set(code) l.context().options.setSelection('String matching',i) @@ -30,7 +30,7 @@ def matching_run(code,optionvalues = range(4)): l.set(code) l.context().options.setSelection('String matching',i) l.iterate() - print "Test do not fail for unsupported string matching mode : %i." % i + print("Test do not fail for unsupported string matching mode : %i." % i) warnings.warn("Test do not fail for unsupported string matching mode : %i." % i) except: pass @@ -40,14 +40,14 @@ def test_axial_match() : f = open(get_filename('test_axial_matching.lpy')) code = f.read() f.close() - matching_run(code,range(1,4)) + matching_run(code,list(range(1,4))) def test_ms_match() : """ Test matching with multiscale axial tree context modification""" f = open(get_filename('test_msmatch.lpy')) code = f.read() f.close() - matching_run(code,range(2,4)) + matching_run(code,list(range(2,4))) def test_ms_match2() : """ Test matching with multiscale axial tree context modification 2""" @@ -60,14 +60,14 @@ def test_ms_match2() : global matched matched = True """ - matching_run(code,range(2,4)) + matching_run(code,list(range(2,4))) def test_axial_msmatch() : """ Test matching with axial tree context modification""" f = open(get_filename('test_axial_msmatch.lpy')) code = f.read() f.close() - matching_run(code,range(2,4)) + matching_run(code,list(range(2,4))) #def test_match_future() : matching_run('test_matching_future.lpy') @@ -75,10 +75,10 @@ def test_axial_msmatch() : if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print 'testing func:', tfn + print('testing func:', tfn) try: tf() except: diff --git a/test/test_ui.py b/test/test_ui.py index 916f4b36..b5c21752 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -49,10 +49,10 @@ def test_exit(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: From ff7ea9f5c357f661056e1151c550b8e576fca082 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 12:51:52 +0200 Subject: [PATCH 15/68] setup.py: Fix installation errors --- setup.py | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/setup.py b/setup.py index 4ad462c5..027d8534 100644 --- a/setup.py +++ b/setup.py @@ -15,8 +15,6 @@ # Package name pkg_name= namespace + '.' + package -wralea_name= namespace + '.' + package + '_wralea' - meta_version = version # check that meta version is updated @@ -29,9 +27,6 @@ print (pkg_name+': version ='+version) - - - # Scons build directory build_prefix = "build-scons" @@ -58,14 +53,18 @@ def compile_interface(): url=url, license=license, - scons_scripts = ['SConstruct'], - namespace_packages = [namespace], create_namespaces = False, # pure python packages - packages = [ pkg_name, pkg_name+'.gui',pkg_name+'.gui.plugins', pkg_name+'.cpfg_compat', wralea_name ], - py_modules = ['lpygui_postinstall'], + packages = [ + pkg_name, + pkg_name + '_d', + pkg_name + '_wralea', + pkg_name + '.gui', + pkg_name + '.gui.plugins', + pkg_name + '.cpfg_compat' + ], # python packages directory package_dir = { '' : 'src',}, @@ -75,21 +74,12 @@ def compile_interface(): package_data = {'' : ['*.pyd', '*.so', '*.dylib', '*.lpy','*.ui','*.qrc'],}, zip_safe = False, - # Specific options of openalea.deploy - lib_dirs = {'lib' : pj(build_prefix, 'lib'),}, - #bin_dirs = {'bin': pj(build_prefix, 'bin'),}, - inc_dirs = {'include' : pj(build_prefix, 'src','cpp') }, - share_dirs = {'share' : 'share', }, - # Dependencies - # entry_points entry_points = { "wralea": ["lpy = openalea.lpy_wralea",], 'gui_scripts': ['lpy = openalea.lpy.gui.lpystudio:main',], 'console_scripts': ['cpfg2lpy = openalea.lpy.cpfg_compat.cpfg2lpy:main',], - }, - - postinstall_scripts = ['lpygui_postinstall'], + }, # Dependencies setup_requires = ['openalea.deploy'], @@ -97,6 +87,4 @@ def compile_interface(): install_requires = install_requires, pylint_packages = ['src/openalea/lpy/gui'] - ) - - +) From 3dc071b314a66808f21ead6b259019079449e186 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 13:03:08 +0200 Subject: [PATCH 16/68] Update Conda Build --- conda/mcondabuild.bat | 1 - conda/meta.yaml | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 conda/mcondabuild.bat diff --git a/conda/mcondabuild.bat b/conda/mcondabuild.bat deleted file mode 100644 index e7edfea4..00000000 --- a/conda/mcondabuild.bat +++ /dev/null @@ -1 +0,0 @@ -conda build . -c openalea/label/unstable -c conda-forge -c msys2 --no-test diff --git a/conda/meta.yaml b/conda/meta.yaml index 60002a26..742295b8 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -24,7 +24,10 @@ requirements: - boost - qt - pyqt + - openalea.deploy + - setuptools run: + - python =3 - openalea.plantgl - boost - qt From c3ef7859d22fb4d7c95caa51cd69c1f7f9530a33 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 13:03:34 +0200 Subject: [PATCH 17/68] Enable warnings MSVC --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf5b0aa3..d59926e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ include("CXX14") # --- (Win32) Multithreaded Compilation if (MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W0") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") endif() # --- Libraries From e4eddf9d62b1ef6b236be42770b53d7034be467c Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 13 May 2019 14:25:42 +0200 Subject: [PATCH 18/68] Fix Conda Build Python version --- conda/meta.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conda/meta.yaml b/conda/meta.yaml index 742295b8..789bfd68 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -19,7 +19,7 @@ build: requirements: build: - - python =3 + - python - openalea.plantgl - boost - qt @@ -27,7 +27,7 @@ requirements: - openalea.deploy - setuptools run: - - python =3 + - python - openalea.plantgl - boost - qt From fd7816ccf6facf5cadc5b8de95d660d812a23f71 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 13 May 2019 14:25:53 +0200 Subject: [PATCH 19/68] Add Conda Constructor file --- construct.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 construct.yaml diff --git a/construct.yaml b/construct.yaml new file mode 100644 index 00000000..cc7e5914 --- /dev/null +++ b/construct.yaml @@ -0,0 +1,21 @@ +# do not edit the following line. It will be updated automatically +{% set version = "2.7.2" %} + +name: openalea.lpy +version: {{ version }} + +channels: + - https://conda.anaconda.org/ethan13310/ + - https://repo.anaconda.com/pkgs/main/ + +specs: + - python + - pyqt + - pyopengl + - pyqglviewer + - scipy + - matplotlib + - openalea.plantgl + - openalea.lpy + +license_file: LICENSE.txt From 646d4e7b0530f709b73727fa890264b3f4d5f622 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 13 May 2019 14:31:11 +0200 Subject: [PATCH 20/68] Auto stash before merge of "master" and "origin/master" --- CMakeLists.txt | 2 +- conda/meta.yaml | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d59926e4..12f95133 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project(lpy_project CXX) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include("Anaconda") -include("CXX14") +# include("CXX14") # --- (Win32) Multithreaded Compilation diff --git a/conda/meta.yaml b/conda/meta.yaml index 789bfd68..c079874d 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -16,13 +16,19 @@ about: build: preserve_egg_dir: True number: 1 + features: + - vc9 [win and py27] + - vc14 [win and py37] + track_features: + - vc9 [win and py27] + - vc14 [win and py37] requirements: build: - python - openalea.plantgl - boost - - qt + - qt =5 - pyqt - openalea.deploy - setuptools @@ -30,12 +36,14 @@ requirements: - python - openalea.plantgl - boost - - qt + - qt =5 - pyqt - ipython - qtconsole - pyopengl - pyqglviewer + - vs2008_runtime [win and py27] + - vs2015_runtime [win and py37] test: requires: From 277fb323fb435c2333e053642804283d7b44979c Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Thu, 16 May 2019 14:03:30 +0200 Subject: [PATCH 21/68] Fix Anaconda environment on Unix systems --- cmake/Anaconda.cmake | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cmake/Anaconda.cmake b/cmake/Anaconda.cmake index 056ca7fe..8b93c778 100644 --- a/cmake/Anaconda.cmake +++ b/cmake/Anaconda.cmake @@ -3,6 +3,13 @@ if (DEFINED ENV{CONDA_PREFIX}) # Anaconda Environment message(STATUS "Anaconda environment detected.") - set(CONDA_ENV "$ENV{CONDA_PREFIX}/Library") - set(CONDA_PYTHON_ENV "$ENV{CONDA_PREFIX}") + file(TO_CMAKE_PATH $ENV{CONDA_PREFIX} TMP_CONDA_ENV) + + if (WIN32) + set(CONDA_ENV "${TMP_CONDA_ENV}/Library/") + else() + set(CONDA_ENV "${TMP_CONDA_ENV}/") + endif() + + set(CONDA_PYTHON_ENV "${TMP_CONDA_ENV}/") endif() From d8c46ae0974fd2c1706d937e1c9ad91c70d8093e Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 27 May 2019 10:13:23 +0200 Subject: [PATCH 22/68] Fix CMake build --- CMakeLists.txt | 3 +-- conda/bld.bat | 9 +++++++-- conda/build.sh | 8 ++++++-- src/cpp/CMakeLists.txt | 4 ++++ src/wrapper/CMakeLists.txt | 10 +++++++--- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12f95133..7aca69d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,6 @@ project(lpy_project CXX) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include("Anaconda") -# include("CXX14") # --- (Win32) Multithreaded Compilation @@ -34,7 +33,7 @@ set(Boost_NO_SYSTEM_PATHS ON) set(Boost_USE_MULTITHREAD ON) set(Boost_USE_STATIC_LIBS OFF) -find_package(Boost 1.67 COMPONENTS ${BOOST_PYTHON_LIB} REQUIRED) +find_package(Boost 1.67 COMPONENTS system ${BOOST_PYTHON_LIB} REQUIRED) # --- Include Directories diff --git a/conda/bld.bat b/conda/bld.bat index 84e5d368..7682c8a0 100644 --- a/conda/bld.bat +++ b/conda/bld.bat @@ -1,6 +1,6 @@ :: Working Dir -mkdir build-cmake -cd build-cmake +mkdir build +cd build :: Build cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% -DCMAKE_BUILD_TYPE=Release .. @@ -9,3 +9,8 @@ nmake if errorlevel 1 exit 1 nmake install if errorlevel 1 exit 1 + +:: Install Python Files +cd .. +%PYTHON% setup.py install +if errorlevel 1 exit 1 diff --git a/conda/build.sh b/conda/build.sh index 524bbccd..c5c9546b 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -1,10 +1,14 @@ #!/bin/bash # Working Dir -mkdir build-cmake -cd build-cmake +mkdir build +cd build # Build cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} -DCMAKE_BUILD_TYPE=Release .. make -j${CPU_COUNT} make install + +# Install Python Files +cd .. +$PYTHON setup.py install --prefix=${PREFIX} diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 13621e94..33df4962 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -25,3 +25,7 @@ endif() # --- Output Library install(TARGETS lpy LIBRARY DESTINATION "lib") + +# --- Install Headers + +install(DIRECTORY "." DESTINATION "include" FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp") diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 32e63ce4..1ba77560 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(__lpy_kernel__ Python3::Python) # Disable Boost Auto-Link target_compile_definitions(__lpy_kernel__ PRIVATE BOOST_ALL_NO_LIB) -target_link_libraries(__lpy_kernel__ Boost::${BOOST_PYTHON_LIB}) +target_link_libraries(__lpy_kernel__ Boost::system Boost::${BOOST_PYTHON_LIB}) # --- Dependencies @@ -21,8 +21,12 @@ add_dependencies(__lpy_kernel__ lpy) # --- Output Library +set_target_properties(__lpy_kernel__ PROPERTIES PREFIX "") + +if (WIN32) + set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") +endif() + set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy") -install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy_d") -install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy_wralea") From c7e265855baef5fc069397ac36c933f0feb2c8d6 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Thu, 10 Oct 2019 17:07:36 +0200 Subject: [PATCH 23/68] fix small bugs --- src/cpp/lsystem.cpp | 2 +- src/openalea/lpy/gui/lpystudio.py | 5 +++++ src/wrapper/export_lsysrule.cpp | 2 +- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/cpp/lsystem.cpp b/src/cpp/lsystem.cpp index e5c966b5..dad7fec9 100644 --- a/src/cpp/lsystem.cpp +++ b/src/cpp/lsystem.cpp @@ -603,7 +603,7 @@ void Lsystem::addSubLsystem(const std::string& lfile) void Lsystem::addSubLsystem(const Lsystem& sublsystem) { - printf("Add info from sublsystem '%s'",sublsystem.getFilename().c_str()); + printf("Add info from sublsystem '%s'\n",sublsystem.getFilename().c_str()); context()->importContext(*sublsystem.context()); size_t groupid = 0; for(std::vector::const_iterator itg = sublsystem.__rules.begin(); itg != sublsystem.__rules.end(); ++itg, ++groupid) diff --git a/src/openalea/lpy/gui/lpystudio.py b/src/openalea/lpy/gui/lpystudio.py index faea4845..64690a46 100644 --- a/src/openalea/lpy/gui/lpystudio.py +++ b/src/openalea/lpy/gui/lpystudio.py @@ -999,6 +999,11 @@ def main(): if len(args) > 1: toopen = map(os.path.abspath,args[1:]) qapp = QApplication([]) + try: + qapp.setAttribute(Qt.AA_DisableHighDpiScaling) + assert qapp.testAttribute(Qt.AA_DisableHighDpiScaling) + except: + pass splash = doc.splashLPy() qapp.processEvents() w = LPyWindow() diff --git a/src/wrapper/export_lsysrule.cpp b/src/wrapper/export_lsysrule.cpp index 9b9a6b1b..3ea147f1 100644 --- a/src/wrapper/export_lsysrule.cpp +++ b/src/wrapper/export_lsysrule.cpp @@ -167,7 +167,7 @@ void export_LsysRule(){ .def("newLeftContext", &LsysRule::newLeftContext, boost::python::return_internal_reference<1>()) .def("rightContext", &LsysRule::rightContext, boost::python::return_internal_reference<1>()) .def("newRightContext", &LsysRule::newRightContext, boost::python::return_internal_reference<1>()) - .def("function", &LsysRule::function, boost::python::return_internal_reference<1>()) + .def("function", &LsysRule::function, boost::python::return_value_policy()) //, boost::python::return_internal_reference<1>()) .def("definition", &LsysRule::definition, boost::python::return_internal_reference<1>()) .def("isCompiled",&LsysRule::isCompiled) .def("compile",(void(LsysRule::*)())&LsysRule::compile) From 52589bf0a2a487adccc98e0688ced40717ce6a59 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:12:24 +0200 Subject: [PATCH 24/68] Add CMake files --- CMakeLists.txt | 52 ++++++++++++++++++++++++++++++++++++++ cmake/Anaconda.cmake | 11 ++++++++ cmake/CXX14.cmake | 25 ++++++++++++++++++ cmake/FindPlantGL.cmake | 33 ++++++++++++++++++++++++ cmake/FindPython.cmake | 11 ++++++++ src/cpp/CMakeLists.txt | 27 ++++++++++++++++++++ src/wrapper/CMakeLists.txt | 24 ++++++++++++++++++ 7 files changed, 183 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/Anaconda.cmake create mode 100644 cmake/CXX14.cmake create mode 100644 cmake/FindPlantGL.cmake create mode 100644 cmake/FindPython.cmake create mode 100644 src/cpp/CMakeLists.txt create mode 100644 src/wrapper/CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..bf5b0aa3 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,52 @@ +# --- L-Py Project + +cmake_minimum_required(VERSION 3.12) +project(lpy_project CXX) + +# --- CMake Modules + +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") + +include("Anaconda") +include("CXX14") + +# --- (Win32) Multithreaded Compilation + +if (MSVC) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W0") +endif() + +# --- Libraries + +find_package(Threads REQUIRED) +find_package(Python REQUIRED) +find_package(Qt5Core CONFIG REQUIRED) +find_package(Qt5Concurrent CONFIG REQUIRED) +find_package(PlantGL REQUIRED) + +# Boost +if (DEFINED CONDA_ENV) + set(BOOST_ROOT ${CONDA_ENV}) + set(BOOST_LIBRARYDIR "${BOOST_ROOT}/lib") +endif() + +set(Boost_NO_SYSTEM_PATHS ON) +set(Boost_USE_MULTITHREAD ON) +set(Boost_USE_STATIC_LIBS OFF) + +find_package(Boost 1.67 COMPONENTS ${BOOST_PYTHON_LIB} REQUIRED) + +# --- Include Directories + +include_directories("src/cpp") + +include_directories(${Boost_INCLUDE_DIR}) + +# --- Library Directory + +link_directories("${CONDA_ENV}/lib") + +# --- Source Directories + +add_subdirectory("src/cpp") +add_subdirectory("src/wrapper") diff --git a/cmake/Anaconda.cmake b/cmake/Anaconda.cmake new file mode 100644 index 00000000..f03509ea --- /dev/null +++ b/cmake/Anaconda.cmake @@ -0,0 +1,11 @@ +# Anaconda Check +if (DEFINED ENV{CONDA_PREFIX}) + # Anaconda Environment + message(STATUS "Anaconda environment detected.") + + if (WIN32) + set(CONDA_ENV "$ENV{CONDA_PREFIX}/Library") + else() + set(CONDA_ENV "$ENV{CONDA_PREFIX}") + endif() +endif() diff --git a/cmake/CXX14.cmake b/cmake/CXX14.cmake new file mode 100644 index 00000000..268b9685 --- /dev/null +++ b/cmake/CXX14.cmake @@ -0,0 +1,25 @@ +# Compiler Check +if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + # Clang (Min 3.4) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.4) + message(FATAL_ERROR "Clang 3.4 or greater is required.") + endif() +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + # GCC (Min 5.1) + if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.1) + message(FATAL_ERROR "GCC 5.1 or greater is required.") + endif() +elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") + # Visual C++ (Min 14.0) + if (MSVC_VERSION LESS 1900) + message(FATAL_ERROR "Microsoft Visual C++ 14.0 (Visual Studio 2015) or greater is required.") + endif() +else() + # Other Compilers + message(WARNING "You are using an unknown compiler. It may not be supported.") +endif() + +# C++14 Standard +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/cmake/FindPlantGL.cmake b/cmake/FindPlantGL.cmake new file mode 100644 index 00000000..bbfcf55e --- /dev/null +++ b/cmake/FindPlantGL.cmake @@ -0,0 +1,33 @@ +# Include Directory +find_path(PLANTGL_INCLUDE_DIR "plantgl/plantgl.h" "libplantgl/plantgl.h" PATHS $ENV{PATH}) + +# Library Directory +find_library(PLANTGL_ALGO_LIBRARY NAMES "pglalgo" "libpglalgo" PATHS $ENV{PATH}) +find_library(PLANTGL_GUI_LIBRARY NAMES "pglgui" "libpglgui" PATHS $ENV{PATH}) +find_library(PLANTGL_MATH_LIBRARY NAMES "pglmath" "libpglmath" PATHS $ENV{PATH}) +find_library(PLANTGL_SG_LIBRARY NAMES "pglsg" "libpglsg" PATHS $ENV{PATH}) +find_library(PLANTGL_TOOL_LIBRARY NAMES "pgltool" "libpgltool" PATHS $ENV{PATH}) + +if (PLANTGL_INCLUDE_DIR AND PLANTGL_ALGO_LIBRARY AND PLANTGL_GUI_LIBRARY AND PLANTGL_MATH_LIBRARY AND PLANTGL_SG_LIBRARY AND PLANTGL_TOOL_LIBRARY) + set(PLANTGL_FOUND ON) + set(PLANTGL_INCLUDE_DIRS ${PLANTGL_INCLUDE_DIR}) + set(PLANTGL_LIBRARIES ${PLANTGL_ALGO_LIBRARY} ${PLANTGL_GUI_LIBRARY} ${PLANTGL_MATH_LIBRARY} ${PLANTGL_SG_LIBRARY} ${PLANTGL_TOOL_LIBRARY}) + + # PlantGL found + message(STATUS "Found PlantGL: TRUE") +else() + set(PLANTGL_FOUND OFF) + + if (PlantGL_FIND_REQUIRED) + # PlantGL not found + message(SEND_ERROR "Unable to find PlantGL library.") + endif() +endif() + +if (PLANTGL_FOUND) + # Build with PlantGL + include_directories(${PLANTGL_INCLUDE_DIRS}) + +elseif (NOT PlantGL_FIND_REQUIRED) + message(STATUS "Building without PlantGL - Library not found.") +endif() diff --git a/cmake/FindPython.cmake b/cmake/FindPython.cmake new file mode 100644 index 00000000..60a6e1e3 --- /dev/null +++ b/cmake/FindPython.cmake @@ -0,0 +1,11 @@ +find_package(Python3 COMPONENTS Development REQUIRED) + +if (Python3_FOUND) + if (Python3_VERSION_MINOR LESS 6) + message(SEND_ERROR "Python 3.6 or greater is required.") + else() + include_directories(${Python3_INCLUDE_DIRS}) + endif() + + set(BOOST_PYTHON_LIB "python3${Python3_VERSION_MINOR}") +endif() diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt new file mode 100644 index 00000000..13621e94 --- /dev/null +++ b/src/cpp/CMakeLists.txt @@ -0,0 +1,27 @@ +# --- Source Files + +file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") + +add_library(lpy SHARED ${SRC_FILES}) + +# --- Linked Libraries + +target_link_libraries(lpy ${PLANTGL_LIBRARIES}) +target_link_libraries(lpy Qt5::Core Qt5::Concurrent) +target_link_libraries(lpy Python3::Python) + +# Disable Boost Auto-Link +target_compile_definitions(lpy PRIVATE BOOST_ALL_NO_LIB) + +target_link_libraries(lpy Boost::${BOOST_PYTHON_LIB}) + +# --- Preprocessor + +if (WIN32) + # Export DLL on Windows + target_compile_definitions(lpy PRIVATE LPY_MAKEDLL) +endif() + +# --- Output Library + +install(TARGETS lpy LIBRARY DESTINATION "lib") diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt new file mode 100644 index 00000000..97930af4 --- /dev/null +++ b/src/wrapper/CMakeLists.txt @@ -0,0 +1,24 @@ +# --- Source Files + +file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") + +add_library(_lpy SHARED ${SRC_FILES}) + +# --- Linked Library + +target_link_libraries(_lpy lpy) +target_link_libraries(_lpy ${PLANTGL_LIBRARIES}) +target_link_libraries(_lpy Python3::Python) + +# Disable Boost Auto-Link +target_compile_definitions(_lpy PRIVATE BOOST_ALL_NO_LIB) + +target_link_libraries(_lpy Boost::${BOOST_PYTHON_LIB}) + +# --- Dependencies + +add_dependencies(_lpy lpy) + +# --- Output Library + +install(TARGETS _lpy LIBRARY DESTINATION "lib") From 3a380d4c8bf436d3e3d0ace88b26fe9985d09195 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:12:53 +0200 Subject: [PATCH 25/68] Remove Visual Studio-related files --- src/lpy.sln | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 src/lpy.sln diff --git a/src/lpy.sln b/src/lpy.sln deleted file mode 100644 index 0766b84b..00000000 --- a/src/lpy.sln +++ /dev/null @@ -1,26 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual C++ Express 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lpy", "cpp\lpy.vcxproj", "{CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wraplpy", "wrapper\wraplpy.vcxproj", "{432DE2EC-508C-4072-9400-1E16CBAB9C78}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}.Debug|Win32.ActiveCfg = Debug|Win32 - {CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}.Debug|Win32.Build.0 = Debug|Win32 - {CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}.Release|Win32.ActiveCfg = Release|Win32 - {CE919D8B-BBFC-4FA8-99E4-8324EE5FEE77}.Release|Win32.Build.0 = Release|Win32 - {432DE2EC-508C-4072-9400-1E16CBAB9C78}.Debug|Win32.ActiveCfg = Debug|Win32 - {432DE2EC-508C-4072-9400-1E16CBAB9C78}.Debug|Win32.Build.0 = Debug|Win32 - {432DE2EC-508C-4072-9400-1E16CBAB9C78}.Release|Win32.ActiveCfg = Release|Win32 - {432DE2EC-508C-4072-9400-1E16CBAB9C78}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal From 96954214acd3882adec9fb5ab3757ba0f5527474 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:13:09 +0200 Subject: [PATCH 26/68] Remove SConscruct files --- SConstruct | 51 ------------------------------------------ src/cpp/SConscript | 23 ------------------- src/wrapper/SConscript | 21 ----------------- 3 files changed, 95 deletions(-) delete mode 100644 SConstruct delete mode 100644 src/cpp/SConscript delete mode 100644 src/wrapper/SConscript diff --git a/SConstruct b/SConstruct deleted file mode 100644 index bc1d02b0..00000000 --- a/SConstruct +++ /dev/null @@ -1,51 +0,0 @@ -# -*-python-*- - -from openalea.sconsx import config, environ -from openalea.sconsx.util.buildprefix import fix_custom_buildprefix -from openalea.sconsx.util.qt_check import detect_installed_qt_version -try: - import openalea.plantgl.config as pglconf -except ImportError: - pglconf = None - -import os - -ALEASolution = config.ALEASolution -pj= os.path.join - -name='lpy' - -options = Variables(['../options.py', 'options.py'], ARGUMENTS ) -if pglconf : - qt_version = pglconf.PGL_QT_VERSION -else: - options.Add(EnumVariable('QT_VERSION','Qt major version to use',str(detect_installed_qt_version(4)),allowed_values=('4','5'))) - - # Create an environment to access qt option values - qt_env = Environment(options=options, tools=[]) - qt_version = eval(qt_env['QT_VERSION']) - - -tools = ['boost_python', 'openalea.plantgl','qt'+str(qt_version)] - -env = ALEASolution(options, tools) -env.Append( CPPPATH = pj( '$build_includedir','lpy' ) ) -env['QT_VERSION'] = str(qt_version) - -# Build stage -prefix= env['build_prefix'] - - -from versionmanager import deployconfig -# create config files -deployconfig(env) - - -SConscript( pj(prefix,"src/cpp/SConscript"), exports={"env":env} ) - -SConscript( pj(prefix,"src/wrapper/SConscript"), exports={"env":env} ) - -Default("build") - -fix_custom_buildprefix(env) - diff --git a/src/cpp/SConscript b/src/cpp/SConscript deleted file mode 100644 index 6322bab6..00000000 --- a/src/cpp/SConscript +++ /dev/null @@ -1,23 +0,0 @@ -# -*-python-*- -Import( "env" ) -lib_env= env.Clone() -qt_version = int(lib_env['QT_VERSION']) -if qt_version == 4: - lib_env.EnableQtModules( [ 'QtCore'])# 'QtSql', 'QtXml']) -else: - lib_env.EnableQtModules( [ 'QtCore', 'QtConcurrent'])# 'QtSql', 'QtXml']) - -includes= lib_env.ALEAGlob('*.h') -sources= lib_env.ALEAGlob('*.cpp') - -# Add defines to export symbols on Windows -DEFINES= list(lib_env['CPPDEFINES']) -DEFINES.append('LPY_MAKEDLL') - -lib_env.AppendUnique(LIBS= ['pgltool','pglmath','pglsg','pglalgo','pglgui']) - -inc= lib_env.ALEAIncludes( "lpy", includes ) - -lib = lib_env.ALEALibrary( "lpy", - sources, - CPPDEFINES = DEFINES ) diff --git a/src/wrapper/SConscript b/src/wrapper/SConscript deleted file mode 100644 index af81ce7b..00000000 --- a/src/wrapper/SConscript +++ /dev/null @@ -1,21 +0,0 @@ -# -*-python-*- - -Import( "env" ) - -import os.path -pj = os.path.join - -py_dir = pj(os.path.pardir,'openalea','lpy') - -# Build wrappers as shared libraries -lib_env=env.Clone() -#lib_env.EnableQt4Modules( [ 'QtCore', 'QtGui', 'QtOpenGL', 'QtNetwork',])# 'QtSql', 'QtXml']) -#lib_env.AppendUnique( CPPPATH = ['$QT4_CPPPATH/Qt'] ) - - -sources= lib_env.ALEAGlob( '*.cpp' ) -target= "__lpy_kernel__" - -lib_env.AppendUnique(LIBS= ['lpy','pgltool','pglmath','pglsg','pglalgo','pglgui']) -lib_env.ALEAWrapper( py_dir, target, sources ) - From 4a3214501fb27769ac3ad005c7f1825713030609 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:13:54 +0200 Subject: [PATCH 27/68] Upgrade to Python 3 API --- src/wrapper/export_axialtree.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wrapper/export_axialtree.cpp b/src/wrapper/export_axialtree.cpp index 9fecb3b9..4c530b00 100644 --- a/src/wrapper/export_axialtree.cpp +++ b/src/wrapper/export_axialtree.cpp @@ -215,7 +215,7 @@ boost::python::object py_varnames(AxialTree * tree) struct axialtree_from_str { static void* convertible(PyObject* py_obj){ - if( !PyString_Check( py_obj ) ) return 0; + if( !PyUnicode_Check( py_obj ) ) return 0; return py_obj; } static void construct( PyObject* obj, boost::python::converter::rvalue_from_python_stage1_data* data){ From 129e3cb136c59f631a324c2715b58fda74199654 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:14:10 +0200 Subject: [PATCH 28/68] Fix wrong namespaces --- src/cpp/lpy_parser.cpp | 2 +- src/cpp/lsystem.cpp | 2 +- src/cpp/lsystem.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpp/lpy_parser.cpp b/src/cpp/lpy_parser.cpp index f0d8b1fc..b4db31f4 100644 --- a/src/cpp/lpy_parser.cpp +++ b/src/cpp/lpy_parser.cpp @@ -1582,7 +1582,7 @@ LpyParsing::parse_moddeclist(std::string::const_iterator& beg, && *_it != '\n' && *_it != ':' && *_it != '=' && *_it != '(' && *_it != '#' && *_it != delim) ++_it; std::string name(bm,_it); - if(name.empty()) LsysSyntaxError("Invalid empty name in declaration of "+TOOLS::number(nb)+" module."); + if(name.empty()) LsysSyntaxError("Invalid empty name in declaration of "+ PGL_NAMESPACE_NAME::number(nb)+" module."); else { result.push_back(ModDeclaration(name)); } while (_it != endpos && (*_it == ' ' || *_it == '\t'))++_it; if(_it == endpos) break; diff --git a/src/cpp/lsystem.cpp b/src/cpp/lsystem.cpp index dad7fec9..e1890afd 100644 --- a/src/cpp/lsystem.cpp +++ b/src/cpp/lsystem.cpp @@ -1205,7 +1205,7 @@ Lsystem::__recursiveInterpretation(AxialTree& workingstring, PglTurtle& turtle; LsysContext& context; - TOOLS::Sequencer timer; + PGL_NAMESPACE_NAME::Sequencer timer; inline bool earlyReturn() { return context.isEarlyReturnEnabled(); } diff --git a/src/cpp/lsystem.h b/src/cpp/lsystem.h index a95718f3..b4fe7bc4 100644 --- a/src/cpp/lsystem.h +++ b/src/cpp/lsystem.h @@ -212,7 +212,7 @@ class LPY_API Lsystem { void addSubLsystem(const std::string& lfile); void addSubLsystem(const Lsystem& sublsystem); - class LPY_API Debugger : public TOOLS::RefCountObject { + class LPY_API Debugger : public PGL_NAMESPACE_NAME::RefCountObject { public: Debugger() : alwaysStop(true) { } virtual ~Debugger() ; From 62cc8ed87f07424132b121dee15b130936c6b0f5 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 29 Apr 2019 12:14:17 +0200 Subject: [PATCH 29/68] Update Conda build --- conda/bld.bat | 12 +++++++++--- conda/build.sh | 11 +++++++---- conda/meta.yaml | 9 +-------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/conda/bld.bat b/conda/bld.bat index b3d75134..84e5d368 100644 --- a/conda/bld.bat +++ b/conda/bld.bat @@ -1,5 +1,11 @@ -COPY options_conda_win.py options.py - -%PYTHON% setup.py install +:: Working Dir +mkdir build-cmake +cd build-cmake +:: Build +cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% -DCMAKE_BUILD_TYPE=Release .. +if errorlevel 1 exit 1 +nmake +if errorlevel 1 exit 1 +nmake install if errorlevel 1 exit 1 diff --git a/conda/build.sh b/conda/build.sh index 2664d705..524bbccd 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -1,7 +1,10 @@ #!/bin/bash -export PKG_CONFIG_PATH=$PREFIX/lib/pkgconfig +# Working Dir +mkdir build-cmake +cd build-cmake -cp options_conda_build.py options.py - -$PYTHON setup.py install --prefix=$PREFIX +# Build +cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} -DCMAKE_BUILD_TYPE=Release .. +make -j${CPU_COUNT} +make install diff --git a/conda/meta.yaml b/conda/meta.yaml index 0690f095..60002a26 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -8,7 +8,6 @@ package: source: path: .. - about: home: https://github.com/openalea/lpy license: Cecill-C @@ -20,22 +19,16 @@ build: requirements: build: - - python - - setuptools - - openalea.deploy - - scons - - openalea.sconsx + - python =3 - openalea.plantgl - boost - qt - pyqt - - openalea.vpltk run: - openalea.plantgl - boost - qt - pyqt - - openalea.vpltk - ipython - qtconsole - pyopengl From ad30ef90557339259f4275e7e7146e7a98ce72a2 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Thu, 2 May 2019 15:28:56 +0200 Subject: [PATCH 30/68] CMake: Update Conda finder --- cmake/Anaconda.cmake | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/cmake/Anaconda.cmake b/cmake/Anaconda.cmake index f03509ea..056ca7fe 100644 --- a/cmake/Anaconda.cmake +++ b/cmake/Anaconda.cmake @@ -3,9 +3,6 @@ if (DEFINED ENV{CONDA_PREFIX}) # Anaconda Environment message(STATUS "Anaconda environment detected.") - if (WIN32) - set(CONDA_ENV "$ENV{CONDA_PREFIX}/Library") - else() - set(CONDA_ENV "$ENV{CONDA_PREFIX}") - endif() + set(CONDA_ENV "$ENV{CONDA_PREFIX}/Library") + set(CONDA_PYTHON_ENV "$ENV{CONDA_PREFIX}") endif() From b45fb85047a2212e47e04ed944549a33ede888df Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:22:05 +0200 Subject: [PATCH 31/68] Upgrade setup.py to Python 3 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 28f25e34..4ad462c5 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ from openalea.deploy.metainfo import read_metainfo metadata = read_metainfo('metainfo.ini', verbose=True) -for key,value in metadata.iteritems(): +for key,value in metadata.items(): exec("%s = '%s'" % (key, value)) ############## @@ -22,7 +22,7 @@ # check that meta version is updated f = pj(os.path.dirname(__file__),'src', 'openalea', 'lpy','__version__.py') d = {} -execfile(f,d,d) +exec(compile(open(f, "rb").read(), f, 'exec'),d,d) version= d['LPY_VERSION_STR'] if meta_version != version: print ('Warning:: Update the version in metainfo.ini !!') From 96313dc3f6e55351ea1aec644739e686b0bdfc6a Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:22:14 +0200 Subject: [PATCH 32/68] Remove setup.cfg --- setup.cfg | 63 ------------------------------------------------------- 1 file changed, 63 deletions(-) delete mode 100644 setup.cfg diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 6b71aa77..00000000 --- a/setup.cfg +++ /dev/null @@ -1,63 +0,0 @@ -# Distutils parameters file -# Use this file to specify custom parameters to pass to setup.py script -# Uncomment necessary options - -[global] -# verbose=0 - -[egg_info] -#tag_build = .dev -#tag_svn_revision = 1 - -[build] -##### scons parameters (use options.py instead) -#scons-ext-param= - -#####scons exe path -#scons-path=C:\Python24 - -#####distutils build directory -#build-lib= - -[install] - -#####openalea data directory -#external-prefix= - -[bdist_rpm] -requires = python >= 2.6 - python-VPlants.PlantGL - PyOpenGL - libQGLViewer - boost - qt - readline -build_requires = python >= 2.6 - python-devel >= 2.6 - python-setuptools >= 0.6 - python-VPlants.PlantGL - python-OpenAlea.Deploy >= 0.9 - python-OpenAlea.SConsX >= 0.9 - qt-devel - boost-devel - boost-python - readline-devel - pkgconfig - freeglut-devel -provides = %{name} = %{version} -obsoletes = %{name} < %{version} -doc_files = AUTHORS.txt ChangeLog.txt README.txt LICENSE.txt -python = /usr/bin/python -packager = OpenAlea Consortium - -[build_sphinx] -source-dir = doc/ -build-dir = doc/_build -all_files = 1 - -[nosetests] -where=test - -[upload_sphinx] -package = lpy -project = vplants From f6d1b32bf32866c31c494433a4e276cd1a3af3a9 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:22:32 +0200 Subject: [PATCH 33/68] Update wrappers CMakeLists --- src/wrapper/CMakeLists.txt | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 97930af4..32e63ce4 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -2,23 +2,27 @@ file(GLOB_RECURSE SRC_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*.cpp") -add_library(_lpy SHARED ${SRC_FILES}) +add_library(__lpy_kernel__ SHARED ${SRC_FILES}) # --- Linked Library -target_link_libraries(_lpy lpy) -target_link_libraries(_lpy ${PLANTGL_LIBRARIES}) -target_link_libraries(_lpy Python3::Python) +target_link_libraries(__lpy_kernel__ lpy) +target_link_libraries(__lpy_kernel__ ${PLANTGL_LIBRARIES}) +target_link_libraries(__lpy_kernel__ Python3::Python) # Disable Boost Auto-Link -target_compile_definitions(_lpy PRIVATE BOOST_ALL_NO_LIB) +target_compile_definitions(__lpy_kernel__ PRIVATE BOOST_ALL_NO_LIB) -target_link_libraries(_lpy Boost::${BOOST_PYTHON_LIB}) +target_link_libraries(__lpy_kernel__ Boost::${BOOST_PYTHON_LIB}) # --- Dependencies -add_dependencies(_lpy lpy) +add_dependencies(__lpy_kernel__ lpy) # --- Output Library -install(TARGETS _lpy LIBRARY DESTINATION "lib") +set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") + +install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy") +install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy_d") +install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy_wralea") From 18b0e51dfac93e4b44dc984110792d13b781391e Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:22:43 +0200 Subject: [PATCH 34/68] Add .lib files to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 796400fe..7b726e30 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ build-scons_qt5 *.so *.dll *.dblite +*.lib # Distribution / packaging .Python From 6f03037df16001bd6fbab219c40952c34059a18d Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Fri, 3 May 2019 12:25:43 +0200 Subject: [PATCH 35/68] Fix old Macintosh end-of-line characters --- .../lpy/gui/plugins/curve2dmanager.py | 159 +++++++++++++++++- .../lpy/gui/plugins/functionmanager.py | 60 ++++++- 2 files changed, 217 insertions(+), 2 deletions(-) diff --git a/src/openalea/lpy/gui/plugins/curve2dmanager.py b/src/openalea/lpy/gui/plugins/curve2dmanager.py index a028bfc1..6b845764 100644 --- a/src/openalea/lpy/gui/plugins/curve2dmanager.py +++ b/src/openalea/lpy/gui/plugins/curve2dmanager.py @@ -1 +1,158 @@ -try: from openalea.plantgl.gui.curve2deditor import Curve2DEditor,Curve2DConstraint except ImportError, e: Curve2DEditor = None from openalea.plantgl.scenegraph import Polyline2D, BezierCurve2D, NurbsCurve2D, Point2Array, Point3Array from openalea.lpy.gui.abstractobjectmanager import * from OpenGL.GL import * from openalea.vpltk.qt import QtGui, QtWidgets def displayLineAsThumbnail(manager, obj, i, objectthumbwidth, color = (1,1,0,0), linecolor = (0.5,0.5,0.5,1.0)): manager.discretizer.clear() b = manager.getBoundingBox(obj) lsize = b.getSize() msize = lsize[lsize.getMaxAbsCoord()] scaling = objectthumbwidth/(2*msize) x0c = -b.getCenter()[0]*scaling y0c = -b.getCenter()[1]*scaling #display lines if 2*abs(y0c) <= objectthumbwidth: glColor4fv(linecolor) glLineWidth(1) glBegin(GL_LINE_STRIP) glVertex2f(-objectthumbwidth/2.,-y0c) glVertex2f(objectthumbwidth/2.,-y0c) glEnd() if 2*abs(x0c) <= objectthumbwidth: glColor4fv(linecolor) glLineWidth(1) glBegin(GL_LINE_STRIP) glVertex2f(x0c,-objectthumbwidth/2.) glVertex2f(x0c,objectthumbwidth/2.) glEnd() # resize and translate pgl object glScalef(scaling,-scaling,1) glTranslatef(*-b.getCenter()) pw = obj.width obj.width = 1 glColor4f(*color) glLineWidth(2) # display curve with plantgl tools obj.apply(manager.renderer) obj.width = pw class TriggerParamFunc: def __init__(self,func,*value): self.func = func self.value= value def __call__(self): self.func(*self.value) class Curve2DManager(AbstractPglObjectManager): """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" def __init__(self): AbstractPglObjectManager.__init__(self,"Curve2D") self.focusCurveColor = (1,1,0,1) self.curveColor = (0.8,0.8,0,1) self.frameColor = (0.5,0.5,0.5,1.0) def getTheme(self): return { 'Curve2D' : [ int(self.curveColor[i] *255) for i in xrange(3)], 'FocusCurve2D' : [ int(self.focusCurveColor[i] *255) for i in xrange(3)], 'FrameColor' : [ int(self.frameColor[i] *255) for i in xrange(3)] } def setTheme(self,theme): if theme.has_key('FocusCurve2D'): self.focusCurveColor = [ theme['FocusCurve2D'][i] *255 for i in xrange(3)] + [1] if theme.has_key('Curve2D'): self.curveColor = [ theme['Curve2D'][i] *255 for i in xrange(3)] + [1] if theme.has_key('FrameColor'): self.frameColor = [ theme['FrameColor'][i] *255 for i in xrange(3)] + [1] def displayThumbnail(self, obj, i , focus, objectthumbwidth): if focus : color = self.focusCurveColor else : color = self.curveColor displayLineAsThumbnail(self,obj, i , objectthumbwidth, color, self.frameColor) def createDefaultObject(self,subtype = None): nbP = 4 if subtype == 'Polyline': return Polyline2D(Point2Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)]) ) if subtype == 'BezierCurve': return BezierCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) else: return NurbsCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) def reset(self,obj): subtype = 'NurbsCurve' if isinstance(obj,Polyline2D): subtype = 'Polyline' elif isinstance(obj,BezierCurve2D): subtype = 'BezierCurve' return self.createDefaultObject(subtype) def getEditor(self,parent): if Curve2DEditor: return Curve2DEditor(parent,Curve2DConstraint()) else : return None def setObjectToEditor(self,editor,obj): """ ask for edition of obj with editor """ from copy import deepcopy editor.setCurve(deepcopy(obj)) def retrieveObjectFromEditor(self,editor): """ ask for current value of object being edited """ return editor.getCurve() def canImportData(self,fname): from os.path import splitext return splitext(fname)[1] == '.cset' def importData(self,fname): from openalea.lpy.cpfg_compat.data_import import import_contours return import_contours(fname) def defaultObjectTypes(self): return ['Polyline','BezierCurve','NurbsCurve'] def fillEditorMenu(self,menubar,editor): """ Function call to fill the menu of the editor """ menu = QtWidgets.QMenu('Curve',menubar) menu.addAction('Flip Horizontally',TriggerParamFunc(self.flipHorizontallyEditor,editor)) menu.addAction('Flip Vertically',TriggerParamFunc(self.flipVerticallyEditor,editor)) menubar.addMenu(menu) menu = QtWidgets.QMenu('Theme',menubar) menu.addAction('Black',lambda : editor.applyTheme(editor.BLACK_THEME)) menu.addAction('White',lambda : editor.applyTheme(editor.WHITE_THEME)) menubar.addMenu(menu) menu = QtWidgets.QMenu('Image',menubar) menu.addAction('Open',lambda : editor.openImage()) menu.addAction('Close',lambda : editor.closeImage()) menubar.addMenu(menu) def completeContextMenu(self,menu,obj,widget): menu.addAction('Flip Horizontally',TriggerParamFunc(self.flipHorizontally,obj,widget)) menu.addAction('Flip Vertically',TriggerParamFunc(self.flipVertically,obj,widget)) def flipHorizontallyEditor(self,editor): self.flipHorizontally(editor.getCurve(),editor) def flipHorizontally(self,obj,widget): if isinstance(obj,Polyline2D): obj.pointList = [(i.x,-i.y) for i in obj.pointList] else: obj.ctrlPointList = [(i.x,-i.y,i.z) for i in obj.ctrlPointList] widget.updateGL() def flipVerticallyEditor(self,editor): self.flipVertically(editor.getCurve(),editor) def flipVertically(self,obj,widget): if isinstance(obj,Polyline2D): obj.pointList = [(-i.x,i.y) for i in obj.pointList] else: obj.ctrlPointList = [(-i.x,i.y,i.z) for i in obj.ctrlPointList] widget.updateGL() def get_managers(): return Curve2DManager() \ No newline at end of file +try: + from openalea.plantgl.gui.curve2deditor import Curve2DEditor,Curve2DConstraint +except ImportError, e: + Curve2DEditor = None +from openalea.plantgl.scenegraph import Polyline2D, BezierCurve2D, NurbsCurve2D, Point2Array, Point3Array +from openalea.lpy.gui.abstractobjectmanager import * +from OpenGL.GL import * +from openalea.vpltk.qt import QtGui, QtWidgets + +def displayLineAsThumbnail(manager, obj, i, objectthumbwidth, color = (1,1,0,0), linecolor = (0.5,0.5,0.5,1.0)): + manager.discretizer.clear() + b = manager.getBoundingBox(obj) + lsize = b.getSize() + msize = lsize[lsize.getMaxAbsCoord()] + scaling = objectthumbwidth/(2*msize) + x0c = -b.getCenter()[0]*scaling + y0c = -b.getCenter()[1]*scaling + #display lines + if 2*abs(y0c) <= objectthumbwidth: + glColor4fv(linecolor) + glLineWidth(1) + glBegin(GL_LINE_STRIP) + glVertex2f(-objectthumbwidth/2.,-y0c) + glVertex2f(objectthumbwidth/2.,-y0c) + glEnd() + if 2*abs(x0c) <= objectthumbwidth: + glColor4fv(linecolor) + glLineWidth(1) + glBegin(GL_LINE_STRIP) + glVertex2f(x0c,-objectthumbwidth/2.) + glVertex2f(x0c,objectthumbwidth/2.) + glEnd() + # resize and translate pgl object + glScalef(scaling,-scaling,1) + glTranslatef(*-b.getCenter()) + pw = obj.width + obj.width = 1 + glColor4f(*color) + glLineWidth(2) + # display curve with plantgl tools + obj.apply(manager.renderer) + obj.width = pw + +class TriggerParamFunc: + def __init__(self,func,*value): + self.func = func + self.value= value + def __call__(self): + self.func(*self.value) + +class Curve2DManager(AbstractPglObjectManager): + """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" + def __init__(self): + AbstractPglObjectManager.__init__(self,"Curve2D") + self.focusCurveColor = (1,1,0,1) + self.curveColor = (0.8,0.8,0,1) + self.frameColor = (0.5,0.5,0.5,1.0) + + def getTheme(self): + return { 'Curve2D' : [ int(self.curveColor[i] *255) for i in xrange(3)], + 'FocusCurve2D' : [ int(self.focusCurveColor[i] *255) for i in xrange(3)], + 'FrameColor' : [ int(self.frameColor[i] *255) for i in xrange(3)] } + + def setTheme(self,theme): + if theme.has_key('FocusCurve2D'): + self.focusCurveColor = [ theme['FocusCurve2D'][i] *255 for i in xrange(3)] + [1] + if theme.has_key('Curve2D'): + self.curveColor = [ theme['Curve2D'][i] *255 for i in xrange(3)] + [1] + if theme.has_key('FrameColor'): + self.frameColor = [ theme['FrameColor'][i] *255 for i in xrange(3)] + [1] + + def displayThumbnail(self, obj, i , focus, objectthumbwidth): + if focus : color = self.focusCurveColor + else : color = self.curveColor + displayLineAsThumbnail(self,obj, i , objectthumbwidth, color, self.frameColor) + + def createDefaultObject(self,subtype = None): + nbP = 4 + if subtype == 'Polyline': + return Polyline2D(Point2Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)]) ) + if subtype == 'BezierCurve': + return BezierCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + else: + return NurbsCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + + def reset(self,obj): + subtype = 'NurbsCurve' + if isinstance(obj,Polyline2D): + subtype = 'Polyline' + elif isinstance(obj,BezierCurve2D): + subtype = 'BezierCurve' + return self.createDefaultObject(subtype) + def getEditor(self,parent): + if Curve2DEditor: + return Curve2DEditor(parent,Curve2DConstraint()) + else : return None + + def setObjectToEditor(self,editor,obj): + """ ask for edition of obj with editor """ + from copy import deepcopy + editor.setCurve(deepcopy(obj)) + + def retrieveObjectFromEditor(self,editor): + """ ask for current value of object being edited """ + return editor.getCurve() + + def canImportData(self,fname): + from os.path import splitext + return splitext(fname)[1] == '.cset' + + def importData(self,fname): + from openalea.lpy.cpfg_compat.data_import import import_contours + return import_contours(fname) + + def defaultObjectTypes(self): + return ['Polyline','BezierCurve','NurbsCurve'] + + def fillEditorMenu(self,menubar,editor): + """ Function call to fill the menu of the editor """ + menu = QtWidgets.QMenu('Curve',menubar) + menu.addAction('Flip Horizontally',TriggerParamFunc(self.flipHorizontallyEditor,editor)) + menu.addAction('Flip Vertically',TriggerParamFunc(self.flipVerticallyEditor,editor)) + menubar.addMenu(menu) + menu = QtWidgets.QMenu('Theme',menubar) + menu.addAction('Black',lambda : editor.applyTheme(editor.BLACK_THEME)) + menu.addAction('White',lambda : editor.applyTheme(editor.WHITE_THEME)) + menubar.addMenu(menu) + menu = QtWidgets.QMenu('Image',menubar) + menu.addAction('Open',lambda : editor.openImage()) + menu.addAction('Close',lambda : editor.closeImage()) + menubar.addMenu(menu) + + def completeContextMenu(self,menu,obj,widget): + menu.addAction('Flip Horizontally',TriggerParamFunc(self.flipHorizontally,obj,widget)) + menu.addAction('Flip Vertically',TriggerParamFunc(self.flipVertically,obj,widget)) + + def flipHorizontallyEditor(self,editor): + self.flipHorizontally(editor.getCurve(),editor) + + def flipHorizontally(self,obj,widget): + if isinstance(obj,Polyline2D): + obj.pointList = [(i.x,-i.y) for i in obj.pointList] + else: + obj.ctrlPointList = [(i.x,-i.y,i.z) for i in obj.ctrlPointList] + widget.updateGL() + + def flipVerticallyEditor(self,editor): + self.flipVertically(editor.getCurve(),editor) + + def flipVertically(self,obj,widget): + if isinstance(obj,Polyline2D): + obj.pointList = [(-i.x,i.y) for i in obj.pointList] + else: + obj.ctrlPointList = [(-i.x,i.y,i.z) for i in obj.ctrlPointList] + widget.updateGL() + +def get_managers(): + return Curve2DManager() diff --git a/src/openalea/lpy/gui/plugins/functionmanager.py b/src/openalea/lpy/gui/plugins/functionmanager.py index 9c1cc07e..f20f61d2 100644 --- a/src/openalea/lpy/gui/plugins/functionmanager.py +++ b/src/openalea/lpy/gui/plugins/functionmanager.py @@ -1 +1,59 @@ -try: from openalea.plantgl.gui.curve2deditor import Curve2DEditor,FuncConstraint except ImportError, e: Curve2DEditor = None from openalea.lpy.gui.abstractobjectmanager import * from curve2dmanager import displayLineAsThumbnail from openalea.vpltk.qt import QtGui, QtWidgets class FunctionManager(AbstractPglObjectManager): """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" def __init__(self): AbstractPglObjectManager.__init__(self,"Function") def displayThumbnail(self,obj,i,focus,objectthumbwidth): displayLineAsThumbnail(self,obj,i,objectthumbwidth,(1,0,1,1)) def createDefaultObject(self,subtype=None): import openalea.plantgl.all as pgl nbP = 4 return pgl.NurbsCurve2D(pgl.Point3Array([(float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) def getEditor(self,parent): if Curve2DEditor: return Curve2DEditor(parent,FuncConstraint()) else: return None def setObjectToEditor(self,editor,obj): """ ask for edition of obj with editor """ from copy import deepcopy editor.setCurve(deepcopy(obj)) def retrieveObjectFromEditor(self,editor): """ ask for current value of object being edited """ return editor.getCurve() def writeObjectToLsysContext(self,obj): return 'pgl.QuantisedFunction('+obj.name+')' def canImportData(self,fname): from os.path import splitext ext = splitext(fname)[1] return ext == '.fset' or ext == '.func' def importData(self,fname): from openalea.lpy.gui.lpfg_data_import import import_functions, import_function from os.path import splitext ext = splitext(fname)[1] if ext == '.fset': return import_functions(fname) else: return import_function(fname) def fillEditorMenu(self,menubar,editor): """ Function call to fill the menu of the editor """ menu = QtWidgets.QMenu('Theme',menubar) menu.addAction('Black',lambda : editor.applyTheme(editor.BLACK_THEME)) menu.addAction('White',lambda : editor.applyTheme(editor.WHITE_THEME)) menubar.addMenu(menu) def get_managers(): return FunctionManager() \ No newline at end of file +try: + from openalea.plantgl.gui.curve2deditor import Curve2DEditor,FuncConstraint +except ImportError, e: + Curve2DEditor = None +from openalea.lpy.gui.abstractobjectmanager import * +from curve2dmanager import displayLineAsThumbnail +from openalea.vpltk.qt import QtGui, QtWidgets + +class FunctionManager(AbstractPglObjectManager): + """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" + def __init__(self): + AbstractPglObjectManager.__init__(self,"Function") + + def displayThumbnail(self,obj,i,focus,objectthumbwidth): + displayLineAsThumbnail(self,obj,i,objectthumbwidth,(1,0,1,1)) + + def createDefaultObject(self,subtype=None): + import openalea.plantgl.all as pgl + nbP = 4 + return pgl.NurbsCurve2D(pgl.Point3Array([(float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + + def getEditor(self,parent): + if Curve2DEditor: + return Curve2DEditor(parent,FuncConstraint()) + else: return None + + def setObjectToEditor(self,editor,obj): + """ ask for edition of obj with editor """ + from copy import deepcopy + editor.setCurve(deepcopy(obj)) + + def retrieveObjectFromEditor(self,editor): + """ ask for current value of object being edited """ + return editor.getCurve() + + def writeObjectToLsysContext(self,obj): + return 'pgl.QuantisedFunction('+obj.name+')' + + def canImportData(self,fname): + from os.path import splitext + ext = splitext(fname)[1] + return ext == '.fset' or ext == '.func' + + def importData(self,fname): + from openalea.lpy.gui.lpfg_data_import import import_functions, import_function + from os.path import splitext + ext = splitext(fname)[1] + if ext == '.fset': return import_functions(fname) + else: return import_function(fname) + + def fillEditorMenu(self,menubar,editor): + """ Function call to fill the menu of the editor """ + menu = QtWidgets.QMenu('Theme',menubar) + menu.addAction('Black',lambda : editor.applyTheme(editor.BLACK_THEME)) + menu.addAction('White',lambda : editor.applyTheme(editor.WHITE_THEME)) + menubar.addMenu(menu) + +def get_managers(): + return FunctionManager() From 9ba79b6e6e82e4f4b0a1da5dff74641f1a70f038 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 12:51:00 +0200 Subject: [PATCH 36/68] Upgrade to Python 3 --- src/openalea/lpy/__init__.py | 12 +-- src/openalea/lpy/__lpyfuture__.py | 6 +- src/openalea/lpy/composition.py | 2 +- src/openalea/lpy/cpfg_compat/cpfg2lpy.py | 36 ++++----- src/openalea/lpy/cpfg_compat/data_import.py | 58 +++++++------- src/openalea/lpy/cpfg_compat/vafile_import.py | 46 +++++------ src/openalea/lpy/defaultparameters.py | 4 +- src/openalea/lpy/gui/compile_ui.py | 18 ++--- src/openalea/lpy/gui/computationtask.py | 6 +- src/openalea/lpy/gui/documentation.py | 4 +- src/openalea/lpy/gui/killsimulationdialog.py | 2 +- src/openalea/lpy/gui/lpycodeeditor.py | 46 +++++------ src/openalea/lpy/gui/lpydock.py | 4 +- src/openalea/lpy/gui/lpypreferences.py | 4 +- src/openalea/lpy/gui/lpyprofiling.py | 14 ++-- src/openalea/lpy/gui/lpystudio.py | 77 ++++++++++--------- src/openalea/lpy/gui/lpystudiodebugger.py | 18 ++--- src/openalea/lpy/gui/lpytabbar.py | 2 +- src/openalea/lpy/gui/lpyview3d.py | 6 +- src/openalea/lpy/gui/objectmanagers.py | 12 +-- src/openalea/lpy/gui/objectpanel.py | 38 ++++----- src/openalea/lpy/gui/optioneditordelegate.py | 2 +- .../lpy/gui/plugins/curve2dmanager.py | 26 +++---- .../lpy/gui/plugins/functionmanager.py | 4 +- .../lpy/gui/plugins/nurbspatchmanager.py | 2 +- src/openalea/lpy/gui/pymodulemonitoring.py | 13 ++-- src/openalea/lpy/gui/reformatingcode.py | 10 +-- src/openalea/lpy/gui/scalareditor.py | 4 +- src/openalea/lpy/gui/settings.py | 10 +-- src/openalea/lpy/gui/simulation.py | 74 +++++++++--------- src/openalea/lpy/gui/svnmanip.py | 24 +++--- src/openalea/lpy/parameterset.py | 8 +- src/openalea/lpy/pytranslation.py | 4 +- src/openalea/lpy/simu_environ.py | 10 +-- src/openalea/lpy_d/__init__.py | 2 +- src/openalea/lpy_wralea/__wralea__.py | 2 +- src/openalea/lpy_wralea/lpy_nodes.py | 2 +- 37 files changed, 307 insertions(+), 305 deletions(-) diff --git a/src/openalea/lpy/__init__.py b/src/openalea/lpy/__init__.py index 335d302e..30aba78e 100644 --- a/src/openalea/lpy/__init__.py +++ b/src/openalea/lpy/__init__.py @@ -1,6 +1,6 @@ -from __version__ import * -from __lpy_kernel__ import * -from parameterset import * +from .__version__ import * +from .__lpy_kernel__ import * +from .parameterset import * def __mod_getattr__(self,name): if self.hasParameter(name): return self.getParameter(name) @@ -16,7 +16,7 @@ def __mod_setattr__(self,name,value): del __mod_getattr__ del __mod_setattr__ -from __lpy_kernel__ import __setCythonAvailable,__setPythonExec +from .__lpy_kernel__ import __setCythonAvailable,__setPythonExec try: import pyximport @@ -115,7 +115,7 @@ def __init__(self, lsystem): self.axiom = self.lsystem.axiom self.nbstep = self.lsystem.derivationLength self.currentstep = -1 - def next(self): + def __next__(self): if self.currentstep == -1: self.axiom = self.lsystem.axiom self.currentstep += 1 @@ -148,7 +148,7 @@ def Lsystem__call__(self,lstring,nbsteps=None): del Lsystem__call__ def __lsystem_getattribute__(self,name): - if self.context().has_key(name): return self.context()[name] + if name in self.context(): return self.context()[name] else: raise AttributeError(name) __original_lsystem_setattr__ = Lsystem.__setattr__ diff --git a/src/openalea/lpy/__lpyfuture__.py b/src/openalea/lpy/__lpyfuture__.py index 7a2c3a35..60341c9c 100644 --- a/src/openalea/lpy/__lpyfuture__.py +++ b/src/openalea/lpy/__lpyfuture__.py @@ -15,7 +15,7 @@ def __check_discard_string(lstring): __last_string = lpy.Lstring(lstring) def enable_string_discard(endeach): - endeach_arg_nb = endeach.func_code.co_argcount + endeach_arg_nb = endeach.__code__.co_argcount if endeach_arg_nb == 0: def wrapped(lstring): global __string_discarded, __last_string @@ -60,13 +60,13 @@ def pushString( stringname ): def popString( stringname ): global __pop_string - if not __string_stack.has_key(stringname): + if stringname not in __string_stack: raise ValueError('Stack of string has not string named '+repr(stringname)) __pop_string = stringname return __string_stack[stringname] def enable_string_pushpop(endeach): - endeach_arg_nb = endeach.func_code.co_argcount + endeach_arg_nb = endeach.__code__.co_argcount def check_push_pop(lstring, res): global __push_string, __pop_string, __string_stack if not __push_string is None: diff --git a/src/openalea/lpy/composition.py b/src/openalea/lpy/composition.py index ce64b247..7147c506 100644 --- a/src/openalea/lpy/composition.py +++ b/src/openalea/lpy/composition.py @@ -37,7 +37,7 @@ def animate(self,lstring = None, nbsteps = 1, dt = 0.1): from openalea.plantgl.all import Sequencer s = Sequencer(dt) clstring = lstring - for i in xrange(nbsteps): + for i in range(nbsteps): clstring = self.derive(clstring) self.plot(clstring) s.touch() diff --git a/src/openalea/lpy/cpfg_compat/cpfg2lpy.py b/src/openalea/lpy/cpfg_compat/cpfg2lpy.py index e68d234f..6829def8 100644 --- a/src/openalea/lpy/cpfg_compat/cpfg2lpy.py +++ b/src/openalea/lpy/cpfg_compat/cpfg2lpy.py @@ -1,5 +1,5 @@ import openalea.lpy as lpy -import vafile_import as vafile +from . import vafile_import as vafile @@ -12,7 +12,7 @@ def empty_line(line): def empty_end_line(txt,index): nbchar = len(txt) if nbchar >= index : return True - for i in xrange(index,nbchar) : + for i in range(index,nbchar) : c = txt[i] if c in '\n': return True if c not in ' \t': return False @@ -194,7 +194,7 @@ def process_rule(predecessor,conditions,precondition,defs,withlineno = True): else: result += indent+'from openalea.lpy.cpfg_compat import select_successor_from_prob\n' result += indent+'successor = select_successor_from_prob(['+','.join([pb for p,s,pb,l in defs])+'])\n' - for i in xrange(len(defs)) : + for i in range(len(defs)) : postcondition, successor, prob, lineno = defs[i] result += indent if i == 0: result += 'if successor == '+str(i)+' : # see line '+str(lineno)+'\n' @@ -338,8 +338,8 @@ def process_current_rule(result, allgvar): line += nline.strip() try: predecessor, successor = line.split('-->') - except Exception, e: - print line + except Exception as e: + print(line) raise e if not ':' in predecessor and not ':' in successor: # simplest rules result += convert_lstring(predecessor) + '-->' + convert_lstring(successor) + '\n' @@ -374,7 +374,7 @@ def process_current_rule(result, allgvar): current_rule.append_succ([postcond, successor, prob,lineno]) if len(allgvar) > 0: gvardec = '# declaration of global variables used in the model\n' - gvardec += ','.join(allgvar) + ' = ' + ','.join([str(None) for i in xrange(len(allgvar))])+'\n\n' + gvardec += ','.join(allgvar) + ' = ' + ','.join([str(None) for i in range(len(allgvar))])+'\n\n' result = result[:proddecposition]+gvardec+result[proddecposition:] return result @@ -417,18 +417,18 @@ def translate_obj(fname): for sfile in sfiles: sworkspace = splitext(basename(sfile))[0] surfaces = [] - for manager in managers.itervalues(): + for manager in managers.values(): fname = join(project,sfile) if manager.canImportData(fname): try: objects = manager.importData(fname) surfaces += [(manager,i) for i in objects] groupofpatches[sworkspace] = [i.name for i in objects] - except Exception, e: + except Exception as e: import sys, traceback exc_info = sys.exc_info() traceback.print_exception(*exc_info) - print 'Cannot import file '+repr(sfile) + print('Cannot import file '+repr(sfile)) break panels += [({'name':sworkspace},surfaces)] @@ -437,17 +437,17 @@ def translate_obj(fname): if funcfiles: functions = [] for funcfile in funcfiles: - for manager in managers.itervalues(): + for manager in managers.values(): fname = join(project,funcfile) if manager.canImportData(fname): try: objects = manager.importData(fname) functions += [(manager,i) for i in objects] - except Exception, e: + except Exception as e: import sys, traceback exc_info = sys.exc_info() traceback.print_exception(*exc_info) - print 'Cannot import file '+repr(funcfile) + print('Cannot import file '+repr(funcfile)) break panels += [({'name':'functions'},functions)] @@ -457,18 +457,18 @@ def translate_obj(fname): if fsetfiles is None: fsetfiles = [] if csetfiles is None: csetfiles = [] for fsetfile in fsetfiles+csetfiles: - for manager in managers.itervalues(): + for manager in managers.values(): fname = join(project,fsetfile) if manager.canImportData(fname): try: objects = manager.importData(fname) managedobjects = [(manager,i) for i in objects] panels += [({'name':basename(splitext(fn)[0])}, managedobjects)] - except Exception, e: + except Exception as e: import sys, traceback exc_info = sys.exc_info() traceback.print_exception(*exc_info) - print 'Cannot import file '+repr(fsetfile) + print('Cannot import file '+repr(fsetfile)) break @@ -493,7 +493,7 @@ def translate_obj(fname): l.turtle.setMaterial(i,mat) nbMaterials = l.turtle.getColorListSize() if nbMaterials > len(materials): - for i in xrange(nbMaterials-1,len(materials)-1,-1): + for i in range(nbMaterials-1,len(materials)-1,-1): l.turtle.removeColor(i) # read desciption @@ -522,7 +522,7 @@ def help(): def main(): import sys if len(sys.argv) < 2: - print help() + print(help()) return lpycode = translate_obj(sys.argv[1]) if len(sys.argv) == 3: @@ -530,7 +530,7 @@ def main(): output.write(lpycode) output.close() else: - print lpycode + print(lpycode) if __name__ == '__main__': diff --git a/src/openalea/lpy/cpfg_compat/data_import.py b/src/openalea/lpy/cpfg_compat/data_import.py index f4cc79c2..9eb74597 100644 --- a/src/openalea/lpy/cpfg_compat/data_import.py +++ b/src/openalea/lpy/cpfg_compat/data_import.py @@ -6,7 +6,7 @@ def import_contours(fn): f.readline() nbitems = int(f.readline().split()[1]) result = [] - for i in xrange(nbitems): + for i in range(nbitems): f.readline() name = f.readline().split()[1] nbpoints = int(f.readline().split()[1]) @@ -15,10 +15,10 @@ def import_contours(fn): if typecurve == 'or': samples = int(f.readline().split()[1]) points = [] - for j in xrange(nbpoints): - coord = map(float,f.readline().split()) + for j in range(nbpoints): + coord = list(map(float,f.readline().split())) point = Vector4(coord[:3]+[1]) - for k in xrange(int(coord[3])): + for k in range(int(coord[3])): points.append(point) if sum([p.z for p in points]) > 0: n = NurbsCurve(points) @@ -36,15 +36,15 @@ def import_functions(fn): f.readline() # funcgalleryver 1 1 nbitems = int(f.readline().split()[1]) # items: 10 result = [] - for i in xrange(nbitems): + for i in range(nbitems): f.readline() # fver 1 1 name = f.readline().split()[1] # name: BR_LEN_0 samples = int(f.readline().split()[1]) # samples: 5 f.readline() # flip: off nbpoints = int(f.readline().split()[1]) # points: 4 points = [] - for j in xrange(nbpoints): - coord = map(float,f.readline().split()) # 0.000000 0.577929 + for j in range(nbpoints): + coord = list(map(float,f.readline().split())) # 0.000000 0.577929 point = Vector3(coord+[1]) points.append(point) n = NurbsCurve2D(points) @@ -61,8 +61,8 @@ def import_function(fn): f.readline() # range 0, 1 nbpoints = int(f.readline().split()[1]) # points: 4 points = [] - for j in xrange(nbpoints): - coord = map(float,f.readline().split()) # 0.000000 0.577929 + for j in range(nbpoints): + coord = list(map(float,f.readline().split())) # 0.000000 0.577929 point = Vector3(coord+[1]) points.append(point) result = NurbsCurve2D(points) @@ -70,7 +70,7 @@ def import_function(fn): result.name = name return result -linetofloat = lambda l : map(float,l.split()) +linetofloat = lambda l : list(map(float,l.split())) def vec3inline(l,i,j,k): values = l.split() return Vector3(float(values[i]),float(values[j]),float(values[k])) @@ -80,34 +80,34 @@ def import_patch(fn): f = open(fn,'r') base = splitext(basename(fn))[0] # read header of the file - f.next() # bbox - nextline = f.next() + next(f) # bbox + nextline = next(f) # PRECISION S: s T: t if nextline.split()[0] == 'PRECISION': - nextline = f.next() + nextline = next(f) # CONTACT POINT X: x Y: y Z: z contact = vec3inline(nextline,3,5,7) # END POINT X: x Y: y Z: z - f.next() + next(f) # HEADING X: x Y: y Z: z - heading = vec3inline(f.next(),2,4,6) + heading = vec3inline(next(f),2,4,6) l = heading.normalize() # UP X: x Y: y Z: z - up = vec3inline(f.next(),2,4,6) + up = vec3inline(next(f),2,4,6) up.normalize() # SIZE: x size = float(f.next().split()[1]) patchlist = [] while True : try : - nextline = f.next() + nextline = next(f) except: break nextline = nextline.strip() dobreak = False while len(nextline) == 0 : try : - nextline = f.next() + nextline = next(f) nextline = nextline.strip() except: dobreak = True @@ -120,13 +120,13 @@ def import_patch(fn): # AL: patch1 A: patch2 AR: patch3 # L: patch4 R: patch5 # BL: patch6 B: patch7 BR: patch8 - for i in xrange(4): f.next() + for i in range(4): next(f) ctrlpoints = [] left = heading^up m = Matrix3(-up,-left,heading) #m = Matrix3(-left, -heading, up) m = m.inverse() - for i in xrange(4): + for i in range(4): v = f.next().split() row = [] for j in range(4): @@ -146,7 +146,7 @@ def import_colormap(fn): import array a = array.array('B') a.fromfile(open(fn,'rb'),256*3) - return [Material('Color_'+str(i),Color3(a[3*i],a[3*i+1],a[3*i+2]),diffuse=0) for i in xrange(256)] + return [Material('Color_'+str(i),Color3(a[3*i],a[3*i+1],a[3*i+2]),diffuse=0) for i in range(256)] def import_materialmap(fn): import array @@ -156,16 +156,16 @@ def import_materialmap(fn): a = array.array('B') try: a.fromfile(stream,15) - except Exception,e: + except Exception as e: break valiter = iter(a) - id = valiter.next() - transparency = valiter.next() - ambient = (valiter.next(),valiter.next(),valiter.next()) - diffuse = (valiter.next(),valiter.next(),valiter.next()) - emission = Color3(valiter.next(),valiter.next(),valiter.next()) - specular = Color3(valiter.next(),valiter.next(),valiter.next()) - shininess = valiter.next() + id = next(valiter) + transparency = next(valiter) + ambient = (next(valiter),next(valiter),next(valiter)) + diffuse = (next(valiter),next(valiter),next(valiter)) + emission = Color3(next(valiter),next(valiter),next(valiter)) + specular = Color3(next(valiter),next(valiter),next(valiter)) + shininess = next(valiter) sdiffuse = sum(diffuse) sambient = sum(ambient) if sdiffuse > 0 and sambient > 0: diff --git a/src/openalea/lpy/cpfg_compat/vafile_import.py b/src/openalea/lpy/cpfg_compat/vafile_import.py index 10f98c7f..c3a63ce6 100644 --- a/src/openalea/lpy/cpfg_compat/vafile_import.py +++ b/src/openalea/lpy/cpfg_compat/vafile_import.py @@ -4,7 +4,7 @@ def parse_config_file(ctext): cline = cline.strip() if len(cline) > 1 and cline[:2] != '/*': key, value = cline.split(':',1) - if config.has_key(key): + if key in config: nvalue = config[key] if type(nvalue) != list: nvalue = [nvalue] nvalue.append(value) @@ -17,48 +17,48 @@ def get_view_info(vconfig): vlpyinitconfig = {} angle_increment = None - if vconfig.has_key('angle factor'): + if 'angle factor' in vconfig: angle_increment = 360 / float(vconfig['angle factor']) - if vconfig.has_key('angle increment'): + if 'angle increment' in vconfig: angle_increment = float(vconfig['angle increment']) if angle_increment: vlpyconfig['AngleIncrement'] = angle_increment - if vconfig.has_key('initial color'): + if 'initial color' in vconfig: vlpyinitconfig['initial_color'] = int(vconfig['initial color'].split()[0]) - if vconfig.has_key('color increment'): + if 'color increment' in vconfig: vlpyconfig['ColorIncrement'] = int(vconfig['color increment'].split()[0]) unit = None - if vconfig.has_key('initial line width'): + if 'initial line width' in vconfig: val,unit = vconfig['initial line width'].split() vlpyinitconfig['initial_line_width'] = float(val) if unit == 'p' or unit == 'pixels': vlpyinitconfig['initial_line_width'] /= 10 - if vconfig.has_key('line width increment'): + if 'line width increment' in vconfig: vlpyconfig['WidthIncrement'] = float(vconfig['line width increment']) if unit == 'p' or unit == 'pixels': vlpyconfig['WidthIncrement'] /= 10 - if vconfig.has_key('initial scale'): + if 'initial scale' in vconfig: vlpyinitconfig['initial_scale'] = float(vconfig['initial scale']) - if vconfig.has_key('scale multiplier'): + if 'scale multiplier' in vconfig: vlpyconfig['ScaleMultiplier'] = float(vconfig['scale multiplier']) - if vconfig.has_key('tropism direction'): - vlpyconfig['tropism_direction'] = map(float,vconfig['tropism direction'].split(',')) + if 'tropism direction' in vconfig: + vlpyconfig['tropism_direction'] = list(map(float,vconfig['tropism direction'].split(','))) - if vconfig.has_key('initial elasticity'): + if 'initial elasticity' in vconfig: vlpyinitconfig['initial_elasticity'] = float(vconfig['initial elasticity']) - if vconfig.has_key('elasticity increment'): + if 'elasticity increment' in vconfig: vlpyconfig['ElasticityIncrement'] = float(vconfig['elasticity increment']) surfaces = None - if vconfig.has_key('surface'): + if 'surface' in vconfig: values = vconfig['surface'] if type(values) != list: values = [values] surfaces = dict() @@ -71,13 +71,13 @@ def get_view_info(vconfig): def translate_view_init(vlpyinitconfig): res = '' - if vlpyinitconfig.has_key('initial_color'): + if 'initial_color' in vlpyinitconfig: res += ',('+str(vlpyinitconfig['initial_color'])+')' - if vlpyinitconfig.has_key('initial_line_width'): + if 'initial_line_width' in vlpyinitconfig: res += '_('+str(vlpyinitconfig['initial_line_width'])+')' - if vlpyinitconfig.has_key('initial_scale'): + if 'initial_scale' in vlpyinitconfig: res += '@D('+str(vlpyinitconfig['initial_scale'])+')' - if vlpyinitconfig.has_key('initial_elasticity'): + if 'initial_elasticity' in vlpyinitconfig: res += '@Ts('+str(vlpyinitconfig['initial_elasticity'])+')' return res @@ -85,21 +85,21 @@ def generate_view_code(vlpyconfig,groupofpatches = None): import os.path code = '# Turtle attributes \n' for att in ['AngleIncrement','ColorIncrement','WidthIncrement','ScaleMultiplier']: - if vlpyconfig.has_key(att): + if att in vlpyconfig: code += 'context().turtle.set'+att+'('+str(vlpyconfig[att])+')\n' - if vlpyconfig.has_key('tropism direction'): + if 'tropism direction' in vlpyconfig: val = vlpyconfig['tropism direction'] code += 'context().turtle.setTropism('+str((val[0],val[2],val[1]))+')\n' if groupofpatches and len(groupofpatches) > 0: code += '# Patch gathering \n' code += 'import openalea.plantgl.all as pgl\n' - for group,patches in groupofpatches.iteritems(): + for group,patches in groupofpatches.items(): code += group+' = pgl.Group(['+','.join(patches)+'])\n' code += group+'.name = '+repr(group)+'\n' - if vlpyconfig.has_key('surfaces'): + if 'surfaces' in vlpyconfig: code += '# Patch declaration in turtle \n' - for name, value in vlpyconfig['surfaces'].iteritems(): + for name, value in vlpyconfig['surfaces'].items(): fname,scale = value code += 'context().turtle.setSurface('+repr(name)+',pgl.Scaled('+str(scale)+','+os.path.splitext(fname)[0]+'))\n' return code diff --git a/src/openalea/lpy/defaultparameters.py b/src/openalea/lpy/defaultparameters.py index b367ea6d..92dcfc92 100644 --- a/src/openalea/lpy/defaultparameters.py +++ b/src/openalea/lpy/defaultparameters.py @@ -40,7 +40,7 @@ def default_parameters_wrapper(function): def wrapper(*args, **kwargs): l = LocalsRetriever(function) params, res = l(*args,**kwargs) - map(get_caller_frame().f_locals.setdefault, params.keys(), params.values()) + list(map(get_caller_frame().f_locals.setdefault, list(params.keys()), list(params.values()))) return res return wrapper @@ -74,7 +74,7 @@ def myparams(i): import inspect if len(inspect.getargspec(function).args) == 0: params, res = LocalsRetriever(function)() - map(get_caller_frame().f_locals.setdefault, params.keys(), params.values()) + list(map(get_caller_frame().f_locals.setdefault, list(params.keys()), list(params.values()))) return function else: return default_parameters_wrapper(function) diff --git a/src/openalea/lpy/gui/compile_ui.py b/src/openalea/lpy/gui/compile_ui.py index ea1f53bb..da998df5 100644 --- a/src/openalea/lpy/gui/compile_ui.py +++ b/src/openalea/lpy/gui/compile_ui.py @@ -1,10 +1,10 @@ -from openalea.vpltk.qt import qt -from openalea.vpltk.qt.uic import compileUi, compile_args +from openalea.plantgl.gui.qt import qt +from openalea.plantgl.gui.qt.uic import compileUi, compile_args import os import sys -from openalea.vpltk.qt import QT_API, PYQT5_API, PYQT4_API, PYSIDE_API +from openalea.plantgl.gui.qt import QT_API, PYQT5_API, PYQT4_API, PYSIDE_API def get_uifnames_from(fname): uiprefix = os.path.splitext(fname)[0] @@ -19,7 +19,7 @@ def get_rcfnames_from(fname): def compile_ui(uifname): """ compile a Ui """ pyfname = get_uifnames_from(uifname) - fstream = file(pyfname,'w') + fstream = open(pyfname,'w') compileUi(uifname, fstream, **compile_args) fstream.close() @@ -33,7 +33,7 @@ def def_exe(suffix = ''): exe = 'pyrcc4'+suffix return exe - if os.environ.has_key('CONDA_PREFIX'): + if 'CONDA_PREFIX' in os.environ: exe = def_exe() elif sys.platform == 'darwin': exe = def_exe('-2.7') @@ -48,8 +48,8 @@ def def_exe(suffix = ''): def detect_file_api(fname): patternapi = {'PyQt5':PYQT5_API, 'PyQt4':PYQT4_API, 'PySide':PYSIDE_API} - txt = file(fname,'r').read() - for pattern,api in patternapi.items(): + txt = open(fname,'r').read() + for pattern,api in list(patternapi.items()): if pattern in txt: return api return None @@ -61,7 +61,7 @@ def check_ui_generation(uifname): not os.path.exists(pyfname) or (os.access(pyfname,os.F_OK|os.W_OK) and os.stat(pyfname).st_mtime < os.stat(uifname).st_mtime or not api in detect_file_api(pyfname))) : - print 'Generate Ui', repr(uifname) + print('Generate Ui', repr(uifname)) compile_ui(uifname) def check_rc_generation(rcfname): @@ -72,5 +72,5 @@ def check_rc_generation(rcfname): not os.path.exists(pyfname) or (os.access(pyfname,os.F_OK|os.W_OK) and os.stat(pyfname).st_mtime < os.stat(rcfname).st_mtime or not api in detect_file_api(pyfname))) : - print 'Generate Rc', repr(rcfname) + print('Generate Rc', repr(rcfname)) compile_rc(rcfname) diff --git a/src/openalea/lpy/gui/computationtask.py b/src/openalea/lpy/gui/computationtask.py index fe786856..ae9a8343 100644 --- a/src/openalea/lpy/gui/computationtask.py +++ b/src/openalea/lpy/gui/computationtask.py @@ -38,7 +38,7 @@ def run(self): try: self.process(self) except : - self.exception = ThreadTransferException(sys.exc_type,sys.exc_value,sys.exc_traceback) + self.exception = ThreadTransferException(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]) else: self.process(self) def finalize(self): @@ -77,7 +77,7 @@ def finalizeTask(self): if not self.computationThread is None: try: self.computationThread.finalize() - except ThreadTransferException, e: + except ThreadTransferException as e: self.graberror((e.exc_type,e.exc_value,e.exc_traceback)) except: self.graberror() @@ -153,7 +153,7 @@ def graberror(self, exc_info = None, displayDialog = True): else: self.endErrorEvent(None) def getErrorMessage(self,exc_info): - print type(exc_info[1]), exc_info[1] + print(type(exc_info[1]), exc_info[1]) msg = str(exc_info[1]) if exc_info[0] == SyntaxError and len(msg) == 0: msg = exc_info[1].msg diff --git a/src/openalea/lpy/gui/documentation.py b/src/openalea/lpy/gui/documentation.py index 5b06aa40..23d849cb 100644 --- a/src/openalea/lpy/gui/documentation.py +++ b/src/openalea/lpy/gui/documentation.py @@ -157,8 +157,8 @@ def aboutVPlants(parent): def splashLPy(): try: return lpyDialog() - except Exception,e: - print e + except Exception as e: + print(e) pass def vplantsDialog(parent = None): diff --git a/src/openalea/lpy/gui/killsimulationdialog.py b/src/openalea/lpy/gui/killsimulationdialog.py index f8a8a598..91129c7d 100644 --- a/src/openalea/lpy/gui/killsimulationdialog.py +++ b/src/openalea/lpy/gui/killsimulationdialog.py @@ -5,7 +5,7 @@ py2exe_release = False from openalea.vpltk.qt import qt -from killsimulationwidget import Ui_KillSimulationDialog +from .killsimulationwidget import Ui_KillSimulationDialog from openalea.vpltk.qt.QtCore import QTimer from openalea.vpltk.qt.QtWidgets import QDialog diff --git a/src/openalea/lpy/gui/lpycodeeditor.py b/src/openalea/lpy/gui/lpycodeeditor.py index 551afc62..d66bad84 100644 --- a/src/openalea/lpy/gui/lpycodeeditor.py +++ b/src/openalea/lpy/gui/lpycodeeditor.py @@ -96,7 +96,7 @@ def setTabViewActivation(self,value): self.tabviewactivated = value self.rehighlight() def highlightBlock(self,text): - text = unicode(text) + text = str(text) if self.activated: lentxt = len(text) prevst = self.currentBlockState() @@ -183,7 +183,7 @@ def highlightBlock(self,text): index = self.tabRule.indexIn(text) if index >= 0: length = self.tabRule.matchedLength() - for i in xrange(index,index+length): + for i in range(index,index+length): if text[i] == '\t': self.setFormat(i, 1 , self.tabFormat) else: @@ -243,15 +243,15 @@ def hasMarker(self): return len(self.markers) != 0 def setMarkerAt(self,line,id): self.markers[line] = id - if self.markerStack.has_key(line): + if line in self.markerStack: del self.markerStack[line] self.update() def hasMarkerAt(self,line): - return self.markers.has_key(line) + return line in self.markers def hasMarkerTypeAt(self,line,id): - if self.markers.has_key(line) : + if line in self.markers : if self.markers[line] == id: return True - if self.markerStack.has_key(line): + if line in self.markerStack: if id in self.markerStack[line]: return True return False @@ -259,7 +259,7 @@ def getCurrentMarkerAt(self,line): return self.markers[line] def removeCurrentMarkerAt(self,line): del self.markers[line] - if self.markerStack.has_key(line): + if line in self.markerStack: self.markers[line] = self.markerStack[line].pop() if len(self.markerStack[line]) == 0: del self.markerStack[line] @@ -273,9 +273,9 @@ def removeMarkerTypeAt(self,line,id): del self.markerStack[line] self.update() def removeAllMarkersAt(self,line): - if self.marker.has_key(line): + if line in self.marker: del self.markers[line] - if self.markerStack.has_key(line): + if line in self.markerStack: del self.markerStack[line] self.update() def removeAllMarkers(self): @@ -285,7 +285,7 @@ def removeAllMarkers(self): def addMarkerAt(self,line,id): val = self.markers.get(line,None) if not val is None: - if not self.markerStack.has_key(line): + if line not in self.markerStack: self.markerStack[line] = [] self.markerStack[line].append(val) self.markers[line] = id @@ -293,7 +293,7 @@ def addMarkerAt(self,line,id): def appendMarkerAt(self,line,id): val = self.markers.get(line,None) if not val is None: - if not self.markerStack.has_key(line): + if line not in self.markerStack: self.markerStack[line] = [] self.markerStack[line].append(id) else: @@ -302,28 +302,28 @@ def appendMarkerAt(self,line,id): def defineMarker(self,id,pixmap): self.markerType[id] = pixmap def getAllMarkers(self,id): - return set([l for l,lid in self.markers.iteritems() if id == lid]).union(set([l for l,lids in self.markerStack.iteritems() if id in lids])) + return set([l for l,lid in self.markers.items() if id == lid]).union(set([l for l,lids in self.markerStack.items() if id in lids])) def decalMarkers(self,line,decal = 1): markers = {} markerStack = {} if decal < 0: - for l,v in self.markers.iteritems(): + for l,v in self.markers.items(): if l <= line+decal: markers[l] = v elif l > line: markers[l+decal] = v - for l,v in self.markerStack.iteritems(): + for l,v in self.markerStack.items(): if l <= line+decal: markerStack[l] = v elif l > line: markerStack[l+decal] = v if decal > 0: - for l,v in self.markers.iteritems(): + for l,v in self.markers.items(): if l < line: markers[l] = v else: markers[l+decal] = v - for l,v in self.markerStack.iteritems(): + for l,v in self.markerStack.items(): if l < line: markerStack[l] = v else: @@ -340,7 +340,7 @@ def restoreState(self,obj): else: self.removeAllMarkers() -ErrorMarker,BreakPointMarker,CodePointMarker = range(3) +ErrorMarker,BreakPointMarker,CodePointMarker = list(range(3)) class LpyCodeEditor(QTextEdit): def __init__(self,parent): @@ -501,7 +501,7 @@ def returnEvent(self): while txtok: ok = cursor.movePosition(QTextCursor.NextCharacter,QTextCursor.KeepAnchor) if not ok: break - txt2 = unicode(cursor.selection().toPlainText()) + txt2 = str(cursor.selection().toPlainText()) txtok = (txt2[-1] in ' \t') if txtok: txt = txt2 @@ -514,7 +514,7 @@ def returnEvent(self): while txtok: ok = cursor.movePosition(QTextCursor.PreviousCharacter,QTextCursor.KeepAnchor) if not ok: break - txt2 = unicode(cursor.selection().toPlainText()) + txt2 = str(cursor.selection().toPlainText()) txtok = (txt2[0] in ' \t') if not txtok: if txt2[0] == ':': @@ -730,7 +730,7 @@ def untab(self): if cursor.selectedText() == '\t': cursor.deleteChar() else: - for i in xrange(len(self.indentation)-1): + for i in range(len(self.indentation)-1): b = cursor.movePosition(QTextCursor.NextCharacter,QTextCursor.KeepAnchor) if not b : break if cursor.selectedText() == self.indentation: @@ -786,7 +786,7 @@ def gotoLine(self,lineno): def gotoLineFromEdit(self): self.gotoLine(int(self.gotoEdit.text())) def setLineInEdit(self): - self.gotoEdit.setText(unicode(self.textCursor().blockNumber()+1)) + self.gotoEdit.setText(str(self.textCursor().blockNumber()+1)) self.gotoEdit.selectAll() def restoreSimuState(self,simu): if self.hasError: @@ -806,7 +806,7 @@ def restoreSimuState(self,simu): def saveSimuState(self,simu): simu.code = self.getCode() if simu.textdocument is None: - print 'custom document clone' + print('custom document clone') simu.textdocument = self.document().clone() simu.cursor = self.textCursor() simu.hvalue = self.horizontalScrollBar().value() @@ -814,7 +814,7 @@ def saveSimuState(self,simu): self.sidebar.saveState(simu) def getCode(self): - return unicode(self.toPlainText()).encode('iso-8859-1','replace') + return str(self.toPlainText()).encode('iso-8859-1','replace') def codeToExecute(self): cursor = self.textCursor() diff --git a/src/openalea/lpy/gui/lpydock.py b/src/openalea/lpy/gui/lpydock.py index 28ee2125..de223844 100644 --- a/src/openalea/lpy/gui/lpydock.py +++ b/src/openalea/lpy/gui/lpydock.py @@ -1,8 +1,8 @@ from openalea.vpltk.qt import qt import debugger_ui import debugger_right_ui -from objectpanel import LpyObjectPanelDock -from lpyshell import set_shell_widget +from .objectpanel import LpyObjectPanelDock +from .lpyshell import set_shell_widget from openalea.vpltk.qt.QtCore import Qt, QCoreApplication from openalea.vpltk.qt.QtGui import QIcon, QPixmap diff --git a/src/openalea/lpy/gui/lpypreferences.py b/src/openalea/lpy/gui/lpypreferences.py index ba785294..837a9e50 100644 --- a/src/openalea/lpy/gui/lpypreferences.py +++ b/src/openalea/lpy/gui/lpypreferences.py @@ -1,9 +1,9 @@ from openalea.vpltk.qt import qt import os -from lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot +from .lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot import generate_ui -import lpyprefwidget +from . import lpyprefwidget from openalea.vpltk.qt.QtCore import QObject, pyqtSignal diff --git a/src/openalea/lpy/gui/lpyprofiling.py b/src/openalea/lpy/gui/lpyprofiling.py index c983d257..322ff7ba 100644 --- a/src/openalea/lpy/gui/lpyprofiling.py +++ b/src/openalea/lpy/gui/lpyprofiling.py @@ -3,7 +3,7 @@ from openalea.vpltk.qt.QtGui import QStandardItem, QStandardItemModel import os -AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot = range(3) +AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot = list(range(3)) class MyItem(QStandardItem): @@ -22,8 +22,8 @@ def profileItem(st,rule_table=None,timing= None, gfname = None): si = MyItem(st.code) else: n = st.code.co_name - p = '('+','.join([st.code.co_varnames[i] for i in xrange(st.code.co_argcount)])+')' - if rule_table.has_key(n): + p = '('+','.join([st.code.co_varnames[i] for i in range(st.code.co_argcount)])+')' + if n in rule_table: n = rule_table[n] n += ':'+p else: @@ -53,7 +53,7 @@ class StEntry: def __init__(self,entry): self.entry = entry if hasattr(entry,'calls') and not entry.calls is None: - self.calls = map(StEntry,list(entry.calls)) + self.calls = list(map(StEntry,list(entry.calls))) else: self.calls = [] def __getattr__(self,name): @@ -63,13 +63,13 @@ def __getattr__(self,name): statdict = {} for s in stats: statdict[s.code] = StEntry(s) - v = statdict.values() + v = list(statdict.values()) for s in v: for subs in s.calls: - if statdict.has_key(subs.code) and subs.entry.callcount == statdict[subs.code].entry.callcount: + if subs.code in statdict and subs.entry.callcount == statdict[subs.code].entry.callcount: subs.calls = statdict[subs.code].calls del statdict[subs.code] - return statdict.values() + return list(statdict.values()) class ProfileItemModel (QStandardItemModel): def __init__(self,a,b,table,lpywidget,fname): diff --git a/src/openalea/lpy/gui/lpystudio.py b/src/openalea/lpy/gui/lpystudio.py index 64690a46..befa0d1e 100644 --- a/src/openalea/lpy/gui/lpystudio.py +++ b/src/openalea/lpy/gui/lpystudio.py @@ -12,21 +12,21 @@ except: py2exe_release = False -import qt_check +from . import qt_check import openalea.vpltk.qt.QtCore try: import PyQGLViewer -except ImportError, e: +except ImportError as e: PyQGLViewer = None import traceback as tb -import documentation as doc -import settings -import lpypreferences -from simulation import LpySimulation -from killsimulationdialog import KillSimulationDialog -from objectpanel import ObjectPanelManager +from . import documentation as doc +from . import settings +from . import lpypreferences +from .simulation import LpySimulation +from .kilsimulationdialog import KillSimulationDialog +from .objectpanel import ObjectPanelManager try: import matplotlib @@ -56,11 +56,11 @@ import generate_ui -import lpydock -import lpymainwindow as lsmw -from computationtask import * -from lpystudiodebugger import LpyVisualDebugger -from lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot +from . import lpydock +from . import lpymainwindow as lsmw +from .computationtask import * +from .lpystudiodebugger import LpyVisualDebugger +from .lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot class LpyPlotter: @@ -257,11 +257,11 @@ def check_lpy_update_available(self): return available def retrieve_official_lpy_version(self): - import urllib2 + import urllib.request, urllib.error, urllib.parse versionurl = 'https://raw.githubusercontent.com/VirtualPlants/lpy/master/src/openalea/lpy/__version__.py' try: - response = urllib2.urlopen(versionurl) - except urllib2.URLError, ue: + response = urllib.request.urlopen(versionurl) + except urllib.error.URLError as ue: import openalea.lpy.__version__ as lv return lv.__version_number__, lv.LPY_VERSION_STR else: @@ -361,7 +361,7 @@ def closeDocument(self,id = None): id = self.currentSimulationId if self.simulations[id].close(): self.documentNames.removeTab(id) - for i in xrange(id+1,len(self.simulations)): + for i in range(id+1,len(self.simulations)): self.simulations[i].index = i-1 self.textEditionWatch = False @@ -457,7 +457,7 @@ def cancelTask(self): self.killsimudialog.run(self.isRunning,self.killTask) else: if self.isRunning(): - print "Force release" + print("Force release") self.releaseCR() def customEvent(self,event): self.viewer_plot(event.scene) @@ -556,7 +556,7 @@ def newfile(self): self.releaseCR() self.currentSimulation().restoreState() def recoverPreviousFiles(self): - import lpytmpfile as tf + from . import lpytmpfile as tf import os torecover = tf.getPreviousTmpLpyFiles() nbrecoverfile = len(torecover) @@ -736,7 +736,7 @@ def nextIterate(self): self.releaseCR() def debug(self): if self.debugMode == True: - self.debugger.next() + next(self.debugger) else: self.debugMode = True self.acquireCR() @@ -811,8 +811,8 @@ def clear(self): self.releaseCR() def appendInHistory(self,fname): if fname is None: - print 'Wrong added file in history' - fname = unicode(fname) + print('Wrong added file in history') + fname = str(fname) if not fname in self.history: self.history.insert(0,fname) elif fname == self.history[0]: @@ -822,7 +822,7 @@ def appendInHistory(self,fname): del self.history[self.historymaxsize:] self.createRecentMenu() def removeInHistory(self,fname): - fname = unicode(fname) + fname = str(fname) if fname in self.history: self.history.remove(fname) self.createRecentMenu() @@ -866,7 +866,7 @@ def createTutorialMenu(self): action.setIcon(iconfile) cmenu.addAction(action) def recentMenuAction(self,action): - self.openfile(unicode(action.data())) + self.openfile(str(action.data())) def clearHistory(self): self.history = [] self.createRecentMenu() @@ -897,7 +897,7 @@ def onlinehelp(self): import webbrowser webbrowser.open("http://openalea.gforge.inria.fr/dokuwiki/doku.php?id=packages:vplants:lpy:main") def initSVNMenu(self): - import svnmanip + from . import svnmanip if not svnmanip.hasSvnSupport() : self.menuSVN.setEnabled(False) else: @@ -910,7 +910,8 @@ def initSVNMenu(self): self.actionSVNIsUpToDate.triggered.connect(self.svnIsUpToDate) # QObject.connect(self.actionSVNIsUpToDate, SIGNAL('triggered(bool)'),self.svnIsUpToDate) def updateSVNMenu(self): - import svnmanip, os + from . import svnmanip + import os if svnmanip.hasSvnSupport() : fname = self.currentSimulation().fname @@ -949,20 +950,20 @@ def svnCommit(self): def versionmessage(): import openalea.lpy.__version__ as lpyversion - print 'L-Py, version '+lpyversion.LPY_VERSION_STR + print('L-Py, version '+lpyversion.LPY_VERSION_STR) def help(): versionmessage() - print 'Frederic Boudon et al., Virtual Plants, CIRAD/INRIA/INRA' - print - print 'lpy [OPTIONS] [FILES]' - print 'OPTIONS:' - print '--help : print this help' - print '--version : print version of the software.' - print '--safe | --no-safe: load settings in a safe or no safe mode' - print '--run lpyfile: run an lpymodel' - print - print 'See http://openalea.gforge.inria.fr/wiki/doku.php?id=packages:vplants:lpy:main for more documentation' + print('Frederic Boudon et al., Virtual Plants, CIRAD/INRIA/INRA') + print() + print('lpy [OPTIONS] [FILES]') + print('OPTIONS:') + print('--help : print this help') + print('--version : print version of the software.') + print('--safe | --no-safe: load settings in a safe or no safe mode') + print('--run lpyfile: run an lpymodel') + print() + print('See http://openalea.gforge.inria.fr/wiki/doku.php?id=packages:vplants:lpy:main for more documentation') def runmodel(fname): from openalea.lpy import Lsystem @@ -996,7 +997,7 @@ def main(): return toopen = [] - if len(args) > 1: toopen = map(os.path.abspath,args[1:]) + if len(args) > 1: toopen = list(map(os.path.abspath,args[1:])) qapp = QApplication([]) try: diff --git a/src/openalea/lpy/gui/lpystudiodebugger.py b/src/openalea/lpy/gui/lpystudiodebugger.py index 20c5a7eb..ce89484a 100644 --- a/src/openalea/lpy/gui/lpystudiodebugger.py +++ b/src/openalea/lpy/gui/lpystudiodebugger.py @@ -1,7 +1,7 @@ import openalea.lpy as lpy from openalea.vpltk.qt import qt from time import clock -from lpycodeeditor import CodePointMarker, BreakPointMarker +from . lpycodeeditor import CodePointMarker, BreakPointMarker import sys import traceback as tb @@ -35,7 +35,7 @@ def __init__(self,lpywidget): self.srcView = self.debugWidget.right.srcView self.destView = self.debugWidget.right.destView self.ruleView = self.debugWidget.right.ruleView - self.debugWidget.right.nextDebugButton.clicked.connect(self.next) # QObject.connect(self.debugWidget.right.nextDebugButton,SIGNAL('clicked()'),self.next) + self.debugWidget.right.nextDebugButton.clicked.connect(self.__next__) # QObject.connect(self.debugWidget.right.nextDebugButton,SIGNAL('clicked()'),self.next) self.debugWidget.right.animateDebugButton.clicked.connect(self.animate) # QObject.connect(self.debugWidget.right.animateDebugButton,SIGNAL('clicked()'),self.animate) self.debugWidget.right.animationDebugSlider.valueChanged.connect(self.setAnimationTiming) # QObject.connect(self.debugWidget.right.animationDebugSlider,SIGNAL('valueChanged(int)'),self.setAnimationTiming) self.debugWidget.right.endDebugButton.clicked.connect(self.continueDebug) # QObject.connect(self.debugWidget.right.endDebugButton,SIGNAL('clicked()'),self.continueDebug) @@ -46,7 +46,7 @@ def startDebugger(self): if not self.lpywidget.debugDock.isWindow(): try: docks = self.lpywidget.tabifiedDockWidget(self.lpywidget.debugDock) - except AttributeError, e: + except AttributeError as e: docks = [] id = self.lpywidget.interpreterDock if id.isVisible and not id.isWindow(): @@ -138,7 +138,7 @@ def total_match(self,pos_beg,pos_end,dest,prod_length,rule,args): self.ruleView.setText(str(rule.lineno)+': '+rule.name()) self.addMarker(rule.lineno) self.setProgress(pos_end if self.direction == lpy.eForward else pos_beg) - self.updateArgs(dict(zip(rule.parameterNames(),args))) + self.updateArgs(dict(list(zip(rule.parameterNames(),args)))) self.wait() self.delMarker() def partial_match(self,pos_beg,pos_end,dest,rule,args): @@ -146,7 +146,7 @@ def partial_match(self,pos_beg,pos_end,dest,rule,args): self.print_dest(dest) self.ruleView.setText(str(rule.lineno)+': '+rule.name()+' --> nothing produce!') self.addMarker(rule.lineno) - self.updateArgs(dict(zip(rule.parameterNames(),args))) + self.updateArgs(dict(list(zip(rule.parameterNames(),args)))) self.wait() self.delMarker() def error_match(self,pos_beg,pos_end,dest,rule,args,exc_info): @@ -154,7 +154,7 @@ def error_match(self,pos_beg,pos_end,dest,rule,args,exc_info): self.print_dest(dest) self.ruleView.setText(str(rule.lineno)+': '+rule.name()+' --> raise exception!') self.addMarker(rule.lineno) - self.updateArgs(dict(zip(rule.parameterNames(),args))) + self.updateArgs(dict(list(zip(rule.parameterNames(),args)))) tb.print_exception(*exc_info) self.lpywidget.errorEvent(exc_info) errmsg = self.lpywidget.getErrorMessage(exc_info) @@ -196,7 +196,7 @@ def wait(self): raise AbortDebugger() if self.breakPointMonitor: self.retrieveBreakPoints() - def next(self): + def __next__(self): self.waitcond.unlock() def animate(self): self.animation = True @@ -228,13 +228,13 @@ def updateArgs(self,args=None): self.simu.lsystem.context().getNamespace(d) if not self.showHidden: lpyobjects = dir(lpy) - d = dict([ (n,v) for n,v in d.iteritems() if not n in lpyobjects and (len(n) < 2 or n[0:2] != '__')]) + d = dict([ (n,v) for n,v in d.items() if not n in lpyobjects and (len(n) < 2 or n[0:2] != '__')]) self.updateTable(self.debugWidget.left.globalTable,d) def updateTable(self,table,args): model = QStandardItemModel(len(args), 2) model.setHorizontalHeaderLabels(["Name", "Value", "Type" ]) indexitem = 0 - for name,val in args.iteritems(): + for name,val in args.items(): si = QStandardItem(name) si.setEditable(False) model.setItem(indexitem, 0, si) diff --git a/src/openalea/lpy/gui/lpytabbar.py b/src/openalea/lpy/gui/lpytabbar.py index e2b6e9dc..e8b6aa31 100644 --- a/src/openalea/lpy/gui/lpytabbar.py +++ b/src/openalea/lpy/gui/lpytabbar.py @@ -1,5 +1,5 @@ from openalea.vpltk.qt import qt -import svnmanip +from . import svnmanip import os from openalea.vpltk.qt.QtCore import QObject, Qt, pyqtSignal diff --git a/src/openalea/lpy/gui/lpyview3d.py b/src/openalea/lpy/gui/lpyview3d.py index cb041473..0b3bdefb 100644 --- a/src/openalea/lpy/gui/lpyview3d.py +++ b/src/openalea/lpy/gui/lpyview3d.py @@ -5,9 +5,9 @@ from openalea.plantgl.gui.pglnqgl import * ParentClass = QGLViewer hasPyQGLViewer = True -except ImportError, e: +except ImportError as e: ParentClass = qt.QtOpenGL.QGLWidget - print 'Missing PyQGLViewer !!!!!! Unstable Lpy !!!!!!!!!' + print('Missing PyQGLViewer !!!!!! Unstable Lpy !!!!!!!!!') hasPyQGLViewer = False class LpyView3D (ParentClass): @@ -37,7 +37,7 @@ def display(self,scene = None): self.camera().setSceneBoundingBox(*bbx2qgl(bbx)) self.showEntireScene() self.updateGL() - else: print 'error computing bbox' + else: print('error computing bbox') else : self.updateGL() def draw(self): diff --git a/src/openalea/lpy/gui/objectmanagers.py b/src/openalea/lpy/gui/objectmanagers.py index fd332721..da39afb0 100644 --- a/src/openalea/lpy/gui/objectmanagers.py +++ b/src/openalea/lpy/gui/objectmanagers.py @@ -22,9 +22,9 @@ def __read_manager_plugins(): listplugins = [ splitext(basename(i))[0] for i in listplugins] listplugins = [ i for i in listplugins if i[:2] != '__'] else: - import plugins.curve2dmanager as cm - import plugins.functionmanager as fm - import plugins.nurbspatchmanager as nm + from .plugins import curve2dmanager as cm + from .plugins import functionmanager as fm + from .plugins import nurbspatchmanager as nm listplugins = [cm,fm,nm] for plugin in listplugins: plugname = plugin @@ -33,7 +33,7 @@ def __read_manager_plugins(): mod = __import__(plugname) else: mod = plugin - except ImportError,e : + except ImportError as e : exc_info = sys.exc_info() traceback.print_exception(*exc_info) warnings.warn("Cannot import "+plugin+" : "+str(e)) @@ -48,10 +48,10 @@ def __read_manager_plugins(): except: managers.append(lmanagers) #print "import manager '"+lmanagers.typename+"' from plugin '"+plugin+"'" - except Exception, e: + except Exception as e: exc_info = sys.exc_info() traceback.print_exception(*exc_info) - print dir(mod) + print(dir(mod)) warnings.warn("Cannot import "+plugin+" : "+str(e)) sys.path = oldpathes return managers diff --git a/src/openalea/lpy/gui/objectpanel.py b/src/openalea/lpy/gui/objectpanel.py index 5946e035..5abe391d 100644 --- a/src/openalea/lpy/gui/objectpanel.py +++ b/src/openalea/lpy/gui/objectpanel.py @@ -5,7 +5,7 @@ import sys, traceback, os from math import sin, pi -from objectmanagers import get_managers +from .objectmanagers import get_managers from openalea.vpltk.qt.QtCore import QObject, QPoint, Qt, pyqtSignal from openalea.vpltk.qt.QtGui import QFont, QFontMetrics, QImageWriter, QColor, QPainter @@ -37,7 +37,7 @@ def renderText(self, x, y, text, font = QFont(), color = None): try: from openalea.vpltk.qt.QtGui import QOpenGLWidget QGLParentClass = QOpenGLWidget - print 'Use QOpenGLWidget' + print('Use QOpenGLWidget') QGLParentClass.mRenderText = renderText @@ -89,7 +89,7 @@ def __call__(self): self.func(*self.value) -from objectdialog import ObjectDialog +from .objectdialog import ObjectDialog class ManagerDialogContainer (QObject): def __init__(self,panel,manager): @@ -215,13 +215,13 @@ def __init__(self,parent, panelmanager = None): self.managerDialogs = {} # dialog for editor corresponding to manager # loading managers - for typename, manager in get_managers().items(): + for typename, manager in list(get_managers().items()): try: md = ManagerDialogContainer(self,manager) md.init() self.managers[typename] = manager self.managerDialogs[manager] = md - except Exception,e: + except Exception as e: exc_info = sys.exc_info() traceback.print_exception(*exc_info) continue @@ -262,17 +262,17 @@ def __init__(self,parent, panelmanager = None): def setTheme(self,theme): self.theme.values.update(theme) - for name,value in self.theme.values.items(): + for name,value in list(self.theme.values.items()): setattr(self.theme,name,[i/255. for i in value]+[0.5 if 'humbnailBackGround' in name else 1.0]) - for m in self.managers.values(): + for m in list(self.managers.values()): m.setTheme(theme) def getTheme(self): from copy import deepcopy theme = deepcopy(self.theme.values) - for m in self.managers.values(): + for m in list(self.managers.values()): theme.update(m.getTheme()) def applyTheme(self,theme): @@ -592,9 +592,9 @@ def heigth(i,nbpoint,maxheigth=self.bgheigth,midheigth=midheigth,bottomheigth=bo else: return midheigth + ((midheigth - bottomheigth) *sin(pi*2*i/float(nbpoint-1))) - points = ([ (self.bgwidth *i / float(nbpoint-1), heigth(i,nbpoint), 0) for i in xrange(nbpoint)]+ - [ (self.bgwidth *i / float(nbpoint-1), 0, 0) for i in xrange(nbpoint)]) - indices = [ (i,i+1,nbpoint+i+1,nbpoint+i) for i in xrange(nbpoint-1)] + points = ([ (self.bgwidth *i / float(nbpoint-1), heigth(i,nbpoint), 0) for i in range(nbpoint)]+ + [ (self.bgwidth *i / float(nbpoint-1), 0, 0) for i in range(nbpoint)]) + indices = [ (i,i+1,nbpoint+i+1,nbpoint+i) for i in range(nbpoint-1)] self.bgObject = QuadSet(points,indices) def drawBackGround(self,w,h): @@ -613,7 +613,7 @@ def drawBackGround(self,w,h): glTranslatef(0,h,-10) glScalef(1,-1,1) nb = w/(self.bgwidth) - for i in xrange(int(nb)+1): + for i in range(int(nb)+1): glColor4fv(c) self.bgObject.apply(self.renderer) glTranslatef(self.bgwidth,0,0) @@ -791,7 +791,7 @@ def createContextMenuActions(self): self.editAction.setFont(f) self.editAction.triggered.connect(self.editSelection) self.newItemMenu = QMenu("New item",self) - for mname, manager in self.managers.items(): + for mname, manager in list(self.managers.items()): subtypes = manager.defaultObjectTypes() if not subtypes is None and len(subtypes) == 1: mname = subtypes[0] @@ -1009,7 +1009,7 @@ def dropEvent(self,event): self.fileDropEvent(str(event.mimeData().urls()[0].toLocalFile())) def fileDropEvent(self,fname): - for manager in self.view.managers.itervalues(): + for manager in self.view.managers.values(): if manager.canImportData(fname): objects = manager.importData(fname) self.view.appendObjects([(manager,i) for i in objects]) @@ -1096,9 +1096,9 @@ def getInfo(self): def setInfo(self,info): self.setName(info['name']) - if info.has_key('active'): + if 'active' in info: self.view.setActive(info['active']) - if info.has_key('visible'): + if 'visible' in info: self.previousVisibility = info['visible'] self.setVisible(info['visible']) @@ -1138,14 +1138,14 @@ def setObjectPanelNb(self,nb, new_visible = True): nbunusedpanels = len(self.unusedpanels) nbreused = min(nbtoadd,nbunusedpanels) if nbreused > 0: - for i in xrange(nbreused): + for i in range(nbreused): npanel,visible = self.unusedpanels.pop(0) self.panels.append(npanel) if visible: npanel.show() self.vparameterView.addAction(npanel.toggleViewAction()) if nbtoadd-nbunusedpanels > 0: - for i in xrange(nbtoadd-nbunusedpanels): + for i in range(nbtoadd-nbunusedpanels): npanel = LpyObjectPanelDock(self.parent,"Panel "+str(i+nbpanel+nbunusedpanels),self) npanel.setStatusBar(self.parent.statusBar()) npanel.valueChanged.connect(self.parent.projectEdited) @@ -1179,7 +1179,7 @@ def completeMenu(self,menu,panel): subpanelmenu = QMenu("Theme",menu) panelmenu.addSeparator() panelmenu.addMenu(subpanelmenu) - for themename,value in ObjectListDisplay.THEMES.iteritems(): + for themename,value in ObjectListDisplay.THEMES.items(): panelAction = QAction(themename,subpanelmenu) panelAction.triggered.connect(TriggerParamFunc(panel.view.applyTheme,value)) diff --git a/src/openalea/lpy/gui/optioneditordelegate.py b/src/openalea/lpy/gui/optioneditordelegate.py index 64100526..81ac3dd3 100644 --- a/src/openalea/lpy/gui/optioneditordelegate.py +++ b/src/openalea/lpy/gui/optioneditordelegate.py @@ -11,7 +11,7 @@ def createEditor(self, parent, option, index): """ Create the editor """ editor = QComboBox(parent) option = index.model().itemFromIndex(index).option - editor.addItems([option[i].name for i in xrange(len(option))]) + editor.addItems([option[i].name for i in range(len(option))]) return editor def setEditorData(self, editor, index): diff --git a/src/openalea/lpy/gui/plugins/curve2dmanager.py b/src/openalea/lpy/gui/plugins/curve2dmanager.py index 6b845764..1ef7d27c 100644 --- a/src/openalea/lpy/gui/plugins/curve2dmanager.py +++ b/src/openalea/lpy/gui/plugins/curve2dmanager.py @@ -1,6 +1,6 @@ try: from openalea.plantgl.gui.curve2deditor import Curve2DEditor,Curve2DConstraint -except ImportError, e: +except ImportError as e: Curve2DEditor = None from openalea.plantgl.scenegraph import Polyline2D, BezierCurve2D, NurbsCurve2D, Point2Array, Point3Array from openalea.lpy.gui.abstractobjectmanager import * @@ -57,17 +57,17 @@ def __init__(self): self.frameColor = (0.5,0.5,0.5,1.0) def getTheme(self): - return { 'Curve2D' : [ int(self.curveColor[i] *255) for i in xrange(3)], - 'FocusCurve2D' : [ int(self.focusCurveColor[i] *255) for i in xrange(3)], - 'FrameColor' : [ int(self.frameColor[i] *255) for i in xrange(3)] } + return { 'Curve2D' : [ int(self.curveColor[i] *255) for i in range(3)], + 'FocusCurve2D' : [ int(self.focusCurveColor[i] *255) for i in range(3)], + 'FrameColor' : [ int(self.frameColor[i] *255) for i in range(3)] } def setTheme(self,theme): - if theme.has_key('FocusCurve2D'): - self.focusCurveColor = [ theme['FocusCurve2D'][i] *255 for i in xrange(3)] + [1] - if theme.has_key('Curve2D'): - self.curveColor = [ theme['Curve2D'][i] *255 for i in xrange(3)] + [1] - if theme.has_key('FrameColor'): - self.frameColor = [ theme['FrameColor'][i] *255 for i in xrange(3)] + [1] + if 'FocusCurve2D' in theme: + self.focusCurveColor = [ theme['FocusCurve2D'][i] *255 for i in range(3)] + [1] + if 'Curve2D' in theme: + self.curveColor = [ theme['Curve2D'][i] *255 for i in range(3)] + [1] + if 'FrameColor' in theme: + self.frameColor = [ theme['FrameColor'][i] *255 for i in range(3)] + [1] def displayThumbnail(self, obj, i , focus, objectthumbwidth): if focus : color = self.focusCurveColor @@ -77,11 +77,11 @@ def displayThumbnail(self, obj, i , focus, objectthumbwidth): def createDefaultObject(self,subtype = None): nbP = 4 if subtype == 'Polyline': - return Polyline2D(Point2Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)]) ) + return Polyline2D(Point2Array([(-0.5+float(i)/(nbP-1),0) for i in range(nbP)]) ) if subtype == 'BezierCurve': - return BezierCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + return BezierCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in range(nbP)],1) ) else: - return NurbsCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + return NurbsCurve2D(Point3Array([(-0.5+float(i)/(nbP-1),0) for i in range(nbP)],1) ) def reset(self,obj): subtype = 'NurbsCurve' diff --git a/src/openalea/lpy/gui/plugins/functionmanager.py b/src/openalea/lpy/gui/plugins/functionmanager.py index f20f61d2..08941d8a 100644 --- a/src/openalea/lpy/gui/plugins/functionmanager.py +++ b/src/openalea/lpy/gui/plugins/functionmanager.py @@ -1,6 +1,6 @@ try: from openalea.plantgl.gui.curve2deditor import Curve2DEditor,FuncConstraint -except ImportError, e: +except ImportError as e: Curve2DEditor = None from openalea.lpy.gui.abstractobjectmanager import * from curve2dmanager import displayLineAsThumbnail @@ -17,7 +17,7 @@ def displayThumbnail(self,obj,i,focus,objectthumbwidth): def createDefaultObject(self,subtype=None): import openalea.plantgl.all as pgl nbP = 4 - return pgl.NurbsCurve2D(pgl.Point3Array([(float(i)/(nbP-1),0) for i in xrange(nbP)],1) ) + return pgl.NurbsCurve2D(pgl.Point3Array([(float(i)/(nbP-1),0) for i in range(nbP)],1) ) def getEditor(self,parent): if Curve2DEditor: diff --git a/src/openalea/lpy/gui/plugins/nurbspatchmanager.py b/src/openalea/lpy/gui/plugins/nurbspatchmanager.py index eec890d2..9085d550 100644 --- a/src/openalea/lpy/gui/plugins/nurbspatchmanager.py +++ b/src/openalea/lpy/gui/plugins/nurbspatchmanager.py @@ -3,7 +3,7 @@ try: from openalea.plantgl.gui.nurbspatcheditor import NurbsPatchEditor from PyQGLViewer import Vec -except ImportError, e: +except ImportError as e: NurbsPatchEditor = None from OpenGL.GL import * from math import pi diff --git a/src/openalea/lpy/gui/pymodulemonitoring.py b/src/openalea/lpy/gui/pymodulemonitoring.py index 54f7271d..aa7da461 100644 --- a/src/openalea/lpy/gui/pymodulemonitoring.py +++ b/src/openalea/lpy/gui/pymodulemonitoring.py @@ -1,3 +1,4 @@ +import importlib class ModuleMonitor: def __init__(self): @@ -6,7 +7,7 @@ def __init__(self): self.sysmodules = sys.modules def _get_current_modules(self): - return set([k for k,m in self.sysmodules.items() if not m is None]) + return set([k for k,m in list(self.sysmodules.items()) if not m is None]) def start(self): self.modules = set() @@ -24,8 +25,8 @@ def reloadall(self, verbose = True): for m in self.modules: module = self.sysmodules[m] if module: - if verbose: print 'Reload',repr(m) - reload(module) + if verbose: print('Reload',repr(m)) + importlib.reload(module) class ModuleMonitorWatcher: def __init__(self, modulemonitor): @@ -72,7 +73,7 @@ def check_local_modules(dir = '.'): pylocalmodules = glob.glob('*.pyc') pylocalmodules = set([op.join(op.abspath(dir),f) for f in pylocalmodules]) result = [] - for modname, module in sys.modules.items(): + for modname, module in list(sys.modules.items()): if not module is None and ('__file__' in module.__dict__) and (op.abspath(module.__file__) in pylocalmodules): result.append(modname) return result @@ -80,5 +81,5 @@ def check_local_modules(dir = '.'): def reload_local_modules(dir = '.', verbose = False): import sys for mod in check_local_modules(dir): - if verbose: print 'Reload', mod - reload(sys.modules[mod]) + if verbose: print('Reload', mod) + importlib.reload(sys.modules[mod]) diff --git a/src/openalea/lpy/gui/reformatingcode.py b/src/openalea/lpy/gui/reformatingcode.py index 52a98c99..4d46d90f 100644 --- a/src/openalea/lpy/gui/reformatingcode.py +++ b/src/openalea/lpy/gui/reformatingcode.py @@ -41,7 +41,7 @@ def detect_signals(filetext): toinsert = {} for oline in filetext.splitlines(True): if oline.startswith('class'): - print oline, oline.split(' \t') + print(oline, oline.split(' \t')) cclass = re.split('[ \t:(]',oline)[1] cline = iline res += oline @@ -122,7 +122,7 @@ def generate_qt_header(qt_classmap): qw = set(qwmodule.__dict__.keys()) qp = set(qpmodule.__dict__.keys()) classmap = {} - for key, value in qt_classmap.items(): + for key, value in list(qt_classmap.items()): nvalue = value.split('.') if key == 'SIGNAL': key = 'pyqtSignal' @@ -135,17 +135,17 @@ def generate_qt_header(qt_classmap): if not nvalue[1] in classmap: classmap[nvalue[1]] = [] classmap[nvalue[1]].append(key) res = '' - for key, value in classmap.items(): + for key, value in list(classmap.items()): value.sort() res += 'from openalea.vpltk.qt.'+key+' import '+', '.join(value)+'\n' return res def qth(text): - print generate_qt_header(generate_qt_classmap(text)) + print(generate_qt_header(generate_qt_classmap(text))) def simmlify_code(filetext,qt_classmap): nfiletext = filetext - for nclass, oclass in qt_classmap.items(): + for nclass, oclass in list(qt_classmap.items()): nfiletext = nfiletext.replace(oclass, nclass) return nfiletext diff --git a/src/openalea/lpy/gui/scalareditor.py b/src/openalea/lpy/gui/scalareditor.py index 5be397c0..1dea0c88 100644 --- a/src/openalea/lpy/gui/scalareditor.py +++ b/src/openalea/lpy/gui/scalareditor.py @@ -1,9 +1,9 @@ from openalea.vpltk.qt import qt -from scalar import * +from .scalar import * import generate_ui import sys -import scalarmetaedit as sme +from . import scalarmetaedit as sme from openalea.vpltk.qt.QtCore import QDataStream, QIODevice, QObject, Qt, pyqtSignal from openalea.vpltk.qt.QtGui import QBrush, QColor, QStandardItem, QStandardItemModel diff --git a/src/openalea/lpy/gui/settings.py b/src/openalea/lpy/gui/settings.py index 7abd6bae..da94b212 100644 --- a/src/openalea/lpy/gui/settings.py +++ b/src/openalea/lpy/gui/settings.py @@ -15,9 +15,9 @@ def restoreState(lpywidget): settings = getSettings() settings.beginGroup('history') - lpywidget.history = [ unicode(i) for i in list(settings.value('RecentFiles')) if not i is None and len(i) > 0] + lpywidget.history = [ str(i) for i in list(settings.value('RecentFiles')) if not i is None and len(i) > 0] try: - openedfiles = [ unicode(i) for i in list(settings.value('OpenedFiles')) if not i is None and len(i) > 0] + openedfiles = [ str(i) for i in list(settings.value('OpenedFiles')) if not i is None and len(i) > 0] except: openedfiles = '' try: @@ -117,7 +117,7 @@ def restoreState(lpywidget): settings.endGroup() if settings.status() != QSettings.NoError: - raise 'settings error' + raise Exception('settings error') del settings if lpywidget.reloadAtStartup and len(openedfiles) > 0: @@ -129,8 +129,8 @@ def restoreState(lpywidget): lpywidget.openfile(openedfiles[lastfocus]) except: pass - except Exception, e: - print "cannot restore correctly state from ini file:", e + except Exception as e: + print("cannot restore correctly state from ini file:", e) def saveState(lpywidget): settings = getSettings() diff --git a/src/openalea/lpy/gui/simulation.py b/src/openalea/lpy/gui/simulation.py index ff75cde1..edd081c6 100644 --- a/src/openalea/lpy/gui/simulation.py +++ b/src/openalea/lpy/gui/simulation.py @@ -1,15 +1,15 @@ from openalea.vpltk.qt import qt from openalea.lpy import * from openalea.plantgl.all import PglTurtle, Viewer, Material, PyStrPrinter, eStatic, eAnimatedPrimitives, eAnimatedScene -import optioneditordelegate as oed +from . import optioneditordelegate as oed import os, shutil, sys, traceback from time import clock, time -from lpystudiodebugger import AbortDebugger -from scalar import * +from .lpystudiodebugger import AbortDebugger +from .scalar import * import cProfile as profiling -from lpyprofiling import * -from lpytmpfile import * -import pymodulemonitoring as pm +from .lpyprofiling import * +from .lpytmpfile import * +from . import pymodulemonitoring as pm from openalea.vpltk.qt.QtCore import QObject, pyqtSignal @@ -83,7 +83,7 @@ def isDefault(self): if self.code != defaultcode : return False if self.textedition == True : return False if self._edited == True: return False - for i in self.desc_items.itervalues(): + for i in self.desc_items.values(): if len(i) > 0: return False ini = self.getInitialisationCode() @@ -108,7 +108,7 @@ def getTabName(self): # t += '*' return t def generateIcon(self): - import svnmanip + from . import svnmanip if self.readonly is True: pixmap = QPixmap(":/images/icons/lock.png") elif self._edited: @@ -164,7 +164,7 @@ def restoreState(self): self.lpywidget.parametersTable.setModel(self.optionModel) self.lpywidget.parametersTable.setItemDelegateForColumn(1,self.optionDelegate) self.textedition, self._edited = te, tf - for key,editor in self.lpywidget.desc_items.iteritems(): + for key,editor in self.lpywidget.desc_items.items(): editor.setText(self.desc_items[key]) self.lpywidget.setTimeStep(self.lsystem.context().animation_timestep) self.lpywidget.materialed.setTurtle(self.lsystem.context().turtle) @@ -193,7 +193,7 @@ def restoreState(self): def saveState(self): #if self.lsystem.isCurrent() :self.lsystem.done() self.lpywidget.codeeditor.saveSimuState(self) - for key,editor in self.lpywidget.desc_items.iteritems(): + for key,editor in self.lpywidget.desc_items.items(): if type(editor) == QLineEdit: self.desc_items[key] = editor.text() else: @@ -211,7 +211,7 @@ def initializeParametersTable(self): category = None categoryItem = None indexitem = 0 - for i in xrange(len(options)): + for i in range(len(options)): option = options[i] if option.category != category: category = option.category @@ -264,9 +264,9 @@ def save(self): if os.path.exists(self.fname) and self.lpywidget.fileBackupEnabled : try: shutil.copy(self.fname,self.fname+'~') - except Exception,e: - print 'Cannot create backup file',repr(self.fname+'~') - print e + except Exception as e: + print('Cannot create backup file',repr(self.fname+'~')) + print(e) self.saveToFile(self.fname) self.mtime = os.stat(self.fname).st_mtime self.lpywidget.statusBar().showMessage("Save file '"+self.fname+"'",2000) @@ -441,35 +441,35 @@ def monitorfile(self): del self.monitoring def updateSvnStatus(self): - import svnmanip + from . import svnmanip if svnmanip.hasSvnSupport(): if (not hasattr(self,'svnstatus') and svnmanip.isSvnFile(self.fname)) or (hasattr(self,'svnstatus') and svnmanip.svnFileTextStatus(self.fname) != self.svnstatus): self.updateTabName(force=True) def svnUpdate(self): - import svnmanip + from . import svnmanip hasupdated = svnmanip.svnUpdate(self.fname,self.lpywidget) if hasupdated: self.reload() self.updateSvnStatus() def svnIsUpToDate(self): - import svnmanip + from . import svnmanip svnmanip.svnIsUpToDate(self.fname,self.lpywidget) self.updateSvnStatus() def svnAdd(self): - import svnmanip + from . import svnmanip svnmanip.svnFileAdd(self.fname) self.updateSvnStatus() def svnRevert(self): - import svnmanip + from . import svnmanip svnmanip.svnFileRevert(self.fname) self.reload() self.updateSvnStatus() def svnCommit(self): - import svnmanip + from . import svnmanip svnmanip.svnFileCommit(self.fname, None, self.lpywidget) self.updateSvnStatus() @@ -536,7 +536,7 @@ def updateLsystemCode(self): lpycode = self.code lpycode += '\n'+self.getInitialisationCode(False) res = self.lsystem.set(lpycode,{},self.lpywidget.showPyCode) - if not res is None: print res + if not res is None: print(res) def getInitialisationCode(self,withall=True): code = self.initialisationFunction(withall) @@ -563,7 +563,7 @@ def initialisationFunction(self, withall=True): if self.fname and len(self.fname) > 0: printer.reference_dir = os.path.abspath(os.path.dirname(self.getStrFname())) #print printer.reference_dir - for i in xrange(nbcurrent): + for i in range(nbcurrent): cmat = currentlist[i] if ( (i >= nbdefault) or (cmat.isTexture()) or @@ -581,7 +581,7 @@ def initialisationFunction(self, withall=True): if not self.lsystem.context().is_animation_timestep_to_default(): init_txt += '\tcontext.animation_timestep = '+str(self.getTimeStep())+'\n' options = self.lsystem.context().options - for i in xrange(len(options)): + for i in range(len(options)): if not options[i].isToDefault(): init_txt += '\tcontext.options.setSelection('+repr(options[i].name)+','+str(options[i].selection)+')\n' if len(self.scalars): @@ -598,7 +598,7 @@ def emptyparameterset(params): for panelinfo,objects in self.visualparameters: if panelinfo.get('active',True) or withall: for manager,obj in objects: - if not intialized_managers.has_key(manager): + if manager not in intialized_managers: intialized_managers[manager] = True init_txt += manager.initWriting('\t') init_txt += manager.writeObject(obj,'\t') @@ -639,7 +639,7 @@ def emptyparameterset(params): def creditsCode(self): txt = '' - for key,value in self.desc_items.iteritems(): + for key,value in self.desc_items.items(): if len(value) > 0: txt += key+' = '+repr(str(value))+'\n' return txt @@ -666,37 +666,37 @@ def opencode(self,txt): exc_info = sys.exc_info() traceback.print_exception(*exc_info) init = None - if context.has_key(context.InitialisationFunctionName): + if context.InitialisationFunctionName in context: del context[context.InitialisationFunctionName] - for key in self.desc_items.iterkeys(): - if context.has_key(key): + for key in self.desc_items.keys(): + if key in context: self.desc_items[key] = context[key] if init is None: init = True else: self.desc_items[key] = '' - from objectmanagers import get_managers + from .objectmanagers import get_managers managers = get_managers() self.visualparameters = [] lpy_code_version = 1.0 - if context.has_key('__lpy_code_version__'): + if '__lpy_code_version__' in context: lpy_code_version = ['__lpy_code_version__'] - if context.has_key('__functions__') and lpy_code_version <= 1.0 : + if '__functions__' in context and lpy_code_version <= 1.0 : functions = context['__functions__'] for n,c in functions: c.name = n # self.functions = [ c for n,c in functions ] funcmanager = managers['Function'] self.visualparameters += [ ({'name':'Functions'}, [(funcmanager,func) for n,func in functions]) ] - if context.has_key('__curves__') and lpy_code_version <= 1.0 : + if '__curves__' in context and lpy_code_version <= 1.0 : curves = context['__curves__'] for n,c in curves: c.name = n # self.curves = [ c for n,c in curves ] curvemanager = managers['Curve2D'] self.visualparameters += [ ({'name':'Curve2D'}, [(curvemanager,curve) for n,curve in curves]) ] - if context.has_key('__scalars__'): + if '__scalars__' in context: scalars = context['__scalars__'] self.scalars = [ ProduceScalar(v) for v in scalars ] - if context.has_key('__parameterset__'): + if '__parameterset__' in context: def checkinfo(info): if type(info) == str: return {'name':info} @@ -708,7 +708,7 @@ def checkinfo(info): import warnings warnings.warn('initialisation failed') else: - for key in self.desc_items.iterkeys(): + for key in self.desc_items.keys(): self.desc_items[key] = '' if self.textdocument: self.lpywidget.textEditionWatch = False @@ -730,7 +730,7 @@ def post_run(self,task): self.lsystem.plot(task.result,True) plottiming = time() - plottiming self.setTree(task.result,task.dl,task.timing,plottiming) - if self.lpywidget.displayMetaInfo and not self.autorun and self.lsystem.context().has_key('__description__'): + if self.lpywidget.displayMetaInfo and not self.autorun and '__description__' in self.lsystem.context(): self.lpywidget.viewer.showMessage(self.lsystem.context()['__description__'],5000) def animate(self,task): @@ -813,7 +813,7 @@ def debug(self): self.setTree(self.lsystem.derive(self.tree,self.nbiterations,1),self.nbiterations+1) else: self.setTree(self.lsystem.derive(self.lsystem.axiom,0,1),1) - except AbortDebugger,e : + except AbortDebugger as e : self.lsystem.clearDebugger() return except : diff --git a/src/openalea/lpy/gui/svnmanip.py b/src/openalea/lpy/gui/svnmanip.py index 14d6790f..d7c53b10 100644 --- a/src/openalea/lpy/gui/svnmanip.py +++ b/src/openalea/lpy/gui/svnmanip.py @@ -1,12 +1,12 @@ from openalea.vpltk.qt import qt from openalea.vpltk.qt.QtWidgets import QDialog, QMessageBox -from settings import getSettings +from .settings import getSettings try : import pysvn has_svn = True -except ImportError, e: +except ImportError as e: has_svn = False @@ -43,9 +43,9 @@ def create_svn_client(): def get_login( realm, username, may_save ): if svn_client_gui_parent is None : - print 'Login is None' + print('Login is None') return False, '', '', False - import logindialog + from . import logindialog dialog = QDialog(svn_client_gui_parent) widget = logindialog.Ui_LoginDialog() widget.setupUi(dialog) @@ -58,7 +58,7 @@ def get_login( realm, username, may_save ): def ssl_client_cert_password_prompt( realm, may_save ): if svn_client_gui_parent is None : return False, '', False - import logindialog + from . import logindialog dialog = QDialog(svn_client_gui_parent) widget = logindialog.Ui_LoginDialog() widget.setupUi(dialog) @@ -133,7 +133,7 @@ def svnUpdate(fname, parent = None): else: if parent : QMessageBox.question(parent,'Update', 'Updated at revision %s' % rev.number) return True - except pysvn.ClientError, ce: + except pysvn.ClientError as ce: QMessageBox.warning(parent,'Update', ce.message) return False @@ -148,7 +148,7 @@ def svnFileAdd(fname): return res def get_log( parent , title = 'SVN Commit'): - import logdialog + from . import logdialog dialog = QDialog(parent) widget = logdialog.Ui_LogDialog() widget.setupUi(dialog) @@ -221,7 +221,7 @@ def svnIsUpToDate( fname, parent = None, silent = False): msg += "Status : "+str(svnFileTextStatus(fname)) QMessageBox.question(parent,'Up-to-date', msg) return True - except pysvn.ClientError, ce: + except pysvn.ClientError as ce: if not silent and parent: QMessageBox.warning(parent,'Up-to-date', ce.message) return True @@ -271,28 +271,28 @@ def isSvnFile(fname): try: res = svnFileTextStatus(fname) return (res != pysvn.wc_status_kind.unversioned and res != pysvn.wc_status_kind.none and res != pysvn.wc_status_kind.ignored) - except pysvn.ClientError,e: + except pysvn.ClientError as e: return False def isSvnModifiedFile(fname): try: res = svnFileTextStatus(fname) return (res == pysvn.wc_status_kind.modified) - except pysvn.ClientError,e: + except pysvn.ClientError as e: return False def isSvnAddedFile(fname): try: res = svnFileTextStatus(fname) return (res == pysvn.wc_status_kind.added) - except pysvn.ClientError,e: + except pysvn.ClientError as e: return False def isSSHRepository(fname): try: res = svnFileInfo(fname) return ('+ssh' in res.url) - except pysvn.ClientError,e: + except pysvn.ClientError as e: return False for d in dir(pysvn.wc_status_kind): diff --git a/src/openalea/lpy/parameterset.py b/src/openalea/lpy/parameterset.py index 8d58be95..be92c2f7 100644 --- a/src/openalea/lpy/parameterset.py +++ b/src/openalea/lpy/parameterset.py @@ -16,13 +16,13 @@ def setdefault(self, *args, **kwd): assert len(args) == 0 or len(kwd) == 0 if len(args) > 0: if len(args) % 2 != 0 : raise ValueError("Should give a list of parameter name and values") - for i in xrange(len(args)/2): + for i in range(len(args)/2): attname = args[2*i] defaultvalue = args[2*i+1] if not hasattr(self,attname): setattr(self,attname,defaultvalue) elif len(kwd) > 0: - for attname, defaultvalue in kwd.items(): + for attname, defaultvalue in list(kwd.items()): if not hasattr(self,attname): setattr(self,attname,defaultvalue) @@ -42,7 +42,7 @@ def set(self, **kwd): def parameter_names(self): """ Gives the name of the parameters """ - return self.__dict__.keys() + return list(self.__dict__.keys()) def copy(self, deep = True): """ Return a deep copy of self """ @@ -51,7 +51,7 @@ def copy(self, deep = True): else: return copy(self) def __repr__(self): - return self.__class__.__name__+'('+','.join([k+'='+repr(v) for k,v in self.__dict__.items()])+')' + return self.__class__.__name__+'('+','.join([k+'='+repr(v) for k,v in list(self.__dict__.items())])+')' def __getitem__(self, attname): return getattr(self,attname) diff --git a/src/openalea/lpy/pytranslation.py b/src/openalea/lpy/pytranslation.py index 8f6c9b3f..db657940 100644 --- a/src/openalea/lpy/pytranslation.py +++ b/src/openalea/lpy/pytranslation.py @@ -7,7 +7,7 @@ def splitmodules(text): last = it while it < len(text): c = text[it] - print it, c + print(it, c) if c.isspace(): pot = it while c.isspace() and it < len(text): @@ -42,7 +42,7 @@ def splitmodules(text): last = it else: m = ModuleClass.get(text[last:it+1]) - print repr(text[last:it+1]), m + print(repr(text[last:it+1]), m) if m is None or m.name == '': it += 1 elif it < len(text)-1 and text[it+1] == '(': diff --git a/src/openalea/lpy/simu_environ.py b/src/openalea/lpy/simu_environ.py index b2ad3453..72757d2b 100644 --- a/src/openalea/lpy/simu_environ.py +++ b/src/openalea/lpy/simu_environ.py @@ -1,5 +1,5 @@ from openalea.plantgl.all import PglTurtle, PyStrPrinter, Material -from __lpy_kernel__ import LpyParsing, LsysContext +from .__lpy_kernel__ import LpyParsing, LsysContext def getInitialisationCode(context = None, scalars = None, visualparameters = None, credits = None, colorlist = None, simplified = False, keepCode_1_0_Compatibility = False, referencedir = None): @@ -42,7 +42,7 @@ def emptyparameterset(params): for panelinfo,objects in visualparameters: if panelinfo.get('active',True) or not simplified: for manager,obj in objects: - if not intialized_managers.has_key(manager): + if manager not in intialized_managers: intialized_managers[manager] = True init_txt += manager.initWriting('\t') init_txt += manager.writeObject(obj,'\t') @@ -93,7 +93,7 @@ def colorListCode(colorlist = None, referencedir = None, indentation = '\t'): printer.line_between_object = 0 if referencedir: printer.reference_dir = referencedir - for i in xrange(nbcurrent): + for i in range(nbcurrent): cmat = colorlist[i] if ( (i >= nbdefault) or (cmat.isTexture()) or @@ -116,7 +116,7 @@ def contextOptionCode(context,indentation = '\t'): if not context.is_animation_timestep_to_default(): init_txt += '\tcontext.animation_timestep = '+str(context.animation_timestep)+'\n' options = context.options - for i in xrange(len(options)): + for i in range(len(options)): if not options[i].isToDefault(): init_txt += '\tcontext.options.setSelection('+repr(options[i].name)+','+str(options[i].selection)+')\n' return init_txt @@ -131,7 +131,7 @@ def scalarCode(scalars = None, indentation = '\t'): def creditsCode(desc_items): txt = '' - for key,value in desc_items.iteritems(): + for key,value in desc_items.items(): if len(value) > 0: txt += key+' = '+repr(str(value))+'\n' return txt diff --git a/src/openalea/lpy_d/__init__.py b/src/openalea/lpy_d/__init__.py index 97a62462..0a7de47b 100644 --- a/src/openalea/lpy_d/__init__.py +++ b/src/openalea/lpy_d/__init__.py @@ -1 +1 @@ -from __lpy_kernel__ import * \ No newline at end of file +from .__lpy_kernel__ import * \ No newline at end of file diff --git a/src/openalea/lpy_wralea/__wralea__.py b/src/openalea/lpy_wralea/__wralea__.py index e56f7995..255875dc 100644 --- a/src/openalea/lpy_wralea/__wralea__.py +++ b/src/openalea/lpy_wralea/__wralea__.py @@ -1,5 +1,5 @@ from openalea.core import * -#from lpy_nodes import WithLpyGui +#from .lpy_nodes import WithLpyGui __name__ = "vplants.l-py" __version__ = '0.0.1' diff --git a/src/openalea/lpy_wralea/lpy_nodes.py b/src/openalea/lpy_wralea/lpy_nodes.py index c30dcd8b..a5f08bfa 100644 --- a/src/openalea/lpy_wralea/lpy_nodes.py +++ b/src/openalea/lpy_wralea/lpy_nodes.py @@ -154,7 +154,7 @@ def showEvent(self,e): except: - print "Import lpy.gui has failed" + print("Import lpy.gui has failed") WithLpyGui = False LSysWidget = None From c852fc5b804c8a72365d0138b5c802037bdafa4e Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 12:51:14 +0200 Subject: [PATCH 37/68] Upgrade tests to Python 3 --- test/cembedding/test_cembedding.py | 2 +- test/test_axialtree.py | 14 ++++++------- test/test_debugger.py | 20 +++++++++---------- test/test_endeach.py | 6 +++--- test/test_execcontext.py | 6 +++--- test/test_fibonacci.py | 2 +- test/test_genscene.py | 2 +- test/test_geometry.py | 6 +++--- test/test_lpytest.py | 10 +++++----- test/test_lsystem_as_module.py | 4 ++-- test/test_lsystemiterator.py | 2 +- test/test_matching.py | 18 ++++++++--------- test/test_memory.py | 10 +++++----- test/test_modnamespace.py | 8 ++++---- test/test_nproduce.py | 10 +++++----- test/test_parsing.py | 14 ++++++------- test/test_predecessor_at_scale.py | 16 +++++++-------- test/test_regexpmatching.py | 6 +++--- test/test_selection.py | 8 ++++---- test/test_shareexamples.py | 4 ++-- test/test_starmatching.py | 32 +++++++++++++++--------------- test/test_stringmatching.py | 4 ++-- test/test_successor_at_scale.py | 14 ++++++------- test/test_tree_matching.py | 20 +++++++++---------- test/test_ui.py | 6 +++--- 25 files changed, 122 insertions(+), 122 deletions(-) diff --git a/test/cembedding/test_cembedding.py b/test/cembedding/test_cembedding.py index 8484d1da..c8715038 100644 --- a/test/cembedding/test_cembedding.py +++ b/test/cembedding/test_cembedding.py @@ -6,7 +6,7 @@ def test_embeddedlpy(): proc = subprocess.Popen(["./embeddedlpy"], stdout=subprocess.PIPE) out, err = proc.communicate() out = out.strip() - print repr(out) + print(repr(out)) assert out == "'+(90);(3)I(6765)I(4181)I(2584)I(1597)I(987)I(610)I(377)I(233)I(144)I(89)I(55)I(34)I(21)I(13)I(8)I(5)I(3)I(2)I(1)I(1)'" if __name__ == '__main__': diff --git a/test/test_axialtree.py b/test/test_axialtree.py index 277ea035..d7edd6e4 100644 --- a/test/test_axialtree.py +++ b/test/test_axialtree.py @@ -9,7 +9,7 @@ def test_repr(): l.makeCurrent() m = ParamModule('B',A()) a = AxialTree([m]) - print a + print(a) def test_well_bracketed(): l = LsysContext() @@ -76,7 +76,7 @@ def test_successor_at_level(): a = AxialTree('BA[A[A][CA]][A]B[[[CA]CA]AA]') l.setModuleScale('B,C',1) l.setModuleScale('A',2) - print a.successor_at_level(0,1) + print(a.successor_at_level(0,1)) assert a.successor_at_level(0,1) == 15 @@ -89,7 +89,7 @@ def test_successor_at_scale(): assert a.successor_at_scale(0,1) == 15 assert a.successor_at_scale(15,1) == 29 a = AxialTree('BA[[A][CA][A]A]BA[[[CA]CA]AA]') - print a.directSon(1),a.directSon(15),a.successor_at_scale(1,2) + print(a.directSon(1),a.directSon(15),a.successor_at_scale(1,2)) assert a.successor_at_scale(1,2) == 16 def test_successor_at_scale2(): @@ -108,16 +108,16 @@ def test_predecessor_at_scale(): l.setModuleScale('B,C',1) l.setModuleScale('A',2) assert a.predecessor_at_scale(15,1) == 0 - print a.predecessor_at_scale(25,2) + print(a.predecessor_at_scale(25,2)) assert a.predecessor_at_scale(25,2) == 1 if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_debugger.py b/test/test_debugger.py index a5322f78..937027ec 100644 --- a/test/test_debugger.py +++ b/test/test_debugger.py @@ -6,27 +6,27 @@ def __init__(self): def begin(self,src,direction): self.direction = direction self.src = src - print 'Axiom:',src + print('Axiom:',src) def end(self,result): - print 'Result:',result + print('Result:',result) def total_match(self,pos_beg,pos_end,dest,prod_length,rule,args): - print pos_beg,pos_end,dest,prod_length,rule,args + print(pos_beg,pos_end,dest,prod_length,rule,args) assert self.src[pos_beg].name == 'B' if self.direction == eForward: - print '*', prod_length - print dest - print self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[-prod_length:] + print('*', prod_length) + print(dest) + print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[-prod_length:]) else: - print self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[:prod_length] + print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[:prod_length]) def partial_match(self,pos_beg,pos_end,dest,rule,args): assert self.src[pos_beg].name == 'C' - print self.src[pos_beg:pos_end],'--',rule.lineno-1,'--> failed' + print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'--> failed') def identity(self,pos,dest): assert self.src[pos].name in 'AC' if self.direction == eForward: - print self.src[pos],'-- ID ->',dest[-1] + print(self.src[pos],'-- ID ->',dest[-1]) else: - print self.src[pos],'-- ID ->',dest[0] + print(self.src[pos],'-- ID ->',dest[0]) lcode = """ Axiom: BAABAC diff --git a/test/test_endeach.py b/test/test_endeach.py index 07acdbe2..079b942e 100644 --- a/test/test_endeach.py +++ b/test/test_endeach.py @@ -204,10 +204,10 @@ def test_endeach_with_return_none(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_execcontext.py b/test/test_execcontext.py index 361cd3f6..391984b3 100644 --- a/test/test_execcontext.py +++ b/test/test_execcontext.py @@ -27,10 +27,10 @@ def ctx(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_fibonacci.py b/test/test_fibonacci.py index 14f18c9b..ec68a27f 100644 --- a/test/test_fibonacci.py +++ b/test/test_fibonacci.py @@ -6,7 +6,7 @@ def test_backward(): """ Computation of the fibonnacci series using fast transfer in backward direction """ l = Lsystem(get_filename('fibonacci.lpy')) a = l.iterate() - print a + print(a) assert a[2][0] == 6765, "Lpy failed to compute fibonacci test" assert a[3][0] == 4181, "Lpy failed to compute fibonacci test" assert a[21][0] == 1, "Lpy failed to compute fibonacci test" diff --git a/test/test_genscene.py b/test/test_genscene.py index 90fc7485..a6d89457 100644 --- a/test/test_genscene.py +++ b/test/test_genscene.py @@ -5,7 +5,7 @@ def sc2dict(s): d = {} for i in s: - if not d.has_key(i.id): + if i.id not in d: d[i.id] = [] d[i.id].append(i) return d diff --git a/test/test_geometry.py b/test/test_geometry.py index ceaf7b74..b99aea54 100644 --- a/test/test_geometry.py +++ b/test/test_geometry.py @@ -45,10 +45,10 @@ def test_surface(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_lpytest.py b/test/test_lpytest.py index 3b1c6bc6..f56299ff 100644 --- a/test/test_lpytest.py +++ b/test/test_lpytest.py @@ -12,8 +12,8 @@ def exec_lpy_tst(lfile): try: l = Lsystem(lfile) l.iterate() - except Exception,e : - print 'Test file :',lfile + except Exception as e : + print('Test file :',lfile) raise e toavoid = [] @@ -25,7 +25,7 @@ def test_lpy_tests(): for lfile in get_lpy_tst(): if os.path.basename(lfile) in toavoid: continue - print lfile + print(lfile) yield exec_lpy_tst,lfile @@ -34,8 +34,8 @@ def test_diese_bug(): try: exec_lpy_tst("diese_bug.lpy") ok = False - except Exception,e: - print e + except Exception as e: + print(e) ok = True assert ok diff --git a/test/test_lsystem_as_module.py b/test/test_lsystem_as_module.py index 001a73df..9d54f484 100644 --- a/test/test_lsystem_as_module.py +++ b/test/test_lsystem_as_module.py @@ -16,9 +16,9 @@ def test_lsystem_as_module(): l.test1 = 2 assert l.test1 == 2 assert l.context()['test1'] == 2 - print 'Axiom:',l.axiom + print('Axiom:',l.axiom) l.axiom = 'B' - print l.axiom, type(l.axiom) + print(l.axiom, type(l.axiom)) assert type(l.axiom) == AxialTree and l.axiom == Lstring('B') if __name__ == '__main__': diff --git a/test/test_lsystemiterator.py b/test/test_lsystemiterator.py index 3bb5171c..e71cbe58 100644 --- a/test/test_lsystemiterator.py +++ b/test/test_lsystemiterator.py @@ -11,7 +11,7 @@ def test_iterator(): """ ) for lstring in l: - print lstring + print(lstring) if __name__ == '__main__': diff --git a/test/test_matching.py b/test/test_matching.py index e1c0a11c..73b217fd 100644 --- a/test/test_matching.py +++ b/test/test_matching.py @@ -13,7 +13,7 @@ def test_matchingmode(): l = Lsystem() modes = { 0: PatternModule.eSimple, 1: PatternModule.eWithStar , 2: PatternModule.eWithStarNValueConstraint } l.set(lcode_matchingmode) - for key,val in modes.items(): + for key,val in list(modes.items()): l.context().options.setSelection('Module matching',key) l.context()['mode'] = val l.iterate() @@ -31,7 +31,7 @@ def EndEach(): """ -def runmatch(code,optionvalues = range(3)): +def runmatch(code,optionvalues = list(range(3))): if type(optionvalues) == int: optionvalues = [optionvalues] for i in range(3): @@ -44,7 +44,7 @@ def runmatch(code,optionvalues = range(3)): try: l.set(lcodebeg+code) l.iterate() - print "Test do not fail for unsupported module matching mode : %i." % i + print("Test do not fail for unsupported module matching mode : %i." % i) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass @@ -162,7 +162,7 @@ def test_match_mod_with_valueargs(): def test_match_mod_with_stararg(): """ Test matching of module with pattern with a star arg as argument """ - runmatch(lcodemodwithstararg,range(1,3)) + runmatch(lcodemodwithstararg,list(range(1,3))) ######################################################## @@ -179,7 +179,7 @@ def test_match_mod_with_stararg(): def test_match_mod_with_stararg_for_two(): """ Test matching of module with pattern with a star arg as argument """ - runmatch(lcodemodwithstararg_for_two,range(1,3)) + runmatch(lcodemodwithstararg_for_two,list(range(1,3))) ######################################################## @@ -194,7 +194,7 @@ def test_match_mod_with_stararg_for_two(): def test_match_mod_with_stararg_for_zero(): """ Test matching of module with pattern with a star arg as argument """ - runmatch(lcodemodwithstararg_for_zero,range(1,3)) + runmatch(lcodemodwithstararg_for_zero,list(range(1,3))) ######################################################## @@ -461,10 +461,10 @@ def test_simple_match() : if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_memory.py b/test/test_memory.py index 3c20177f..2d838612 100644 --- a/test/test_memory.py +++ b/test/test_memory.py @@ -14,15 +14,15 @@ def test_AT( nb = maxlength, size = maxsize): """ Test creation of AxialTree """ - for i in xrange(nb): + for i in range(nb): a = AxialTree('F'*size) del a def test_PAT( nb = maxlength, size = maxsize): """ Test creation of Parametric AxialTree """ - for i in xrange(nb): + for i in range(nb): a = AxialTree() - for j in xrange(size): + for j in range(size): a += 'F('+str(j)+')' del a @@ -31,7 +31,7 @@ def test_LsRuleWithGlobalContext(): l = LsysRule() try: l.set('F --> F') - except NameError,e : + except NameError as e : import warnings warnings.warn("GlobalContext has not lpy symbols") @@ -57,7 +57,7 @@ def lnLs(l = 8): else: res = 6 a = 5 - for i in xrange(l-2): + for i in range(l-2): res += a*6 a *= 5 res += a*11 diff --git a/test/test_modnamespace.py b/test/test_modnamespace.py index c0c12dfd..09775cfa 100644 --- a/test/test_modnamespace.py +++ b/test/test_modnamespace.py @@ -10,7 +10,7 @@ def test_modclasstable(): ids.sort() #cl.sort(lambda x,y : cmp(x.id,y.id)) #print cl - assert ids == range(len(ids)) and "All predefined modules are not registered or other modules are still registered" + assert ids == list(range(len(ids))) and "All predefined modules are not registered or other modules are still registered" lcode1 = """ module BABA @@ -122,10 +122,10 @@ def test_scale_declaration(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_nproduce.py b/test/test_nproduce.py index f1a451ec..cd464f8f 100644 --- a/test/test_nproduce.py +++ b/test/test_nproduce.py @@ -4,18 +4,18 @@ def test_nproduce(verbose = False): """ Test use of nproduce """ l=Lsystem(get_filename('test_nproduce.lpy')) - if verbose: print l.axiom + if verbose: print(l.axiom) res = l.derive(1) - if verbose: print res + if verbose: print(res) assert len(res) == 2 and res[1].name == 'B' res = l.derive(res,1,1) - if verbose: print res + if verbose: print(res) assert len(res) == 1 and res[0].name == 'C' res = l.derive(res,2,1) - if verbose: print res + if verbose: print(res) assert len(res) == 1 and res[0].name == 'D' res = l.derive(res,3,1) - if verbose: print res + if verbose: print(res) assert len(res) == 0 if __name__ == '__main__': diff --git a/test/test_parsing.py b/test/test_parsing.py index 64699ccb..4c719fe1 100644 --- a/test/test_parsing.py +++ b/test/test_parsing.py @@ -8,7 +8,7 @@ def test_lstring2py(): declare('tralala,toto') lstr = 'FF[+F]tralala(2)[toto]' l = eval(lstring2py(lstr)) - print l + print(l) assert len(l) == 10 ax = AxialTree(l) assert len(ax) == 10 @@ -72,9 +72,9 @@ def test_format_reading(verbose = False): version = 2.5 s = LpyParsing.VersionTag % version s+='\n' - print s + print(s) read_version = LpyParsing.getFormatVersion(s) - print read_version + print(read_version) assert read_version == version supported_versions = LpyParsing.formats for v in supported_versions: @@ -108,16 +108,16 @@ def test_multi_line_production(verbose = False): l.set(lmlcode) try: l.iterate() - except Exception,e: + except Exception as e: import sys lineno = tb.extract_tb(sys.exc_info()[2])[-1][1] assert lineno == 10 if __name__ == '__main__': - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_predecessor_at_scale.py b/test/test_predecessor_at_scale.py index aa355201..78ed31ff 100644 --- a/test/test_predecessor_at_scale.py +++ b/test/test_predecessor_at_scale.py @@ -33,17 +33,17 @@ def test_predecessor_at_scale(assertion = True): l.setCode(lsysbasecode) l.makeCurrent() lstring = l.axiom - print lstring + print(lstring) for i,m in enumerate(lstring): pred = lstring.predecessor_at_scale(i,1) pred2 = lstring.predecessor_at_scale(i,2) - print i,m, - print '\t',pred, - if not pred is None: print lstring[pred], - print '\t',pred == res_1[i], - print '\t',pred2, - if not pred2 is None: print lstring[pred2], - print '\t',pred2 == res_2[i] + print(i,m, end=' ') + print('\t',pred, end=' ') + if not pred is None: print(lstring[pred], end=' ') + print('\t',pred == res_1[i], end=' ') + print('\t',pred2, end=' ') + if not pred2 is None: print(lstring[pred2], end=' ') + print('\t',pred2 == res_2[i]) if assertion: assert pred == res_1[i] and pred2 == res_2[i] diff --git a/test/test_regexpmatching.py b/test/test_regexpmatching.py index d68573ae..b1fa7e37 100644 --- a/test/test_regexpmatching.py +++ b/test/test_regexpmatching.py @@ -13,12 +13,12 @@ def EndEach(): assert matched """ -def runmatch(code, lcodebeg = lcodebeg,optionvalues = range(3)): +def runmatch(code, lcodebeg = lcodebeg,optionvalues = list(range(3))): if type(optionvalues) == int: optionvalues = [optionvalues] for i in range(3): l = Lsystem() - print i + print(i) l.context().options.setSelection('Module matching',i) if i in optionvalues: l.set(lcodebeg+code) @@ -27,7 +27,7 @@ def runmatch(code, lcodebeg = lcodebeg,optionvalues = range(3)): try: l.set(lcodebeg+code) l.iterate() - print "Test do not fail for unsupported module matching mode : %i." % i + print("Test do not fail for unsupported module matching mode : %i." % i) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass diff --git a/test/test_selection.py b/test/test_selection.py index 84060154..c6e0c7d4 100644 --- a/test/test_selection.py +++ b/test/test_selection.py @@ -8,7 +8,7 @@ def display(self,sc): pass def selection(self): if not self.selectionAsked: - print 'selection' + print('selection') self.selectionAsked = True return [3] @@ -20,13 +20,13 @@ def test_selection(): ln = len(l.axiom) l.context().makeCurrent() assert l.axiom == AxialTree('N[+NN][-N]N') and 'Invalid axiom parsing' - print l.axiom + print(l.axiom) res = l.iterate(1) - print res + print(res) assert len(res) == ln+1 assert res[3].name == '%' res = l.derive(res,1,1) - print res + print(res) assert len(res) == ln-2 assert plot.selectionAsked and "Selection has not been asked" l.done() diff --git a/test/test_shareexamples.py b/test/test_shareexamples.py index 77249f20..3cdc9bfa 100644 --- a/test/test_shareexamples.py +++ b/test/test_shareexamples.py @@ -12,8 +12,8 @@ def exec_share_example(lfile): try: l = Lsystem(lfile) l.iterate() - except Exception,e : - print 'Example file :',lfile + except Exception as e : + print('Example file :',lfile) raise e diff --git a/test/test_starmatching.py b/test/test_starmatching.py index 19e526c2..02485e48 100644 --- a/test/test_starmatching.py +++ b/test/test_starmatching.py @@ -12,7 +12,7 @@ def test_matchingmode(): l = Lsystem() modes = { 0: PatternModule.eSimple, 1: PatternModule.eWithStar , 2: PatternModule.eWithStarNValueConstraint } l.set(lcode_matchingmode) - for key,val in modes.items(): + for key,val in list(modes.items()): l.context().options.setSelection('Module matching',key) l.context()['mode'] = val l.iterate() @@ -30,7 +30,7 @@ def EndEach(): """ -def runmatch(code,optionvalues = range(3)): +def runmatch(code,optionvalues = list(range(3))): if type(optionvalues) == int: optionvalues = [optionvalues] for i in range(3): @@ -43,7 +43,7 @@ def runmatch(code,optionvalues = range(3)): try: l.set(lcodebeg+code) l.iterate() - print "Test do not fail for unsupported module matching mode : %i." % i + print("Test do not fail for unsupported module matching mode : %i." % i) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass @@ -63,7 +63,7 @@ def runmatch(code,optionvalues = range(3)): def test_match_mod_with_starmod(): """ Test matching of module with pattern with a star module """ - runmatch(lcodemodwithstarmod,range(1,3)) + runmatch(lcodemodwithstarmod,list(range(1,3))) ######################################################## @@ -80,7 +80,7 @@ def test_match_mod_with_starmod(): def test_match_mod_with_starmod_withnamearg(): """ Test matching of module with pattern with a star module and name arg """ - runmatch(lcodemodwithstarmod_withnamearg,range(1,3)) + runmatch(lcodemodwithstarmod_withnamearg,list(range(1,3))) ######################################################## @@ -100,7 +100,7 @@ def test_match_mod_with_starmod_withnamearg(): def test_match_mod_with_starmod_onearg(): """ Test matching of module with one arg with pattern with a star module """ - runmatch(lcodemodwithstarmod_onearg,range(1,3)) + runmatch(lcodemodwithstarmod_onearg,list(range(1,3))) ######################################################## @@ -118,7 +118,7 @@ def test_match_mod_with_starmod_onearg(): def test_match_mod_with_starmod_onearg_staronly(): """ Test matching of module with one arg with pattern with a star module only """ - runmatch(lcodemodwithstarmod_onearg_staronly,range(1,3)) + runmatch(lcodemodwithstarmod_onearg_staronly,list(range(1,3))) ######################################################## @@ -139,7 +139,7 @@ def test_match_mod_with_starmod_onearg_staronly(): def test_match_mod_with_starmod_two(): """ Test matching of module with two arg with pattern with a star module """ - runmatch(lcodemodwithstarmod_two,range(1,3)) + runmatch(lcodemodwithstarmod_two,list(range(1,3))) ######################################################## @@ -159,7 +159,7 @@ def test_match_mod_with_starmod_two(): def test_match_mod_with_starmod_two_staronly(): """ Test matching of module with two arg with pattern with a star module only """ - runmatch(lcodemodwithstarmod_two_staronly,range(1,3)) + runmatch(lcodemodwithstarmod_two_staronly,list(range(1,3))) ######################################################## @@ -174,7 +174,7 @@ def test_match_mod_with_starmod_two_staronly(): def test_match_mod_with_starmod_stararg(): """ Test matching of module with two arg with pattern with a star module with star args""" - runmatch(lcodemodwithstarmod_stararg,range(1,3)) + runmatch(lcodemodwithstarmod_stararg,list(range(1,3))) ######################################################## @@ -189,7 +189,7 @@ def test_match_mod_with_starmod_stararg(): def test_match_mod_with_starmod_stararg_name(): """ Test matching of module with two arg with pattern with a star module with args name and star args """ - runmatch(lcodemodwithstarmod_stararg_name,range(1,3)) + runmatch(lcodemodwithstarmod_stararg_name,list(range(1,3))) ######################################################## @@ -204,7 +204,7 @@ def test_match_mod_with_starmod_stararg_name(): def test_match_mod_with_starmod_args_and_stararg(): """ Test matching of module with two arg with pattern with a star module with 2 args and star args """ - runmatch(lcodemodwithstarmod_args_and_stararg,range(1,3)) + runmatch(lcodemodwithstarmod_args_and_stararg,list(range(1,3))) ######################################################## @@ -221,7 +221,7 @@ def test_match_mod_with_starmod_args_and_stararg(): def test_match_mod_with_starmod_enoughargs_and_stararg(): """ Test matching of module with two arg with pattern with a star module with enough args and star args """ - runmatch(lcodemodwithstarmod_enoughargs_and_stararg,range(1,3)) + runmatch(lcodemodwithstarmod_enoughargs_and_stararg,list(range(1,3))) ######################################################## @@ -417,10 +417,10 @@ def Start(): backward() if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: diff --git a/test/test_stringmatching.py b/test/test_stringmatching.py index 40f43f8b..c5e39d4e 100644 --- a/test/test_stringmatching.py +++ b/test/test_stringmatching.py @@ -9,6 +9,6 @@ def test_stringmatching(): a.addIdentity(1) a.append(1,2) b = a.begin() - for i in xrange(15): + for i in range(15): b.nextValues() - assert b.values() == (10,15) \ No newline at end of file + assert list(b.values()) == (10,15) \ No newline at end of file diff --git a/test/test_successor_at_scale.py b/test/test_successor_at_scale.py index 4f9db4bd..c1d855fc 100644 --- a/test/test_successor_at_scale.py +++ b/test/test_successor_at_scale.py @@ -40,13 +40,13 @@ def test_successor_at_scale(assertion = True): if assertion: assert pred == res_1[i] and pred2 == res_2[i] else : - print i,m, - print '\t',pred, - if not pred is None: print lstring[pred], - print '\t',pred == res_1[i], - print '\t',pred2, - if not pred2 is None: print lstring[pred2], - print '\t',pred2 == res_2[i] + print(i,m, end=' ') + print('\t',pred, end=' ') + if not pred is None: print(lstring[pred], end=' ') + print('\t',pred == res_1[i], end=' ') + print('\t',pred2, end=' ') + if not pred2 is None: print(lstring[pred2], end=' ') + print('\t',pred2 == res_2[i]) if __name__ == '__main__': test_successor_at_scale(False) diff --git a/test/test_tree_matching.py b/test/test_tree_matching.py index 570a7902..da298f0e 100644 --- a/test/test_tree_matching.py +++ b/test/test_tree_matching.py @@ -15,12 +15,12 @@ def EndEach(): assert matched """ -def matching_run(code,optionvalues = range(4)): +def matching_run(code,optionvalues = list(range(4))): if type(optionvalues) == int: optionvalues = [optionvalues] for i in range(4): l = Lsystem() - print 'option =',i + print('option =',i) if i in optionvalues: l.set(code) l.context().options.setSelection('String matching',i) @@ -30,7 +30,7 @@ def matching_run(code,optionvalues = range(4)): l.set(code) l.context().options.setSelection('String matching',i) l.iterate() - print "Test do not fail for unsupported string matching mode : %i." % i + print("Test do not fail for unsupported string matching mode : %i." % i) warnings.warn("Test do not fail for unsupported string matching mode : %i." % i) except: pass @@ -40,14 +40,14 @@ def test_axial_match() : f = open(get_filename('test_axial_matching.lpy')) code = f.read() f.close() - matching_run(code,range(1,4)) + matching_run(code,list(range(1,4))) def test_ms_match() : """ Test matching with multiscale axial tree context modification""" f = open(get_filename('test_msmatch.lpy')) code = f.read() f.close() - matching_run(code,range(2,4)) + matching_run(code,list(range(2,4))) def test_ms_match2() : """ Test matching with multiscale axial tree context modification 2""" @@ -60,14 +60,14 @@ def test_ms_match2() : global matched matched = True """ - matching_run(code,range(2,4)) + matching_run(code,list(range(2,4))) def test_axial_msmatch() : """ Test matching with axial tree context modification""" f = open(get_filename('test_axial_msmatch.lpy')) code = f.read() f.close() - matching_run(code,range(2,4)) + matching_run(code,list(range(2,4))) #def test_match_future() : matching_run('test_matching_future.lpy') @@ -75,10 +75,10 @@ def test_axial_msmatch() : if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print 'testing func:', tfn + print('testing func:', tfn) try: tf() except: diff --git a/test/test_ui.py b/test/test_ui.py index 916f4b36..b5c21752 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -49,10 +49,10 @@ def test_exit(): if __name__ == '__main__': import traceback as tb - test_func = [ (n,v) for n,v in globals().items() if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].func_code.co_firstlineno,y[1].func_code.co_firstlineno)) + test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] + test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print tfn + print(tfn) try: tf() except: From a3de8f64c9644a9f57947aede12c6dcbf9e3ac68 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 12:51:52 +0200 Subject: [PATCH 38/68] setup.py: Fix installation errors --- setup.py | 32 ++++++++++---------------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/setup.py b/setup.py index 4ad462c5..027d8534 100644 --- a/setup.py +++ b/setup.py @@ -15,8 +15,6 @@ # Package name pkg_name= namespace + '.' + package -wralea_name= namespace + '.' + package + '_wralea' - meta_version = version # check that meta version is updated @@ -29,9 +27,6 @@ print (pkg_name+': version ='+version) - - - # Scons build directory build_prefix = "build-scons" @@ -58,14 +53,18 @@ def compile_interface(): url=url, license=license, - scons_scripts = ['SConstruct'], - namespace_packages = [namespace], create_namespaces = False, # pure python packages - packages = [ pkg_name, pkg_name+'.gui',pkg_name+'.gui.plugins', pkg_name+'.cpfg_compat', wralea_name ], - py_modules = ['lpygui_postinstall'], + packages = [ + pkg_name, + pkg_name + '_d', + pkg_name + '_wralea', + pkg_name + '.gui', + pkg_name + '.gui.plugins', + pkg_name + '.cpfg_compat' + ], # python packages directory package_dir = { '' : 'src',}, @@ -75,21 +74,12 @@ def compile_interface(): package_data = {'' : ['*.pyd', '*.so', '*.dylib', '*.lpy','*.ui','*.qrc'],}, zip_safe = False, - # Specific options of openalea.deploy - lib_dirs = {'lib' : pj(build_prefix, 'lib'),}, - #bin_dirs = {'bin': pj(build_prefix, 'bin'),}, - inc_dirs = {'include' : pj(build_prefix, 'src','cpp') }, - share_dirs = {'share' : 'share', }, - # Dependencies - # entry_points entry_points = { "wralea": ["lpy = openalea.lpy_wralea",], 'gui_scripts': ['lpy = openalea.lpy.gui.lpystudio:main',], 'console_scripts': ['cpfg2lpy = openalea.lpy.cpfg_compat.cpfg2lpy:main',], - }, - - postinstall_scripts = ['lpygui_postinstall'], + }, # Dependencies setup_requires = ['openalea.deploy'], @@ -97,6 +87,4 @@ def compile_interface(): install_requires = install_requires, pylint_packages = ['src/openalea/lpy/gui'] - ) - - +) From 3928a5c0467467bfcf9b404224a9617bd6355d43 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 13:03:08 +0200 Subject: [PATCH 39/68] Update Conda Build --- conda/mcondabuild.bat | 1 - conda/meta.yaml | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) delete mode 100644 conda/mcondabuild.bat diff --git a/conda/mcondabuild.bat b/conda/mcondabuild.bat deleted file mode 100644 index e7edfea4..00000000 --- a/conda/mcondabuild.bat +++ /dev/null @@ -1 +0,0 @@ -conda build . -c openalea/label/unstable -c conda-forge -c msys2 --no-test diff --git a/conda/meta.yaml b/conda/meta.yaml index 60002a26..742295b8 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -24,7 +24,10 @@ requirements: - boost - qt - pyqt + - openalea.deploy + - setuptools run: + - python =3 - openalea.plantgl - boost - qt From ee46e7e6314c294c2d7dbbba33514e393858ca17 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 6 May 2019 13:03:34 +0200 Subject: [PATCH 40/68] Enable warnings MSVC --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bf5b0aa3..d59926e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,7 +13,7 @@ include("CXX14") # --- (Win32) Multithreaded Compilation if (MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /W0") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") endif() # --- Libraries From 81e3e094c09855ae73c837ec3047865c97a7a658 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 13 May 2019 14:25:42 +0200 Subject: [PATCH 41/68] Fix Conda Build Python version --- conda/meta.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conda/meta.yaml b/conda/meta.yaml index 742295b8..789bfd68 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -19,7 +19,7 @@ build: requirements: build: - - python =3 + - python - openalea.plantgl - boost - qt @@ -27,7 +27,7 @@ requirements: - openalea.deploy - setuptools run: - - python =3 + - python - openalea.plantgl - boost - qt From 81265858e9f6b3553bd2c2f92f86df3029aefe39 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 13 May 2019 14:25:53 +0200 Subject: [PATCH 42/68] Add Conda Constructor file --- construct.yaml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 construct.yaml diff --git a/construct.yaml b/construct.yaml new file mode 100644 index 00000000..cc7e5914 --- /dev/null +++ b/construct.yaml @@ -0,0 +1,21 @@ +# do not edit the following line. It will be updated automatically +{% set version = "2.7.2" %} + +name: openalea.lpy +version: {{ version }} + +channels: + - https://conda.anaconda.org/ethan13310/ + - https://repo.anaconda.com/pkgs/main/ + +specs: + - python + - pyqt + - pyopengl + - pyqglviewer + - scipy + - matplotlib + - openalea.plantgl + - openalea.lpy + +license_file: LICENSE.txt From ebc91c7553f2594827f4e5e06606b4e7537e2076 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 13 May 2019 14:31:11 +0200 Subject: [PATCH 43/68] Auto stash before merge of "master" and "origin/master" --- CMakeLists.txt | 2 +- conda/meta.yaml | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d59926e4..12f95133 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ project(lpy_project CXX) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include("Anaconda") -include("CXX14") +# include("CXX14") # --- (Win32) Multithreaded Compilation diff --git a/conda/meta.yaml b/conda/meta.yaml index 789bfd68..c079874d 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -16,13 +16,19 @@ about: build: preserve_egg_dir: True number: 1 + features: + - vc9 [win and py27] + - vc14 [win and py37] + track_features: + - vc9 [win and py27] + - vc14 [win and py37] requirements: build: - python - openalea.plantgl - boost - - qt + - qt =5 - pyqt - openalea.deploy - setuptools @@ -30,12 +36,14 @@ requirements: - python - openalea.plantgl - boost - - qt + - qt =5 - pyqt - ipython - qtconsole - pyopengl - pyqglviewer + - vs2008_runtime [win and py27] + - vs2015_runtime [win and py37] test: requires: From b9ee618ea466b4b41039e48a61202169d4bfd487 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Thu, 16 May 2019 14:03:30 +0200 Subject: [PATCH 44/68] Fix Anaconda environment on Unix systems --- cmake/Anaconda.cmake | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/cmake/Anaconda.cmake b/cmake/Anaconda.cmake index 056ca7fe..8b93c778 100644 --- a/cmake/Anaconda.cmake +++ b/cmake/Anaconda.cmake @@ -3,6 +3,13 @@ if (DEFINED ENV{CONDA_PREFIX}) # Anaconda Environment message(STATUS "Anaconda environment detected.") - set(CONDA_ENV "$ENV{CONDA_PREFIX}/Library") - set(CONDA_PYTHON_ENV "$ENV{CONDA_PREFIX}") + file(TO_CMAKE_PATH $ENV{CONDA_PREFIX} TMP_CONDA_ENV) + + if (WIN32) + set(CONDA_ENV "${TMP_CONDA_ENV}/Library/") + else() + set(CONDA_ENV "${TMP_CONDA_ENV}/") + endif() + + set(CONDA_PYTHON_ENV "${TMP_CONDA_ENV}/") endif() From feb6c56a7c28c40ad5f95c318e2fe48e9735f723 Mon Sep 17 00:00:00 2001 From: Ethan Margaillan Date: Mon, 27 May 2019 10:13:23 +0200 Subject: [PATCH 45/68] Fix CMake build --- CMakeLists.txt | 3 +-- conda/bld.bat | 9 +++++++-- conda/build.sh | 8 ++++++-- src/cpp/CMakeLists.txt | 4 ++++ src/wrapper/CMakeLists.txt | 10 +++++++--- 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 12f95133..7aca69d4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,6 @@ project(lpy_project CXX) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") include("Anaconda") -# include("CXX14") # --- (Win32) Multithreaded Compilation @@ -34,7 +33,7 @@ set(Boost_NO_SYSTEM_PATHS ON) set(Boost_USE_MULTITHREAD ON) set(Boost_USE_STATIC_LIBS OFF) -find_package(Boost 1.67 COMPONENTS ${BOOST_PYTHON_LIB} REQUIRED) +find_package(Boost 1.67 COMPONENTS system ${BOOST_PYTHON_LIB} REQUIRED) # --- Include Directories diff --git a/conda/bld.bat b/conda/bld.bat index 84e5d368..7682c8a0 100644 --- a/conda/bld.bat +++ b/conda/bld.bat @@ -1,6 +1,6 @@ :: Working Dir -mkdir build-cmake -cd build-cmake +mkdir build +cd build :: Build cmake -G "NMake Makefiles" -DCMAKE_INSTALL_PREFIX=%LIBRARY_PREFIX% -DCMAKE_BUILD_TYPE=Release .. @@ -9,3 +9,8 @@ nmake if errorlevel 1 exit 1 nmake install if errorlevel 1 exit 1 + +:: Install Python Files +cd .. +%PYTHON% setup.py install +if errorlevel 1 exit 1 diff --git a/conda/build.sh b/conda/build.sh index 524bbccd..c5c9546b 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -1,10 +1,14 @@ #!/bin/bash # Working Dir -mkdir build-cmake -cd build-cmake +mkdir build +cd build # Build cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} -DCMAKE_BUILD_TYPE=Release .. make -j${CPU_COUNT} make install + +# Install Python Files +cd .. +$PYTHON setup.py install --prefix=${PREFIX} diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 13621e94..33df4962 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -25,3 +25,7 @@ endif() # --- Output Library install(TARGETS lpy LIBRARY DESTINATION "lib") + +# --- Install Headers + +install(DIRECTORY "." DESTINATION "include" FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp") diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 32e63ce4..1ba77560 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(__lpy_kernel__ Python3::Python) # Disable Boost Auto-Link target_compile_definitions(__lpy_kernel__ PRIVATE BOOST_ALL_NO_LIB) -target_link_libraries(__lpy_kernel__ Boost::${BOOST_PYTHON_LIB}) +target_link_libraries(__lpy_kernel__ Boost::system Boost::${BOOST_PYTHON_LIB}) # --- Dependencies @@ -21,8 +21,12 @@ add_dependencies(__lpy_kernel__ lpy) # --- Output Library +set_target_properties(__lpy_kernel__ PROPERTIES PREFIX "") + +if (WIN32) + set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") +endif() + set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy") -install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy_d") -install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy_wralea") From 9de4f099532aecf4e1ed221ef7781481c553ca6c Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Fri, 11 Oct 2019 17:33:08 +0200 Subject: [PATCH 46/68] upgrade to python 3 --- cmake/FindPlantGL.cmake | 135 +++++++++++++++--- setup.py | 2 +- src/cpp/lsyscontext.cpp | 9 +- src/openalea/lpy/gui/abstractobjectmanager.py | 4 +- src/openalea/lpy/gui/codeeditor.py | 2 +- src/openalea/lpy/gui/computationtask.py | 8 +- src/openalea/lpy/gui/documentation.py | 8 +- src/openalea/lpy/gui/generate_ui.py | 5 +- src/openalea/lpy/gui/killsimulationdialog.py | 8 +- src/openalea/lpy/gui/lpycodeeditor.py | 10 +- src/openalea/lpy/gui/lpydock.py | 12 +- src/openalea/lpy/gui/lpypreferences.py | 10 +- src/openalea/lpy/gui/lpyprofiling.py | 6 +- src/openalea/lpy/gui/lpyshell.py | 2 +- src/openalea/lpy/gui/lpystudio.py | 23 ++- src/openalea/lpy/gui/lpystudiodebugger.py | 8 +- src/openalea/lpy/gui/lpytabbar.py | 8 +- src/openalea/lpy/gui/lpytmpfile.py | 4 +- src/openalea/lpy/gui/lpyview3d.py | 4 +- src/openalea/lpy/gui/objectdialog.py | 6 +- src/openalea/lpy/gui/objectpanel.py | 13 +- src/openalea/lpy/gui/optioneditordelegate.py | 2 +- .../lpy/gui/plugins/curve2dmanager.py | 2 +- .../lpy/gui/plugins/functionmanager.py | 2 +- src/openalea/lpy/gui/qt_check.py | 2 +- src/openalea/lpy/gui/reformatingcode.py | 2 +- src/openalea/lpy/gui/scalareditor.py | 18 +-- src/openalea/lpy/gui/settings.py | 10 +- src/openalea/lpy/gui/simulation.py | 17 +-- src/openalea/lpy/gui/streamredirection.py | 2 +- src/openalea/lpy/gui/svnmanip.py | 4 +- src/wrapper/CMakeLists.txt | 4 +- 32 files changed, 232 insertions(+), 120 deletions(-) diff --git a/cmake/FindPlantGL.cmake b/cmake/FindPlantGL.cmake index bbfcf55e..76b50e46 100644 --- a/cmake/FindPlantGL.cmake +++ b/cmake/FindPlantGL.cmake @@ -1,33 +1,136 @@ +foreach(v PLANTGL_INCLUDEDIR PLANTGL_LIBRARYDIR) + set(_env $ENV{${v}}) +endforeach() + +#set(PGL_DEBUG ON) + +if (PLANTGL_ROOT) + if(PGL_DEBUG) + message(STATUS "PLANTGL_ROOT: " ${PLANTGL_ROOT}) + endif() + if (NOT PLANTGL_INCLUDEDIR) + set(PLANTGL_INCLUDEDIR ${PLANTGL_ROOT}/include) + endif() + if (NOT PLANTGL_LIBRARYDIR) + set(PLANTGL_LIBRARYDIR ${PLANTGL_ROOT}/lib) + endif() +endif() + +if (PGL_DEBUG AND PLANTGL_INCLUDEDIR) + message(STATUS "PLANTGL_INCLUDEDIR: " ${PLANTGL_INCLUDEDIR}) +endif() + +if (PGL_DEBUG AND PLANTGL_LIBRARYDIR) + message(STATUS "PLANTGL_LIBRARYDIR: " ${PLANTGL_LIBRARYDIR}) +endif() + # Include Directory -find_path(PLANTGL_INCLUDE_DIR "plantgl/plantgl.h" "libplantgl/plantgl.h" PATHS $ENV{PATH}) +find_path(PLANTGL_INCLUDE_DIR + NAMES "plantgl/plantgl.h" + HINTS ${PLANTGL_INCLUDEDIR} $ENV{PATH}) + +if (NOT PLANTGL_INCLUDE_DIR) + set(PLANTGL_FOUND OFF) + + if (PlantGL_FIND_REQUIRED) + # PlantGL not found + message(SEND_ERROR "Unable to find PlantGL headers.") + endif() +endif() # Library Directory -find_library(PLANTGL_ALGO_LIBRARY NAMES "pglalgo" "libpglalgo" PATHS $ENV{PATH}) -find_library(PLANTGL_GUI_LIBRARY NAMES "pglgui" "libpglgui" PATHS $ENV{PATH}) -find_library(PLANTGL_MATH_LIBRARY NAMES "pglmath" "libpglmath" PATHS $ENV{PATH}) -find_library(PLANTGL_SG_LIBRARY NAMES "pglsg" "libpglsg" PATHS $ENV{PATH}) -find_library(PLANTGL_TOOL_LIBRARY NAMES "pgltool" "libpgltool" PATHS $ENV{PATH}) +find_library(PLANTGL_SG_LIBRARY + NAMES "pglsg" "libpglsg" + PATHS ${PLANTGL_LIBRARYDIR} $ENV{PATH}) -if (PLANTGL_INCLUDE_DIR AND PLANTGL_ALGO_LIBRARY AND PLANTGL_GUI_LIBRARY AND PLANTGL_MATH_LIBRARY AND PLANTGL_SG_LIBRARY AND PLANTGL_TOOL_LIBRARY) - set(PLANTGL_FOUND ON) - set(PLANTGL_INCLUDE_DIRS ${PLANTGL_INCLUDE_DIR}) - set(PLANTGL_LIBRARIES ${PLANTGL_ALGO_LIBRARY} ${PLANTGL_GUI_LIBRARY} ${PLANTGL_MATH_LIBRARY} ${PLANTGL_SG_LIBRARY} ${PLANTGL_TOOL_LIBRARY}) - - # PlantGL found - message(STATUS "Found PlantGL: TRUE") -else() +get_filename_component(PLANTGL_LIBRARY_DIR ${PLANTGL_SG_LIBRARY} DIRECTORY) + +if (NOT PLANTGL_LIBRARY_DIR) set(PLANTGL_FOUND OFF) if (PlantGL_FIND_REQUIRED) # PlantGL not found - message(SEND_ERROR "Unable to find PlantGL library.") + message(SEND_ERROR "Unable to find PlantGL libraries repository.") endif() endif() -if (PLANTGL_FOUND) + +if (PLANTGL_INCLUDE_DIR AND PLANTGL_LIBRARY_DIR) + set(PLANTGL_FOUND ON) + # PlantGL found + message(STATUS "Found PlantGL: TRUE") + + find_library(PLANTGL_MATH_LIBRARY + NAMES "pglmath" "libpglmath" + PATHS ${PLANTGL_LIBRARY_DIR} $ENV{PATH}) + if (NOT PLANTGL_MATH_LIBRARY) + message(SEND_ERROR "Unable to find PlantGL math library.") + endif() + + find_library(PLANTGL_TOOL_LIBRARY + NAMES "pgltool" "libpgltool" + PATHS ${PLANTGL_LIBRARY_DIR} $ENV{PATH}) + if (NOT PLANTGL_TOOL_LIBRARY) + message(SEND_ERROR "Unable to find PlantGL tool library.") + endif() + + find_library(PLANTGL_ALGO_LIBRARY + NAMES "pglalgo" "libpglalgo" + PATHS ${PLANTGL_LIBRARY_DIR} $ENV{PATH}) + if (NOT PLANTGL_ALGO_LIBRARY) + message(SEND_ERROR "Unable to find PlantGL algo library.") + endif() + + find_library(PLANTGL_GUI_LIBRARY + NAMES "pglgui" "libpglgui" + PATHS ${PLANTGL_LIBRARY_DIR} $ENV{PATH}) + if (NOT PLANTGL_GUI_LIBRARY) + message(SEND_ERROR "Unable to find PlantGL gui library.") + endif() + + set(PLANTGL_LIBRARIES ${PLANTGL_MATH_LIBRARY} ${PLANTGL_TOOL_LIBRARY} ${PLANTGL_SG_LIBRARY} ${PLANTGL_ALGO_LIBRARY} ${PLANTGL_GUI_LIBRARY}) + # Build with PlantGL + set(PLANTGL_INCLUDE_DIRS ${PLANTGL_INCLUDE_DIR}) + set(PLANTGL_LIBRARY_DIRS ${PLANTGL_LIBRARY_DIR}) include_directories(${PLANTGL_INCLUDE_DIRS}) + link_directories(${PLANTGL_LIBRARY_DIRS}) + + elseif (NOT PlantGL_FIND_REQUIRED) message(STATUS "Building without PlantGL - Library not found.") endif() + + +# Set PLANTGL_FOUND based only on header location and version. +# It will be updated below for component libraries. +if(PLANTGL_FOUND) + if(PGL_DEBUG) + message(STATUS "location of plantgl/version.h: ${PLANTGL_INCLUDE_DIR}/plantgl/version.h") + endif() + + # Extract PGL_VERSION from version.h + set(PGL_VERSION 0) + file(STRINGS "${PLANTGL_INCLUDE_DIR}/plantgl/version.h" _PGL_VERSION_HPP_CONTENTS REGEX "#define PGL_VERSION 0x") + set(_PGL_VERSION_REGEX "([0-9]+)") + if("${_PGL_VERSION_HPP_CONTENTS}" MATCHES ".*#define PGL_VERSION 0x${_PGL_VERSION_REGEX}.*") + set(PGL_VERSION "${CMAKE_MATCH_1}") + endif() + unset(_PGL_VERSION_HPP_CONTENTS) + + math(EXPR PGL_MAJOR_VERSION "${PGL_VERSION} / 10000") + math(EXPR PGL_MINOR_VERSION "${PGL_VERSION} / 100 % 100") + math(EXPR PGL_SUBMINOR_VERSION "${PGL_VERSION} % 100") + + set(PGL_ERROR_REASON + "${PGL_ERROR_REASON}PlantGL version: ${PGL_MAJOR_VERSION}.${PGL_MINOR_VERSION}.${PGL_SUBMINOR_VERSION}\nPlantGL include path: ${PLANTGL_INCLUDE_DIR}") + message(STATUS "version.h reveals plantgl " + "${PGL_MAJOR_VERSION}.${PGL_MINOR_VERSION}.${PGL_SUBMINOR_VERSION}") + set(PGL_FOUND ON) + +else() + set(PGL_FOUND OFF) + set(PGL_ERROR_REASON + "${PGL_ERROR_REASON}Unable to find the PlantGL header files. Please set PGL_INCLUDEDIR to the directory containing PlantGL's headers.") +endif() \ No newline at end of file diff --git a/setup.py b/setup.py index 027d8534..fdd7520f 100644 --- a/setup.py +++ b/setup.py @@ -28,7 +28,7 @@ # Scons build directory -build_prefix = "build-scons" +build_prefix = "build-cmake" from setuptools import setup from openalea.deploy.binary_deps import binary_deps diff --git a/src/cpp/lsyscontext.cpp b/src/cpp/lsyscontext.cpp index 75ab6b2b..41bb122c 100644 --- a/src/cpp/lsyscontext.cpp +++ b/src/cpp/lsyscontext.cpp @@ -648,8 +648,13 @@ LsysContext::clearNamespace() { void LsysContext::namespaceInitialisation() { - if (!hasObject("__builtins__")) - setObjectToGlobals("__builtins__", object(handle<>(borrowed( PyModule_GetDict(PyImport_AddModule("__builtin__")))))); + if (!hasObject("__builtins__")){ + copyObjectToGlobals("__builtins__",globalContext()); + + // object builtin = boost::python::import("__builtin__"); + // setObjectToGlobals("__builtins__", builtin); + // setObjectToGlobals("__builtins__", object(handle<>(borrowed( PyModule_GetDict(PyImport_AddModule("__builtin__")))))); + } if (!hasObject("nproduce")){ Compilation::compile("from openalea.lpy import *",globals(),globals()); diff --git a/src/openalea/lpy/gui/abstractobjectmanager.py b/src/openalea/lpy/gui/abstractobjectmanager.py index fc925fae..c0e53d11 100644 --- a/src/openalea/lpy/gui/abstractobjectmanager.py +++ b/src/openalea/lpy/gui/abstractobjectmanager.py @@ -1,4 +1,4 @@ -from openalea.vpltk.qt.QtCore import QObject +from openalea.plantgl.gui.qt.QtCore import QObject MouseFocus, Selection, Actived = 1,2,4 @@ -108,4 +108,4 @@ def writeObject(self,obj,indentation): printer.line_between_object = 0 obj.apply(printer) return printer.str() - \ No newline at end of file + diff --git a/src/openalea/lpy/gui/codeeditor.py b/src/openalea/lpy/gui/codeeditor.py index 62ba5ba7..e2440217 100644 --- a/src/openalea/lpy/gui/codeeditor.py +++ b/src/openalea/lpy/gui/codeeditor.py @@ -7,7 +7,7 @@ # # WARNING! All changes made in this file will be lost! -from openalea.vpltk.qt import qt +from openalea.plantgl.gui.qt import qt class Ui_CodeEditor(object): def setupUi(self, CodeEditor): diff --git a/src/openalea/lpy/gui/computationtask.py b/src/openalea/lpy/gui/computationtask.py index ae9a8343..ccde0666 100644 --- a/src/openalea/lpy/gui/computationtask.py +++ b/src/openalea/lpy/gui/computationtask.py @@ -1,11 +1,11 @@ -from openalea.vpltk.qt import qt -from qt_check import QT_VERSION +from openalea.plantgl.gui.qt import qt +from .qt_check import QT_VERSION import traceback as tb import sys -from openalea.vpltk.qt.QtCore import QMutex, QObject, QThread, pyqtSignal -from openalea.vpltk.qt.QtWidgets import QMessageBox +from openalea.plantgl.gui.qt.QtCore import QMutex, QObject, QThread, pyqtSignal +from openalea.plantgl.gui.qt.QtWidgets import QMessageBox class ThreadTransferException (Exception): diff --git a/src/openalea/lpy/gui/documentation.py b/src/openalea/lpy/gui/documentation.py index 23d849cb..6315bfb8 100644 --- a/src/openalea/lpy/gui/documentation.py +++ b/src/openalea/lpy/gui/documentation.py @@ -1,11 +1,11 @@ from openalea.lpy import helpTurtle,LPY_VERSION_STR -from openalea.vpltk.qt import qt +from openalea.plantgl.gui.qt import qt import os -from openalea.vpltk.qt.QtCore import Qt -from openalea.vpltk.qt.QtGui import QPixmap -from openalea.vpltk.qt.QtWidgets import QMessageBox, QSplashScreen +from openalea.plantgl.gui.qt.QtCore import Qt +from openalea.plantgl.gui.qt.QtGui import QPixmap +from openalea.plantgl.gui.qt.QtWidgets import QMessageBox, QSplashScreen vplogofilename = ':/logo/biglogo.png' lpylogofilename = ':/logo/flower.png' diff --git a/src/openalea/lpy/gui/generate_ui.py b/src/openalea/lpy/gui/generate_ui.py index 658289b1..167bc1a0 100644 --- a/src/openalea/lpy/gui/generate_ui.py +++ b/src/openalea/lpy/gui/generate_ui.py @@ -6,9 +6,10 @@ py2exe_release = False if not py2exe_release: - import compile_ui as ui + import openalea.lpy.gui.compile_ui as ui import os.path ldir = os.path.dirname(__file__) + print("Generate Ui") ui.check_ui_generation(os.path.join(ldir, 'lpymainwindow.ui')) ui.check_ui_generation(os.path.join(ldir, 'debugger_ui.ui')) ui.check_ui_generation(os.path.join(ldir, 'debugger_right_ui.ui')) @@ -20,4 +21,4 @@ ui.check_ui_generation(os.path.join(ldir, 'scalarmetaedit.ui')) ui.check_ui_generation(os.path.join(ldir, 'scalarfloatmetaedit.ui')) del ldir - pass \ No newline at end of file + pass diff --git a/src/openalea/lpy/gui/killsimulationdialog.py b/src/openalea/lpy/gui/killsimulationdialog.py index 91129c7d..ee468fbf 100644 --- a/src/openalea/lpy/gui/killsimulationdialog.py +++ b/src/openalea/lpy/gui/killsimulationdialog.py @@ -4,11 +4,11 @@ except: py2exe_release = False -from openalea.vpltk.qt import qt +from openalea.plantgl.gui.qt import qt from .killsimulationwidget import Ui_KillSimulationDialog -from openalea.vpltk.qt.QtCore import QTimer -from openalea.vpltk.qt.QtWidgets import QDialog +from openalea.plantgl.gui.qt.QtCore import QTimer +from openalea.plantgl.gui.qt.QtWidgets import QDialog class KillSimulationDialog (QDialog,Ui_KillSimulationDialog): def __init__(self,parent): @@ -48,4 +48,4 @@ def step(self): def finishProcess(self): self.timer.stop() if self.condition(): - self.killer() \ No newline at end of file + self.killer() diff --git a/src/openalea/lpy/gui/lpycodeeditor.py b/src/openalea/lpy/gui/lpycodeeditor.py index d66bad84..b5622903 100644 --- a/src/openalea/lpy/gui/lpycodeeditor.py +++ b/src/openalea/lpy/gui/lpycodeeditor.py @@ -1,7 +1,7 @@ -from openalea.vpltk.qt import qt -from openalea.vpltk.qt.QtCore import QMimeData, QObject, QPoint, QRegExp, QTimer, Qt, pyqtSignal -from openalea.vpltk.qt.QtGui import QColor, QFont, QPainter, QPalette, QPen, QPixmap, QSyntaxHighlighter, QTextCharFormat, QTextCursor, QTextDocument, QTextOption -from openalea.vpltk.qt.QtWidgets import QLabel, QTextEdit, QWidget +from openalea.plantgl.gui.qt import qt +from openalea.plantgl.gui.qt.QtCore import QMimeData, QObject, QPoint, QRegExp, QTimer, Qt, pyqtSignal +from openalea.plantgl.gui.qt.QtGui import QColor, QFont, QPainter, QPalette, QPen, QPixmap, QSyntaxHighlighter, QTextCharFormat, QTextCursor, QTextDocument, QTextOption +from openalea.plantgl.gui.qt.QtWidgets import QLabel, QTextEdit, QWidget class LineData: def __init__(self,i = None,p = None): @@ -833,4 +833,4 @@ def codeToExecute(self): torem = len(fline) - len(nfline) nlines = [l[torem:] for l in lines] cmd = '\n'.join(nlines) - return cmd \ No newline at end of file + return cmd diff --git a/src/openalea/lpy/gui/lpydock.py b/src/openalea/lpy/gui/lpydock.py index de223844..7be3eb81 100644 --- a/src/openalea/lpy/gui/lpydock.py +++ b/src/openalea/lpy/gui/lpydock.py @@ -1,12 +1,12 @@ -from openalea.vpltk.qt import qt -import debugger_ui -import debugger_right_ui +from . import debugger_ui +from . import debugger_right_ui from .objectpanel import LpyObjectPanelDock from .lpyshell import set_shell_widget -from openalea.vpltk.qt.QtCore import Qt, QCoreApplication -from openalea.vpltk.qt.QtGui import QIcon, QPixmap -from openalea.vpltk.qt.QtWidgets import QApplication, QDockWidget, QSplitter, QWidget +from openalea.plantgl.gui.qt import qt +from openalea.plantgl.gui.qt.QtCore import Qt, QCoreApplication +from openalea.plantgl.gui.qt.QtGui import QIcon, QPixmap +from openalea.plantgl.gui.qt.QtWidgets import QApplication, QDockWidget, QSplitter, QWidget _translate = QCoreApplication.translate class DebugLeftWidget(QWidget,debugger_ui.Ui_Form): diff --git a/src/openalea/lpy/gui/lpypreferences.py b/src/openalea/lpy/gui/lpypreferences.py index 837a9e50..22624e61 100644 --- a/src/openalea/lpy/gui/lpypreferences.py +++ b/src/openalea/lpy/gui/lpypreferences.py @@ -1,13 +1,13 @@ -from openalea.vpltk.qt import qt +from openalea.plantgl.gui.qt import qt import os from .lpyprofiling import AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot -import generate_ui +from . import generate_ui from . import lpyprefwidget -from openalea.vpltk.qt.QtCore import QObject, pyqtSignal -from openalea.vpltk.qt.QtWidgets import QDialog +from openalea.plantgl.gui.qt.QtCore import QObject, pyqtSignal +from openalea.plantgl.gui.qt.QtWidgets import QDialog class LpyPreferences: @@ -90,4 +90,4 @@ def setPofilingButton(self,value): self.widget.profilingNoPlotButton.setChecked(True) def setOutputRedirection(self): self.editor.shellwidget.setOutputRedirection(self.widget.LPyConsoleButton.isChecked(),self.widget.systemConsoleButton.isChecked()) - \ No newline at end of file + diff --git a/src/openalea/lpy/gui/lpyprofiling.py b/src/openalea/lpy/gui/lpyprofiling.py index 322ff7ba..87d7d9d5 100644 --- a/src/openalea/lpy/gui/lpyprofiling.py +++ b/src/openalea/lpy/gui/lpyprofiling.py @@ -1,6 +1,6 @@ -from openalea.vpltk.qt import qt -from openalea.vpltk.qt.QtCore import QObject, Qt, pyqtSignal -from openalea.vpltk.qt.QtGui import QStandardItem, QStandardItemModel +from openalea.plantgl.gui.qt import qt +from openalea.plantgl.gui.qt.QtCore import QObject, Qt, pyqtSignal +from openalea.plantgl.gui.qt.QtGui import QStandardItem, QStandardItemModel import os AnimatedProfiling, ProfilingWithFinalPlot, ProfilingWithNoPlot = list(range(3)) diff --git a/src/openalea/lpy/gui/lpyshell.py b/src/openalea/lpy/gui/lpyshell.py index 16c2231c..20c9fc96 100644 --- a/src/openalea/lpy/gui/lpyshell.py +++ b/src/openalea/lpy/gui/lpyshell.py @@ -2,7 +2,7 @@ from qtconsole.rich_jupyter_widget import RichJupyterWidget from qtconsole.inprocess import QtInProcessKernelManager -from streamredirection import GraphicalStreamRedirection +from .streamredirection import GraphicalStreamRedirection class LpyShellWidget(RichJupyterWidget, GraphicalStreamRedirection): diff --git a/src/openalea/lpy/gui/lpystudio.py b/src/openalea/lpy/gui/lpystudio.py index befa0d1e..d3916658 100644 --- a/src/openalea/lpy/gui/lpystudio.py +++ b/src/openalea/lpy/gui/lpystudio.py @@ -13,7 +13,7 @@ py2exe_release = False from . import qt_check -import openalea.vpltk.qt.QtCore +import openalea.plantgl.gui.qt.QtCore try: import PyQGLViewer except ImportError as e: @@ -25,7 +25,7 @@ from . import settings from . import lpypreferences from .simulation import LpySimulation -from .kilsimulationdialog import KillSimulationDialog +from .killsimulationdialog import KillSimulationDialog from .objectpanel import ObjectPanelManager try: @@ -38,14 +38,14 @@ from openalea.lpy import * -from openalea.vpltk.qt.compat import * -from openalea.vpltk.qt.QtCore import QCoreApplication, QEvent, QMutex, QObject, QThread, QWaitCondition, Qt, pyqtSignal, pyqtSlot -from openalea.vpltk.qt.QtGui import QIcon, QPixmap, QTextCursor -from openalea.vpltk.qt.QtWidgets import QAction, QApplication, QDialog, QFileDialog, QInputDialog, QMainWindow, QMessageBox, QTabBar +from openalea.plantgl.gui.qt.compat import * +from openalea.plantgl.gui.qt.QtCore import QCoreApplication, QEvent, QMutex, QObject, QThread, QWaitCondition, Qt, pyqtSignal, pyqtSlot +from openalea.plantgl.gui.qt.QtGui import QIcon, QPixmap, QTextCursor +from openalea.plantgl.gui.qt.QtWidgets import QAction, QApplication, QDialog, QFileDialog, QInputDialog, QMainWindow, QMessageBox, QTabBar try: - from openalea.vpltk.qt.QtPrintSupport import QPrintDialog, QPrinter + from openalea.plantgl.gui.qt.QtPrintSupport import QPrintDialog, QPrinter except: - from openalea.vpltk.qt.QtGui import QPrintDialog, QPrinter + from openalea.plantgl.gui.qt.QtGui import QPrintDialog, QPrinter # Restore default signal handler for CTRL+C @@ -54,8 +54,7 @@ # Add local dir as import dir sys.path = ['']+sys.path -import generate_ui - +from . import generate_ui from . import lpydock from . import lpymainwindow as lsmw from .computationtask import * @@ -86,7 +85,7 @@ class LPyWindow(QMainWindow, lsmw.Ui_MainWindow, ComputationTaskManager) : instances = [] - def __init__(self, parent=None, withinterpreter = True): + def __init__(self, parent=None, withinterpreter = False): """ :param parent : parent window """ @@ -277,7 +276,7 @@ def check_lpy_update(self, silent = False): self.svnLastDateChecked = time.time() officialversion,offverstring = self.retrieve_official_lpy_version() if lv.__version_number__ < officialversion: - QMessageBox.information(self,"Lpy Update","Your version is "+lv.LPY_VERSION_STR+".\nA new version of lpy seems available on github :"+offverstring+"\nPlease update sources of lpy, plantgl, vpltk and recompile.") + QMessageBox.information(self,"Lpy Update","Your version is "+lv.LPY_VERSION_STR+".\nA new version of lpy seems available on github :"+offverstring+"\nPlease update sources of lpy, plantgl, plantgl.gui and recompile.") elif not silent: QMessageBox.information(self,"Lpy Update","Your version is "+lv.LPY_VERSION_STR+".\nYou are up-to-date!") else: diff --git a/src/openalea/lpy/gui/lpystudiodebugger.py b/src/openalea/lpy/gui/lpystudiodebugger.py index ce89484a..4d5444f0 100644 --- a/src/openalea/lpy/gui/lpystudiodebugger.py +++ b/src/openalea/lpy/gui/lpystudiodebugger.py @@ -1,5 +1,5 @@ import openalea.lpy as lpy -from openalea.vpltk.qt import qt +from openalea.plantgl.gui.qt import qt from time import clock from . lpycodeeditor import CodePointMarker, BreakPointMarker @@ -7,9 +7,9 @@ import traceback as tb -from openalea.vpltk.qt.QtCore import QCoreApplication, QMutex, QObject, pyqtSignal -from openalea.vpltk.qt.QtGui import QStandardItem, QStandardItemModel -from openalea.vpltk.qt.QtWidgets import QMessageBox +from openalea.plantgl.gui.qt.QtCore import QCoreApplication, QMutex, QObject, pyqtSignal +from openalea.plantgl.gui.qt.QtGui import QStandardItem, QStandardItemModel +from openalea.plantgl.gui.qt.QtWidgets import QMessageBox class AbortDebugger(Exception): def __init__(self,txt=''): diff --git a/src/openalea/lpy/gui/lpytabbar.py b/src/openalea/lpy/gui/lpytabbar.py index e8b6aa31..c636d1c2 100644 --- a/src/openalea/lpy/gui/lpytabbar.py +++ b/src/openalea/lpy/gui/lpytabbar.py @@ -1,9 +1,9 @@ -from openalea.vpltk.qt import qt -from . import svnmanip +from openalea.plantgl.gui.qt import qt +import openalea.lpy.gui.svnmanip as svnmanip import os -from openalea.vpltk.qt.QtCore import QObject, Qt, pyqtSignal -from openalea.vpltk.qt.QtWidgets import QApplication, QMenu, QMessageBox, QTabBar, QWidget +from openalea.plantgl.gui.qt.QtCore import QObject, Qt, pyqtSignal +from openalea.plantgl.gui.qt.QtWidgets import QApplication, QMenu, QMessageBox, QTabBar, QWidget class LpyTabBar(QTabBar): diff --git a/src/openalea/lpy/gui/lpytmpfile.py b/src/openalea/lpy/gui/lpytmpfile.py index 5a5a0576..5cd7714a 100644 --- a/src/openalea/lpy/gui/lpytmpfile.py +++ b/src/openalea/lpy/gui/lpytmpfile.py @@ -1,4 +1,4 @@ -from openalea.vpltk.qt.QtCore import QDir +from openalea.plantgl.gui.qt.QtCore import QDir import os def getTmpLpyDir(): @@ -29,4 +29,4 @@ def getPreviousTmpLpyFiles(): tmpdir = getTmpLpyDir() tmpfiles = os.listdir(tmpdir) tmpfiles = [os.path.abspath(os.path.join(tmpdir,f)) for f in tmpfiles if (prefix in f) and (suffix in f)] - return tmpfiles \ No newline at end of file + return tmpfiles diff --git a/src/openalea/lpy/gui/lpyview3d.py b/src/openalea/lpy/gui/lpyview3d.py index 0b3bdefb..9ea93f47 100644 --- a/src/openalea/lpy/gui/lpyview3d.py +++ b/src/openalea/lpy/gui/lpyview3d.py @@ -1,5 +1,5 @@ from openalea.plantgl.all import * -from openalea.vpltk.qt import qt +from openalea.plantgl.gui.qt import qt try: from PyQGLViewer import QGLViewer, Vec from openalea.plantgl.gui.pglnqgl import * @@ -71,4 +71,4 @@ def saveTSnapshot(self,fname): if not hasPyQGLViewer: def paintGL(self): self.draw() - LpyView3D.paintGL = paintGL \ No newline at end of file + LpyView3D.paintGL = paintGL diff --git a/src/openalea/lpy/gui/objectdialog.py b/src/openalea/lpy/gui/objectdialog.py index e5a0667b..204bd0ef 100644 --- a/src/openalea/lpy/gui/objectdialog.py +++ b/src/openalea/lpy/gui/objectdialog.py @@ -4,10 +4,10 @@ except: py2exe_release = False -from openalea.vpltk.qt import qt +from openalea.plantgl.gui.qt import qt -from openalea.vpltk.qt.QtCore import QObject, pyqtSignal -from openalea.vpltk.qt.QtWidgets import QApplication, QCheckBox, QDialog, QHBoxLayout, QLayout, QMenuBar, QPushButton, QSizePolicy, QSpacerItem, QVBoxLayout +from openalea.plantgl.gui.qt.QtCore import QObject, pyqtSignal +from openalea.plantgl.gui.qt.QtWidgets import QApplication, QCheckBox, QDialog, QHBoxLayout, QLayout, QMenuBar, QPushButton, QSizePolicy, QSpacerItem, QVBoxLayout class ObjectDialog(QDialog): diff --git a/src/openalea/lpy/gui/objectpanel.py b/src/openalea/lpy/gui/objectpanel.py index 5abe391d..62e2ac11 100644 --- a/src/openalea/lpy/gui/objectpanel.py +++ b/src/openalea/lpy/gui/objectpanel.py @@ -1,5 +1,5 @@ from openalea.plantgl.all import * -from openalea.vpltk import qt +from openalea.plantgl.gui import qt from OpenGL.GL import * from OpenGL.GLU import * import sys, traceback, os @@ -7,9 +7,9 @@ from .objectmanagers import get_managers -from openalea.vpltk.qt.QtCore import QObject, QPoint, Qt, pyqtSignal -from openalea.vpltk.qt.QtGui import QFont, QFontMetrics, QImageWriter, QColor, QPainter -from openalea.vpltk.qt.QtWidgets import QAction, QApplication, QDockWidget, QFileDialog, QLineEdit, QMenu, QMessageBox, QScrollArea, QVBoxLayout, QWidget +from openalea.plantgl.gui.qt.QtCore import QObject, QPoint, Qt, pyqtSignal +from openalea.plantgl.gui.qt.QtGui import QFont, QFontMetrics, QImageWriter, QColor, QPainter +from openalea.plantgl.gui.qt.QtWidgets import QAction, QApplication, QDockWidget, QFileDialog, QLineEdit, QMenu, QMessageBox, QScrollArea, QVBoxLayout, QWidget def renderText(self, x, y, text, font = QFont(), color = None): #print 'renderText' @@ -35,14 +35,15 @@ def renderText(self, x, y, text, font = QFont(), color = None): pass try: - from openalea.vpltk.qt.QtGui import QOpenGLWidget + assert False + from openalea.plantgl.gui.qt.QtGui import QOpenGLWidget QGLParentClass = QOpenGLWidget print('Use QOpenGLWidget') QGLParentClass.mRenderText = renderText except: - from openalea.vpltk.qt.QtOpenGL import QGLWidget + from openalea.plantgl.gui.qt.QtOpenGL import QGLWidget QGLParentClass = QGLWidget def mRenderText(self, x, y, text, font = QFont(), color = None): diff --git a/src/openalea/lpy/gui/optioneditordelegate.py b/src/openalea/lpy/gui/optioneditordelegate.py index 81ac3dd3..6e6a1876 100644 --- a/src/openalea/lpy/gui/optioneditordelegate.py +++ b/src/openalea/lpy/gui/optioneditordelegate.py @@ -1,4 +1,4 @@ -from openalea.vpltk.qt.QtWidgets import QComboBox, QItemDelegate +from openalea.plantgl.gui.qt.QtWidgets import QComboBox, QItemDelegate class OptionEditorDelegate(QItemDelegate): diff --git a/src/openalea/lpy/gui/plugins/curve2dmanager.py b/src/openalea/lpy/gui/plugins/curve2dmanager.py index 1ef7d27c..09f6bdbd 100644 --- a/src/openalea/lpy/gui/plugins/curve2dmanager.py +++ b/src/openalea/lpy/gui/plugins/curve2dmanager.py @@ -5,7 +5,7 @@ from openalea.plantgl.scenegraph import Polyline2D, BezierCurve2D, NurbsCurve2D, Point2Array, Point3Array from openalea.lpy.gui.abstractobjectmanager import * from OpenGL.GL import * -from openalea.vpltk.qt import QtGui, QtWidgets +from openalea.plantgl.gui.qt import QtGui, QtWidgets def displayLineAsThumbnail(manager, obj, i, objectthumbwidth, color = (1,1,0,0), linecolor = (0.5,0.5,0.5,1.0)): manager.discretizer.clear() diff --git a/src/openalea/lpy/gui/plugins/functionmanager.py b/src/openalea/lpy/gui/plugins/functionmanager.py index 08941d8a..06e02bd2 100644 --- a/src/openalea/lpy/gui/plugins/functionmanager.py +++ b/src/openalea/lpy/gui/plugins/functionmanager.py @@ -4,7 +4,7 @@ Curve2DEditor = None from openalea.lpy.gui.abstractobjectmanager import * from curve2dmanager import displayLineAsThumbnail -from openalea.vpltk.qt import QtGui, QtWidgets +from openalea.plantgl.gui.qt import QtGui, QtWidgets class FunctionManager(AbstractPglObjectManager): """see the doc of the objectmanager abtsract class to undesrtand the implementation of the functions""" diff --git a/src/openalea/lpy/gui/qt_check.py b/src/openalea/lpy/gui/qt_check.py index 405a1335..d896d54c 100644 --- a/src/openalea/lpy/gui/qt_check.py +++ b/src/openalea/lpy/gui/qt_check.py @@ -8,7 +8,7 @@ if QT_VERSION == 4: os.environ.setdefault('QT_API_VERSION', '2') -from openalea.vpltk import qt +from openalea.plantgl.gui import qt if QT_VERSION == 4: import sip diff --git a/src/openalea/lpy/gui/reformatingcode.py b/src/openalea/lpy/gui/reformatingcode.py index 4d46d90f..656dbd7a 100644 --- a/src/openalea/lpy/gui/reformatingcode.py +++ b/src/openalea/lpy/gui/reformatingcode.py @@ -137,7 +137,7 @@ def generate_qt_header(qt_classmap): res = '' for key, value in list(classmap.items()): value.sort() - res += 'from openalea.vpltk.qt.'+key+' import '+', '.join(value)+'\n' + res += 'from openalea.plantgl.gui.qt.'+key+' import '+', '.join(value)+'\n' return res def qth(text): diff --git a/src/openalea/lpy/gui/scalareditor.py b/src/openalea/lpy/gui/scalareditor.py index 1dea0c88..75d21e75 100644 --- a/src/openalea/lpy/gui/scalareditor.py +++ b/src/openalea/lpy/gui/scalareditor.py @@ -1,13 +1,13 @@ -from openalea.vpltk.qt import qt -from .scalar import * -import generate_ui +from openalea.plantgl.gui.qt import qt +from openalea.lpy.gui.scalar import * +from . import generate_ui import sys -from . import scalarmetaedit as sme +import openalea.lpy.gui.scalarmetaedit as sme -from openalea.vpltk.qt.QtCore import QDataStream, QIODevice, QObject, Qt, pyqtSignal -from openalea.vpltk.qt.QtGui import QBrush, QColor, QStandardItem, QStandardItemModel -from openalea.vpltk.qt.QtWidgets import QDialog, QDoubleSpinBox, QHBoxLayout, QItemDelegate, QLabel, QMenu, QPushButton, QSlider, QSpinBox, QTreeView, QWidget +from openalea.plantgl.gui.qt.QtCore import QDataStream, QIODevice, QObject, Qt, pyqtSignal +from openalea.plantgl.gui.qt.QtGui import QBrush, QColor, QStandardItem, QStandardItemModel +from openalea.plantgl.gui.qt.QtWidgets import QDialog, QDoubleSpinBox, QHBoxLayout, QItemDelegate, QLabel, QMenu, QPushButton, QSlider, QSpinBox, QTreeView, QWidget class ScalarDialog(QDialog,sme.Ui_ScalarDialog): @@ -31,7 +31,7 @@ def updateRange(self,v): self.maxValueEdit.setValue(self.minValueEdit.value()+1) self.valueEdit.setRange(self.minValueEdit.value(),self.maxValueEdit.value()) -import scalarfloatmetaedit as sfme +from . import scalarfloatmetaedit as sfme class FloatScalarDialog(QDialog,sfme.Ui_FloatScalarDialog): def __init__(self,*args): @@ -365,4 +365,4 @@ def moveItem(self, r0, r1): else: self.scalars.insert(r1,item) self.replotScalars() - self.valueChanged.emit() \ No newline at end of file + self.valueChanged.emit() diff --git a/src/openalea/lpy/gui/settings.py b/src/openalea/lpy/gui/settings.py index da94b212..122c3993 100644 --- a/src/openalea/lpy/gui/settings.py +++ b/src/openalea/lpy/gui/settings.py @@ -1,8 +1,8 @@ -from openalea.vpltk.qt.compat import * -from openalea.vpltk.qt import qt -from openalea.vpltk.qt.QtCore import QSettings -from openalea.vpltk.qt.QtGui import QFont -from openalea.vpltk.qt.QtWidgets import QApplication +from openalea.plantgl.gui.qt.compat import * +from openalea.plantgl.gui.qt import qt +from openalea.plantgl.gui.qt.QtCore import QSettings +from openalea.plantgl.gui.qt.QtGui import QFont +from openalea.plantgl.gui.qt.QtWidgets import QApplication import os diff --git a/src/openalea/lpy/gui/simulation.py b/src/openalea/lpy/gui/simulation.py index edd081c6..d0b5f650 100644 --- a/src/openalea/lpy/gui/simulation.py +++ b/src/openalea/lpy/gui/simulation.py @@ -1,4 +1,4 @@ -from openalea.vpltk.qt import qt +from openalea.plantgl.gui.qt import qt from openalea.lpy import * from openalea.plantgl.all import PglTurtle, Viewer, Material, PyStrPrinter, eStatic, eAnimatedPrimitives, eAnimatedScene from . import optioneditordelegate as oed @@ -12,9 +12,9 @@ from . import pymodulemonitoring as pm -from openalea.vpltk.qt.QtCore import QObject, pyqtSignal -from openalea.vpltk.qt.QtGui import QBrush, QColor, QFont, QIcon, QPainter, QPixmap, QStandardItem, QStandardItemModel -from openalea.vpltk.qt.QtWidgets import QFileDialog, QLineEdit, QMessageBox +from openalea.plantgl.gui.qt.QtCore import QObject, pyqtSignal +from openalea.plantgl.gui.qt.QtGui import QBrush, QColor, QFont, QIcon, QPainter, QPixmap, QStandardItem, QStandardItemModel +from openalea.plantgl.gui.qt.QtWidgets import QFileDialog, QLineEdit, QMessageBox defaultcode = "Axiom: \n\nderivation length: 1\nproduction:\n\n\ninterpretation:\n\n\nendlsystem\n" @@ -326,7 +326,7 @@ def updateReadOnly(self): panel.setEnabled(not self.readonly) def saveToFile(self,fname): - f = file(fname,'w') + f = open(fname,'w') f.write(self.code) initcode = self.getInitialisationCode() if len(initcode) > 0 : @@ -352,7 +352,7 @@ def open(self,fname): elif answer == QMessageBox.Discard: os.remove(bckupname) os.chdir(os.path.dirname(self.fname)) - code = file(readname,'rU').read() + code = open(readname,'rU').read() self.readonly = (not os.access(fname, os.W_OK)) self.textedition = recovery self.setEdited(recovery) @@ -364,7 +364,7 @@ def importtmpfile(self,fname): self.textedition = True self.setEdited(True) try: - lpycode = file(fname,'rU').read() + lpycode = open(fname,'rU').read() self.opencode(lpycode) self._tmpfname = fname except: @@ -681,6 +681,7 @@ def opencode(self,txt): lpy_code_version = 1.0 if '__lpy_code_version__' in context: lpy_code_version = ['__lpy_code_version__'] + print(lpy_code_version) if '__functions__' in context and lpy_code_version <= 1.0 : functions = context['__functions__'] for n,c in functions: c.name = n @@ -891,4 +892,4 @@ def cancel(self): def cleanup(self): self.lsystem.forceRelease() - self.lsystem.clear() \ No newline at end of file + self.lsystem.clear() diff --git a/src/openalea/lpy/gui/streamredirection.py b/src/openalea/lpy/gui/streamredirection.py index 96904e5d..76f284ed 100644 --- a/src/openalea/lpy/gui/streamredirection.py +++ b/src/openalea/lpy/gui/streamredirection.py @@ -16,7 +16,7 @@ ################################################################################ -#from openalea.vpltk import qt +#from openalea.plantgl.gui import qt # RedirectionEventId = qt.QtCore.QEvent.User + 100 import sys diff --git a/src/openalea/lpy/gui/svnmanip.py b/src/openalea/lpy/gui/svnmanip.py index d7c53b10..ff507876 100644 --- a/src/openalea/lpy/gui/svnmanip.py +++ b/src/openalea/lpy/gui/svnmanip.py @@ -1,5 +1,5 @@ -from openalea.vpltk.qt import qt -from openalea.vpltk.qt.QtWidgets import QDialog, QMessageBox +from openalea.plantgl.gui.qt import qt +from openalea.plantgl.gui.qt.QtWidgets import QDialog, QMessageBox from .settings import getSettings diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 1ba77560..54b98d0a 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -27,6 +27,8 @@ if (WIN32) set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") endif() -set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") +if (APPLE) + set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".so") +endif() install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy") From 73c2036af1aa90ff2ed75bbd7b718e54f52096a9 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Fri, 18 Oct 2019 13:25:08 +0200 Subject: [PATCH 47/68] fig bug with cmake file --- cmake/FindPlantGL.cmake | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/cmake/FindPlantGL.cmake b/cmake/FindPlantGL.cmake index ac2b2298..33d73c7b 100644 --- a/cmake/FindPlantGL.cmake +++ b/cmake/FindPlantGL.cmake @@ -1,4 +1,3 @@ -<<<<<<< HEAD foreach(v PLANTGL_INCLUDEDIR PLANTGL_LIBRARYDIR) set(_env $ENV{${v}}) endforeach() @@ -47,31 +46,10 @@ find_library(PLANTGL_SG_LIBRARY get_filename_component(PLANTGL_LIBRARY_DIR ${PLANTGL_SG_LIBRARY} DIRECTORY) if (NOT PLANTGL_LIBRARY_DIR) -======= -# Include Directory -find_path(PLANTGL_INCLUDE_DIR "plantgl/plantgl.h" "libplantgl/plantgl.h" PATHS $ENV{PATH}) - -# Library Directory -find_library(PLANTGL_ALGO_LIBRARY NAMES "pglalgo" "libpglalgo" PATHS $ENV{PATH}) -find_library(PLANTGL_GUI_LIBRARY NAMES "pglgui" "libpglgui" PATHS $ENV{PATH}) -find_library(PLANTGL_MATH_LIBRARY NAMES "pglmath" "libpglmath" PATHS $ENV{PATH}) -find_library(PLANTGL_SG_LIBRARY NAMES "pglsg" "libpglsg" PATHS $ENV{PATH}) -find_library(PLANTGL_TOOL_LIBRARY NAMES "pgltool" "libpgltool" PATHS $ENV{PATH}) - -if (PLANTGL_INCLUDE_DIR AND PLANTGL_ALGO_LIBRARY AND PLANTGL_GUI_LIBRARY AND PLANTGL_MATH_LIBRARY AND PLANTGL_SG_LIBRARY AND PLANTGL_TOOL_LIBRARY) - set(PLANTGL_FOUND ON) - set(PLANTGL_INCLUDE_DIRS ${PLANTGL_INCLUDE_DIR}) - set(PLANTGL_LIBRARIES ${PLANTGL_ALGO_LIBRARY} ${PLANTGL_GUI_LIBRARY} ${PLANTGL_MATH_LIBRARY} ${PLANTGL_SG_LIBRARY} ${PLANTGL_TOOL_LIBRARY}) - - # PlantGL found - message(STATUS "Found PlantGL: TRUE") -else() ->>>>>>> 54134afec6f633aeb6e50e2025be517d9adc4368 set(PLANTGL_FOUND OFF) if (PlantGL_FIND_REQUIRED) # PlantGL not found -<<<<<<< HEAD message(SEND_ERROR "Unable to find PlantGL libraries repository.") endif() endif() @@ -119,20 +97,10 @@ if (PLANTGL_INCLUDE_DIR AND PLANTGL_LIBRARY_DIR) link_directories(${PLANTGL_LIBRARY_DIRS}) -======= - message(SEND_ERROR "Unable to find PlantGL library.") - endif() -endif() - -if (PLANTGL_FOUND) - # Build with PlantGL - include_directories(${PLANTGL_INCLUDE_DIRS}) ->>>>>>> 54134afec6f633aeb6e50e2025be517d9adc4368 elseif (NOT PlantGL_FIND_REQUIRED) message(STATUS "Building without PlantGL - Library not found.") endif() -<<<<<<< HEAD # Set PLANTGL_FOUND based only on header location and version. @@ -166,5 +134,3 @@ else() set(PGL_ERROR_REASON "${PGL_ERROR_REASON}Unable to find the PlantGL header files. Please set PGL_INCLUDEDIR to the directory containing PlantGL's headers.") endif() -======= ->>>>>>> 54134afec6f633aeb6e50e2025be517d9adc4368 From 0a3d290c931944489177644035219a6bd18d538d Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Mon, 21 Oct 2019 15:58:24 +0200 Subject: [PATCH 48/68] improve python 3 compat --- src/cpp/axialtree.cpp | 19 ++++----- src/cpp/lpy_python.cpp | 66 +++++++++++++++++++++++++++++++ src/cpp/lpy_python.h | 57 ++++++++++++++++++++++++++ src/cpp/module.cpp | 18 ++++----- test/test_axialtree.py | 6 +-- test/test_debugger.py | 18 ++++----- test/test_kwd.lpy | 2 +- test/test_kwd2.lpy | 2 +- test/test_lpytest.py | 2 +- test/test_lsystem_as_module.py | 4 +- test/test_matching.py | 2 +- test/test_multiline_produce.lpy | 2 +- test/test_nproduce.py | 2 +- test/test_perf.lpy | 2 +- test/test_predecessor_at_scale.py | 2 +- test/test_regexpmatching.py | 2 +- test/test_selection.py | 2 +- test/test_shareexamples.py | 2 +- test/test_starmatching.py | 2 +- test/test_successor_at_scale.py | 2 +- test/test_tree_matching.py | 6 +-- 21 files changed, 172 insertions(+), 48 deletions(-) create mode 100644 src/cpp/lpy_python.cpp create mode 100644 src/cpp/lpy_python.h diff --git a/src/cpp/axialtree.cpp b/src/cpp/axialtree.cpp index b8727ab0..209d749b 100644 --- a/src/cpp/axialtree.cpp +++ b/src/cpp/axialtree.cpp @@ -33,12 +33,12 @@ #include "lpy_parser.h" #include "tracker.h" #include "matching.h" +#include "lpy_python.h" using namespace boost::python; LPY_BEGIN_NAMESPACE - /*---------------------------------------------------------------------------*/ AxialTree::AxialTree(): @@ -69,15 +69,16 @@ AxialTree::AxialTree(const ParamModule& m): AxialTree::AxialTree(const boost::python::list& l): BaseType(){ IncTracker(AxialTree) - object iter_obj = object( handle<>( PyObject_GetIter( l.ptr() ) ) ); - while( true ) + PySeqIterator iter_obj ( l ); + + while(iter_obj.is_valid()) { - object obj; - try { obj = iter_obj.attr( "next" )(); } - catch( error_already_set ){ PyErr_Clear(); break; } + object obj = iter_obj.next(); + extract idext(obj); - if (idext.check()) - __string().push_back(idext()); + if (idext.check()){ + __string().push_back(ParamModule(idext())); + } else { extract st(obj); if(st.check()) @@ -92,7 +93,7 @@ AxialTree::AxialTree(const boost::python::list& l): else __string().push_back(extract(obj)()); } } - } + } } } diff --git a/src/cpp/lpy_python.cpp b/src/cpp/lpy_python.cpp new file mode 100644 index 00000000..c6cf9478 --- /dev/null +++ b/src/cpp/lpy_python.cpp @@ -0,0 +1,66 @@ +/* --------------------------------------------------------------------------- + # + # L-Py: L-systems in Python + # + # Copyright 2003-2008 UMR Cirad/Inria/Inra Dap - Virtual Plant Team + # + # File author(s): F. Boudon (frederic.boudon@cirad.fr) + # + # --------------------------------------------------------------------------- + # + # GNU General Public Licence + # + # This program is free software; you can redistribute it and/or + # modify it under the terms of the GNU General Public License as + # published by the Free Software Foundation; either version 2 of + # the License, or (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS For A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public + # License along with this program; see the file COPYING. If not, + # write to the Free Software Foundation, Inc., 59 + # Temple Place - Suite 330, Boston, MA 02111-1307, USA. + # + # --------------------------------------------------------------------------- + */ + + +#include "lpy_python.h" + +/*---------------------------------------------------------------------------*/ + +PySeqIterator::PySeqIterator(boost::python::object seq) : + __iter_obj( ), __valid(true) +{ + PyObject * pyiter = PyObject_GetIter( seq.ptr() ) ; + __valid = (pyiter != NULL); + __iter_obj = boost::python::object(boost::python::handle<>( pyiter ) ); + _next(); +} + +bool PySeqIterator::is_valid() const { return __valid;} + +boost::python::object PySeqIterator::next() +{ + boost::python::object result = __next_obj; + _next(); + return result; + +} + +void PySeqIterator::_next() +{ + if (__valid) { + PyObject * item = PyIter_Next(__iter_obj.ptr()); + __valid = (item != NULL); + if (__valid) + __next_obj = boost::python::object( boost::python::handle(item)); + else + __next_obj = boost::python::object(); + } +} + diff --git a/src/cpp/lpy_python.h b/src/cpp/lpy_python.h new file mode 100644 index 00000000..fbe6160f --- /dev/null +++ b/src/cpp/lpy_python.h @@ -0,0 +1,57 @@ +/* --------------------------------------------------------------------------- + # + # L-Py: L-systems in Python + # + # Copyright 2003-2008 UMR Cirad/Inria/Inra Dap - Virtual Plant Team + # + # File author(s): F. Boudon (frederic.boudon@cirad.fr) + # + # --------------------------------------------------------------------------- + # + # GNU General Public Licence + # + # This program is free software; you can redistribute it and/or + # modify it under the terms of the GNU General Public License as + # published by the Free Software Foundation; either version 2 of + # the License, or (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS For A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public + # License along with this program; see the file COPYING. If not, + # write to the Free Software Foundation, Inc., 59 + # Temple Place - Suite 330, Boston, MA 02111-1307, USA. + # + # --------------------------------------------------------------------------- + */ + +#ifndef __lpy_python_h__ +#define __lpy_python_h__ + +#include "lpy_config.h" +#include + +/*---------------------------------------------------------------------------*/ + + +class PySeqIterator { +public: + PySeqIterator(boost::python::object seq) ; + + bool is_valid() const ; + + boost::python::object next() ; + +protected: + void _next() ; + + boost::python::object __iter_obj; + boost::python::object __next_obj; + bool __valid; + +}; + +#endif \ No newline at end of file diff --git a/src/cpp/module.cpp b/src/cpp/module.cpp index 279039b3..834f6220 100644 --- a/src/cpp/module.cpp +++ b/src/cpp/module.cpp @@ -33,6 +33,7 @@ #include "patternmodule.h" #include "matching.h" #include "lsyscontext.h" +#include "lpy_python.h" #include "lpy_parser.h" #include "tracker.h" #include "packedargs.h" @@ -94,13 +95,12 @@ boost::python::object LPY::getFunctionRepr() { return GlobalContext::getFunction void processArgList(ModuleClassPtr mclass, ParamModule::ParameterList& args, boost::python::object arg, size_t start = 0){ extract isdict(arg); if (!isdict.check()){ - object iter_obj = object( handle<>( PyObject_GetIter( arg.ptr() ) ) ); - for(size_t i = 0; i < start; ++i) iter_obj.attr( "next" )(); - try { while( true ) appendParam(args,iter_obj.attr( "next" )()); } - catch( error_already_set ){ PyErr_Clear(); } + PySeqIterator iter_obj( arg); + for(size_t i = 0; i < start && iter_obj.is_valid(); ++i) iter_obj.next(); + while( iter_obj.is_valid() ) appendParam(args,iter_obj.next( )); } else { - boost::python::object iter_obj = isdict().iteritems(); + PySeqIterator iter_obj(isdict().items()); size_t nbstdparam = args.size(); if (nbstdparam + len(arg) < mclass->getNamedParameterNb()){ std::stringstream str; @@ -111,9 +111,8 @@ void processArgList(ModuleClassPtr mclass, ParamModule::ParameterList& args, boo while( true ) { - boost::python::object obj; - try { obj = iter_obj.attr( "next" )(); } - catch( boost::python::error_already_set ){ PyErr_Clear(); break; } + boost::python::object obj = iter_obj.next(); + if (!iter_obj.is_valid()) break; std::string pname = extract( obj[0] )(); size_t pposition = mclass->getParameterPosition(pname); @@ -186,7 +185,8 @@ ParamModule::ParamModule(): BaseType() {} ParamModule::ParamModule(size_t classid): - BaseType(classid) {} + BaseType(classid) { + } ParamModule::ParamModule(const std::string& name) : BaseType() diff --git a/test/test_axialtree.py b/test/test_axialtree.py index d7edd6e4..e06fcb9e 100644 --- a/test/test_axialtree.py +++ b/test/test_axialtree.py @@ -76,7 +76,7 @@ def test_successor_at_level(): a = AxialTree('BA[A[A][CA]][A]B[[[CA]CA]AA]') l.setModuleScale('B,C',1) l.setModuleScale('A',2) - print(a.successor_at_level(0,1)) + print((a.successor_at_level(0,1))) assert a.successor_at_level(0,1) == 15 @@ -89,7 +89,7 @@ def test_successor_at_scale(): assert a.successor_at_scale(0,1) == 15 assert a.successor_at_scale(15,1) == 29 a = AxialTree('BA[[A][CA][A]A]BA[[[CA]CA]AA]') - print(a.directSon(1),a.directSon(15),a.successor_at_scale(1,2)) + print((a.directSon(1),a.directSon(15),a.successor_at_scale(1,2))) assert a.successor_at_scale(1,2) == 16 def test_successor_at_scale2(): @@ -108,7 +108,7 @@ def test_predecessor_at_scale(): l.setModuleScale('B,C',1) l.setModuleScale('A',2) assert a.predecessor_at_scale(15,1) == 0 - print(a.predecessor_at_scale(25,2)) + print((a.predecessor_at_scale(25,2))) assert a.predecessor_at_scale(25,2) == 1 diff --git a/test/test_debugger.py b/test/test_debugger.py index 937027ec..a1dd2144 100644 --- a/test/test_debugger.py +++ b/test/test_debugger.py @@ -6,27 +6,27 @@ def __init__(self): def begin(self,src,direction): self.direction = direction self.src = src - print('Axiom:',src) + print(('Axiom:',src)) def end(self,result): - print('Result:',result) + print(('Result:',result)) def total_match(self,pos_beg,pos_end,dest,prod_length,rule,args): - print(pos_beg,pos_end,dest,prod_length,rule,args) + print((pos_beg,pos_end,dest,prod_length,rule,args)) assert self.src[pos_beg].name == 'B' if self.direction == eForward: - print('*', prod_length) + print(('*', prod_length)) print(dest) - print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[-prod_length:]) + print((self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[-prod_length:])) else: - print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[:prod_length]) + print((self.src[pos_beg:pos_end],'--',rule.lineno-1,'-->',dest[:prod_length])) def partial_match(self,pos_beg,pos_end,dest,rule,args): assert self.src[pos_beg].name == 'C' - print(self.src[pos_beg:pos_end],'--',rule.lineno-1,'--> failed') + print((self.src[pos_beg:pos_end],'--',rule.lineno-1,'--> failed')) def identity(self,pos,dest): assert self.src[pos].name in 'AC' if self.direction == eForward: - print(self.src[pos],'-- ID ->',dest[-1]) + print((self.src[pos],'-- ID ->',dest[-1])) else: - print(self.src[pos],'-- ID ->',dest[0]) + print((self.src[pos],'-- ID ->',dest[0])) lcode = """ Axiom: BAABAC diff --git a/test/test_kwd.lpy b/test/test_kwd.lpy index 1f284ee2..296673b6 100644 --- a/test/test_kwd.lpy +++ b/test/test_kwd.lpy @@ -2,7 +2,7 @@ module A(x,t) Axiom: A(1,2) -results = [False for i in xrange(20) ] +results = [False for i in range(20) ] def validate(i): global results diff --git a/test/test_kwd2.lpy b/test/test_kwd2.lpy index f7bc8451..bb324553 100644 --- a/test/test_kwd2.lpy +++ b/test/test_kwd2.lpy @@ -2,7 +2,7 @@ module A(x,t) Axiom: A(1,2,3) -results = [False for i in xrange(22) ] +results = [False for i in range(22) ] def validate(i): global results diff --git a/test/test_lpytest.py b/test/test_lpytest.py index f56299ff..ede5a339 100644 --- a/test/test_lpytest.py +++ b/test/test_lpytest.py @@ -13,7 +13,7 @@ def exec_lpy_tst(lfile): l = Lsystem(lfile) l.iterate() except Exception as e : - print('Test file :',lfile) + print(('Test file :',lfile)) raise e toavoid = [] diff --git a/test/test_lsystem_as_module.py b/test/test_lsystem_as_module.py index 9d54f484..57ebe2de 100644 --- a/test/test_lsystem_as_module.py +++ b/test/test_lsystem_as_module.py @@ -16,9 +16,9 @@ def test_lsystem_as_module(): l.test1 = 2 assert l.test1 == 2 assert l.context()['test1'] == 2 - print('Axiom:',l.axiom) + print(('Axiom:',l.axiom)) l.axiom = 'B' - print(l.axiom, type(l.axiom)) + print((l.axiom, type(l.axiom))) assert type(l.axiom) == AxialTree and l.axiom == Lstring('B') if __name__ == '__main__': diff --git a/test/test_matching.py b/test/test_matching.py index 73b217fd..16d89400 100644 --- a/test/test_matching.py +++ b/test/test_matching.py @@ -44,7 +44,7 @@ def runmatch(code,optionvalues = list(range(3))): try: l.set(lcodebeg+code) l.iterate() - print("Test do not fail for unsupported module matching mode : %i." % i) + print(("Test do not fail for unsupported module matching mode : %i." % i)) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass diff --git a/test/test_multiline_produce.lpy b/test/test_multiline_produce.lpy index 5f1c1b12..5e190740 100644 --- a/test/test_multiline_produce.lpy +++ b/test/test_multiline_produce.lpy @@ -1,6 +1,6 @@ def End(lstring): assert len(lstring) == 3 - for i in xrange(3): + for i in range(3): n = lstring[i].name assert n != '\n' assert n != '\r' diff --git a/test/test_nproduce.py b/test/test_nproduce.py index cd464f8f..6c3cd313 100644 --- a/test/test_nproduce.py +++ b/test/test_nproduce.py @@ -4,7 +4,7 @@ def test_nproduce(verbose = False): """ Test use of nproduce """ l=Lsystem(get_filename('test_nproduce.lpy')) - if verbose: print(l.axiom) + if verbose: print((l.axiom)) res = l.derive(1) if verbose: print(res) assert len(res) == 2 and res[1].name == 'B' diff --git a/test/test_perf.lpy b/test/test_perf.lpy index b0651c81..000045df 100644 --- a/test/test_perf.lpy +++ b/test/test_perf.lpy @@ -15,7 +15,7 @@ derivation length: 100 production: A : - for i in xrange(1000): + for i in range(1000): nproduce BC(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0)C(0) C(x) --> C(0) diff --git a/test/test_predecessor_at_scale.py b/test/test_predecessor_at_scale.py index 78ed31ff..98553945 100644 --- a/test/test_predecessor_at_scale.py +++ b/test/test_predecessor_at_scale.py @@ -5,7 +5,7 @@ module I,L : scale = 2 Axiom: nproduce E L U I I I - for i in xrange(1): + for i in range(1): nproduce U I I I nproduce E L ''' diff --git a/test/test_regexpmatching.py b/test/test_regexpmatching.py index b1fa7e37..bbced58f 100644 --- a/test/test_regexpmatching.py +++ b/test/test_regexpmatching.py @@ -27,7 +27,7 @@ def runmatch(code, lcodebeg = lcodebeg,optionvalues = list(range(3))): try: l.set(lcodebeg+code) l.iterate() - print("Test do not fail for unsupported module matching mode : %i." % i) + print(("Test do not fail for unsupported module matching mode : %i." % i)) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass diff --git a/test/test_selection.py b/test/test_selection.py index c6e0c7d4..b73601e7 100644 --- a/test/test_selection.py +++ b/test/test_selection.py @@ -20,7 +20,7 @@ def test_selection(): ln = len(l.axiom) l.context().makeCurrent() assert l.axiom == AxialTree('N[+NN][-N]N') and 'Invalid axiom parsing' - print(l.axiom) + print((l.axiom)) res = l.iterate(1) print(res) assert len(res) == ln+1 diff --git a/test/test_shareexamples.py b/test/test_shareexamples.py index 3cdc9bfa..3465fd41 100644 --- a/test/test_shareexamples.py +++ b/test/test_shareexamples.py @@ -13,7 +13,7 @@ def exec_share_example(lfile): l = Lsystem(lfile) l.iterate() except Exception as e : - print('Example file :',lfile) + print(('Example file :',lfile)) raise e diff --git a/test/test_starmatching.py b/test/test_starmatching.py index 02485e48..b073c816 100644 --- a/test/test_starmatching.py +++ b/test/test_starmatching.py @@ -43,7 +43,7 @@ def runmatch(code,optionvalues = list(range(3))): try: l.set(lcodebeg+code) l.iterate() - print("Test do not fail for unsupported module matching mode : %i." % i) + print(("Test do not fail for unsupported module matching mode : %i." % i)) warnings.warn("Test do not fail for unsupported module matching mode : %i." % i) except: pass diff --git a/test/test_successor_at_scale.py b/test/test_successor_at_scale.py index c1d855fc..e869055a 100644 --- a/test/test_successor_at_scale.py +++ b/test/test_successor_at_scale.py @@ -5,7 +5,7 @@ module I,L : scale = 2 Axiom: nproduce E L U I I I - for i in xrange(1): + for i in range(1): nproduce U I I I nproduce E L ''' diff --git a/test/test_tree_matching.py b/test/test_tree_matching.py index da298f0e..c0dd8818 100644 --- a/test/test_tree_matching.py +++ b/test/test_tree_matching.py @@ -20,7 +20,7 @@ def matching_run(code,optionvalues = list(range(4))): optionvalues = [optionvalues] for i in range(4): l = Lsystem() - print('option =',i) + print(('option =',i)) if i in optionvalues: l.set(code) l.context().options.setSelection('String matching',i) @@ -30,7 +30,7 @@ def matching_run(code,optionvalues = list(range(4))): l.set(code) l.context().options.setSelection('String matching',i) l.iterate() - print("Test do not fail for unsupported string matching mode : %i." % i) + print(("Test do not fail for unsupported string matching mode : %i." % i)) warnings.warn("Test do not fail for unsupported string matching mode : %i." % i) except: pass @@ -78,7 +78,7 @@ def test_axial_msmatch() : test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) for tfn,tf in test_func: - print('testing func:', tfn) + print(('testing func:', tfn)) try: tf() except: From 6b19640a99e1370272885928817232fccb036093 Mon Sep 17 00:00:00 2001 From: Julien Wintz Date: Wed, 23 Oct 2019 09:55:18 +0200 Subject: [PATCH 49/68] Various fixes WRT/ Python 3. --- CMakeLists.txt | 2 +- cmake/FindPlantGL.cmake | 4 +- setup.py | 25 ++++-- src/openalea/lpy/gui/__init__.py | 1 - src/openalea/lpy/gui/compile_ui.py | 1 + src/openalea/lpy/gui/lpydock.py | 24 +++--- src/openalea/lpy/gui/lpymainwindow.ui | 10 +-- src/openalea/lpy/gui/lpyshell.py | 19 ++--- src/openalea/lpy/gui/lpystudio.py | 11 ++- src/openalea/lpy/gui/shared_data.py | 114 ++++++++++++++++++++++++++ 10 files changed, 169 insertions(+), 42 deletions(-) delete mode 100644 src/openalea/lpy/gui/__init__.py create mode 100644 src/openalea/lpy/gui/shared_data.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 7aca69d4..e4c12ab5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ set(Boost_NO_SYSTEM_PATHS ON) set(Boost_USE_MULTITHREAD ON) set(Boost_USE_STATIC_LIBS OFF) -find_package(Boost 1.67 COMPONENTS system ${BOOST_PYTHON_LIB} REQUIRED) +find_package(Boost COMPONENTS system ${BOOST_PYTHON_LIB} REQUIRED) # --- Include Directories diff --git a/cmake/FindPlantGL.cmake b/cmake/FindPlantGL.cmake index 33d73c7b..32de9eea 100644 --- a/cmake/FindPlantGL.cmake +++ b/cmake/FindPlantGL.cmake @@ -27,7 +27,7 @@ endif() # Include Directory find_path(PLANTGL_INCLUDE_DIR NAMES "plantgl/plantgl.h" - HINTS ${PLANTGL_INCLUDEDIR} $ENV{PATH}) + HINTS ${PLANTGL_INCLUDEDIR} $ENV{PATH} $ENV{CONDA_PREFIX}/include) if (NOT PLANTGL_INCLUDE_DIR) set(PLANTGL_FOUND OFF) @@ -41,7 +41,7 @@ endif() # Library Directory find_library(PLANTGL_SG_LIBRARY NAMES "pglsg" "libpglsg" - PATHS ${PLANTGL_LIBRARYDIR} $ENV{PATH}) + PATHS ${PLANTGL_LIBRARYDIR} $ENV{PATH} $ENV{CONDA_PREFIX}/lib $ENV{CONDA_PREFIX}/lib64) get_filename_component(PLANTGL_LIBRARY_DIR ${PLANTGL_SG_LIBRARY} DIRECTORY) diff --git a/setup.py b/setup.py index fdd7520f..4c5e6af6 100644 --- a/setup.py +++ b/setup.py @@ -5,10 +5,25 @@ import os, sys pj = os.path.join -from openalea.deploy.metainfo import read_metainfo -metadata = read_metainfo('metainfo.ini', verbose=True) -for key,value in metadata.items(): - exec("%s = '%s'" % (key, value)) +# from openalea.deploy.metainfo import read_metainfo +# metadata = read_metainfo('metainfo.ini', verbose=True) +# for key,value in metadata.items(): +# exec("%s = '%s'" % (key, value)) + +version = '2.7.1' +release = '2.7' +project = 'openalea' +package = 'lpy' +name = 'OpenAlea.Lpy' +namespace = 'openalea' +pkg_name = 'openalea.lpy' +description = 'Lindenmayer Systems in Python package for OpenAlea.' +long_description= 'L-Py is a simulation software that mixes L-systems construction with the Python high-level modeling language. ' +authors = 'Frederic Boudon' +authors_email = 'frederic.boudon@cirad.fr' +url= 'https://github.com/openalea/lpy' +# LGPL compatible INRIA license +license = 'Cecill-C' ############## # Setup script @@ -31,7 +46,7 @@ build_prefix = "build-cmake" from setuptools import setup -from openalea.deploy.binary_deps import binary_deps +# from openalea.deploy.binary_deps import binary_deps def compile_interface(): cwd = os.getcwd() diff --git a/src/openalea/lpy/gui/__init__.py b/src/openalea/lpy/gui/__init__.py deleted file mode 100644 index d3f5a12f..00000000 --- a/src/openalea/lpy/gui/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/openalea/lpy/gui/compile_ui.py b/src/openalea/lpy/gui/compile_ui.py index da998df5..9f4b577f 100644 --- a/src/openalea/lpy/gui/compile_ui.py +++ b/src/openalea/lpy/gui/compile_ui.py @@ -20,6 +20,7 @@ def compile_ui(uifname): """ compile a Ui """ pyfname = get_uifnames_from(uifname) fstream = open(pyfname,'w') +# compile_args["from_imports"] = "" compileUi(uifname, fstream, **compile_args) fstream.close() diff --git a/src/openalea/lpy/gui/lpydock.py b/src/openalea/lpy/gui/lpydock.py index 7be3eb81..e4b637da 100644 --- a/src/openalea/lpy/gui/lpydock.py +++ b/src/openalea/lpy/gui/lpydock.py @@ -4,7 +4,7 @@ from .lpyshell import set_shell_widget from openalea.plantgl.gui.qt import qt -from openalea.plantgl.gui.qt.QtCore import Qt, QCoreApplication +from openalea.plantgl.gui.qt.QtCore import Qt, QCoreApplication, QTimer from openalea.plantgl.gui.qt.QtGui import QIcon, QPixmap from openalea.plantgl.gui.qt.QtWidgets import QApplication, QDockWidget, QSplitter, QWidget _translate = QCoreApplication.translate @@ -26,7 +26,7 @@ def showMessage(self,msg,timeout): self.statusBar.showMessage(msg,timeout) else: print(msg) - + def initDocks(lpywidget): prevdock = None st = lpywidget.statusBar() @@ -86,14 +86,18 @@ def initDocks(lpywidget): lpywidget.interpreter = None lpywidget.interpreterDock.hide() - if lpywidget.withinterpreter : - action = lpywidget.interpreterDock.toggleViewAction() - action.setShortcut(QCoreApplication.translate("MainWindow", "Ctrl+P")) - lpywidget.menuView.addSeparator() - lpywidget.menuView.addAction(action) + if lpywidget.withinterpreter: + action = lpywidget.interpreterDock.toggleViewAction() + action.setShortcut(QCoreApplication.translate("MainWindow", "Ctrl+P")) + lpywidget.menuView.addSeparator() + lpywidget.menuView.addAction(action) - lpywidget.addDockWidget(Qt.BottomDockWidgetArea,lpywidget.interpreterDock) - lpywidget.tabifyDockWidget(lpywidget.debugDock,lpywidget.interpreterDock) + lpywidget.addDockWidget(Qt.BottomDockWidgetArea,lpywidget.interpreterDock) + lpywidget.tabifyDockWidget(lpywidget.debugDock,lpywidget.interpreterDock) else: lpywidget.interpreter = None - + +async def initShell(lpywidget): + lpywidget.interpreter.locals['window'] = lpywidget + await lpywidget.shell.run_code('from openalea.plantgl.all import *') + await lpywidget.shell.run_code('from openalea.lpy import *') diff --git a/src/openalea/lpy/gui/lpymainwindow.ui b/src/openalea/lpy/gui/lpymainwindow.ui index cb0a1825..fe97d584 100644 --- a/src/openalea/lpy/gui/lpymainwindow.ui +++ b/src/openalea/lpy/gui/lpymainwindow.ui @@ -1765,29 +1765,29 @@ LpyCodeEditor QTextEdit -
lpycodeeditor.h
+
openalea/lpy/gui/lpycodeeditor.h
LpyTabBar QWidget -
lpytabbar.h
+
openalea/lpy/gui/lpytabbar.h
1
ScalarEditor QTreeView -
scalareditor.h
+
openalea/lpy/gui/scalareditor.h
LpyTabBarNeighbor QWidget -
lpytabbar.h
+
openalea/lpy/gui/lpytabbar.h
1
LpyView3D QWidget -
lpyview3d.h
+
openalea/lpy/gui/lpyview3d.h
1
diff --git a/src/openalea/lpy/gui/lpyshell.py b/src/openalea/lpy/gui/lpyshell.py index 20c9fc96..adbffec0 100644 --- a/src/openalea/lpy/gui/lpyshell.py +++ b/src/openalea/lpy/gui/lpyshell.py @@ -2,9 +2,9 @@ from qtconsole.rich_jupyter_widget import RichJupyterWidget from qtconsole.inprocess import QtInProcessKernelManager -from .streamredirection import GraphicalStreamRedirection +# from .streamredirection import GraphicalStreamRedirection -class LpyShellWidget(RichJupyterWidget, GraphicalStreamRedirection): +class LpyShellWidget(RichJupyterWidget): #, GraphicalStreamRedirection): def __init__(self, parent=None): """ @@ -19,9 +19,9 @@ def __init__(self, parent=None): self.kernel_manager.start_kernel(show_banner=False) self.kernel = self.kernel_manager.kernel - self.kernel.gui = 'qt4' - self.shell = self.kernel.shell + self.kernel.gui = 'qt' + self.shell = self.kernel.shell self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() @@ -29,15 +29,10 @@ def __init__(self, parent=None): self.kernel.locals = self.kernel.shell.user_ns # Multiple Stream Redirection - GraphicalStreamRedirection.__init__(self, self.kernel.stdout, self.kernel.stderr) + # GraphicalStreamRedirection.__init__(self, self.kernel.stdout, self.kernel.stderr) def set_shell_widget(lpywidget): - #import sip - #assert sip.getapi('QString') == 2 - - import sys - ipython_widget = LpyShellWidget(lpywidget.interpreterDock) lpywidget.interpreterDock.setWidget(ipython_widget) @@ -46,7 +41,3 @@ def set_shell_widget(lpywidget): lpywidget.shellwidget = ipython_widget lpywidget.interpreter = kernel lpywidget.shell = kernel.shell - - lpywidget.interpreter.locals['window'] = lpywidget - lpywidget.shell.run_code('from openalea.plantgl.all import *') - lpywidget.shell.run_code('from openalea.lpy import *') diff --git a/src/openalea/lpy/gui/lpystudio.py b/src/openalea/lpy/gui/lpystudio.py index d3916658..66b91616 100644 --- a/src/openalea/lpy/gui/lpystudio.py +++ b/src/openalea/lpy/gui/lpystudio.py @@ -2,6 +2,7 @@ import os import stat import shutil +import asyncio # for py2exe try: @@ -39,7 +40,7 @@ from openalea.plantgl.gui.qt.compat import * -from openalea.plantgl.gui.qt.QtCore import QCoreApplication, QEvent, QMutex, QObject, QThread, QWaitCondition, Qt, pyqtSignal, pyqtSlot +from openalea.plantgl.gui.qt.QtCore import QCoreApplication, QEvent, QMutex, QObject, QThread, QWaitCondition, QTimer, Qt, pyqtSignal, pyqtSlot from openalea.plantgl.gui.qt.QtGui import QIcon, QPixmap, QTextCursor from openalea.plantgl.gui.qt.QtWidgets import QAction, QApplication, QDialog, QFileDialog, QInputDialog, QMainWindow, QMessageBox, QTabBar try: @@ -85,7 +86,7 @@ class LPyWindow(QMainWindow, lsmw.Ui_MainWindow, ComputationTaskManager) : instances = [] - def __init__(self, parent=None, withinterpreter = False): + def __init__(self, parent=None, withinterpreter = True): """ :param parent : parent window """ @@ -93,7 +94,6 @@ def __init__(self, parent=None, withinterpreter = False): ComputationTaskManager.__init__(self) lsmw.Ui_MainWindow.__init__(self) - import weakref LPyWindow.instances.append(weakref.ref(self)) @@ -101,6 +101,9 @@ def __init__(self, parent=None, withinterpreter = False): self.setupUi(self) self.editToolBar.hide() lpydock.initDocks(self) + + QTimer.singleShot(1000, lambda: lpydock.initShell(self)) + self.preferences = lpypreferences.LpyPreferences(self) icon = QIcon() icon.addPixmap(QPixmap(":/images/icons/history.png"),QIcon.Normal,QIcon.Off) @@ -843,7 +846,7 @@ def createTutorialMenu(self): iconfile.addPixmap(QPixmap(":/images/icons/codefile.png"),QIcon.Normal,QIcon.Off) iconfolder = QIcon() iconfolder.addPixmap(QPixmap(":/images/icons/fileopen.png"),QIcon.Normal,QIcon.Off) - from openalea.deploy.shared_data import shared_data + from openalea.lpy.gui.shared_data import shared_data import openalea.lpy shared_data_path = shared_data(openalea.lpy.__path__, share_path='share/tutorial') if not shared_data_path is None: diff --git a/src/openalea/lpy/gui/shared_data.py b/src/openalea/lpy/gui/shared_data.py new file mode 100644 index 00000000..54f6bb97 --- /dev/null +++ b/src/openalea/lpy/gui/shared_data.py @@ -0,0 +1,114 @@ +# -*- python -*- +# +# OpenAlea.Deploy: OpenAlea setuptools extension +# +# Copyright 2008 INRIA - CIRAD - INRA +# +# File author(s): Thomas Cokelae +# +# Distributed under the Cecill-C License. +# See accompanying file LICENSE.txt or copy at +# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html +# +# OpenAlea WebSite : http://openalea.gforge.inria.fr +# + +"""INRIA GForge SOAP python API wrappers (based on SOAPpy) + +""" +import types +import os +from os.path import join as pj +from os.path import realpath, isdir, isfile +try: + from path import Path +except ImportError: + try: + from path import path as Path + except ImportError: + try: + from openalea.core.path import path as Path + except ImportError: + from IPython.external.path import path as Path + +__license__ = "Cecill-C" +__revision__ = " $Id: gforge.py 2243 2010-02-08 17:08:47Z cokelaer $ " + +_share_path = pj('share', 'data') + + +def shared_data(package_path, filename=None, pattern=None, + share_path=_share_path): + """Return a valid pathname pointing to a shared-data directory or a shared-data file. + + :Parameters: + - `package_path` (str or list) - Can be either a string representing a package path or a list of package paths. (e.g. + :py:class:`path`('/home/user/openalea/deploy/src/openalea/deploy') or [:py:class:`path`('/usr/lib/pymodules/python2.7/numpy')]). + If package_path is a list, then the first element of package_path is used. + - `filename` (str) - An optional valid filename without any path that is expected + to be found in :py:obj:`share_path`. + - `share_path` (str) - The path where the share data directory is expected to be found. + The default value is :py:const:`.share_path`. Important: All users should keep this + default value in order to ease the share of data between the different packages. + + :Returns: + a valid directory path if filename is not provided, and a valid file path to + filename (including filename) otherwise. The directory or file is searched firstly into + ':py:obj:`package_path`, then into ':py:obj:`package_path` parent directory, then + into ':py:obj:`package_path` parent parent directory, and so on, going up until the parent parent + directory of the last Python package found. + If no valid path is found, returns None. + + :Returns Type: + str + + :Examples: + + >>> shared_data(['/home/user/mypackage']) + '/home/user/mypackage/share/data' + >>> shared_data('/home/user/mypackage', 'my_file.csv') + '/home/user/mypackage/share/data/my_file.csv' + >>> shared_data(['/home/user/mypackage'], share_path='share/databases') + '/home/user/mypackage/share/databases' + >>> import mypackage + >>> shared_data(mypackage, pattern='*.mtg') + ['/home/user/mypackage/share/databases/mtg1.mtg', ...] + """ + + if isinstance(package_path, types.ModuleType): + package_path = package_path.__path__ + + if isinstance(package_path, list): + if len(package_path) == 0: + return None + else: + package_path = package_path[0] + package_path = Path(package_path) + ff = package_path / share_path + ff = ff.realpath() + shared_data_path = None + if ff.isdir(): + if filename is None: + shared_data_path = ff + if pattern: + l = ff.glob(pattern) + if l: + shared_data_path = l + else: + ff = ff / filename + ff = ff.realpath() + if ff.isfile(): + shared_data_path = ff + + if shared_data_path is None and (package_path / '__init__.py').isfile(): + shared_data_path = shared_data(package_path.parent, filename, pattern, + share_path) + if shared_data_path is None: + shared_data_path = shared_data(package_path.parent.parent, filename, + pattern, share_path) + + return shared_data_path + + +# Backward compatibility +get_shared_data_path = shared_data From fd31087688d558b9f984dcb7195710bf6fd79498 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Wed, 23 Oct 2019 20:56:27 +0200 Subject: [PATCH 50/68] fig various bugs --- src/openalea/lpy/gui/lpycodeeditor.py | 4 +-- src/openalea/lpy/gui/lpypreferences.py | 18 +++++----- src/openalea/lpy/gui/settings.py | 48 +++++++++++++------------- src/openalea/lpy/gui/shared_data.py | 46 ++++++++++++------------ 4 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/openalea/lpy/gui/lpycodeeditor.py b/src/openalea/lpy/gui/lpycodeeditor.py index b5622903..1d36f5d7 100644 --- a/src/openalea/lpy/gui/lpycodeeditor.py +++ b/src/openalea/lpy/gui/lpycodeeditor.py @@ -814,7 +814,7 @@ def saveSimuState(self,simu): self.sidebar.saveState(simu) def getCode(self): - return str(self.toPlainText()).encode('iso-8859-1','replace') + return str(str(self.toPlainText()).encode('iso-8859-1','replace')) def codeToExecute(self): cursor = self.textCursor() @@ -833,4 +833,4 @@ def codeToExecute(self): torem = len(fline) - len(nfline) nlines = [l[torem:] for l in lines] cmd = '\n'.join(nlines) - return cmd + return cmd diff --git a/src/openalea/lpy/gui/lpypreferences.py b/src/openalea/lpy/gui/lpypreferences.py index 22624e61..508a7504 100644 --- a/src/openalea/lpy/gui/lpypreferences.py +++ b/src/openalea/lpy/gui/lpypreferences.py @@ -57,13 +57,13 @@ def show(self): self.widget.profilingNoPlotButton.clicked.connect(self.setProfilingNoPlotMode) # QObject.connect(self.widget.profilingNoPlotButton,SIGNAL('clicked(bool)'),self.setProfilingNoPlotMode) self.widget.integratedViewEdit.setChecked(self.editor.use_own_view3D) self.widget.integratedViewEdit.clicked.connect(self.editor.setIntegratedView3D) # QObject.connect(self.widget.integratedViewEdit,SIGNAL('clicked(bool)'),self.editor.setIntegratedView3D) - if not self.editor.withinterpreter: - self.widget.textOutputBox.setEnabled(False) - else: - self.widget.LPyConsoleButton.setChecked(self.editor.shellwidget.isSelfStdOutRedirection() or self.editor.shellwidget.hasMultipleStdOutRedirection()) - self.widget.LPyConsoleButton.clicked.connect(self.setOutputRedirection) # QObject.connect(self.widget.LPyConsoleButton,SIGNAL('clicked(bool)'),self.setOutputRedirection) - self.widget.systemConsoleButton.setChecked(self.editor.shellwidget.isSysStdOutRedirection() or self.editor.shellwidget.hasMultipleStdOutRedirection()) - self.widget.systemConsoleButton.clicked.connect(self.setOutputRedirection) # QObject.connect(self.widget.systemConsoleButton,SIGNAL('clicked(bool)'),self.setOutputRedirection) + #if not self.editor.withinterpreter: + self.widget.textOutputBox.setEnabled(False) + #else: + # self.widget.LPyConsoleButton.setChecked(self.editor.shellwidget.isSelfStdOutRedirection() or self.editor.shellwidget.hasMultipleStdOutRedirection()) + # self.widget.LPyConsoleButton.clicked.connect(self.setOutputRedirection) # QObject.connect(self.widget.LPyConsoleButton,SIGNAL('clicked(bool)'),self.setOutputRedirection) + # self.widget.systemConsoleButton.setChecked(self.editor.shellwidget.isSysStdOutRedirection() or self.editor.shellwidget.hasMultipleStdOutRedirection()) + # self.widget.systemConsoleButton.clicked.connect(self.setOutputRedirection) # QObject.connect(self.widget.systemConsoleButton,SIGNAL('clicked(bool)'),self.setOutputRedirection) self.dialog.show() def chooseCCompilerPath(self): p = QFileDialog.getExistingDirectory(self.editor, "Choose Compiler Path", self.editor.cCompilerPath ) @@ -88,6 +88,6 @@ def setPofilingButton(self,value): self.widget.profilingFinalPlotButton.setChecked(True) else: self.widget.profilingNoPlotButton.setChecked(True) - def setOutputRedirection(self): - self.editor.shellwidget.setOutputRedirection(self.widget.LPyConsoleButton.isChecked(),self.widget.systemConsoleButton.isChecked()) + #def setOutputRedirection(self): + # self.editor.shellwidget.setOutputRedirection(self.widget.LPyConsoleButton.isChecked(),self.widget.systemConsoleButton.isChecked()) diff --git a/src/openalea/lpy/gui/settings.py b/src/openalea/lpy/gui/settings.py index 122c3993..d127d5e4 100644 --- a/src/openalea/lpy/gui/settings.py +++ b/src/openalea/lpy/gui/settings.py @@ -94,18 +94,18 @@ def restoreState(lpywidget): if fstr != 'default' and f.fromString(fstr): #print 'read font',fstr lpywidget.codeeditor.setEditionFont(f) - settings.endGroup() - settings.beginGroup('stdout') - lc = settings.value('lpyshell',True)=='true' - sc = settings.value('sysconsole',False)=='true' - lpywidget.shellwidget.setOutputRedirection(lc,sc,1) - settings.endGroup() + #settings.endGroup() + #settings.beginGroup('stdout') + #lc = settings.value('lpyshell',True)=='true' + #sc = settings.value('sysconsole',False)=='true' + #lpywidget.shellwidget.setOutputRedirection(lc,sc,1) + #settings.endGroup() - settings.beginGroup('stderr') - lc = settings.value('lpyshell',True)=='true' - sc = settings.value('sysconsole',False)=='true' - lpywidget.shellwidget.setOutputRedirection(lc,sc,2) - settings.endGroup() + #settings.beginGroup('stderr') + #lc = settings.value('lpyshell',True)=='true' + #sc = settings.value('sysconsole',False)=='true' + #lpywidget.shellwidget.setOutputRedirection(lc,sc,2) + #settings.endGroup() settings.beginGroup('edition') lpywidget.codeeditor.replaceTab = settings.value('replaceTab',lpywidget.codeeditor.replaceTab)=='true' @@ -179,19 +179,19 @@ def saveState(lpywidget): else: settings.setValue('editionfont','default') settings.endGroup() - if not lpywidget.interpreter is None: - settings.beginGroup('stdout') - outinshell = lpywidget.shellwidget.hasMultipleStdOutRedirection() or lpywidget.shellwidget.isSelfStdOutRedirection() - outinsys = lpywidget.shellwidget.hasMultipleStdOutRedirection() or lpywidget.shellwidget.isSysStdOutRedirection() - settings.setValue('lpyshell',to_qvariant(outinshell)) - settings.setValue('sysconsole',to_qvariant(outinsys)) - settings.endGroup() - settings.beginGroup('stderr') - errinshell = lpywidget.shellwidget.hasMultipleStdErrRedirection() or lpywidget.shellwidget.isSelfStdErrRedirection() - errinsys = lpywidget.shellwidget.hasMultipleStdErrRedirection() or lpywidget.shellwidget.isSysStdErrRedirection() - settings.setValue('lpyshell',to_qvariant(errinshell)) - settings.setValue('sysconsole',to_qvariant(errinsys)) - settings.endGroup() + # if not lpywidget.interpreter is None: + # settings.beginGroup('stdout') + # outinshell = lpywidget.shellwidget.hasMultipleStdOutRedirection() or lpywidget.shellwidget.isSelfStdOutRedirection() + # outinsys = lpywidget.shellwidget.hasMultipleStdOutRedirection() or lpywidget.shellwidget.isSysStdOutRedirection() + # settings.setValue('lpyshell',to_qvariant(outinshell)) + # settings.setValue('sysconsole',to_qvariant(outinsys)) + # settings.endGroup() + # settings.beginGroup('stderr') + # errinshell = lpywidget.shellwidget.hasMultipleStdErrRedirection() or lpywidget.shellwidget.isSelfStdErrRedirection() + # errinsys = lpywidget.shellwidget.hasMultipleStdErrRedirection() or lpywidget.shellwidget.isSysStdErrRedirection() + # settings.setValue('lpyshell',to_qvariant(errinshell)) + # settings.setValue('sysconsole',to_qvariant(errinsys)) + # settings.endGroup() settings.beginGroup('syntax') settings.setValue('highlighted',to_qvariant(lpywidget.codeeditor.isSyntaxHighLightActivated())) settings.setValue('tabview',to_qvariant(lpywidget.codeeditor.isTabHighLightActivated())) diff --git a/src/openalea/lpy/gui/shared_data.py b/src/openalea/lpy/gui/shared_data.py index 54f6bb97..a3fc4d11 100644 --- a/src/openalea/lpy/gui/shared_data.py +++ b/src/openalea/lpy/gui/shared_data.py @@ -19,17 +19,20 @@ import types import os from os.path import join as pj -from os.path import realpath, isdir, isfile -try: - from path import Path -except ImportError: - try: - from path import path as Path - except ImportError: - try: - from openalea.core.path import path as Path - except ImportError: - from IPython.external.path import path as Path +from os.path import realpath, isdir, isfile, dirname +import glob + + +# try: +# from path import Path +# except ModuleNotFoundError: +# try: +# from path import path as Path +# except ModuleNotFoundError: +# try: +# from openalea.core.path import path as Path +# except ModuleNotFoundError: +# from IPython.utils.path import Path __license__ = "Cecill-C" __revision__ = " $Id: gforge.py 2243 2010-02-08 17:08:47Z cokelaer $ " @@ -83,28 +86,27 @@ def shared_data(package_path, filename=None, pattern=None, return None else: package_path = package_path[0] - package_path = Path(package_path) - ff = package_path / share_path - ff = ff.realpath() + ff = pj(package_path, share_path) + ff = realpath(ff) shared_data_path = None - if ff.isdir(): + if isdir(ff): if filename is None: shared_data_path = ff if pattern: - l = ff.glob(pattern) + l = glob.glob(pj(ff, pattern)) if l: shared_data_path = l else: - ff = ff / filename - ff = ff.realpath() - if ff.isfile(): + ff = pj(ff,filename) + ff = realpath(ff) + if isfile(ff): shared_data_path = ff - if shared_data_path is None and (package_path / '__init__.py').isfile(): - shared_data_path = shared_data(package_path.parent, filename, pattern, + if shared_data_path is None and isfile(pj(package_path, '__init__.py')): + shared_data_path = shared_data(dirname(package_path), filename, pattern, share_path) if shared_data_path is None: - shared_data_path = shared_data(package_path.parent.parent, filename, + shared_data_path = shared_data(dirname(dirname(package_path)), filename, pattern, share_path) return shared_data_path From a029d112c4580f5ba5fe029bc195db621e26ee4a Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Wed, 23 Oct 2019 22:09:32 +0200 Subject: [PATCH 51/68] fix pb with text retrieval --- src/openalea/lpy/gui/lpycodeeditor.py | 2 +- src/openalea/lpy/gui/lpydock.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openalea/lpy/gui/lpycodeeditor.py b/src/openalea/lpy/gui/lpycodeeditor.py index 1d36f5d7..a710f9c7 100644 --- a/src/openalea/lpy/gui/lpycodeeditor.py +++ b/src/openalea/lpy/gui/lpycodeeditor.py @@ -814,7 +814,7 @@ def saveSimuState(self,simu): self.sidebar.saveState(simu) def getCode(self): - return str(str(self.toPlainText()).encode('iso-8859-1','replace')) + return str(self.toPlainText()).encode('iso-8859-1','replace').decode('iso-8859-1') def codeToExecute(self): cursor = self.textCursor() diff --git a/src/openalea/lpy/gui/lpydock.py b/src/openalea/lpy/gui/lpydock.py index e4b637da..2cb35961 100644 --- a/src/openalea/lpy/gui/lpydock.py +++ b/src/openalea/lpy/gui/lpydock.py @@ -97,7 +97,7 @@ def initDocks(lpywidget): else: lpywidget.interpreter = None -async def initShell(lpywidget): +def initShell(lpywidget): lpywidget.interpreter.locals['window'] = lpywidget - await lpywidget.shell.run_code('from openalea.plantgl.all import *') - await lpywidget.shell.run_code('from openalea.lpy import *') + lpywidget.shell.run_code('from openalea.plantgl.all import *') + lpywidget.shell.run_code('from openalea.lpy import *') From 1926b2cadccea746139cee563e97722bec92a476 Mon Sep 17 00:00:00 2001 From: Julien Wintz Date: Wed, 23 Oct 2019 09:55:18 +0200 Subject: [PATCH 52/68] Various fixes WRT/ Python 3. --- CMakeLists.txt | 2 +- cmake/FindPlantGL.cmake | 4 +- setup.py | 25 ++++-- src/openalea/lpy/gui/__init__.py | 1 - src/openalea/lpy/gui/compile_ui.py | 1 + src/openalea/lpy/gui/lpydock.py | 24 +++--- src/openalea/lpy/gui/lpymainwindow.ui | 10 +-- src/openalea/lpy/gui/lpyshell.py | 19 ++--- src/openalea/lpy/gui/lpystudio.py | 11 ++- src/openalea/lpy/gui/shared_data.py | 114 ++++++++++++++++++++++++++ 10 files changed, 169 insertions(+), 42 deletions(-) delete mode 100644 src/openalea/lpy/gui/__init__.py create mode 100644 src/openalea/lpy/gui/shared_data.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 7aca69d4..e4c12ab5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,7 +33,7 @@ set(Boost_NO_SYSTEM_PATHS ON) set(Boost_USE_MULTITHREAD ON) set(Boost_USE_STATIC_LIBS OFF) -find_package(Boost 1.67 COMPONENTS system ${BOOST_PYTHON_LIB} REQUIRED) +find_package(Boost COMPONENTS system ${BOOST_PYTHON_LIB} REQUIRED) # --- Include Directories diff --git a/cmake/FindPlantGL.cmake b/cmake/FindPlantGL.cmake index 33d73c7b..32de9eea 100644 --- a/cmake/FindPlantGL.cmake +++ b/cmake/FindPlantGL.cmake @@ -27,7 +27,7 @@ endif() # Include Directory find_path(PLANTGL_INCLUDE_DIR NAMES "plantgl/plantgl.h" - HINTS ${PLANTGL_INCLUDEDIR} $ENV{PATH}) + HINTS ${PLANTGL_INCLUDEDIR} $ENV{PATH} $ENV{CONDA_PREFIX}/include) if (NOT PLANTGL_INCLUDE_DIR) set(PLANTGL_FOUND OFF) @@ -41,7 +41,7 @@ endif() # Library Directory find_library(PLANTGL_SG_LIBRARY NAMES "pglsg" "libpglsg" - PATHS ${PLANTGL_LIBRARYDIR} $ENV{PATH}) + PATHS ${PLANTGL_LIBRARYDIR} $ENV{PATH} $ENV{CONDA_PREFIX}/lib $ENV{CONDA_PREFIX}/lib64) get_filename_component(PLANTGL_LIBRARY_DIR ${PLANTGL_SG_LIBRARY} DIRECTORY) diff --git a/setup.py b/setup.py index fdd7520f..4c5e6af6 100644 --- a/setup.py +++ b/setup.py @@ -5,10 +5,25 @@ import os, sys pj = os.path.join -from openalea.deploy.metainfo import read_metainfo -metadata = read_metainfo('metainfo.ini', verbose=True) -for key,value in metadata.items(): - exec("%s = '%s'" % (key, value)) +# from openalea.deploy.metainfo import read_metainfo +# metadata = read_metainfo('metainfo.ini', verbose=True) +# for key,value in metadata.items(): +# exec("%s = '%s'" % (key, value)) + +version = '2.7.1' +release = '2.7' +project = 'openalea' +package = 'lpy' +name = 'OpenAlea.Lpy' +namespace = 'openalea' +pkg_name = 'openalea.lpy' +description = 'Lindenmayer Systems in Python package for OpenAlea.' +long_description= 'L-Py is a simulation software that mixes L-systems construction with the Python high-level modeling language. ' +authors = 'Frederic Boudon' +authors_email = 'frederic.boudon@cirad.fr' +url= 'https://github.com/openalea/lpy' +# LGPL compatible INRIA license +license = 'Cecill-C' ############## # Setup script @@ -31,7 +46,7 @@ build_prefix = "build-cmake" from setuptools import setup -from openalea.deploy.binary_deps import binary_deps +# from openalea.deploy.binary_deps import binary_deps def compile_interface(): cwd = os.getcwd() diff --git a/src/openalea/lpy/gui/__init__.py b/src/openalea/lpy/gui/__init__.py deleted file mode 100644 index d3f5a12f..00000000 --- a/src/openalea/lpy/gui/__init__.py +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/openalea/lpy/gui/compile_ui.py b/src/openalea/lpy/gui/compile_ui.py index da998df5..9f4b577f 100644 --- a/src/openalea/lpy/gui/compile_ui.py +++ b/src/openalea/lpy/gui/compile_ui.py @@ -20,6 +20,7 @@ def compile_ui(uifname): """ compile a Ui """ pyfname = get_uifnames_from(uifname) fstream = open(pyfname,'w') +# compile_args["from_imports"] = "" compileUi(uifname, fstream, **compile_args) fstream.close() diff --git a/src/openalea/lpy/gui/lpydock.py b/src/openalea/lpy/gui/lpydock.py index 7be3eb81..e4b637da 100644 --- a/src/openalea/lpy/gui/lpydock.py +++ b/src/openalea/lpy/gui/lpydock.py @@ -4,7 +4,7 @@ from .lpyshell import set_shell_widget from openalea.plantgl.gui.qt import qt -from openalea.plantgl.gui.qt.QtCore import Qt, QCoreApplication +from openalea.plantgl.gui.qt.QtCore import Qt, QCoreApplication, QTimer from openalea.plantgl.gui.qt.QtGui import QIcon, QPixmap from openalea.plantgl.gui.qt.QtWidgets import QApplication, QDockWidget, QSplitter, QWidget _translate = QCoreApplication.translate @@ -26,7 +26,7 @@ def showMessage(self,msg,timeout): self.statusBar.showMessage(msg,timeout) else: print(msg) - + def initDocks(lpywidget): prevdock = None st = lpywidget.statusBar() @@ -86,14 +86,18 @@ def initDocks(lpywidget): lpywidget.interpreter = None lpywidget.interpreterDock.hide() - if lpywidget.withinterpreter : - action = lpywidget.interpreterDock.toggleViewAction() - action.setShortcut(QCoreApplication.translate("MainWindow", "Ctrl+P")) - lpywidget.menuView.addSeparator() - lpywidget.menuView.addAction(action) + if lpywidget.withinterpreter: + action = lpywidget.interpreterDock.toggleViewAction() + action.setShortcut(QCoreApplication.translate("MainWindow", "Ctrl+P")) + lpywidget.menuView.addSeparator() + lpywidget.menuView.addAction(action) - lpywidget.addDockWidget(Qt.BottomDockWidgetArea,lpywidget.interpreterDock) - lpywidget.tabifyDockWidget(lpywidget.debugDock,lpywidget.interpreterDock) + lpywidget.addDockWidget(Qt.BottomDockWidgetArea,lpywidget.interpreterDock) + lpywidget.tabifyDockWidget(lpywidget.debugDock,lpywidget.interpreterDock) else: lpywidget.interpreter = None - + +async def initShell(lpywidget): + lpywidget.interpreter.locals['window'] = lpywidget + await lpywidget.shell.run_code('from openalea.plantgl.all import *') + await lpywidget.shell.run_code('from openalea.lpy import *') diff --git a/src/openalea/lpy/gui/lpymainwindow.ui b/src/openalea/lpy/gui/lpymainwindow.ui index cb0a1825..fe97d584 100644 --- a/src/openalea/lpy/gui/lpymainwindow.ui +++ b/src/openalea/lpy/gui/lpymainwindow.ui @@ -1765,29 +1765,29 @@ LpyCodeEditor QTextEdit -
lpycodeeditor.h
+
openalea/lpy/gui/lpycodeeditor.h
LpyTabBar QWidget -
lpytabbar.h
+
openalea/lpy/gui/lpytabbar.h
1
ScalarEditor QTreeView -
scalareditor.h
+
openalea/lpy/gui/scalareditor.h
LpyTabBarNeighbor QWidget -
lpytabbar.h
+
openalea/lpy/gui/lpytabbar.h
1
LpyView3D QWidget -
lpyview3d.h
+
openalea/lpy/gui/lpyview3d.h
1
diff --git a/src/openalea/lpy/gui/lpyshell.py b/src/openalea/lpy/gui/lpyshell.py index 20c9fc96..adbffec0 100644 --- a/src/openalea/lpy/gui/lpyshell.py +++ b/src/openalea/lpy/gui/lpyshell.py @@ -2,9 +2,9 @@ from qtconsole.rich_jupyter_widget import RichJupyterWidget from qtconsole.inprocess import QtInProcessKernelManager -from .streamredirection import GraphicalStreamRedirection +# from .streamredirection import GraphicalStreamRedirection -class LpyShellWidget(RichJupyterWidget, GraphicalStreamRedirection): +class LpyShellWidget(RichJupyterWidget): #, GraphicalStreamRedirection): def __init__(self, parent=None): """ @@ -19,9 +19,9 @@ def __init__(self, parent=None): self.kernel_manager.start_kernel(show_banner=False) self.kernel = self.kernel_manager.kernel - self.kernel.gui = 'qt4' - self.shell = self.kernel.shell + self.kernel.gui = 'qt' + self.shell = self.kernel.shell self.kernel_client = self.kernel_manager.client() self.kernel_client.start_channels() @@ -29,15 +29,10 @@ def __init__(self, parent=None): self.kernel.locals = self.kernel.shell.user_ns # Multiple Stream Redirection - GraphicalStreamRedirection.__init__(self, self.kernel.stdout, self.kernel.stderr) + # GraphicalStreamRedirection.__init__(self, self.kernel.stdout, self.kernel.stderr) def set_shell_widget(lpywidget): - #import sip - #assert sip.getapi('QString') == 2 - - import sys - ipython_widget = LpyShellWidget(lpywidget.interpreterDock) lpywidget.interpreterDock.setWidget(ipython_widget) @@ -46,7 +41,3 @@ def set_shell_widget(lpywidget): lpywidget.shellwidget = ipython_widget lpywidget.interpreter = kernel lpywidget.shell = kernel.shell - - lpywidget.interpreter.locals['window'] = lpywidget - lpywidget.shell.run_code('from openalea.plantgl.all import *') - lpywidget.shell.run_code('from openalea.lpy import *') diff --git a/src/openalea/lpy/gui/lpystudio.py b/src/openalea/lpy/gui/lpystudio.py index d3916658..66b91616 100644 --- a/src/openalea/lpy/gui/lpystudio.py +++ b/src/openalea/lpy/gui/lpystudio.py @@ -2,6 +2,7 @@ import os import stat import shutil +import asyncio # for py2exe try: @@ -39,7 +40,7 @@ from openalea.plantgl.gui.qt.compat import * -from openalea.plantgl.gui.qt.QtCore import QCoreApplication, QEvent, QMutex, QObject, QThread, QWaitCondition, Qt, pyqtSignal, pyqtSlot +from openalea.plantgl.gui.qt.QtCore import QCoreApplication, QEvent, QMutex, QObject, QThread, QWaitCondition, QTimer, Qt, pyqtSignal, pyqtSlot from openalea.plantgl.gui.qt.QtGui import QIcon, QPixmap, QTextCursor from openalea.plantgl.gui.qt.QtWidgets import QAction, QApplication, QDialog, QFileDialog, QInputDialog, QMainWindow, QMessageBox, QTabBar try: @@ -85,7 +86,7 @@ class LPyWindow(QMainWindow, lsmw.Ui_MainWindow, ComputationTaskManager) : instances = [] - def __init__(self, parent=None, withinterpreter = False): + def __init__(self, parent=None, withinterpreter = True): """ :param parent : parent window """ @@ -93,7 +94,6 @@ def __init__(self, parent=None, withinterpreter = False): ComputationTaskManager.__init__(self) lsmw.Ui_MainWindow.__init__(self) - import weakref LPyWindow.instances.append(weakref.ref(self)) @@ -101,6 +101,9 @@ def __init__(self, parent=None, withinterpreter = False): self.setupUi(self) self.editToolBar.hide() lpydock.initDocks(self) + + QTimer.singleShot(1000, lambda: lpydock.initShell(self)) + self.preferences = lpypreferences.LpyPreferences(self) icon = QIcon() icon.addPixmap(QPixmap(":/images/icons/history.png"),QIcon.Normal,QIcon.Off) @@ -843,7 +846,7 @@ def createTutorialMenu(self): iconfile.addPixmap(QPixmap(":/images/icons/codefile.png"),QIcon.Normal,QIcon.Off) iconfolder = QIcon() iconfolder.addPixmap(QPixmap(":/images/icons/fileopen.png"),QIcon.Normal,QIcon.Off) - from openalea.deploy.shared_data import shared_data + from openalea.lpy.gui.shared_data import shared_data import openalea.lpy shared_data_path = shared_data(openalea.lpy.__path__, share_path='share/tutorial') if not shared_data_path is None: diff --git a/src/openalea/lpy/gui/shared_data.py b/src/openalea/lpy/gui/shared_data.py new file mode 100644 index 00000000..54f6bb97 --- /dev/null +++ b/src/openalea/lpy/gui/shared_data.py @@ -0,0 +1,114 @@ +# -*- python -*- +# +# OpenAlea.Deploy: OpenAlea setuptools extension +# +# Copyright 2008 INRIA - CIRAD - INRA +# +# File author(s): Thomas Cokelae +# +# Distributed under the Cecill-C License. +# See accompanying file LICENSE.txt or copy at +# http://www.cecill.info/licences/Licence_CeCILL-C_V1-en.html +# +# OpenAlea WebSite : http://openalea.gforge.inria.fr +# + +"""INRIA GForge SOAP python API wrappers (based on SOAPpy) + +""" +import types +import os +from os.path import join as pj +from os.path import realpath, isdir, isfile +try: + from path import Path +except ImportError: + try: + from path import path as Path + except ImportError: + try: + from openalea.core.path import path as Path + except ImportError: + from IPython.external.path import path as Path + +__license__ = "Cecill-C" +__revision__ = " $Id: gforge.py 2243 2010-02-08 17:08:47Z cokelaer $ " + +_share_path = pj('share', 'data') + + +def shared_data(package_path, filename=None, pattern=None, + share_path=_share_path): + """Return a valid pathname pointing to a shared-data directory or a shared-data file. + + :Parameters: + - `package_path` (str or list) - Can be either a string representing a package path or a list of package paths. (e.g. + :py:class:`path`('/home/user/openalea/deploy/src/openalea/deploy') or [:py:class:`path`('/usr/lib/pymodules/python2.7/numpy')]). + If package_path is a list, then the first element of package_path is used. + - `filename` (str) - An optional valid filename without any path that is expected + to be found in :py:obj:`share_path`. + - `share_path` (str) - The path where the share data directory is expected to be found. + The default value is :py:const:`.share_path`. Important: All users should keep this + default value in order to ease the share of data between the different packages. + + :Returns: + a valid directory path if filename is not provided, and a valid file path to + filename (including filename) otherwise. The directory or file is searched firstly into + ':py:obj:`package_path`, then into ':py:obj:`package_path` parent directory, then + into ':py:obj:`package_path` parent parent directory, and so on, going up until the parent parent + directory of the last Python package found. + If no valid path is found, returns None. + + :Returns Type: + str + + :Examples: + + >>> shared_data(['/home/user/mypackage']) + '/home/user/mypackage/share/data' + >>> shared_data('/home/user/mypackage', 'my_file.csv') + '/home/user/mypackage/share/data/my_file.csv' + >>> shared_data(['/home/user/mypackage'], share_path='share/databases') + '/home/user/mypackage/share/databases' + >>> import mypackage + >>> shared_data(mypackage, pattern='*.mtg') + ['/home/user/mypackage/share/databases/mtg1.mtg', ...] + """ + + if isinstance(package_path, types.ModuleType): + package_path = package_path.__path__ + + if isinstance(package_path, list): + if len(package_path) == 0: + return None + else: + package_path = package_path[0] + package_path = Path(package_path) + ff = package_path / share_path + ff = ff.realpath() + shared_data_path = None + if ff.isdir(): + if filename is None: + shared_data_path = ff + if pattern: + l = ff.glob(pattern) + if l: + shared_data_path = l + else: + ff = ff / filename + ff = ff.realpath() + if ff.isfile(): + shared_data_path = ff + + if shared_data_path is None and (package_path / '__init__.py').isfile(): + shared_data_path = shared_data(package_path.parent, filename, pattern, + share_path) + if shared_data_path is None: + shared_data_path = shared_data(package_path.parent.parent, filename, + pattern, share_path) + + return shared_data_path + + +# Backward compatibility +get_shared_data_path = shared_data From 3a2748c80bf7864adcf5e92d5815710ef1c4b409 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Wed, 23 Oct 2019 20:56:27 +0200 Subject: [PATCH 53/68] fig various bugs --- src/openalea/lpy/gui/lpycodeeditor.py | 4 +-- src/openalea/lpy/gui/lpypreferences.py | 18 +++++----- src/openalea/lpy/gui/settings.py | 48 +++++++++++++------------- src/openalea/lpy/gui/shared_data.py | 46 ++++++++++++------------ 4 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/openalea/lpy/gui/lpycodeeditor.py b/src/openalea/lpy/gui/lpycodeeditor.py index b5622903..1d36f5d7 100644 --- a/src/openalea/lpy/gui/lpycodeeditor.py +++ b/src/openalea/lpy/gui/lpycodeeditor.py @@ -814,7 +814,7 @@ def saveSimuState(self,simu): self.sidebar.saveState(simu) def getCode(self): - return str(self.toPlainText()).encode('iso-8859-1','replace') + return str(str(self.toPlainText()).encode('iso-8859-1','replace')) def codeToExecute(self): cursor = self.textCursor() @@ -833,4 +833,4 @@ def codeToExecute(self): torem = len(fline) - len(nfline) nlines = [l[torem:] for l in lines] cmd = '\n'.join(nlines) - return cmd + return cmd diff --git a/src/openalea/lpy/gui/lpypreferences.py b/src/openalea/lpy/gui/lpypreferences.py index 22624e61..508a7504 100644 --- a/src/openalea/lpy/gui/lpypreferences.py +++ b/src/openalea/lpy/gui/lpypreferences.py @@ -57,13 +57,13 @@ def show(self): self.widget.profilingNoPlotButton.clicked.connect(self.setProfilingNoPlotMode) # QObject.connect(self.widget.profilingNoPlotButton,SIGNAL('clicked(bool)'),self.setProfilingNoPlotMode) self.widget.integratedViewEdit.setChecked(self.editor.use_own_view3D) self.widget.integratedViewEdit.clicked.connect(self.editor.setIntegratedView3D) # QObject.connect(self.widget.integratedViewEdit,SIGNAL('clicked(bool)'),self.editor.setIntegratedView3D) - if not self.editor.withinterpreter: - self.widget.textOutputBox.setEnabled(False) - else: - self.widget.LPyConsoleButton.setChecked(self.editor.shellwidget.isSelfStdOutRedirection() or self.editor.shellwidget.hasMultipleStdOutRedirection()) - self.widget.LPyConsoleButton.clicked.connect(self.setOutputRedirection) # QObject.connect(self.widget.LPyConsoleButton,SIGNAL('clicked(bool)'),self.setOutputRedirection) - self.widget.systemConsoleButton.setChecked(self.editor.shellwidget.isSysStdOutRedirection() or self.editor.shellwidget.hasMultipleStdOutRedirection()) - self.widget.systemConsoleButton.clicked.connect(self.setOutputRedirection) # QObject.connect(self.widget.systemConsoleButton,SIGNAL('clicked(bool)'),self.setOutputRedirection) + #if not self.editor.withinterpreter: + self.widget.textOutputBox.setEnabled(False) + #else: + # self.widget.LPyConsoleButton.setChecked(self.editor.shellwidget.isSelfStdOutRedirection() or self.editor.shellwidget.hasMultipleStdOutRedirection()) + # self.widget.LPyConsoleButton.clicked.connect(self.setOutputRedirection) # QObject.connect(self.widget.LPyConsoleButton,SIGNAL('clicked(bool)'),self.setOutputRedirection) + # self.widget.systemConsoleButton.setChecked(self.editor.shellwidget.isSysStdOutRedirection() or self.editor.shellwidget.hasMultipleStdOutRedirection()) + # self.widget.systemConsoleButton.clicked.connect(self.setOutputRedirection) # QObject.connect(self.widget.systemConsoleButton,SIGNAL('clicked(bool)'),self.setOutputRedirection) self.dialog.show() def chooseCCompilerPath(self): p = QFileDialog.getExistingDirectory(self.editor, "Choose Compiler Path", self.editor.cCompilerPath ) @@ -88,6 +88,6 @@ def setPofilingButton(self,value): self.widget.profilingFinalPlotButton.setChecked(True) else: self.widget.profilingNoPlotButton.setChecked(True) - def setOutputRedirection(self): - self.editor.shellwidget.setOutputRedirection(self.widget.LPyConsoleButton.isChecked(),self.widget.systemConsoleButton.isChecked()) + #def setOutputRedirection(self): + # self.editor.shellwidget.setOutputRedirection(self.widget.LPyConsoleButton.isChecked(),self.widget.systemConsoleButton.isChecked()) diff --git a/src/openalea/lpy/gui/settings.py b/src/openalea/lpy/gui/settings.py index 122c3993..d127d5e4 100644 --- a/src/openalea/lpy/gui/settings.py +++ b/src/openalea/lpy/gui/settings.py @@ -94,18 +94,18 @@ def restoreState(lpywidget): if fstr != 'default' and f.fromString(fstr): #print 'read font',fstr lpywidget.codeeditor.setEditionFont(f) - settings.endGroup() - settings.beginGroup('stdout') - lc = settings.value('lpyshell',True)=='true' - sc = settings.value('sysconsole',False)=='true' - lpywidget.shellwidget.setOutputRedirection(lc,sc,1) - settings.endGroup() + #settings.endGroup() + #settings.beginGroup('stdout') + #lc = settings.value('lpyshell',True)=='true' + #sc = settings.value('sysconsole',False)=='true' + #lpywidget.shellwidget.setOutputRedirection(lc,sc,1) + #settings.endGroup() - settings.beginGroup('stderr') - lc = settings.value('lpyshell',True)=='true' - sc = settings.value('sysconsole',False)=='true' - lpywidget.shellwidget.setOutputRedirection(lc,sc,2) - settings.endGroup() + #settings.beginGroup('stderr') + #lc = settings.value('lpyshell',True)=='true' + #sc = settings.value('sysconsole',False)=='true' + #lpywidget.shellwidget.setOutputRedirection(lc,sc,2) + #settings.endGroup() settings.beginGroup('edition') lpywidget.codeeditor.replaceTab = settings.value('replaceTab',lpywidget.codeeditor.replaceTab)=='true' @@ -179,19 +179,19 @@ def saveState(lpywidget): else: settings.setValue('editionfont','default') settings.endGroup() - if not lpywidget.interpreter is None: - settings.beginGroup('stdout') - outinshell = lpywidget.shellwidget.hasMultipleStdOutRedirection() or lpywidget.shellwidget.isSelfStdOutRedirection() - outinsys = lpywidget.shellwidget.hasMultipleStdOutRedirection() or lpywidget.shellwidget.isSysStdOutRedirection() - settings.setValue('lpyshell',to_qvariant(outinshell)) - settings.setValue('sysconsole',to_qvariant(outinsys)) - settings.endGroup() - settings.beginGroup('stderr') - errinshell = lpywidget.shellwidget.hasMultipleStdErrRedirection() or lpywidget.shellwidget.isSelfStdErrRedirection() - errinsys = lpywidget.shellwidget.hasMultipleStdErrRedirection() or lpywidget.shellwidget.isSysStdErrRedirection() - settings.setValue('lpyshell',to_qvariant(errinshell)) - settings.setValue('sysconsole',to_qvariant(errinsys)) - settings.endGroup() + # if not lpywidget.interpreter is None: + # settings.beginGroup('stdout') + # outinshell = lpywidget.shellwidget.hasMultipleStdOutRedirection() or lpywidget.shellwidget.isSelfStdOutRedirection() + # outinsys = lpywidget.shellwidget.hasMultipleStdOutRedirection() or lpywidget.shellwidget.isSysStdOutRedirection() + # settings.setValue('lpyshell',to_qvariant(outinshell)) + # settings.setValue('sysconsole',to_qvariant(outinsys)) + # settings.endGroup() + # settings.beginGroup('stderr') + # errinshell = lpywidget.shellwidget.hasMultipleStdErrRedirection() or lpywidget.shellwidget.isSelfStdErrRedirection() + # errinsys = lpywidget.shellwidget.hasMultipleStdErrRedirection() or lpywidget.shellwidget.isSysStdErrRedirection() + # settings.setValue('lpyshell',to_qvariant(errinshell)) + # settings.setValue('sysconsole',to_qvariant(errinsys)) + # settings.endGroup() settings.beginGroup('syntax') settings.setValue('highlighted',to_qvariant(lpywidget.codeeditor.isSyntaxHighLightActivated())) settings.setValue('tabview',to_qvariant(lpywidget.codeeditor.isTabHighLightActivated())) diff --git a/src/openalea/lpy/gui/shared_data.py b/src/openalea/lpy/gui/shared_data.py index 54f6bb97..a3fc4d11 100644 --- a/src/openalea/lpy/gui/shared_data.py +++ b/src/openalea/lpy/gui/shared_data.py @@ -19,17 +19,20 @@ import types import os from os.path import join as pj -from os.path import realpath, isdir, isfile -try: - from path import Path -except ImportError: - try: - from path import path as Path - except ImportError: - try: - from openalea.core.path import path as Path - except ImportError: - from IPython.external.path import path as Path +from os.path import realpath, isdir, isfile, dirname +import glob + + +# try: +# from path import Path +# except ModuleNotFoundError: +# try: +# from path import path as Path +# except ModuleNotFoundError: +# try: +# from openalea.core.path import path as Path +# except ModuleNotFoundError: +# from IPython.utils.path import Path __license__ = "Cecill-C" __revision__ = " $Id: gforge.py 2243 2010-02-08 17:08:47Z cokelaer $ " @@ -83,28 +86,27 @@ def shared_data(package_path, filename=None, pattern=None, return None else: package_path = package_path[0] - package_path = Path(package_path) - ff = package_path / share_path - ff = ff.realpath() + ff = pj(package_path, share_path) + ff = realpath(ff) shared_data_path = None - if ff.isdir(): + if isdir(ff): if filename is None: shared_data_path = ff if pattern: - l = ff.glob(pattern) + l = glob.glob(pj(ff, pattern)) if l: shared_data_path = l else: - ff = ff / filename - ff = ff.realpath() - if ff.isfile(): + ff = pj(ff,filename) + ff = realpath(ff) + if isfile(ff): shared_data_path = ff - if shared_data_path is None and (package_path / '__init__.py').isfile(): - shared_data_path = shared_data(package_path.parent, filename, pattern, + if shared_data_path is None and isfile(pj(package_path, '__init__.py')): + shared_data_path = shared_data(dirname(package_path), filename, pattern, share_path) if shared_data_path is None: - shared_data_path = shared_data(package_path.parent.parent, filename, + shared_data_path = shared_data(dirname(dirname(package_path)), filename, pattern, share_path) return shared_data_path From 8b5309f131821c99d69e9245987c4be8655bc57d Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Wed, 23 Oct 2019 22:09:32 +0200 Subject: [PATCH 54/68] fix pb with text retrieval --- src/openalea/lpy/gui/lpycodeeditor.py | 2 +- src/openalea/lpy/gui/lpydock.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/openalea/lpy/gui/lpycodeeditor.py b/src/openalea/lpy/gui/lpycodeeditor.py index 1d36f5d7..a710f9c7 100644 --- a/src/openalea/lpy/gui/lpycodeeditor.py +++ b/src/openalea/lpy/gui/lpycodeeditor.py @@ -814,7 +814,7 @@ def saveSimuState(self,simu): self.sidebar.saveState(simu) def getCode(self): - return str(str(self.toPlainText()).encode('iso-8859-1','replace')) + return str(self.toPlainText()).encode('iso-8859-1','replace').decode('iso-8859-1') def codeToExecute(self): cursor = self.textCursor() diff --git a/src/openalea/lpy/gui/lpydock.py b/src/openalea/lpy/gui/lpydock.py index e4b637da..2cb35961 100644 --- a/src/openalea/lpy/gui/lpydock.py +++ b/src/openalea/lpy/gui/lpydock.py @@ -97,7 +97,7 @@ def initDocks(lpywidget): else: lpywidget.interpreter = None -async def initShell(lpywidget): +def initShell(lpywidget): lpywidget.interpreter.locals['window'] = lpywidget - await lpywidget.shell.run_code('from openalea.plantgl.all import *') - await lpywidget.shell.run_code('from openalea.lpy import *') + lpywidget.shell.run_code('from openalea.plantgl.all import *') + lpywidget.shell.run_code('from openalea.lpy import *') From 6b1ebef7fb8db095af79427f99f62c0ddf6ab4dc Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Thu, 24 Oct 2019 00:40:16 +0200 Subject: [PATCH 55/68] fix qt text bug --- src/openalea/lpy/gui/simulation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/openalea/lpy/gui/simulation.py b/src/openalea/lpy/gui/simulation.py index d0b5f650..d5815d2d 100644 --- a/src/openalea/lpy/gui/simulation.py +++ b/src/openalea/lpy/gui/simulation.py @@ -197,7 +197,7 @@ def saveState(self): if type(editor) == QLineEdit: self.desc_items[key] = editor.text() else: - self.desc_items[key] = editor.toPlainText().encode('iso-8859-1','replace') + self.desc_items[key] = editor.toPlainText().encode('iso-8859-1','replace').decode('iso-8859-1') #self.functions = self.lpywidget.functionpanel.getFunctions() #self.curves = self.lpywidget.curvepanel.getCurves() self.visualparameters = [(panel.getInfo(),panel.getObjects()) for panel in self.lpywidget.getObjectPanels()] @@ -336,7 +336,7 @@ def saveToFile(self,fname): f.close() def getStrFname(self): - return self.fname.encode('iso-8859-1','replace') + return self.fname.encode('iso-8859-1','replace').decode('iso-8859-1') def open(self,fname): self.setFname(fname) From e4694fa18ca97baa656149dc30683b8d090000e7 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Thu, 24 Oct 2019 01:16:16 +0200 Subject: [PATCH 56/68] fix pb with scalar editor --- src/openalea/lpy/gui/scalareditor.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openalea/lpy/gui/scalareditor.py b/src/openalea/lpy/gui/scalareditor.py index 75d21e75..82256b85 100644 --- a/src/openalea/lpy/gui/scalareditor.py +++ b/src/openalea/lpy/gui/scalareditor.py @@ -261,7 +261,7 @@ def createContextMenu(self): self.editAction = self.menu.addAction("Edit",self.editMetaScalar) def selection(self): items = list(set([i.row() for i in self.selectedIndexes()])) - items.sort(lambda x,y: -cmp(x,y)) + items.sort(key = lambda x : -x) return items def deleteScalars(self): for i in self.selection(): From f5ee358e880436d6bd9e356ea4237fe4e64db995 Mon Sep 17 00:00:00 2001 From: Julien Wintz Date: Sat, 9 Nov 2019 23:19:01 +0100 Subject: [PATCH 57/68] Packaging cont'd. --- CMakeLists.txt | 19 ++++++++++++------- src/cpp/CMakeLists.txt | 2 +- src/wrapper/CMakeLists.txt | 2 +- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e4c12ab5..24869a3c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,25 +15,30 @@ if (MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") endif() + +## ################################################################### +## Dependencies - Python +## ################################################################### + +find_package (Python3 COMPONENTS Interpreter Development) + +include_directories(${Python3_INCLUDE_DIRS}) + # --- Libraries find_package(Threads REQUIRED) -find_package(Python REQUIRED) find_package(Qt5Core CONFIG REQUIRED) find_package(Qt5Concurrent CONFIG REQUIRED) find_package(PlantGL REQUIRED) -# Boost -if (DEFINED CONDA_ENV) - set(BOOST_ROOT ${CONDA_ENV}) - set(BOOST_LIBRARYDIR "${BOOST_ROOT}/lib") -endif() +set(BOOST_ROOT $ENV{CONDA_PREFIX}) +set(BOOST_LIBRARYDIR "${BOOST_ROOT}/lib") set(Boost_NO_SYSTEM_PATHS ON) set(Boost_USE_MULTITHREAD ON) set(Boost_USE_STATIC_LIBS OFF) -find_package(Boost COMPONENTS system ${BOOST_PYTHON_LIB} REQUIRED) +find_package(Boost COMPONENTS system python37 REQUIRED) # --- Include Directories diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 33df4962..2f7f38c1 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(lpy Python3::Python) # Disable Boost Auto-Link target_compile_definitions(lpy PRIVATE BOOST_ALL_NO_LIB) -target_link_libraries(lpy Boost::${BOOST_PYTHON_LIB}) +target_link_libraries(lpy Boost::python37) # --- Preprocessor diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index 54b98d0a..e0aeab06 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -13,7 +13,7 @@ target_link_libraries(__lpy_kernel__ Python3::Python) # Disable Boost Auto-Link target_compile_definitions(__lpy_kernel__ PRIVATE BOOST_ALL_NO_LIB) -target_link_libraries(__lpy_kernel__ Boost::system Boost::${BOOST_PYTHON_LIB}) +target_link_libraries(__lpy_kernel__ Boost::system Boost::python37) # --- Dependencies From f5a17be9d82cef8e8b14a68eb5cbc9f5d9163afd Mon Sep 17 00:00:00 2001 From: Julien Wintz Date: Mon, 11 Nov 2019 16:20:01 +0100 Subject: [PATCH 58/68] Almost there. --- CMakeLists.txt | 16 +++ conda/build.sh | 6 +- conda/meta.yaml | 151 +++++++++++++++++----------- setup.py | 10 +- src/openalea/lpy/__init__.py | 2 +- src/openalea/lpy/gui/compile_ui.py | 5 +- src/openalea/lpy/gui/generate_ui.py | 3 +- 7 files changed, 124 insertions(+), 69 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24869a3c..3b22212f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,22 @@ cmake_minimum_required(VERSION 3.12) project(lpy_project CXX) +# --- Build setup + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CMAKE_SKIP_BUILD_RPATH FALSE) +set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") +set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) + +if("${isSystemDir}" STREQUAL "-1") + set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") +endif("${isSystemDir}" STREQUAL "-1") + # --- CMake Modules set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") diff --git a/conda/build.sh b/conda/build.sh index c5c9546b..e3c8a314 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -1,14 +1,14 @@ #!/bin/bash -# Working Dir +if [[ -d build ]]; then + rm -rf build +fi mkdir build cd build -# Build cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} -DCMAKE_BUILD_TYPE=Release .. make -j${CPU_COUNT} make install -# Install Python Files cd .. $PYTHON setup.py install --prefix=${PREFIX} diff --git a/conda/meta.yaml b/conda/meta.yaml index c079874d..1f630b70 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -1,58 +1,93 @@ -# do not edit the following line. It will be updated automatically -{% set version = "2.7.2" %} - -package: - name: openalea.lpy - version: {{ version }} - -source: - path: .. - -about: - home: https://github.com/openalea/lpy - license: Cecill-C - summary: L-Py is a simulation software that mixes L-systems construction with the Python high-level modeling language. - -build: - preserve_egg_dir: True - number: 1 - features: - - vc9 [win and py27] - - vc14 [win and py37] - track_features: - - vc9 [win and py27] - - vc14 [win and py37] - -requirements: - build: - - python - - openalea.plantgl - - boost - - qt =5 - - pyqt - - openalea.deploy - - setuptools - run: - - python - - openalea.plantgl - - boost - - qt =5 - - pyqt - - ipython - - qtconsole - - pyopengl - - pyqglviewer - - vs2008_runtime [win and py27] - - vs2015_runtime [win and py37] - -test: - requires: - - nose - imports: - - openalea.lpy - source_files: - - test/ - - share/ - commands: - - nosetests -v -I test_predecessor_at_scale.py -I test_ui.py [unix] - - nosetests -v -I test_predecessor_at_scale.py -I test_ui.py -I test_axialtree.py -I test_successor_at_scale.py [win] +{% set version = "2.7.2" %} + +package: + name: openalea.lpy + version: {{ version }} + +source: + path: .. + +about: + home: https://github.com/openalea/lpy + license: Cecill-C + summary: L-Py is a simulation software that mixes L-systems construction with the Python high-level modeling language. + +build: + preserve_egg_dir: True + number: 1 + features: + - vc9 [win and py27] + - vc14 [win and py37] + track_features: + - vc9 [win and py27] + - vc14 [win and py37] + +requirements: + build: + - cmake >=3.2.0 + - binutils_impl_linux-64<2.31.0 # [linux] + - {{ compiler('cxx') }} + - {{ cdt('xorg-x11-proto-devel') }} # [linux] + - {{ cdt('mesa-libgl-devel') }} # [linux] + - {{ cdt('mesa-libegl-devel') }} # [linux] + - {{ cdt('mesa-dri-drivers') }} # [linux] + - {{ cdt('libx11-devel') }} # [linux] + - {{ cdt('libXt-devel') }} # [linux] + - {{ cdt('libICE-devel') }} # [linux] + - {{ cdt('libuuid-devel') }} # [linux] + - {{ cdt('libSM-devel') }} # [linux] + - {{ cdt('libxext-devel') }} # [linux] + - {{ cdt('libxcb') }} # [linux] + - {{ cdt('libxrender-devel') }} # [linux] + - {{ cdt('libxau-devel') }} # [linux] + - {{ cdt('libdrm-devel') }} # [linux] + - {{ cdt('libxcomposite-devel') }} # [linux] + - {{ cdt('libxcursor-devel') }} # [linux] + - {{ cdt('libxi-devel') }} # [linux] + - {{ cdt('libxrandr-devel') }} # [linux] + - {{ cdt('pciutils-devel') }} # [linux] + - {{ cdt('libxscrnsaver-devel') }} # [linux] + - {{ cdt('libxtst-devel') }} # [linux] + - {{ cdt('libselinux-devel') }} # [linux] + - {{ cdt('libxdamage') }} # [linux] + - {{ cdt('libxdamage-devel') }} # [linux] + - {{ cdt('libxfixes') }} # [linux] + - {{ cdt('libxfixes-devel') }} # [linux] + - {{ cdt('libxxf86vm') }} # [linux] + - python=3.7 + - qt >=5.9.0 + - boost-cpp + - py-boost + - setuptools +# - openalea.deploy + - cmake >=3.12.0 + - openalea.plantgl + - pyqt + host: + - openalea.plantgl + - boost-cpp + - python=3.7 + - py-boost + run: + - python=3.7 + - openalea.plantgl + - boost-cpp + - qt >=5.9.0 + - pyqt + - ipython +# - qtconsole + - pyopengl +# - pyqglviewer + - vs2008_runtime [win and py27] + - vs2015_runtime [win and py37] +# test: +# requires: +# - nose +# imports: +# - openalea.lpy +# source_files: +# - test/ +# - share/ +# commands: +# - nosetests -v -I test_predecessor_at_scale.py -I test_ui.py [unix] +# - nosetests -v -I test_predecessor_at_scale.py -I test_ui.py -I test_axialtree.py -I test_successor_at_scale.py [win] diff --git a/setup.py b/setup.py index 4c5e6af6..31521140 100644 --- a/setup.py +++ b/setup.py @@ -94,12 +94,12 @@ def compile_interface(): "wralea": ["lpy = openalea.lpy_wralea",], 'gui_scripts': ['lpy = openalea.lpy.gui.lpystudio:main',], 'console_scripts': ['cpfg2lpy = openalea.lpy.cpfg_compat.cpfg2lpy:main',], - }, + } # Dependencies - setup_requires = ['openalea.deploy'], - dependency_links = ['http://openalea.gforge.inria.fr/pi'], - install_requires = install_requires, + # setup_requires = ['openalea.deploy'], + # dependency_links = ['http://openalea.gforge.inria.fr/pi'], + # install_requires = install_requires - pylint_packages = ['src/openalea/lpy/gui'] + # pylint_packages = ['src/openalea/lpy/gui'] ) diff --git a/src/openalea/lpy/__init__.py b/src/openalea/lpy/__init__.py index 30aba78e..d40c560d 100644 --- a/src/openalea/lpy/__init__.py +++ b/src/openalea/lpy/__init__.py @@ -1,5 +1,5 @@ from .__version__ import * -from .__lpy_kernel__ import * +# from .__lpy_kernel__ import * from .parameterset import * def __mod_getattr__(self,name): diff --git a/src/openalea/lpy/gui/compile_ui.py b/src/openalea/lpy/gui/compile_ui.py index 9f4b577f..b15c5de2 100644 --- a/src/openalea/lpy/gui/compile_ui.py +++ b/src/openalea/lpy/gui/compile_ui.py @@ -1,5 +1,8 @@ -from openalea.plantgl.gui.qt import qt +print("DEBUG ===== 1") +# from openalea.plantgl.gui.qt import qt +print("DEBUG ===== 2") from openalea.plantgl.gui.qt.uic import compileUi, compile_args +print("DEBUG ===== 3") import os import sys diff --git a/src/openalea/lpy/gui/generate_ui.py b/src/openalea/lpy/gui/generate_ui.py index 167bc1a0..893472e3 100644 --- a/src/openalea/lpy/gui/generate_ui.py +++ b/src/openalea/lpy/gui/generate_ui.py @@ -6,7 +6,8 @@ py2exe_release = False if not py2exe_release: - import openalea.lpy.gui.compile_ui as ui + import compile_ui as ui + print("Generate Ui - imported") import os.path ldir = os.path.dirname(__file__) print("Generate Ui") From 822f049688311deabb95a5c0af074c437bb36967 Mon Sep 17 00:00:00 2001 From: Julien Wintz Date: Mon, 11 Nov 2019 17:46:09 +0100 Subject: [PATCH 59/68] Packaging continued. --- conda/build.sh | 2 ++ conda/meta.yaml | 38 ++++++++++++++++++++++++------------ setup.py | 5 +++++ src/openalea/lpy/__init__.py | 2 +- 4 files changed, 34 insertions(+), 13 deletions(-) diff --git a/conda/build.sh b/conda/build.sh index e3c8a314..541e05f5 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -11,4 +11,6 @@ make -j${CPU_COUNT} make install cd .. +sed -i '' '1,1 s/^/#/' $CONDA_PREFIX/lib/python3.7/site-packages/openalea/plantgl/gui/__init__.py +sed -i '' '1,1 s/^/#/' $BUILD_PREFIX/lib/python3.7/site-packages/openalea/plantgl/gui/__init__.py $PYTHON setup.py install --prefix=${PREFIX} diff --git a/conda/meta.yaml b/conda/meta.yaml index 1f630b70..2e958c01 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -21,7 +21,6 @@ build: track_features: - vc9 [win and py27] - vc14 [win and py37] - requirements: build: - cmake >=3.2.0 @@ -68,18 +67,33 @@ requirements: - boost-cpp - python=3.7 - py-boost + - gmp [unix] + # - cgal [unix] + - qhull + - ann + - eigen + - pyqt >=5.6.0 + - pyopengl + - scipy + - matplotlib run: - - python=3.7 - - openalea.plantgl - - boost-cpp - - qt >=5.9.0 - - pyqt - - ipython -# - qtconsole - - pyopengl -# - pyqglviewer - - vs2008_runtime [win and py27] - - vs2015_runtime [win and py37] + - python=3.7 + - openalea.plantgl + - boost-cpp + - qt >=5.9.0 + - gmp [unix] + # - cgal [unix] + - qhull + - ann + - eigen + - pyqt >=5.6.0 + - ipython + # - qtconsole + - py-boost + - pyopengl + # - pyqglviewer + - vs2008_runtime [win and py27] + - vs2015_runtime [win and py37] # test: # requires: # - nose diff --git a/setup.py b/setup.py index 31521140..0fc9d982 100644 --- a/setup.py +++ b/setup.py @@ -51,9 +51,14 @@ def compile_interface(): cwd = os.getcwd() os.chdir(pj('src','openalea','lpy','gui')) + print("HERE - 1") sys.path = ['']+sys.path + print(sys.path) + print("HERE - 2") import generate_ui + print("HERE - 3") os.chdir(cwd) + print("HERE - 4") compile_interface() install_requires = [] diff --git a/src/openalea/lpy/__init__.py b/src/openalea/lpy/__init__.py index d40c560d..30aba78e 100644 --- a/src/openalea/lpy/__init__.py +++ b/src/openalea/lpy/__init__.py @@ -1,5 +1,5 @@ from .__version__ import * -# from .__lpy_kernel__ import * +from .__lpy_kernel__ import * from .parameterset import * def __mod_getattr__(self,name): From de6988aa389a8d27d2f766ff4aa9bda90e49e6b4 Mon Sep 17 00:00:00 2001 From: Julien Wintz Date: Mon, 11 Nov 2019 22:20:35 +0100 Subject: [PATCH 60/68] Packaging continued. --- conda/build.sh | 1 + options_conda_build.py | 12 ------------ src/openalea/lpy/gui/generate_ui.py | 1 + 3 files changed, 2 insertions(+), 12 deletions(-) delete mode 100644 options_conda_build.py diff --git a/conda/build.sh b/conda/build.sh index 541e05f5..4c9d456f 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -13,4 +13,5 @@ make install cd .. sed -i '' '1,1 s/^/#/' $CONDA_PREFIX/lib/python3.7/site-packages/openalea/plantgl/gui/__init__.py sed -i '' '1,1 s/^/#/' $BUILD_PREFIX/lib/python3.7/site-packages/openalea/plantgl/gui/__init__.py +sed -i '' '1,1 s/^/#/' $PREFIX/lib/python3.7/site-packages/openalea/plantgl/gui/__init__.py $PYTHON setup.py install --prefix=${PREFIX} diff --git a/options_conda_build.py b/options_conda_build.py deleted file mode 100644 index f9ca0502..00000000 --- a/options_conda_build.py +++ /dev/null @@ -1,12 +0,0 @@ -import os -pj=os.path.join - -PREFIX = os.path.abspath(os.environ.get('PREFIX')) -SRC_DIR = os.environ.get('SRC_DIR') - -vplants_plantgl_include = pj(PREFIX,'include') -vplants_plantgl_lib = pj(PREFIX,'lib') - -if 'CPU_COUNT' in os.environ: - num_jobs = os.environ['CPU_COUNT'] - diff --git a/src/openalea/lpy/gui/generate_ui.py b/src/openalea/lpy/gui/generate_ui.py index 893472e3..54488968 100644 --- a/src/openalea/lpy/gui/generate_ui.py +++ b/src/openalea/lpy/gui/generate_ui.py @@ -7,6 +7,7 @@ if not py2exe_release: import compile_ui as ui +# from . import compile_ui as ui print("Generate Ui - imported") import os.path ldir = os.path.dirname(__file__) From f49b6a9effe9a88269f24508baa478e39010e289 Mon Sep 17 00:00:00 2001 From: Julien Wintz Date: Mon, 11 Nov 2019 23:55:55 +0100 Subject: [PATCH 61/68] Packaging continued. --- conda/meta.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conda/meta.yaml b/conda/meta.yaml index 2e958c01..c4506f50 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -62,6 +62,7 @@ requirements: - cmake >=3.12.0 - openalea.plantgl - pyqt + - qtconsole host: - openalea.plantgl - boost-cpp @@ -92,6 +93,7 @@ requirements: - py-boost - pyopengl # - pyqglviewer + - qtconsole - vs2008_runtime [win and py27] - vs2015_runtime [win and py37] # test: From b696e788b487fc7a76888d66db0e789ecc88e1b8 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Mon, 18 Nov 2019 13:45:32 +0100 Subject: [PATCH 62/68] fix bug with python 3 port --- share/examples/dynamicprofile.lpy | 2 +- share/examples/ex_lsystem5.lpy | 2 +- src/cpp/error.cpp | 7 +-- src/cpp/lpy_parser.cpp | 11 ++++- src/cpp/lsyscontext.cpp | 36 ++++++++------- src/openalea/lpy/__init__.py | 1 + src/wrapper/export_axialtree.cpp | 3 +- src/wrapper/export_lstring.h | 38 +++++++++++++++- test/lpytest/import_with_module_in_name.lpy | 2 +- test/lpytest/multiscalexmatching.lpy | 11 ++--- test/lpytest/multiscalexmatching2.lpy | 6 +-- test/lpytest/nodeposition2.lpy | 4 +- test/lpytest/test_components.lpy | 2 +- test/lpytest/test_concavepoly.lpy | 6 +-- test/lpytest/test_consider_bracket.lpy | 2 +- test/lpytest/test_deflateargs.lpy | 4 +- test/lpytest/test_deflatekwd.lpy | 4 +- test/lpytest/test_frame.lpy | 2 +- test/lpytest/test_functionalaxiom.lpy | 2 +- test/lpytest/test_getmod.lpy | 4 +- test/lpytest/test_getmod_sons.lpy | 2 +- test/lpytest/test_in_left_context.lpy | 3 +- test/lpytest/test_in_right_context.lpy | 6 +-- test/lpytest/test_inheritance.lpy | 6 +-- test/lpytest/test_inheritance_simple.lpy | 4 +- test/lpytest/test_lateral_msmatch.lpy | 2 +- test/lpytest/test_leftcontext.lpy | 2 +- test/lpytest/test_lstring_change.lpy | 2 +- test/lpytest/test_lstring_change2.lpy | 2 +- test/lpytest/test_lstring_change3.lpy | 2 +- test/lpytest/test_lstring_pushpop.lpy | 9 ++-- test/lpytest/test_ms_flow.lpy | 8 ++-- test/lpytest/test_multiple_inleftcontext.lpy | 4 +- test/lpytest/test_newleftcontext.lpy | 2 +- test/lpytest/test_newrightcontext.lpy | 2 +- .../lpytest/test_parametric_inleftcontext.lpy | 2 +- test/lpytest/test_path.lpy | 6 +-- test/lpytest/test_path4.lpy | 2 +- test/lpytest/test_profile.lpy | 2 +- test/lpytest/test_repr.lpy | 4 +- test/lpytest/test_scalars.lpy | 4 +- test/lpytest/test_shape_ids.lpy | 2 +- test/lpytest/test_startendinterpretation.lpy | 2 +- test/lpytest/test_stringleftcontext.lpy | 2 +- test/test_axial_matching.lpy | 2 +- test/test_axial_msmatch.lpy | 2 +- test/test_dynrules.py | 2 +- test/test_group.lpy | 2 +- test/test_kwd.lpy | 42 +++++++++--------- test/test_kwd2.lpy | 44 +++++++++---------- test/test_perf.lpy | 2 +- test/test_simple_matching.lpy | 2 +- test/test_stringmatching.py | 2 +- test/test_ui.py | 2 +- 54 files changed, 192 insertions(+), 141 deletions(-) diff --git a/share/examples/dynamicprofile.lpy b/share/examples/dynamicprofile.lpy index a981c8b5..2d9d0e19 100644 --- a/share/examples/dynamicprofile.lpy +++ b/share/examples/dynamicprofile.lpy @@ -10,7 +10,7 @@ p = profile.deepcopy() curves = [(n,v) for n,v in globals().items() if 'axis' in n and type(v) == NurbsCurve2D ] for n,v in curves: v.name = n curves = [v for n,v in curves] -curves.sort(lambda x,y : cmp(x.name,y.name)) +curves.sort(key = lambda x : x.name) #time between each curve diff --git a/share/examples/ex_lsystem5.lpy b/share/examples/ex_lsystem5.lpy index a31a3b56..5139ad57 100644 --- a/share/examples/ex_lsystem5.lpy +++ b/share/examples/ex_lsystem5.lpy @@ -8,7 +8,7 @@ derivation length: 3 production: A : - for i in xrange(100): + for i in range(100): nproduce K(1,i) K(x,i)K(y,j) << K(z,m) : diff --git a/src/cpp/error.cpp b/src/cpp/error.cpp index 4836cad8..a2e29db8 100644 --- a/src/cpp/error.cpp +++ b/src/cpp/error.cpp @@ -63,9 +63,10 @@ LPY_API void LsysSyntaxError(const std::string& error) LPY_API void LsysSyntaxError(const std::string& error,const std::string& filename, int lineno) { if (!filename.empty() || lineno >=0){ - std::stringstream stream; - stream << (filename.empty()?"":filename) << ':' << lineno << ':' << error; - PyErr_SetString(PyExc_SyntaxError, stream.str().c_str()); + // std::stringstream stream; + // stream << (filename.empty()?"":filename) << ':' << lineno << ':' << error; + PyErr_SetString(PyExc_SyntaxError, error.c_str()); + PyErr_SyntaxLocation(filename.c_str(), lineno); boost::python::throw_error_already_set(); } else LsysSyntaxError(error); diff --git a/src/cpp/lpy_parser.cpp b/src/cpp/lpy_parser.cpp index b4db31f4..8c13a5b5 100644 --- a/src/cpp/lpy_parser.cpp +++ b/src/cpp/lpy_parser.cpp @@ -985,7 +985,16 @@ Lsystem::set( const std::string& _rules , std::string * pycode, code+='\n'+addedcode; if(pycode) *pycode = code; // printf("%s",code.c_str()); - __context.compile(code); + try { + __context.compile(code); + } + catch (const error_already_set& e) { + if (PyErr_ExceptionMatches(PyExc_SyntaxError)){ + // PyErr_SyntaxLocation(getFilename().c_str(), 0); + } + boost::python::throw_error_already_set(); + // boost::python::handle_exception(); + } __importPyFunctions(); if (__context.hasObject(LsysContext::AxiomVariable)){ if (!axiom_is_function){ diff --git a/src/cpp/lsyscontext.cpp b/src/cpp/lsyscontext.cpp index 41bb122c..ac14f306 100644 --- a/src/cpp/lsyscontext.cpp +++ b/src/cpp/lsyscontext.cpp @@ -922,37 +922,39 @@ LsysContext::func(const std::string& funcname){ return object(); } +size_t func_nb_args(boost::python::object function) { + char * attrname = +#if PY_MAJOR_VERSION == 2 + "func_code" +#else + "__code__" +#endif + ; + try { + return extract(function.attr(attrname).attr("co_argcount"))(); + } + catch (...) { PyErr_Clear(); return 0; } +} + void LsysContext::check_init_functions() { if (hasObject("StartEach")) { - try { - __nbargs_of_starteach = extract(getObject("StartEach").attr("func_code").attr("co_argcount"))(); - } - catch (...) { PyErr_Clear(); __nbargs_of_starteach = 0; } - } + __nbargs_of_starteach = func_nb_args(getObject("StartEach")); + } else __nbargs_of_starteach = 0; if (hasObject("Start")) { - try { - __nbargs_of_start = extract(getObject("Start").attr("func_code").attr("co_argcount"))(); - } - catch (...) { PyErr_Clear(); __nbargs_of_start = 0; } + __nbargs_of_start = func_nb_args(getObject("Start")); } else __nbargs_of_start = 0; if (hasObject("EndEach")) { - try { - __nbargs_of_endeach = extract(getObject("EndEach").attr("func_code").attr("co_argcount"))(); - } - catch (...) { PyErr_Clear(); __nbargs_of_endeach = 0; } + __nbargs_of_endeach = func_nb_args(getObject("EndEach")); } else __nbargs_of_endeach = 0; if (hasObject("End")) { - try { - __nbargs_of_end = extract(getObject("End").attr("func_code").attr("co_argcount"))(); - } - catch (...) { PyErr_Clear(); __nbargs_of_end = 0; } + __nbargs_of_end = func_nb_args(getObject("End")); } else __nbargs_of_end = 0; } diff --git a/src/openalea/lpy/__init__.py b/src/openalea/lpy/__init__.py index 30aba78e..99cdead6 100644 --- a/src/openalea/lpy/__init__.py +++ b/src/openalea/lpy/__init__.py @@ -125,6 +125,7 @@ def __next__(self): self.axiom = self.lsystem.derive(self.axiom,self.currentstep,1) self.currentstep += 1 return self.axiom + next = __next__ def __iter__(self): return self diff --git a/src/wrapper/export_axialtree.cpp b/src/wrapper/export_axialtree.cpp index 4c530b00..b24af358 100644 --- a/src/wrapper/export_axialtree.cpp +++ b/src/wrapper/export_axialtree.cpp @@ -285,7 +285,8 @@ void export_AxialTree() { class_ ("AxialTreeIterator", init("AxialTreeIterator(AxialTree)")) - .def("next",&PyAxialTreeIterator::next,return_internal_reference<>(), (bp::arg("onlyConsidered")=false)) + .def("next",&PyAxialTreeIterator::next,return_internal_reference<>(), (bp::arg("onlyConsidered")=false)) + .def("__next__",&PyAxialTreeIterator::next,return_internal_reference<>(), (bp::arg("onlyConsidered")=false)) .def("current",&PyAxialTreeIterator::currentValue,return_internal_reference<>()) .def("__length_hint__",&PyAxialTreeIterator::size) .def( "__iter__", &py_ati_iter ) diff --git a/src/wrapper/export_lstring.h b/src/wrapper/export_lstring.h index 5b971893..29423978 100644 --- a/src/wrapper/export_lstring.h +++ b/src/wrapper/export_lstring.h @@ -48,6 +48,22 @@ LString& py_lstring_imult(LString* lstring, int i) { return *lstring; } +template +size_t normedindex(LString * tree, boost::python::object pos, bool start = true) +{ + int ipos = 0; + size_t len = tree->size(); + if (pos == boost::python::object()) { + ipos = (start?0:len); + } + else { + ipos = boost::python::extract(pos)(); + } + while (ipos < 0) ipos += len; + while (ipos > len) ipos -= len; + return (size_t)ipos; +} + template boost::python::object iter_to_int(LString * tree, typename LString::const_iterator pos) @@ -184,6 +200,24 @@ void py_prepend_lstring(LString * first, const std::string& pattern) { first->pr template void py_insert_lstring(LString * first, int i, const std::string& pattern) { first->insertItemAt(i,LString(pattern)); } + +template +boost::python::object py_getslice(LString * tree, boost::python::slice sl) +{ + size_t start = normedindex(tree,sl.start()); + size_t stop = normedindex(tree,sl.stop(), false); + LString result = tree->template getRange(start, stop); + return boost::python::object(result); +} + +template +void py_delslice(LString * tree, boost::python::slice sl) +{ + size_t start = normedindex(tree,sl.start()); + size_t stop = normedindex(tree,sl.stop(), false); + tree->removeRange(start, stop); +} + template class lstring_func : public boost::python::def_visitor > { @@ -200,10 +234,10 @@ class lstring_func : public boost::python::def_visitor > .def("clear", &LString::clear) .def("__len__", &LString::size) .def("__getitem__",&LString::getItemAt, boost::python::return_internal_reference<1>()) + .def("__getitem__",&py_getslice) .def("__setitem__",&LString::setItemAt) .def("__delitem__",&LString::removeItemAt) - .def("__getslice__",(LString (LString::*)(size_t,size_t)const)&LString::getRange) - .def("__delslice__",&LString::removeRange) + .def("__delitem__",&py_delslice) .def("append",(void(LString::*)(const Module&))&LString::append) .def("append",(void(LString::*)(const LString&))&LString::append) .def("append",&py_append_lstring) diff --git a/test/lpytest/import_with_module_in_name.lpy b/test/lpytest/import_with_module_in_name.lpy index 484bb1d0..59aab0ab 100644 --- a/test/lpytest/import_with_module_in_name.lpy +++ b/test/lpytest/import_with_module_in_name.lpy @@ -1,6 +1,6 @@ import os fname = 'a_module2.py' -f = file(fname,'w') +f = open(fname,'w') f.write('def test(): pass') f.close() diff --git a/test/lpytest/multiscalexmatching.lpy b/test/lpytest/multiscalexmatching.lpy index 5fc4e371..ce3516c5 100644 --- a/test/lpytest/multiscalexmatching.lpy +++ b/test/lpytest/multiscalexmatching.lpy @@ -11,8 +11,9 @@ def StartEach(): multiscalemode = context().options.find('String matching').currentValue() in ['As Multiscale AxialTree','As Multi-level AxialTree'] resinf = [0,3] ressup = [5 if multiscalemode else 3,2] - print context().options.find('String matching').currentValue() + print(context().options.find('String matching').currentValue()) context().options.find('String matching').activateSelection() + print 'toto' @@ -37,8 +38,8 @@ A > x($B(b)): if (len(b) == res): warnings.warn('Multiscale context and Regular Expression not compatible') else: - print 'Expect : A >', 'B'*res - print 'Found : A >', 'B'*len(b) + print('Expect : A >', 'B'*res) + print('Found : A >', 'B'*len(b)) assert len(b) == res x($B(b)) < A: @@ -48,8 +49,8 @@ x($B(b)) < A: if (len(b) == res): warnings.warn('Multiscale context and Regular Expression not compatible') else: - print 'Expect : ', 'B'*res ,' < A' - print 'Found : ', 'B'*len(b) ,' < A' + print('Expect : ', 'B'*res ,' < A') + print('Found : ', 'B'*len(b) ,' < A') assert len(b) == res interpretation: diff --git a/test/lpytest/multiscalexmatching2.lpy b/test/lpytest/multiscalexmatching2.lpy index c0711687..f7ffac19 100644 --- a/test/lpytest/multiscalexmatching2.lpy +++ b/test/lpytest/multiscalexmatching2.lpy @@ -8,7 +8,7 @@ def StartEach(): multiscalemode = context().options.find('String matching').currentValue() in ['As Multiscale AxialTree','As Multi-level AxialTree'] resinf = [0,3] ressup = [5 if multiscalemode else 3,2] - print context().options.find('String matching').currentValue() + print(context().options.find('String matching').currentValue()) context().options.find('String matching').activateSelection() def End(): @@ -31,8 +31,8 @@ A : while InLeftContext(B) : nbleftB += 1 resL = resinf.pop(0) - print 'Expect :', 'B'* resL,'< A >' ,'B'*resR - print 'Found :', 'B'* nbleftB,'< A >' ,'B'*nbrightB + print('Expect :', 'B'* resL,'< A >' ,'B'*resR) + print('Found :', 'B'* nbleftB,'< A >' ,'B'*nbrightB) assert nbrightB == resR assert nbleftB == resL diff --git a/test/lpytest/nodeposition2.lpy b/test/lpytest/nodeposition2.lpy index 284b5e17..a0870cc3 100644 --- a/test/lpytest/nodeposition2.lpy +++ b/test/lpytest/nodeposition2.lpy @@ -5,13 +5,13 @@ positions = [] def StartEach(): useGroup(getGroup()%2 +1) - print 'group',getGroup() + print('group',getGroup()) global positions positions = [] def EndEach(): if getGroup() == 2: - print len(positions) + print(len(positions)) Axiom: A diff --git a/test/lpytest/test_components.lpy b/test/lpytest/test_components.lpy index 05e0a025..d7eb64d6 100644 --- a/test/lpytest/test_components.lpy +++ b/test/lpytest/test_components.lpy @@ -6,7 +6,7 @@ Axiom: A(3) B [ B A(1) B ] B A(2) B B derivation length: 1 production: $A(a): - print a.components_at_scale(2) + print(a.components_at_scale(2)) assert len(a.components()) == a.nbcomponents assert len(a.components_at_scale(2)) == a.nbcomponents diff --git a/test/lpytest/test_concavepoly.lpy b/test/lpytest/test_concavepoly.lpy index 51e83c10..b4073546 100644 --- a/test/lpytest/test_concavepoly.lpy +++ b/test/lpytest/test_concavepoly.lpy @@ -1,12 +1,12 @@ from openalea.plantgl.all import pgl_support_extension def End(lstring,lscene): - print len(lscene) + print(len(lscene)) faceset = lscene[-1].geometry - print map(list,faceset.indexList) + print(list(map(list,faceset.indexList))) # assert faceset.indexList == [[1,2,3],[3,4,5],[0,1,3,5],[0,5,6,7],[7,8,9],[9,10,11],[7,9,11],[0,7,11]] if pgl_support_extension('CGAL'): - indexList = map(list,faceset.indexList) + indexList = list(map(list,faceset.indexList)) assert indexList == [[0,11,10],[10,9,8],[0,10,8,7,6],[0,6,5,4],[0,4,3,2],[0,2,1]] or indexList == [[10, 9, 8], [0, 11, 10, 8], [0, 8, 7, 6], [0, 6, 5, 4], [0, 4, 3, 2], [0, 2, 1]] diff --git a/test/lpytest/test_consider_bracket.lpy b/test/lpytest/test_consider_bracket.lpy index d5ff0f4d..786bf165 100644 --- a/test/lpytest/test_consider_bracket.lpy +++ b/test/lpytest/test_consider_bracket.lpy @@ -1,7 +1,7 @@ from openalea.plantgl.all import * def EndEach(lstring): - print lstring + print(lstring) assert lstring == Lstring("M(4) [ M(1) ] M(2) M(1)") backward() diff --git a/test/lpytest/test_deflateargs.lpy b/test/lpytest/test_deflateargs.lpy index 1a66cf4f..3e60d63a 100644 --- a/test/lpytest/test_deflateargs.lpy +++ b/test/lpytest/test_deflateargs.lpy @@ -1,5 +1,5 @@ def End(lstring): - print lstring, type(lstring[0][0]) + print(lstring, type(lstring[0][0])) assert lstring == Lstring('A(0,1)') module A(x,y) @@ -10,7 +10,7 @@ derivation length: 1 production: A(*p) : - print p + print(p) p[1] += 1 produce A(*p) diff --git a/test/lpytest/test_deflatekwd.lpy b/test/lpytest/test_deflatekwd.lpy index be8f5089..48768ffb 100644 --- a/test/lpytest/test_deflatekwd.lpy +++ b/test/lpytest/test_deflatekwd.lpy @@ -1,5 +1,5 @@ def End(lstring): - print lstring, type(lstring[0][0]) + print(lstring, type(lstring[0][0])) assert lstring == Lstring('A(0,1)') module A(x,y) @@ -10,7 +10,7 @@ derivation length: 1 production: A(**p) : - print p + print(p) p['y'] += 1 #del p['x'] #p['z'] = 0 diff --git a/test/lpytest/test_frame.lpy b/test/lpytest/test_frame.lpy index 69aee5dd..bd7c3dca 100644 --- a/test/lpytest/test_frame.lpy +++ b/test/lpytest/test_frame.lpy @@ -14,7 +14,7 @@ production: a > ?F(*arg): if getIterationNb() % 10 == 0: - print arg + print(arg) homomorphism: a --> Frame(2,0.8,1.5) diff --git a/test/lpytest/test_functionalaxiom.lpy b/test/lpytest/test_functionalaxiom.lpy index fabecd77..0f8c9ed0 100644 --- a/test/lpytest/test_functionalaxiom.lpy +++ b/test/lpytest/test_functionalaxiom.lpy @@ -3,7 +3,7 @@ def End(lstring): assert len(lstring) == 20 Axiom: - for i in xrange(10): + for i in range(10): nproduce F f derivation length: 1 diff --git a/test/lpytest/test_getmod.lpy b/test/lpytest/test_getmod.lpy index 45daf89a..6885ebff 100644 --- a/test/lpytest/test_getmod.lpy +++ b/test/lpytest/test_getmod.lpy @@ -6,7 +6,7 @@ def StartEach(): def EndEach(lstring): global result - print result + print(result) assert result == { 'A' : (0, '[B]'), 'B' : (1, 'None') } assert lstring == 'AAAB' @@ -22,7 +22,7 @@ production: $A(a) : global result assert a.name in 'AB' - print a.name,'sons[',a.position(),']=',a.sons() + print(a.name,'sons[',a.position(),']=',a.sons()) result[a.name] = (a.position(),str(a.sons())) produce A $a diff --git a/test/lpytest/test_getmod_sons.lpy b/test/lpytest/test_getmod_sons.lpy index 897b278c..596a8da0 100644 --- a/test/lpytest/test_getmod_sons.lpy +++ b/test/lpytest/test_getmod_sons.lpy @@ -12,7 +12,7 @@ production: $A(a) : assert a.name in 'AB' - print a.name,'sons[',a.position(),']=' , a.sons() + print(a.name,'sons[',a.position(),']=' , a.sons()) produce new('A' if a.name == 'B' else 'B')[+$a]$a diff --git a/test/lpytest/test_in_left_context.lpy b/test/lpytest/test_in_left_context.lpy index 5c277328..77ac8576 100644 --- a/test/lpytest/test_in_left_context.lpy +++ b/test/lpytest/test_in_left_context.lpy @@ -9,7 +9,8 @@ B : assert InLeftContext(G) == False assert InLeftContext(D) == True produce C - else: raise ValueError('inLeftContext') + else: + raise ValueError('inLeftContext') interpretation: diff --git a/test/lpytest/test_in_right_context.lpy b/test/lpytest/test_in_right_context.lpy index 4885ef95..bbb7ca3f 100644 --- a/test/lpytest/test_in_right_context.lpy +++ b/test/lpytest/test_in_right_context.lpy @@ -5,12 +5,12 @@ production: B : params = {} - print 'A' + print('A') if inRightContext('A(x)', params) : assert params['x'] == 1 - print 'G' + print('G') assert InRightContext(G) == False - print 'D' + print('D') assert InRightContext(D) == True produce C else: diff --git a/test/lpytest/test_inheritance.lpy b/test/lpytest/test_inheritance.lpy index d5323e10..8d87b4c6 100644 --- a/test/lpytest/test_inheritance.lpy +++ b/test/lpytest/test_inheritance.lpy @@ -10,13 +10,13 @@ derivation length: 1 production: A(*args): - print 'A(',args,')' + print('A(',args,')') B(*args): - print 'B(',args,')' + print('B(',args,')') C(*args): - print 'C(',args,')' + print('C(',args,')') interpretation: diff --git a/test/lpytest/test_inheritance_simple.lpy b/test/lpytest/test_inheritance_simple.lpy index 4c99ea27..7f053724 100644 --- a/test/lpytest/test_inheritance_simple.lpy +++ b/test/lpytest/test_inheritance_simple.lpy @@ -9,10 +9,10 @@ derivation length: 1 production: A: - print 'Find A' + print('Find A') *(name): - print 'find',name + print('find',name) interpretation: diff --git a/test/lpytest/test_lateral_msmatch.lpy b/test/lpytest/test_lateral_msmatch.lpy index 8dd934e0..65ab5d0f 100644 --- a/test/lpytest/test_lateral_msmatch.lpy +++ b/test/lpytest/test_lateral_msmatch.lpy @@ -7,7 +7,7 @@ derivation length: 1 production: A(x) > [[A(y)]] : - print x,y + print(x,y) homomorphism: diff --git a/test/lpytest/test_leftcontext.lpy b/test/lpytest/test_leftcontext.lpy index 1a4e3a16..0a144348 100644 --- a/test/lpytest/test_leftcontext.lpy +++ b/test/lpytest/test_leftcontext.lpy @@ -6,7 +6,7 @@ derivation length: 1 production: A < C : - print 'matched' + print('matched') interpretation: diff --git a/test/lpytest/test_lstring_change.lpy b/test/lpytest/test_lstring_change.lpy index 85366c06..64c52633 100644 --- a/test/lpytest/test_lstring_change.lpy +++ b/test/lpytest/test_lstring_change.lpy @@ -10,7 +10,7 @@ def EndEach(): def End(lstring): - print 'End', len(lstring), lstring + print('End', len(lstring), lstring) assert len(lstring) == 1 Axiom: A diff --git a/test/lpytest/test_lstring_change2.lpy b/test/lpytest/test_lstring_change2.lpy index 360925ab..6e3066e2 100644 --- a/test/lpytest/test_lstring_change2.lpy +++ b/test/lpytest/test_lstring_change2.lpy @@ -3,7 +3,7 @@ def EndEach(lstring): lstring[0][0] = 2 def End(lstring): - print 'End', lstring + print('End', lstring) assert lstring[0][0] == 2 Axiom: A(1) diff --git a/test/lpytest/test_lstring_change3.lpy b/test/lpytest/test_lstring_change3.lpy index 7da47d16..80b7a586 100644 --- a/test/lpytest/test_lstring_change3.lpy +++ b/test/lpytest/test_lstring_change3.lpy @@ -4,7 +4,7 @@ iterbackup = 1 def End(lstring): - print 'End', len(lstring), lstring + print('End', len(lstring), lstring) assert len(lstring) == 1 Axiom: A diff --git a/test/lpytest/test_lstring_pushpop.lpy b/test/lpytest/test_lstring_pushpop.lpy index e2b908b4..fe931333 100644 --- a/test/lpytest/test_lstring_pushpop.lpy +++ b/test/lpytest/test_lstring_pushpop.lpy @@ -1,5 +1,6 @@ +import importlib import openalea.lpy.__lpyfuture__ -reload (openalea.lpy.__lpyfuture__) +importlib.reload (openalea.lpy.__lpyfuture__) from openalea.lpy.__lpyfuture__ import * iterbackupcreation = 1 @@ -8,13 +9,13 @@ iterbackupretrieval = 9 @enable_string_pushpop def EndEach(lstring): if getIterationNb() == iterbackupcreation: - print 'push', lstring + print('push', lstring) pushString('test') elif getIterationNb() == iterbackupretrieval: - print 'pop', popString('test'), 'instead of',lstring + print('pop', popString('test'), 'instead of',lstring) def End(lstring): - print 'End', len(lstring), lstring + print('End', len(lstring), lstring) assert len(lstring) == 1 Axiom: A diff --git a/test/lpytest/test_ms_flow.lpy b/test/lpytest/test_ms_flow.lpy index 6924e227..cd9bd58e 100644 --- a/test/lpytest/test_ms_flow.lpy +++ b/test/lpytest/test_ms_flow.lpy @@ -9,7 +9,7 @@ unitwidth = 0.3 nodewidth = 0.4 def EndEach(lstring): - #print lstring + #print(lstring) pass Axiom: _(nodewidth)-(90)G @@ -21,11 +21,11 @@ decomposition: G : nproduce ELU(1)I(1) - for i in xrange(nbINode-1): + for i in range(nbINode-1): nproduce I(0) - for i in xrange(nbUnit-1): + for i in range(nbUnit-1): nproduce U(0) - for j in xrange(nbINode): + for j in range(nbINode): nproduce I(0) produce EL diff --git a/test/lpytest/test_multiple_inleftcontext.lpy b/test/lpytest/test_multiple_inleftcontext.lpy index 6466bdbb..125f55a0 100644 --- a/test/lpytest/test_multiple_inleftcontext.lpy +++ b/test/lpytest/test_multiple_inleftcontext.lpy @@ -2,7 +2,7 @@ NBB = 10 Axiom: nproduce C - for i in xrange(NBB): + for i in range(NBB): nproduce B produce A @@ -13,7 +13,7 @@ A : nbB = 0 while InLeftContext(B): nbB += 1 - print 'Found',nbB,'B' + print('Found',nbB,'B') assert nbB == NBB produce C diff --git a/test/lpytest/test_newleftcontext.lpy b/test/lpytest/test_newleftcontext.lpy index 643b177c..f68c1491 100644 --- a/test/lpytest/test_newleftcontext.lpy +++ b/test/lpytest/test_newleftcontext.lpy @@ -1,5 +1,5 @@ def EndEach(lstring): - print lstring + print(lstring) assert lstring == 'BSABSA' Axiom: B A B A diff --git a/test/lpytest/test_newrightcontext.lpy b/test/lpytest/test_newrightcontext.lpy index 7d573985..1ed01849 100644 --- a/test/lpytest/test_newrightcontext.lpy +++ b/test/lpytest/test_newrightcontext.lpy @@ -1,5 +1,5 @@ def EndEach(lstring): - print lstring + print(lstring) assert lstring == 'B A S B A S' Axiom: B A B A diff --git a/test/lpytest/test_parametric_inleftcontext.lpy b/test/lpytest/test_parametric_inleftcontext.lpy index 21a8d383..d0586270 100644 --- a/test/lpytest/test_parametric_inleftcontext.lpy +++ b/test/lpytest/test_parametric_inleftcontext.lpy @@ -6,7 +6,7 @@ production: B : args = {} if InLeftContext(A(x), args) : - print args['x'] + print(args['x']) diff --git a/test/lpytest/test_path.lpy b/test/lpytest/test_path.lpy index a2c9d18c..27e0c06e 100644 --- a/test/lpytest/test_path.lpy +++ b/test/lpytest/test_path.lpy @@ -14,13 +14,13 @@ production: A(x,lastdir) : u0 = x/l u1 = (x+1)/l - print x, u0,u1 + print(x, u0,u1) t = path.getPointAt(path.c(u1))-path.getPointAt(path.c(u0)) t.normalize() - print lastdir,t + print(lastdir,t) a = angle(lastdir,t) lastdir = t - print a + print(a) if x == nbpt/2: nproduce [+(60)/(180)+(degrees(a))F(1)A(x+1,lastdir)] produce +(degrees(a))F(1)A(x+1,lastdir) diff --git a/test/lpytest/test_path4.lpy b/test/lpytest/test_path4.lpy index 2cf95907..c883c8e5 100644 --- a/test/lpytest/test_path4.lpy +++ b/test/lpytest/test_path4.lpy @@ -15,7 +15,7 @@ Leaf : nproduce _(width(0)) SetContour(leaf_profile) ;(2) StartGC() SetGuide(leaf_path,leaf_size) nbstep = int(leaf_size/leaf_step) ustep = 1. / nbstep - for i in xrange(nbstep+1): + for i in range(nbstep+1): nproduce _(width(ustep*i)*2) F(leaf_step) endlsystem diff --git a/test/lpytest/test_profile.lpy b/test/lpytest/test_profile.lpy index 1df82bd4..303dfbbb 100644 --- a/test/lpytest/test_profile.lpy +++ b/test/lpytest/test_profile.lpy @@ -16,7 +16,7 @@ production: A(x) : x = min(0.9999,x) a = angle(axis.getTangentAt(x),axis.getTangentAt(x+dt)) - print x + print(x) produce &(a)_(leafwidth(x))F(0.1)A(x+dt) homomorphism: diff --git a/test/lpytest/test_repr.lpy b/test/lpytest/test_repr.lpy index ac651e01..df8193d4 100644 --- a/test/lpytest/test_repr.lpy +++ b/test/lpytest/test_repr.lpy @@ -3,8 +3,8 @@ class A: pass def EndEach(lstring): - print lstring - print repr(lstring) + print(lstring) + print(repr(lstring)) Axiom: B(A()) diff --git a/test/lpytest/test_scalars.lpy b/test/lpytest/test_scalars.lpy index db1c13ae..6076ba22 100644 --- a/test/lpytest/test_scalars.lpy +++ b/test/lpytest/test_scalars.lpy @@ -1,5 +1,5 @@ -print length -print mybool +print(length) +print(mybool) initial_view = 5 diff --git a/test/lpytest/test_shape_ids.lpy b/test/lpytest/test_shape_ids.lpy index e51831da..e3a48d12 100644 --- a/test/lpytest/test_shape_ids.lpy +++ b/test/lpytest/test_shape_ids.lpy @@ -1,5 +1,5 @@ def End(lstring,lscene): - lsceneids = lscene.todict().keys() + lsceneids = list(lscene.todict().keys()) lsceneids.sort() assert len(lsceneids) == lstring.count('A') + lstring.count('B') + lstring.count('C') assert lsceneids == [2,5,7,10,12,15] diff --git a/test/lpytest/test_startendinterpretation.lpy b/test/lpytest/test_startendinterpretation.lpy index c03d0524..2c650812 100644 --- a/test/lpytest/test_startendinterpretation.lpy +++ b/test/lpytest/test_startendinterpretation.lpy @@ -1,5 +1,5 @@ def StartInterpretation(): - print 'StartInterpretation' + print('StartInterpretation') produce @O(0.2)+(90) diff --git a/test/lpytest/test_stringleftcontext.lpy b/test/lpytest/test_stringleftcontext.lpy index b9daa196..a664d51c 100644 --- a/test/lpytest/test_stringleftcontext.lpy +++ b/test/lpytest/test_stringleftcontext.lpy @@ -4,7 +4,7 @@ derivation length: 1 production: I(t) < A : - print 'ok',t + print('ok',t) assert t == 1 interpretation: diff --git a/test/test_axial_matching.lpy b/test/test_axial_matching.lpy index 7c168264..74788a76 100644 --- a/test/test_axial_matching.lpy +++ b/test/test_axial_matching.lpy @@ -19,7 +19,7 @@ production: A(a) < B(b) > [C(c)]D(d) : global matched matched = True - print 'a =',a,',b =',b,',c =',c,',d =',d + print('a =',a,',b =',b,',c =',c,',d =',d) assert d == 5 produce B(b) diff --git a/test/test_axial_msmatch.lpy b/test/test_axial_msmatch.lpy index 100c22ff..543a6472 100644 --- a/test/test_axial_msmatch.lpy +++ b/test/test_axial_msmatch.lpy @@ -22,7 +22,7 @@ production: A(a) < B(b) > [C(c)]D(d) : global matched matched = True - print 'a =',a,',b =',b,',c =',c,',d =',d + print('a =',a,',b =',b,',c =',c,',d =',d) assert d == 5 produce B(b) diff --git a/test/test_dynrules.py b/test/test_dynrules.py index e173931c..6774b436 100644 --- a/test/test_dynrules.py +++ b/test/test_dynrules.py @@ -2,7 +2,7 @@ code = """ def EndEach(lstring): - print 'Lstring [',getIterationNb(),']: ',lstring + print ('Lstring [',getIterationNb(),']: ',lstring) def End(lstring): assert len(lstring) == 1 and lstring[0] == 'C' diff --git a/test/test_group.lpy b/test/test_group.lpy index 4254862d..af69dd3e 100644 --- a/test/test_group.lpy +++ b/test/test_group.lpy @@ -7,7 +7,7 @@ def StartEach(): prev = getGroup() if getGroup() == 1: useGroup(2) else: useGroup(1) - print 'Group:',prev,'-->',getGroup() + print ('Group:',prev,'-->',getGroup()) currentmatch = None match0 = False diff --git a/test/test_kwd.lpy b/test/test_kwd.lpy index 296673b6..b1500536 100644 --- a/test/test_kwd.lpy +++ b/test/test_kwd.lpy @@ -22,7 +22,7 @@ def End(): failed = [] for i,v in enumerate(results): if not v: - print 'Error on test',i + print('Error on test',i) failed.append(i) if len(failed) > 0: raise ValueError(failed) @@ -31,88 +31,88 @@ production: *(*args): validate(0) - print '0 : args=',args + print('0 : args=',args) assert list(args) == ['A', 1, 2] *(**kwds): validate(1) - print '1 : kwd=',kwds + print('1 : kwd=',kwds) assert kwds == {'x': 1, 'name': 'A', 't': 2} *(*args,**kwds): validate(2) - print '2 : kwd=',kwds , 'args=',args + print('2 : kwd=',kwds , 'args=',args) assert kwds == {'x': 1, 'name': 'A', 't': 2} assert args == [] *(name,*args,**kwds): validate(3) - print '3 : name=',name,'kwd=',kwds , 'args=',args + print('3 : name=',name,'kwd=',kwds , 'args=',args) assert name == 'A' assert kwds == {'x': 1, 't': 2} assert args == [] *(name,x,*args,**kwds): validate(4) - print '4 : name=',name,'x=',x,'kwd=',kwds , 'args=',args + print('4 : name=',name,'x=',x,'kwd=',kwds , 'args=',args) assert name == 'A' and x == 1 assert kwds == {'t': 2} assert args == [] *(name,x,y,*args,**kwds): validate(5) - print '5 : name=',name,'x=',x,'y=',y,'kwd=',kwds , 'args=',args + print('5 : name=',name,'x=',x,'y=',y,'kwd=',kwds , 'args=',args) assert name == 'A' and x == 1 and y == 2 assert kwds == {} assert args == [] *(name,x,y,z,*args,**kwds): unvalidate(6) - print '6 : name=',name,'x=',x,'y=',y,'z=',z,'kwd=',kwds , 'args=',args + print('6 : name=',name,'x=',x,'y=',y,'z=',z,'kwd=',kwds , 'args=',args) *(name,**kwds): validate(7) - print '7 : name=',name,'kwd=',kwds + print('7 : name=',name,'kwd=',kwds ) assert name == 'A' assert kwds == {'x': 1, 't': 2} *(name,x,**kwds): validate(8) - print '8 : name=',name,'x=',x,'kwd=',kwds + print('8 : name=',name,'x=',x,'kwd=',kwds ) assert name == 'A' and x == 1 assert kwds == {'t': 2} *(name,x,y,**kwds): validate(9) - print '9 : name=',name,'x=',x,'y=',y,'kwd=',kwds + print('9 : name=',name,'x=',x,'y=',y,'kwd=',kwds ) assert name == 'A' and x == 1 and y == 2 assert kwds == {} *(name,x,y,z,**kwds): unvalidate(10) - print '10 : name=',name,'x=',x,'y=',y,'z=',z,'kwd=',kwds + print('10 : name=',name,'x=',x,'y=',y,'z=',z,'kwd=',kwds ) A(*args): validate(11) - print '11 : args=',args + print('11 : args=',args) assert list(args) == [ 1, 2] A(**kwds): validate(12) - print '12 : kwd=',kwds + print('12 : kwd=',kwds) assert kwds == {'x': 1, 't': 2} A(*args,**kwds): validate(13) - print '13 : kwd=',kwds, 'args=',repr(args) + print('13 : kwd=',kwds, 'args=',repr(args)) assert kwds == {'x': 1, 't': 2} assert args == [] A(x,*args,**kwds): validate(14) - print '14 : x=',x,'kwd=',kwds , 'args=',args + print('14 : x=',x,'kwd=',kwds , 'args=',args) assert x == 1 assert kwds == {'t': 2} assert args == [] @@ -120,30 +120,30 @@ A(x,*args,**kwds): A(x,y,*args,**kwds): validate(15) - print '15 : x=',x,'y=',y,'kwd=',kwds , 'args=',args + print('15 : x=',x,'y=',y,'kwd=',kwds , 'args=',args) assert x == 1 and y == 2 assert kwds == {} assert args == [] A(x,y,z,*args,**kwds): unvalidate(16) - print '16 : x=',x,'y=',y,'z=',z,'kwd=',kwds , 'args=',args + print('16 : x=',x,'y=',y,'z=',z,'kwd=',kwds , 'args=',args) A(x,**kwds): validate(17) - print '17 : x=',x,'kwd=',kwds + print('17 : x=',x,'kwd=',kwds ) assert x == 1 assert kwds == {'t': 2} A(x,y,**kwds): validate(18) - print '18 : x=',x,'y=',y,'kwd=',kwds + print('18 : x=',x,'y=',y,'kwd=',kwds ) assert x == 1 and y == 2 assert kwds == {} A(x,y,z,**kwds): unvalidate(19) - print '19 :', name,'x=',x,'y=',y,'z=',z,'kwd=',kwds + print('19 :', name,'x=',x,'y=',y,'z=',z,'kwd=',kwds ) interpretation: diff --git a/test/test_kwd2.lpy b/test/test_kwd2.lpy index bb324553..51d73098 100644 --- a/test/test_kwd2.lpy +++ b/test/test_kwd2.lpy @@ -22,7 +22,7 @@ def End(): failed = [] for i,v in enumerate(results): if not v: - print 'Error on test',i + print('Error on test',i) failed.append(i) if len(failed) > 0: raise ValueError(failed) @@ -31,7 +31,7 @@ production: *(*args): validate(0) - print '0 : args=',args + print('0 : args=',args) assert list(args) == ['A', 1, 2, 3] *(**kwds): @@ -40,91 +40,91 @@ production: *(*args,**kwds): validate(2) - print '2 : kwd=',kwds , 'args=',args + print('2 : kwd=',kwds , 'args=',args) assert kwds == {'x': 2, 'name': 'A', 't': 3} assert args == [1] *(name,*args,**kwds): validate(3) - print '3 : name=',name,'kwd=',kwds , 'args=',args + print('3 : name=',name,'kwd=',kwds , 'args=',args) assert name == 'A' assert kwds == {'x': 2, 't': 3} assert args == [1] *(name,*args): validate(20) - print '20 : name=',name, 'args=',args + print('20 : name=',name, 'args=',args) assert name == 'A' assert args == [1,2,3] *(name,**kwds): unvalidate(21) - print '21 : name=',name,'kwd=',kwds + print('21 : name=',name,'kwd=',kwds ) *(name, x, *args, **kwds): validate(4) - print '4 : name=',name,'x=',x,'kwd=',kwds , 'args=',args + print('4 : name=',name,'x=',x,'kwd=',kwds , 'args=',args) assert name == 'A' and x == 1 assert kwds == {'x': 2, 't': 3} assert args == [] *(name,x,y,*args,**kwds): validate(5) - print '5 : name=',name,'x=',x,'y=',y,'kwd=',kwds , 'args=',args + print('5 : name=',name,'x=',x,'y=',y,'kwd=',kwds , 'args=',args) assert name == 'A' and x == 1 and y == 2 assert kwds == {'t': 3} assert args == [] *(name,x,y,z,*args,**kwds): validate(6) - print '6 : name=',name,'x=',x,'y=',y,'z=',z,'kwd=',kwds , 'args=',args + print('6 : name=',name,'x=',x,'y=',y,'z=',z,'kwd=',kwds , 'args=',args) assert name == 'A' and x == 1 and y == 2 and z == 3 assert kwds == {} assert args == [] *(name,**kwds): unvalidate(7) - print '7 : name=',name,'kwd=',kwds + print('7 : name=',name,'kwd=',kwds ) *(name,x,**kwds): validate(8) - print '8 : name=',name,'x=',x,'kwd=',kwds + print('8 : name=',name,'x=',x,'kwd=',kwds ) assert name == 'A' and x == 1 assert kwds == {'x': 2, 't': 3} *(name,x,y,**kwds): validate(9) - print '9 : name=',name,'x=',x,'y=',y,'kwd=',kwds + print('9 : name=',name,'x=',x,'y=',y,'kwd=',kwds ) assert name == 'A' and x == 1 and y == 2 assert kwds == {'t': 3} *(name,x,y,z,**kwds): validate(10) - print '10 : name=',name,'x=',x,'y=',y,'z=',z,'kwd=',kwds + print('10 : name=',name,'x=',x,'y=',y,'z=',z,'kwd=',kwds ) assert name == 'A' and x == 1 and y == 2 and z == 3 assert kwds == {} A(*args): validate(11) - print '11 : args=',args + print('11 : args=',args) assert list(args) == [ 1, 2,3] A(**kwds): unvalidate(12) - print '12 : kwd=',kwds + print('12 : kwd=',kwds) A(*args, **kwds): validate(13) - print '13 : kwd=',kwds, 'args=',repr(args) + print('13 : kwd=',kwds, 'args=',repr(args)) assert kwds == {'x': 2, 't': 3} assert args == [1] A(x,*args,**kwds): validate(14) - print '14 : x=',x,'kwd=',kwds , 'args=',args + print('14 : x=',x,'kwd=',kwds , 'args=',args) assert x == 1 assert kwds == {'x': 2, 't': 3} assert args == [] @@ -132,33 +132,33 @@ A(x,*args,**kwds): A(x,y,*args,**kwds): validate(15) - print '15 : x=',x,'y=',y,'kwd=',kwds , 'args=',args + print('15 : x=',x,'y=',y,'kwd=',kwds , 'args=',args) assert x == 1 and y == 2 assert kwds == {'t': 3} assert args == [] A(x,y,z,*args,**kwds): validate(16) - print '16 : x=',x,'y=',y,'z=',z,'kwd=',kwds , 'args=',args + print('16 : x=',x,'y=',y,'z=',z,'kwd=',kwds , 'args=',args) assert x == 1 and y == 2 and z == 3 assert kwds == {} assert args == [] A(x,**kwds): validate(17) - print '17 : x=',x,'kwd=',kwds + print('17 : x=',x,'kwd=',kwds ) assert x == 1 assert kwds == {'x': 2, 't': 3} A(x,y,**kwds): validate(18) - print '18 : x=',x,'y=',y,'kwd=',kwds + print('18 : x=',x,'y=',y,'kwd=',kwds ) assert x == 1 and y == 2 assert kwds == {'t': 3} A(x,y,z,**kwds): validate(19) - print '19 :','x=',x,'y=',y,'z=',z,'kwd=',kwds + print('19 :','x=',x,'y=',y,'z=',z,'kwd=',kwds ) assert x == 1 and y == 2 and z == 3 assert kwds == {} diff --git a/test/test_perf.lpy b/test/test_perf.lpy index 000045df..10f6a7a9 100644 --- a/test/test_perf.lpy +++ b/test/test_perf.lpy @@ -8,7 +8,7 @@ def Start(): timer = clock() def End(): - print 'time=',clock()-timer + print('time=',clock()-timer) derivation length: 100 diff --git a/test/test_simple_matching.lpy b/test/test_simple_matching.lpy index eeddd5d5..77c22854 100644 --- a/test/test_simple_matching.lpy +++ b/test/test_simple_matching.lpy @@ -6,7 +6,7 @@ def StartEach(): def EndEach(): - print getIterationNb(),matched + print (getIterationNb(),matched) assert not matched is None if getIterationNb() == 5: assert matched == 1 diff --git a/test/test_stringmatching.py b/test/test_stringmatching.py index c5e39d4e..00b9e68e 100644 --- a/test/test_stringmatching.py +++ b/test/test_stringmatching.py @@ -11,4 +11,4 @@ def test_stringmatching(): b = a.begin() for i in range(15): b.nextValues() - assert list(b.values()) == (10,15) \ No newline at end of file + assert tuple(b.values()) == (10,15) \ No newline at end of file diff --git a/test/test_ui.py b/test/test_ui.py index b5c21752..e451d720 100644 --- a/test/test_ui.py +++ b/test/test_ui.py @@ -1,5 +1,5 @@ from openalea.lpy.gui.lpystudio import * -from openalea.vpltk.qt import qt +from openalea.plantgl.gui import qt import sys,os class TLPyWindow (LPyWindow): From 3ca1c816e70e3b0838faa76de2d47895116d811e Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Wed, 20 Nov 2019 16:38:25 +0100 Subject: [PATCH 63/68] improve python3 compat --- share/examples/apicaldominancy.lpy | 7 ++-- src/cpp/lpy_parser.cpp | 4 +- src/cpp/lpyrun.cpp | 2 +- src/cpp/lsyscontext.cpp | 45 ++++++++++++++------- src/cpp/lsyscontext.h | 7 ++-- src/cpp/module.cpp | 8 ++-- src/openalea/lpy/gui/simulation.py | 2 +- test/lpytest/import_with_module_in_name.lpy | 14 ++++--- test/lpytest/multiscalexmatching.lpy | 2 +- test/lpytest/test_pproduce.lpy | 4 +- test/lpytest/test_unicode.lpy | 7 ++-- test/test_lpytest.py | 8 +++- test/test_msmatch.lpy | 4 +- test/test_shareexamples.py | 4 +- test/test_tree_matching.py | 11 ++--- 15 files changed, 78 insertions(+), 51 deletions(-) diff --git a/share/examples/apicaldominancy.lpy b/share/examples/apicaldominancy.lpy index 4c9065d6..872b8ddb 100644 --- a/share/examples/apicaldominancy.lpy +++ b/share/examples/apicaldominancy.lpy @@ -17,7 +17,7 @@ def Start(): timing = t.time() def End(): - print 'Execution time :',t.time()-timing + print ('Execution time :',t.time()-timing) def txt(val): return str(round(val,2))[:5] @@ -96,5 +96,6 @@ endlsystem ###### INITIALISATION ###### def __initialiseContext__(context): - from openalea.plantgl.scenegraph import Material,ImageTexture,Color3 - context.turtle.setMaterial(1,Material('Brown',Color3(33,22,6),2.72727,Color3(40,40,40),Color3(0,0,0),1,0)) + from openalea.plantgl.all import PglTurtle + from openalea.plantgl.scenegraph import Material,ImageTexture,Color3 + context.turtle.setMaterial(1,Material('Brown',Color3(33,22,6),2.72727,Color3(40,40,40),Color3(0,0,0),1,0)) diff --git a/src/cpp/lpy_parser.cpp b/src/cpp/lpy_parser.cpp index 8c13a5b5..1fc50108 100644 --- a/src/cpp/lpy_parser.cpp +++ b/src/cpp/lpy_parser.cpp @@ -483,7 +483,7 @@ Lsystem::set( const std::string& _rules , std::string * pycode, if (LpyParsing::isValidVariableName(itmod->name)) code += itmod->name+" = ModuleClass.get('"+itmod->name+"')"; } - code+="# "+std::string(_it2,_it); + code+=" # "+std::string(_it2,_it); beg = _it; toendlineA(_it,endpycode); } @@ -508,7 +508,7 @@ Lsystem::set( const std::string& _rules , std::string * pycode, if(has_keyword_pattern(_it,begcode,endpycode,"undeclare")){ code+=std::string(beg,_it2); LpyParsing::ModNameList modules = LpyParsing::parse_modlist(_it,endpycode,false); - code+="# "+std::string(_it2,_it); + code+=" # "+std::string(_it2,_it); for(LpyParsing::ModNameList::const_iterator itmod = modules.begin(); itmod != modules.end(); ++itmod){ ModuleClassPtr mod = ModuleClassTable::get().find(*itmod); diff --git a/src/cpp/lpyrun.cpp b/src/cpp/lpyrun.cpp index c7e963e9..93ab3275 100644 --- a/src/cpp/lpyrun.cpp +++ b/src/cpp/lpyrun.cpp @@ -50,9 +50,9 @@ void cleanLpy() std::cerr << "****** pre-cleaning *******" << std::endl; Tracker::printReport(); #endif - LsysContext::cleanContexts(); ModuleClassTable::clearModuleClasses (); ViewerApplication::exit (); + LsysContext::cleanContexts(); #ifdef TRACKER_ENABLED std::cerr << "****** post-cleaning ******" << std::endl; Tracker::printReport(); diff --git a/src/cpp/lsyscontext.cpp b/src/cpp/lsyscontext.cpp index ac14f306..c6ee019f 100644 --- a/src/cpp/lsyscontext.cpp +++ b/src/cpp/lsyscontext.cpp @@ -65,13 +65,13 @@ static LsysContext * DEFAULT_LSYSCONTEXT = NULL; static LsysContext * CURRENT_LSYSCONTEXT = NULL; static QMutex CURRENT_LSYSCONTEXT_MUTEX; - +/* class ContextGarbageCollector { public: ContextGarbageCollector() {} ~ContextGarbageCollector() { - // std::cerr << "context garbage collector" << std::endl; + printf("context garbage collector\n"); if (GLOBAL_LSYSCONTEXT){ LsysContext::cleanContexts(); } @@ -79,25 +79,30 @@ class ContextGarbageCollector protected: static ContextGarbageCollector __INSTANCE; }; +*/ void LsysContext::cleanContexts(){ + // VERY STRANGE: Cannot delete global and default context. QMutexLocker locker(&CURRENT_LSYSCONTEXT_MUTEX); if (DEFAULT_LSYSCONTEXT){ - delete DEFAULT_LSYSCONTEXT; + // delete DEFAULT_LSYSCONTEXT; DEFAULT_LSYSCONTEXT = NULL; } if (GLOBAL_LSYSCONTEXT) { - delete GLOBAL_LSYSCONTEXT; - GLOBAL_LSYSCONTEXT = NULL; + if(!(LSYSCONTEXT_STACK.empty() && GLOBAL_LSYSCONTEXT->isCurrent())) + while(!GLOBAL_LSYSCONTEXT->isCurrent()) currentContext()->done(); + assert(LSYSCONTEXT_STACK.empty() && GLOBAL_LSYSCONTEXT->isCurrent() && "LsysContext not all done!"); + + // delete GLOBAL_LSYSCONTEXT; + GLOBAL_LSYSCONTEXT = NULL; } } LsysContext * LsysContext::globalContext() { - if(!GLOBAL_LSYSCONTEXT) GLOBAL_LSYSCONTEXT = new GlobalContext(); - return GLOBAL_LSYSCONTEXT; + return GlobalContext::get(); } void createDefaultContext() @@ -649,10 +654,10 @@ void LsysContext::namespaceInitialisation() { if (!hasObject("__builtins__")){ - copyObjectToGlobals("__builtins__",globalContext()); + // copyObjectToGlobals("__builtins__",globalContext()); - // object builtin = boost::python::import("__builtin__"); - // setObjectToGlobals("__builtins__", builtin); + object builtins = boost::python::import("builtins"); + setObjectToGlobals("__builtins__", builtins); // setObjectToGlobals("__builtins__", object(handle<>(borrowed( PyModule_GetDict(PyImport_AddModule("__builtin__")))))); } @@ -923,7 +928,7 @@ LsysContext::func(const std::string& funcname){ } size_t func_nb_args(boost::python::object function) { - char * attrname = + const char * attrname = #if PY_MAJOR_VERSION == 2 "func_code" #else @@ -1185,12 +1190,18 @@ LocalContext::globals() const GlobalContext::GlobalContext(): LsysContext(){ - __globals = handle<>(borrowed( PyModule_GetDict(PyImport_AddModule("__main__")))); + __globals = object(handle<>(borrowed(PyModule_GetDict(PyImport_AddModule("__main__"))))); } -GlobalContext::~GlobalContext() +GlobalContext * GlobalContext::get() { + if(!GLOBAL_LSYSCONTEXT) GLOBAL_LSYSCONTEXT = new GlobalContext(); + return GLOBAL_LSYSCONTEXT; +} + +GlobalContext::~GlobalContext() +{ if(!(LSYSCONTEXT_STACK.empty() && isCurrent())) while(!isCurrent()) currentContext()->done(); assert(LSYSCONTEXT_STACK.empty() && isCurrent() && "LsysContext not all done!"); @@ -1199,7 +1210,7 @@ GlobalContext::~GlobalContext() PyObject * GlobalContext::globals() const -{ return __globals.get(); } +{ return __globals.ptr(); } boost::python::object GlobalContext::__reprFunc; @@ -1217,6 +1228,10 @@ GlobalContext::getFunctionRepr() { return __reprFunc; } - +void +GlobalContext::clearNamespace() { + __locals.clear(); +} /*---------------------------------------------------------------------------*/ + \ No newline at end of file diff --git a/src/cpp/lsyscontext.h b/src/cpp/lsyscontext.h index c35342cc..e42974b4 100644 --- a/src/cpp/lsyscontext.h +++ b/src/cpp/lsyscontext.h @@ -434,15 +434,16 @@ class LPY_API LocalContext : public LsysContext { class LPY_API GlobalContext : public LsysContext { public: - GlobalContext(); ~GlobalContext(); virtual PyObject * globals() const ; static boost::python::object getFunctionRepr(); - + virtual void clearNamespace(); + static GlobalContext * get(); protected: + GlobalContext(); - boost::python::handle<> __globals; + boost::python::object __globals; static boost::python::object __reprFunc; }; diff --git a/src/cpp/module.cpp b/src/cpp/module.cpp index 834f6220..772da66d 100644 --- a/src/cpp/module.cpp +++ b/src/cpp/module.cpp @@ -109,10 +109,9 @@ void processArgList(ModuleClassPtr mclass, ParamModule::ParameterList& args, boo } pgl_hash_set missingargs; - while( true ) - { + + do { boost::python::object obj = iter_obj.next(); - if (!iter_obj.is_valid()) break; std::string pname = extract( obj[0] )(); size_t pposition = mclass->getParameterPosition(pname); @@ -142,7 +141,8 @@ void processArgList(ModuleClassPtr mclass, ParamModule::ParameterList& args, boo appendParam(args,obj[1]); } } - } + } while( iter_obj.is_valid() ); + if (missingargs.size() > 0) { std::stringstream str; str << mclass->name << " takes exactly " << mclass->getNamedParameterNb()<< " (" << missingargs.size() << " missing)"; diff --git a/src/openalea/lpy/gui/simulation.py b/src/openalea/lpy/gui/simulation.py index d5815d2d..40484f60 100644 --- a/src/openalea/lpy/gui/simulation.py +++ b/src/openalea/lpy/gui/simulation.py @@ -680,7 +680,7 @@ def opencode(self,txt): self.visualparameters = [] lpy_code_version = 1.0 if '__lpy_code_version__' in context: - lpy_code_version = ['__lpy_code_version__'] + lpy_code_version = context['__lpy_code_version__'] print(lpy_code_version) if '__functions__' in context and lpy_code_version <= 1.0 : functions = context['__functions__'] diff --git a/test/lpytest/import_with_module_in_name.lpy b/test/lpytest/import_with_module_in_name.lpy index 59aab0ab..b0c85eeb 100644 --- a/test/lpytest/import_with_module_in_name.lpy +++ b/test/lpytest/import_with_module_in_name.lpy @@ -6,13 +6,17 @@ f.close() try: from a_module2 import test -except Exception,e: - os.remove(fname) - os.remove(fname+'c') +except Exception as e: + if os.path.exists(fname) : + os.remove(fname) + if os.path.exists(fname+'c') : + os.remove(fname+'c') raise e -os.remove(fname) -os.remove(fname+'c') +if os.path.exists(fname) : + os.remove(fname) +if os.path.exists(fname+'c') : + os.remove(fname+'c') Axiom: diff --git a/test/lpytest/multiscalexmatching.lpy b/test/lpytest/multiscalexmatching.lpy index ce3516c5..04affe40 100644 --- a/test/lpytest/multiscalexmatching.lpy +++ b/test/lpytest/multiscalexmatching.lpy @@ -13,7 +13,7 @@ def StartEach(): ressup = [5 if multiscalemode else 3,2] print(context().options.find('String matching').currentValue()) context().options.find('String matching').activateSelection() - print 'toto' + print('toto') diff --git a/test/lpytest/test_pproduce.lpy b/test/lpytest/test_pproduce.lpy index 4b914d44..6fd9c51b 100644 --- a/test/lpytest/test_pproduce.lpy +++ b/test/lpytest/test_pproduce.lpy @@ -17,8 +17,8 @@ B(x) : A(1,x) B(2/0) ) - except Exception,e: - print e + except Exception as e: + print (e) A(x): x /0 diff --git a/test/lpytest/test_unicode.lpy b/test/lpytest/test_unicode.lpy index d38fa761..bb0f3c67 100644 --- a/test/lpytest/test_unicode.lpy +++ b/test/lpytest/test_unicode.lpy @@ -1,10 +1,11 @@ -# test special character: é è § -Axiom: A('é') é +#coding: utf-8 +# test special character: é è § +Axiom: A(u'é') é derivation length: 1 production: -é --> é +é --> é interpretation: diff --git a/test/test_lpytest.py b/test/test_lpytest.py index ede5a339..f9c4e800 100644 --- a/test/test_lpytest.py +++ b/test/test_lpytest.py @@ -13,7 +13,7 @@ def exec_lpy_tst(lfile): l = Lsystem(lfile) l.iterate() except Exception as e : - print(('Test file :',lfile)) + print('Test file :',lfile) raise e toavoid = [] @@ -42,4 +42,8 @@ def test_diese_bug(): if __name__ == '__main__': for e,f in test_lpy_tests(): - e(f) \ No newline at end of file + try: + e(f) + except Exception as e: + print('****** FAILED:',f) + print(e) diff --git a/test/test_msmatch.lpy b/test/test_msmatch.lpy index 814a2d94..1f7f0102 100644 --- a/test/test_msmatch.lpy +++ b/test/test_msmatch.lpy @@ -10,7 +10,7 @@ def Start(): matched = False def EndEach(lstring): - print lstring + print (lstring) assert matched == True derivation length: 1 @@ -19,7 +19,7 @@ production: TA(x)B < C: global matched matched = True - print x + print (x) produce C homomorphism: diff --git a/test/test_shareexamples.py b/test/test_shareexamples.py index 3465fd41..8942477d 100644 --- a/test/test_shareexamples.py +++ b/test/test_shareexamples.py @@ -13,14 +13,14 @@ def exec_share_example(lfile): l = Lsystem(lfile) l.iterate() except Exception as e : - print(('Example file :',lfile)) + print('Example file :',lfile) raise e def test_share_examples(): """ Test all lpy examples from share/ repository """ for lfile in get_share_examples(): - yield exec_share_example,lfile + yield exec_share_example, lfile if __name__ == '__main__': for e,f in test_share_examples(): diff --git a/test/test_tree_matching.py b/test/test_tree_matching.py index c0dd8818..4121b959 100644 --- a/test/test_tree_matching.py +++ b/test/test_tree_matching.py @@ -11,8 +11,9 @@ def StartEach(): def EndEach(): - print matched + print(matched) assert matched + """ def matching_run(code,optionvalues = list(range(4))): @@ -20,7 +21,7 @@ def matching_run(code,optionvalues = list(range(4))): optionvalues = [optionvalues] for i in range(4): l = Lsystem() - print(('option =',i)) + print('option =',i) if i in optionvalues: l.set(code) l.context().options.setSelection('String matching',i) @@ -30,7 +31,7 @@ def matching_run(code,optionvalues = list(range(4))): l.set(code) l.context().options.setSelection('String matching',i) l.iterate() - print(("Test do not fail for unsupported string matching mode : %i." % i)) + print("Test do not fail for unsupported string matching mode : %i." % i) warnings.warn("Test do not fail for unsupported string matching mode : %i." % i) except: pass @@ -76,9 +77,9 @@ def test_axial_msmatch() : if __name__ == '__main__': import traceback as tb test_func = [ (n,v) for n,v in list(globals().items()) if 'test' in n] - test_func.sort(lambda x,y : cmp(x[1].__code__.co_firstlineno,y[1].__code__.co_firstlineno)) + test_func.sort(key = lambda x : x[1].__code__.co_firstlineno) for tfn,tf in test_func: - print(('testing func:', tfn)) + print('testing func:', tfn) try: tf() except: From 89a172c0cafb40c4d918051d169d54d1b596e211 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Tue, 26 Nov 2019 13:53:27 +0100 Subject: [PATCH 64/68] fix bug with slice access --- src/wrapper/export_module.h | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/wrapper/export_module.h b/src/wrapper/export_module.h index d473fd0a..0b87c69d 100644 --- a/src/wrapper/export_module.h +++ b/src/wrapper/export_module.h @@ -30,6 +30,27 @@ #include + +template +boost::python::list py_getslice(T * module, boost::python::slice sl) { + int beg = 0; + if (sl.start() != boost::python::object()) beg = boost::python::extract(sl.start())(); + int end = module->size(); + if (sl.stop() != boost::python::object()) end = boost::python::extract(sl.stop())(); + return module->getSliceItemAt(beg, end); + +} + +template +void py_delslice(T * module, boost::python::slice sl) { + int beg = 0; + if (sl.start() != boost::python::object()) beg = boost::python::extract(sl.start())(); + int end = module->size(); + if (sl.stop() != boost::python::object()) end = boost::python::extract(sl.stop())(); + return module->delSliceItemAt(beg, end); + +} + template class module_func : public boost::python::def_visitor > { @@ -46,8 +67,8 @@ class module_func : public boost::python::def_visitor > .def("__getitem__",&ParamModule::getItemAt) .def("__setitem__",&ParamModule::setItemAt) .def("__delitem__",&ParamModule::delItemAt) - .def("__getslice__",&ParamModule::getSliceItemAt) - .def("__delslice__",&ParamModule::delSliceItemAt) + .def("__getitem__",&py_getslice) + .def("__delitem__",&py_delslice) .def("append",&ParamModule::append) .def("prepend",&ParamModule::prepend) From 4fce73de4086e5edd87791c7975476d3051d40f9 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Fri, 24 Jan 2020 15:59:40 +0100 Subject: [PATCH 65/68] fix conda build on mac --- CMakeLists.txt | 37 +++++++----- build.sh | 1 + cmake/Anaconda.cmake | 57 +++++++++++++++++- cmake/CXX14.cmake | 6 +- cmake/pywrapper.cmake | 35 +++++++++++ conda/build.sh | 65 +++++++++++++++++++-- conda/meta.yaml | 94 +++++++----------------------- setup.py | 63 +++++++++----------- src/cpp/CMakeLists.txt | 6 +- src/openalea/__init__.py | 18 +----- src/openalea/lpy/gui/compile_ui.py | 6 +- src/openalea/lpy_d/__init__.py | 1 - src/wrapper/CMakeLists.txt | 15 +---- 13 files changed, 234 insertions(+), 170 deletions(-) create mode 100755 build.sh create mode 100644 cmake/pywrapper.cmake delete mode 100644 src/openalea/lpy_d/__init__.py diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b22212f..913e3c1f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,13 +1,16 @@ -# --- L-Py Project +# --- CMake Modules cmake_minimum_required(VERSION 3.12) +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") +include("Anaconda") +include("pywrapper") + +# --- L-Py Project + project(lpy_project CXX) # --- Build setup -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_SKIP_BUILD_RPATH FALSE) set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") @@ -19,11 +22,14 @@ if("${isSystemDir}" STREQUAL "-1") set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib") endif("${isSystemDir}" STREQUAL "-1") -# --- CMake Modules -set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") -include("Anaconda") +# --- CXX11 Compilation + +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) +set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") # --- (Win32) Multithreaded Compilation @@ -33,11 +39,12 @@ endif() ## ################################################################### -## Dependencies - Python +## Dependencies ## ################################################################### -find_package (Python3 COMPONENTS Interpreter Development) +# --- Python +find_package (Python3 COMPONENTS Interpreter Development) include_directories(${Python3_INCLUDE_DIRS}) # --- Libraries @@ -47,14 +54,16 @@ find_package(Qt5Core CONFIG REQUIRED) find_package(Qt5Concurrent CONFIG REQUIRED) find_package(PlantGL REQUIRED) -set(BOOST_ROOT $ENV{CONDA_PREFIX}) -set(BOOST_LIBRARYDIR "${BOOST_ROOT}/lib") +if (USE_CONDA) + set(BOOST_ROOT ${CONDA_ENV}) +endif() set(Boost_NO_SYSTEM_PATHS ON) set(Boost_USE_MULTITHREAD ON) set(Boost_USE_STATIC_LIBS OFF) +set(BUILD_SHARED_LIBS ON) -find_package(Boost COMPONENTS system python37 REQUIRED) +find_package(Boost COMPONENTS system python REQUIRED) # --- Include Directories @@ -64,7 +73,9 @@ include_directories(${Boost_INCLUDE_DIR}) # --- Library Directory -link_directories("${CONDA_ENV}/lib") +if (DEFINED CONDA_ENV) + link_directories("${CONDA_ENV}/lib") +endif() # --- Source Directories diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..727a0bfe --- /dev/null +++ b/build.sh @@ -0,0 +1 @@ +conda build . -c conda-forge -c fredboudon -c defaults --python=3.7 diff --git a/cmake/Anaconda.cmake b/cmake/Anaconda.cmake index 8b93c778..f364d36a 100644 --- a/cmake/Anaconda.cmake +++ b/cmake/Anaconda.cmake @@ -1,9 +1,14 @@ # Anaconda Check if (DEFINED ENV{CONDA_PREFIX}) # Anaconda Environment - message(STATUS "Anaconda environment detected.") + message(STATUS "Anaconda environment detected: " $ENV{CONDA_PREFIX}) - file(TO_CMAKE_PATH $ENV{CONDA_PREFIX} TMP_CONDA_ENV) + + if (DEFINED ENV{BUILD_PREFIX}) + file(TO_CMAKE_PATH $ENV{BUILD_PREFIX} TMP_CONDA_ENV) + else() + file(TO_CMAKE_PATH $ENV{CONDA_PREFIX} TMP_CONDA_ENV) + endif() if (WIN32) set(CONDA_ENV "${TMP_CONDA_ENV}/Library/") @@ -12,4 +17,52 @@ if (DEFINED ENV{CONDA_PREFIX}) endif() set(CONDA_PYTHON_ENV "${TMP_CONDA_ENV}/") + + set(USE_CONDA ON) + +else() + message(STATUS "Compilation outside an anaconda environment.") + set(USE_CONDA OFF) +endif() + + +if (DEFINED ENV{CONDA_BUILD}) + message(STATUS "Conda build detected. " $ENV{CONDA_BUILD}) + + # specify the cross compiler + set(CMAKE_C_COMPILER $ENV{CC}) + set(CMAKE_LINKER $ENV{LD}) + set(CMAKE_AR $ENV{AR}) + set(CMAKE_NM $ENV{NM}) + set(CMAKE_RANLIB $ENV{RANLIB}) + set(CMAKE_STRIP $ENV{STRIP}) + set(CMAKE_INSTALL_NAME_TOOL $ENV{INSTALL_NAME_TOOL}) + #CMAKE_MAKE_PROGRAM + #CMAKE_OBJCOPY + #CMAKE_OBJDUMP + + if (APPLE) + set(CMAKE_OSX_ARCHITECTURES $ENV{OSX_ARCH}) + endif() + + set(CMAKE_CXX_COMPILER $ENV{CXX}) + set(CMAKE_CXX_COMPILER_RANLIB $ENV{RANLIB}) + set(CMAKE_CXX_COMPILER_AR $ENV{AR}) + + # where is the target environment + set(CMAKE_FIND_ROOT_PATH $ENV{PREFIX} $ENV{BUILD_PREFIX} $ENV{BUILD_PREFIX}/$ENV{HOST}/sysroot $ENV{CONDA_BUILD_SYSROOT}) + + # search for programs in the build host directories + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + # for libraries and headers in the target directories + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) + + + set(USE_CONDA_BUILD ON) +else() + set(USE_CONDA_BUILD OFF) endif() + + + diff --git a/cmake/CXX14.cmake b/cmake/CXX14.cmake index 268b9685..4969e6a0 100644 --- a/cmake/CXX14.cmake +++ b/cmake/CXX14.cmake @@ -20,6 +20,6 @@ else() endif() # C++14 Standard -set(CMAKE_CXX_STANDARD 14) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_CXX_EXTENSIONS OFF) +#set(CMAKE_CXX_STANDARD 14) +#set(CMAKE_CXX_STANDARD_REQUIRED ON) +#set(CMAKE_CXX_EXTENSIONS OFF) diff --git a/cmake/pywrapper.cmake b/cmake/pywrapper.cmake new file mode 100644 index 00000000..c16742d5 --- /dev/null +++ b/cmake/pywrapper.cmake @@ -0,0 +1,35 @@ + + +function(pgllib_link_python libwrapname) + if(NOT APPLE OR NOT USE_CONDA) + if (Python3_FOUND) + target_link_libraries(${libwrapname} Python3::Python) + elseif (Python2_FOUND) + target_link_libraries(${libwrapname} Python2::Python) + endif() + else() + message(STATUS "Do not link with Python directly : " ${libwrapname}) + endif() + + # Disable Boost Auto-Link + #target_compile_definitions(${libwrapname} PRIVATE BOOST_ALL_NO_LIB) + + #target_link_libraries(${libwrapname} Boost::system Boost::thread Boost::python ) + +endfunction() + + + +function(pglwrapper_install libwrapname) + set_target_properties(${libwrapname} PROPERTIES PREFIX "") + + if (WIN32) + set_target_properties(${libwrapname} PROPERTIES SUFFIX ".pyd") + endif() + + if (APPLE) + set_target_properties(${libwrapname} PROPERTIES SUFFIX ".so") + endif() + + install(TARGETS ${libwrapname} DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy") +endfunction() diff --git a/conda/build.sh b/conda/build.sh index 4c9d456f..6dfe3a10 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -6,12 +6,65 @@ fi mkdir build cd build -cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} -DCMAKE_PREFIX_PATH=${PREFIX} -DCMAKE_BUILD_TYPE=Release .. -make -j${CPU_COUNT} +if [ `uname` = "Darwin" ]; then + SYSTEM_DEPENDENT_ARGS=( + "-DCMAKE_OSX_SYSROOT=${CONDA_BUILD_SYSROOT}" + ) + export LDFLAGS="-undefined dynamic_lookup ${LDFLAGS}" +else + SYSTEM_DEPENDENT_ARGS=( + "-DOPENGL_opengl_LIBRARY=${BUILD_PREFIX}/${HOST}/sysroot/usr/lib64/libGL.so" + "-DOPENGL_glx_LIBRARY=${BUILD_PREFIX}/${HOST}/sysroot/usr/lib64/libGL.so" + ) +fi + +export SYSTEM_DEPENDENT_ARGS + +echo +echo "****** CMAKE" +which cmake +echo 'CONDA_BUILD_SYSROOT:' $CONDA_BUILD_SYSROOT +echo +echo "****** ENV" +env + +echo +echo "****** CMAKE CONFIG" + +cmake -DCMAKE_INSTALL_PREFIX=${PREFIX} \ + -DCMAKE_PREFIX_PATH=${PREFIX} \ + -DCMAKE_BUILD_TYPE=Release \ + ${SYSTEM_DEPENDENT_ARGS[@]} \ + -LAH .. + +echo +echo "****** LPY CONFIG" +cat $SRC_DIR/src/openalea/lpy/__version__.py + +echo +echo "****** COMPILE" +export VERBOSE=1 +make -j${CPU_COUNT} +echo "****** INSTALL CXX LIB" make install +echo +echo "****** INSTALL PYTHON LIB" cd .. -sed -i '' '1,1 s/^/#/' $CONDA_PREFIX/lib/python3.7/site-packages/openalea/plantgl/gui/__init__.py -sed -i '' '1,1 s/^/#/' $BUILD_PREFIX/lib/python3.7/site-packages/openalea/plantgl/gui/__init__.py -sed -i '' '1,1 s/^/#/' $PREFIX/lib/python3.7/site-packages/openalea/plantgl/gui/__init__.py -$PYTHON setup.py install --prefix=${PREFIX} +echo "PYTHON:" ${PYTHON} + +#echo "** PYTHON CALL" +#export PYTHONPATH=${PREFIX}/lib/python${PY_VER}/site-packages/ +${PYTHON} setup.py install --prefix=${PREFIX} + +echo +echo "****** CHECK PYTHON LIB" +ls -R $PREFIX/lib/python3.7/site-packages/OpenAlea.Lpy-2.7.2-py3.7.egg/ +cat $PREFIX/lib/python3.7/site-packages/OpenAlea.Lpy-2.7.2-py3.7.egg/openalea/__init__.py + +# To check if Python lib is not in the dependencies with conda-forge distribution. +# See https://github.com/conda-forge/boost-feedstock/issues/81 +#if [ `uname` = "Darwin" ]; then +# otool -L `${PYTHON} -c "import openalea.lpy.__lpy_kernel__ as lpy ; print(lpy.__file__)"` +#fi +echo "****** END OF BUILD PROCESS" diff --git a/conda/meta.yaml b/conda/meta.yaml index c4506f50..4a5db68d 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -1,8 +1,9 @@ -{% set version = "2.7.2" %} +#{% set version = "2.7.2" %} +{% set data = load_setup_py_data() %} package: name: openalea.lpy - version: {{ version }} + version: {{ data.get('version') }} source: path: .. @@ -14,88 +15,37 @@ about: build: preserve_egg_dir: True - number: 1 - features: - - vc9 [win and py27] - - vc14 [win and py37] - track_features: - - vc9 [win and py27] - - vc14 [win and py37] + number: 2 requirements: build: - - cmake >=3.2.0 - binutils_impl_linux-64<2.31.0 # [linux] - {{ compiler('cxx') }} - - {{ cdt('xorg-x11-proto-devel') }} # [linux] - - {{ cdt('mesa-libgl-devel') }} # [linux] - - {{ cdt('mesa-libegl-devel') }} # [linux] - - {{ cdt('mesa-dri-drivers') }} # [linux] - - {{ cdt('libx11-devel') }} # [linux] - - {{ cdt('libXt-devel') }} # [linux] - - {{ cdt('libICE-devel') }} # [linux] - - {{ cdt('libuuid-devel') }} # [linux] - - {{ cdt('libSM-devel') }} # [linux] - - {{ cdt('libxext-devel') }} # [linux] - - {{ cdt('libxcb') }} # [linux] - - {{ cdt('libxrender-devel') }} # [linux] - - {{ cdt('libxau-devel') }} # [linux] - - {{ cdt('libdrm-devel') }} # [linux] - - {{ cdt('libxcomposite-devel') }} # [linux] - - {{ cdt('libxcursor-devel') }} # [linux] - - {{ cdt('libxi-devel') }} # [linux] - - {{ cdt('libxrandr-devel') }} # [linux] - - {{ cdt('pciutils-devel') }} # [linux] - - {{ cdt('libxscrnsaver-devel') }} # [linux] - - {{ cdt('libxtst-devel') }} # [linux] - - {{ cdt('libselinux-devel') }} # [linux] - - {{ cdt('libxdamage') }} # [linux] - - {{ cdt('libxdamage-devel') }} # [linux] - - {{ cdt('libxfixes') }} # [linux] - - {{ cdt('libxfixes-devel') }} # [linux] - - {{ cdt('libxxf86vm') }} # [linux] - - python=3.7 - - qt >=5.9.0 - - boost-cpp - - py-boost - - setuptools -# - openalea.deploy + - python {{PY_VER}} - cmake >=3.12.0 - - openalea.plantgl - - pyqt - - qtconsole + - pkg-config # [linux] + - make # [unix] + - menuinst # [win] host: + - python {{PY_VER}} + - setuptools + # - openalea.deploy - openalea.plantgl - - boost-cpp - - python=3.7 - - py-boost - - gmp [unix] - # - cgal [unix] - - qhull - - ann - - eigen - - pyqt >=5.6.0 - - pyopengl - - scipy - - matplotlib + - boost + - pyqt run: - - python=3.7 + - python {{PY_VER}} + - setuptools + # - openalea.deploy - openalea.plantgl - - boost-cpp - - qt >=5.9.0 - - gmp [unix] - # - cgal [unix] - - qhull - - ann - - eigen - - pyqt >=5.6.0 + - boost + - pyqt - ipython - # - qtconsole - - py-boost - pyopengl - # - pyqglviewer - qtconsole - - vs2008_runtime [win and py27] - - vs2015_runtime [win and py37] + # - pyqglviewer + # - scipy + # - matplotlib + # - openalea.mtg # test: # requires: # - nose diff --git a/setup.py b/setup.py index 0fc9d982..f37fdce9 100644 --- a/setup.py +++ b/setup.py @@ -5,13 +5,6 @@ import os, sys pj = os.path.join -# from openalea.deploy.metainfo import read_metainfo -# metadata = read_metainfo('metainfo.ini', verbose=True) -# for key,value in metadata.items(): -# exec("%s = '%s'" % (key, value)) - -version = '2.7.1' -release = '2.7' project = 'openalea' package = 'lpy' name = 'OpenAlea.Lpy' @@ -19,7 +12,7 @@ pkg_name = 'openalea.lpy' description = 'Lindenmayer Systems in Python package for OpenAlea.' long_description= 'L-Py is a simulation software that mixes L-systems construction with the Python high-level modeling language. ' -authors = 'Frederic Boudon' +authors = 'Frédéric Boudon' authors_email = 'frederic.boudon@cirad.fr' url= 'https://github.com/openalea/lpy' # LGPL compatible INRIA license @@ -31,37 +24,37 @@ # Package name pkg_name= namespace + '.' + package -meta_version = version # check that meta version is updated -f = pj(os.path.dirname(__file__),'src', 'openalea', 'lpy','__version__.py') -d = {} -exec(compile(open(f, "rb").read(), f, 'exec'),d,d) -version= d['LPY_VERSION_STR'] -if meta_version != version: - print ('Warning:: Update the version in metainfo.ini !!') -print (pkg_name+': version ='+version) +lpydir = pj(os.path.dirname(__file__),'src', 'openalea', 'lpy') +versionfile = pj(lpydir,'__version__.py') +versioninfo = {} +with open(versionfile) as fp: + exec(fp.read(), versioninfo) -# Scons build directory -build_prefix = "build-cmake" +version= versioninfo['LPY_VERSION_STR'] +print (pkg_name+': version = '+version) -from setuptools import setup -# from openalea.deploy.binary_deps import binary_deps + +# cmake build directory +build_prefix = "build-cmake" def compile_interface(): cwd = os.getcwd() - os.chdir(pj('src','openalea','lpy','gui')) - print("HERE - 1") + os.chdir(pj(lpydir,'gui')) sys.path = ['']+sys.path - print(sys.path) - print("HERE - 2") import generate_ui - print("HERE - 3") os.chdir(cwd) - print("HERE - 4") -compile_interface() -install_requires = [] + py2exe_file = pj(lpydir,'gui','py2exe_release.py') + if not os.path.exists(py2exe_file): + open(py2exe_file,'w').close() + +if 'install' in sys.argv: + compile_interface() + + +from setuptools import setup setup( name=name, @@ -78,8 +71,8 @@ def compile_interface(): # pure python packages packages = [ + namespace, pkg_name, - pkg_name + '_d', pkg_name + '_wralea', pkg_name + '.gui', pkg_name + '.gui.plugins', @@ -89,9 +82,13 @@ def compile_interface(): # python packages directory package_dir = { '' : 'src',}, + package_data={ + "": ["share/*","share/*/*","share/*/*/*","share/*/*/*/*", '*.pyd', '*.so', '*.dylib', '*.lpy','*.ui','*.qrc'], + }, + # Add package platform libraries if any include_package_data = True, - package_data = {'' : ['*.pyd', '*.so', '*.dylib', '*.lpy','*.ui','*.qrc'],}, + #package_data = {'' : ['*.pyd', '*.so', '*.dylib', '*.lpy','*.ui','*.qrc'],}, zip_safe = False, # Dependencies @@ -101,10 +98,4 @@ def compile_interface(): 'console_scripts': ['cpfg2lpy = openalea.lpy.cpfg_compat.cpfg2lpy:main',], } - # Dependencies - # setup_requires = ['openalea.deploy'], - # dependency_links = ['http://openalea.gforge.inria.fr/pi'], - # install_requires = install_requires - - # pylint_packages = ['src/openalea/lpy/gui'] ) diff --git a/src/cpp/CMakeLists.txt b/src/cpp/CMakeLists.txt index 2f7f38c1..5cfb4734 100644 --- a/src/cpp/CMakeLists.txt +++ b/src/cpp/CMakeLists.txt @@ -8,12 +8,12 @@ add_library(lpy SHARED ${SRC_FILES}) target_link_libraries(lpy ${PLANTGL_LIBRARIES}) target_link_libraries(lpy Qt5::Core Qt5::Concurrent) -target_link_libraries(lpy Python3::Python) +pgllib_link_python(lpy) # Disable Boost Auto-Link target_compile_definitions(lpy PRIVATE BOOST_ALL_NO_LIB) -target_link_libraries(lpy Boost::python37) +target_link_libraries(lpy Boost::python) # --- Preprocessor @@ -28,4 +28,4 @@ install(TARGETS lpy LIBRARY DESTINATION "lib") # --- Install Headers -install(DIRECTORY "." DESTINATION "include" FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp") +install(DIRECTORY "." DESTINATION "include/lpy" FILES_MATCHING PATTERN "*.h" PATTERN "*.hpp") diff --git a/src/openalea/__init__.py b/src/openalea/__init__.py index 64ac5e45..de40ea7c 100644 --- a/src/openalea/__init__.py +++ b/src/openalea/__init__.py @@ -1,17 +1 @@ -try: - import pkg_resources - pkg_resources.declare_namespace(__name__) -except ImportError: - import pkgutil - __path__ = pkgutil.extend_path(__path__, __name__) - - -try: - from __init_path__ import set_path - set_path() -except: - pass - -import modulefinder -for p in __path__: - modulefinder.AddPackagePath(__name__, p) +__import__('pkg_resources').declare_namespace(__name__) diff --git a/src/openalea/lpy/gui/compile_ui.py b/src/openalea/lpy/gui/compile_ui.py index b15c5de2..adc52166 100644 --- a/src/openalea/lpy/gui/compile_ui.py +++ b/src/openalea/lpy/gui/compile_ui.py @@ -1,13 +1,9 @@ -print("DEBUG ===== 1") -# from openalea.plantgl.gui.qt import qt -print("DEBUG ===== 2") +from openalea.plantgl.gui.qt import QT_API, PYQT5_API, PYQT4_API, PYSIDE_API from openalea.plantgl.gui.qt.uic import compileUi, compile_args -print("DEBUG ===== 3") import os import sys -from openalea.plantgl.gui.qt import QT_API, PYQT5_API, PYQT4_API, PYSIDE_API def get_uifnames_from(fname): uiprefix = os.path.splitext(fname)[0] diff --git a/src/openalea/lpy_d/__init__.py b/src/openalea/lpy_d/__init__.py deleted file mode 100644 index 0a7de47b..00000000 --- a/src/openalea/lpy_d/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .__lpy_kernel__ import * \ No newline at end of file diff --git a/src/wrapper/CMakeLists.txt b/src/wrapper/CMakeLists.txt index e0aeab06..5e21f7b9 100644 --- a/src/wrapper/CMakeLists.txt +++ b/src/wrapper/CMakeLists.txt @@ -8,12 +8,12 @@ add_library(__lpy_kernel__ SHARED ${SRC_FILES}) target_link_libraries(__lpy_kernel__ lpy) target_link_libraries(__lpy_kernel__ ${PLANTGL_LIBRARIES}) -target_link_libraries(__lpy_kernel__ Python3::Python) +pgllib_link_python(__lpy_kernel__) # Disable Boost Auto-Link target_compile_definitions(__lpy_kernel__ PRIVATE BOOST_ALL_NO_LIB) -target_link_libraries(__lpy_kernel__ Boost::system Boost::python37) +target_link_libraries(__lpy_kernel__ Boost::system Boost::python) # --- Dependencies @@ -21,14 +21,5 @@ add_dependencies(__lpy_kernel__ lpy) # --- Output Library -set_target_properties(__lpy_kernel__ PROPERTIES PREFIX "") +pglwrapper_install(__lpy_kernel__) -if (WIN32) - set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".pyd") -endif() - -if (APPLE) - set_target_properties(__lpy_kernel__ PROPERTIES SUFFIX ".so") -endif() - -install(TARGETS __lpy_kernel__ DESTINATION "${CMAKE_SOURCE_DIR}/src/openalea/lpy") From 9f1627fba3e6ccd607f86f0889f649bfc343e1f1 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Fri, 24 Jan 2020 16:02:13 +0100 Subject: [PATCH 66/68] set version to 3.0 --- src/openalea/lpy/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/openalea/lpy/__version__.py b/src/openalea/lpy/__version__.py index fcf0127f..9a455e3c 100644 --- a/src/openalea/lpy/__version__.py +++ b/src/openalea/lpy/__version__.py @@ -1,4 +1,4 @@ -__version_number__ = 0x020702 +__version_number__ = 0x030000 __revision_str__="" From 142e171becc7a844be978156fbf4fb8b8802f3de Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Wed, 29 Jan 2020 16:44:49 +0100 Subject: [PATCH 67/68] add channel for CI --- appveyor.yml | 2 ++ conda/build.sh | 11 ++++++----- conda/meta.yaml | 6 ++---- travis.yml | 4 +++- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 7ad3d65b..4a05c293 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,6 +12,8 @@ install: - git clone https://github.com/OpenAlea/appveyor-ci.git appveyor-ci - cd appveyor-ci - call install.bat + - conda config --prepend channels conda-forge + - conda config --prepend channels fredboudon before_build: - call before_build.bat diff --git a/conda/build.sh b/conda/build.sh index 6dfe3a10..c1988da7 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -59,12 +59,13 @@ ${PYTHON} setup.py install --prefix=${PREFIX} echo echo "****** CHECK PYTHON LIB" -ls -R $PREFIX/lib/python3.7/site-packages/OpenAlea.Lpy-2.7.2-py3.7.egg/ -cat $PREFIX/lib/python3.7/site-packages/OpenAlea.Lpy-2.7.2-py3.7.egg/openalea/__init__.py # To check if Python lib is not in the dependencies with conda-forge distribution. # See https://github.com/conda-forge/boost-feedstock/issues/81 -#if [ `uname` = "Darwin" ]; then -# otool -L `${PYTHON} -c "import openalea.lpy.__lpy_kernel__ as lpy ; print(lpy.__file__)"` -#fi +if [ `uname` = "Darwin" ]; then + alias ldd='otool -L' +fi + +ldd `${PYTHON} -c "import openalea.lpy.__lpy_kernel__ as lpy ; print(lpy.__file__)"` + echo "****** END OF BUILD PROCESS" diff --git a/conda/meta.yaml b/conda/meta.yaml index 4a5db68d..b74fda79 100644 --- a/conda/meta.yaml +++ b/conda/meta.yaml @@ -15,7 +15,7 @@ about: build: preserve_egg_dir: True - number: 2 + number: 3 requirements: build: - binutils_impl_linux-64<2.31.0 # [linux] @@ -28,21 +28,19 @@ requirements: host: - python {{PY_VER}} - setuptools - # - openalea.deploy - openalea.plantgl - boost - pyqt run: - python {{PY_VER}} - setuptools - # - openalea.deploy - openalea.plantgl - boost - pyqt - ipython - pyopengl - qtconsole - # - pyqglviewer + - pyqglviewer # - scipy # - matplotlib # - openalea.mtg diff --git a/travis.yml b/travis.yml index 4857dc40..88e85d3c 100644 --- a/travis.yml +++ b/travis.yml @@ -11,12 +11,14 @@ services: env: - CONDA_RECIPE=conda - CONDA_VERSION=2 + CONDA_VERSION=3 install: - git clone https://github.com/openalea/travis-ci.git - cd travis-ci - source install.sh + - conda config --prepend channels fredboudon + - conda config --prepend channels conda-forge before_script: - source before_script.sh From 0a8df0ee9c3fe8d55dcf652fcdc24a452b0ed380 Mon Sep 17 00:00:00 2001 From: Frederic Boudon Date: Wed, 29 Jan 2020 18:11:38 +0100 Subject: [PATCH 68/68] fix bug on lib testing on mac --- conda/build.sh | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/conda/build.sh b/conda/build.sh index c1988da7..af75983a 100644 --- a/conda/build.sh +++ b/conda/build.sh @@ -63,9 +63,11 @@ echo "****** CHECK PYTHON LIB" # To check if Python lib is not in the dependencies with conda-forge distribution. # See https://github.com/conda-forge/boost-feedstock/issues/81 if [ `uname` = "Darwin" ]; then - alias ldd='otool -L' + export LDD='otool -L' +else + export LDD='ldd' fi -ldd `${PYTHON} -c "import openalea.lpy.__lpy_kernel__ as lpy ; print(lpy.__file__)"` +${LDD} `${PYTHON} -c "import openalea.lpy.__lpy_kernel__ as lpy ; print(lpy.__file__)"` echo "****** END OF BUILD PROCESS"