Skip to content

Commit

Permalink
improve python 3 compat
Browse files Browse the repository at this point in the history
  • Loading branch information
fredboudon committed Oct 21, 2019
1 parent 73c2036 commit 0a3d290
Show file tree
Hide file tree
Showing 21 changed files with 172 additions and 48 deletions.
19 changes: 10 additions & 9 deletions src/cpp/axialtree.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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():
Expand Down Expand Up @@ -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<size_t> idext(obj);
if (idext.check())
__string().push_back(idext());
if (idext.check()){
__string().push_back(ParamModule(idext()));
}
else {
extract<std::string> st(obj);
if(st.check())
Expand All @@ -92,7 +93,7 @@ AxialTree::AxialTree(const boost::python::list& l):
else __string().push_back(extract<ParamModule>(obj)());
}
}
}
}
}
}

Expand Down
66 changes: 66 additions & 0 deletions src/cpp/lpy_python.cpp
Original file line number Diff line number Diff line change
@@ -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<PyObject>(item));
else
__next_obj = boost::python::object();
}
}

57 changes: 57 additions & 0 deletions src/cpp/lpy_python.h
Original file line number Diff line number Diff line change
@@ -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 <boost/python.hpp>

/*---------------------------------------------------------------------------*/


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
18 changes: 9 additions & 9 deletions src/cpp/module.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<boost::python::dict> 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;
Expand All @@ -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<std::string>( obj[0] )();
size_t pposition = mclass->getParameterPosition(pname);
Expand Down Expand Up @@ -186,7 +185,8 @@ ParamModule::ParamModule():
BaseType() {}

ParamModule::ParamModule(size_t classid):
BaseType(classid) {}
BaseType(classid) {
}

ParamModule::ParamModule(const std::string& name) :
BaseType()
Expand Down
6 changes: 3 additions & 3 deletions test/test_axialtree.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand All @@ -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():
Expand All @@ -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


Expand Down
18 changes: 9 additions & 9 deletions test/test_debugger.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/test_kwd.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/test_kwd2.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/test_lpytest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down
4 changes: 2 additions & 2 deletions test/test_lsystem_as_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -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__':
Expand Down
2 changes: 1 addition & 1 deletion test/test_matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/test_multiline_produce.lpy
Original file line number Diff line number Diff line change
@@ -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'
Expand Down
2 changes: 1 addition & 1 deletion test/test_nproduce.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
2 changes: 1 addition & 1 deletion test/test_perf.lpy
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion test/test_predecessor_at_scale.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
'''
Expand Down
2 changes: 1 addition & 1 deletion test/test_regexpmatching.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/test_selection.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion test/test_shareexamples.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
Loading

0 comments on commit 0a3d290

Please sign in to comment.