Drop support for python2.

Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it>
pull/12/head
Michele Calgaro 2 years ago committed by Slávek Banko
parent 3b188e184d
commit d85bd77116
No known key found for this signature in database
GPG Key ID: 608F5293A04BE668

@ -6,7 +6,7 @@ fi
AC_ARG_VAR([XSLTPROC])
AC_ARG_VAR([PYTHON])
AC_PATH_PROG([XSLTPROC],[xsltproc],[echo])
AC_PATH_PROG([PYTHON],[python2])
AC_PATH_PROG([PYTHON],[python3])
if test -z "$PYTHON"; then
AC_PATH_PROG([PYTHON],[python])
fi

@ -1,78 +1,78 @@
import pcop
def registeredApplications():
"""Return a list of current DCOP registered applications."""
return pcop.app_list()
"""Return a list of current DCOP registered applications."""
return pcop.app_list()
def apps():
"""Return a list of current DCOP registered applications."""
return pcop.app_list()
"""Return a list of current DCOP registered applications."""
return pcop.app_list()
def anyAppCalled(appName):
"""Return any application instance called appName, or None if none currently registered."""
for app in apps():
if appName==app or appName+'-'==app[:len(appName)+1]:
return DCOPApplication(app)
return None
"""Return any application instance called appName, or None if none currently registered."""
for app in apps():
if appName==app or appName+'-'==app[:len(appName)+1]:
return DCOPApplication(app)
return None
def registerAs(appid, addpid=1):
"""Register the application with DCOP and return the ID. This is needed in order to receive DCOP requests."""
return pcop.register_as(appid,addpid)
"""Register the application with DCOP and return the ID. This is needed in order to receive DCOP requests."""
return pcop.register_as(appid,addpid)
def processEvents():
"""Process any waiting QT events, then return."""
pcop.process_events()
"""Process any waiting QT events, then return."""
pcop.process_events()
def connectDCOPSignal(sender,senderObj,signal,receiverObj,slot,vol=1):
"""Connect a dcop signal"""
return pcop.connect_dcop_signal(sender,senderObj,signal,receiverObj,slot,vol)
"""Connect a dcop signal"""
return pcop.connect_dcop_signal(sender,senderObj,signal,receiverObj,slot,vol)
def disconnectDCOPSignal(sender,senderObj,signal,receiverObj,slot):
"""Connect a dcop signal"""
return pcop.disconnect_dcop_signal(sender,senderObj,signal,receiverObj,slot)
"""Connect a dcop signal"""
return pcop.disconnect_dcop_signal(sender,senderObj,signal,receiverObj,slot)
class DCOPApplication(object):
def __init__( self, name ):
self.name = name
def __getattr__( self, item ):
if item == "__repr__":
return object.__repr__
if item == "__str__":
return object.__str__
if item == "__call__":
return object.__call__
if item == "_objects_":
return pcop.obj_list(self.name)
if item == "__repr__":
return object.__repr__
if item == "__str__":
return object.__str__
if item == "__call__":
return object.__call__
if item == "_objects_":
return pcop.obj_list(self.name)
return DCOPObject( self.name, item )
def _object_(self, object):
return DCOPObject( self.name, object )
def _object_(self, object):
return DCOPObject( self.name, object )
class DCOPObject(object):
def __init__( self, appname, name ):
self.appname = appname
self.name = name
def __repr__( self ):
return "DCOPObject(%s,%s)" % ( self.appname, self.name )
def __repr__( self ):
return "DCOPObject(%s,%s)" % ( self.appname, self.name )
def __str__( self ):
return "DCOPObject(%s,%s)" % ( self.appname, self.name )
def __str__( self ):
return "DCOPObject(%s,%s)" % ( self.appname, self.name )
def __getattr__( self, item ):
if item == "__repr__":
return object.__repr__
if item == "__str__":
return object.__str__
if item == "__call__":
return object.__call__
if item == "_methods_":
return pcop.method_list( self.appname, self.name )
if item == "__repr__":
return object.__repr__
if item == "__str__":
return object.__str__
if item == "__call__":
return object.__call__
if item == "_methods_":
return pcop.method_list( self.appname, self.name )
return DCOPMethod( self.appname, self.name, item )
def _method_(self, method):
return DCOPMethod( self.appname, self.name, method )
def _method_(self, method):
return DCOPMethod( self.appname, self.name, method )
class DCOPMethod(object):
def __init__( self, appname, objname, name ):
@ -80,43 +80,43 @@ class DCOPMethod(object):
self.objname = objname
self.name = name
def __repr__( self ):
return "DCOPMethod(%s,%s,%s)" % ( self.appname, self.objname, self.name )
def __repr__( self ):
return "DCOPMethod(%s,%s,%s)" % ( self.appname, self.objname, self.name )
def __str__( self ):
return "DCOPMethod(%s,%s,%s)" % ( self.appname, self.objname, self.name )
def __str__( self ):
return "DCOPMethod(%s,%s,%s)" % ( self.appname, self.objname, self.name )
def __call__( self, *args ):
return pcop.dcop_call( self.appname, self.objname, self.name, args )
return pcop.dcop_call( self.appname, self.objname, self.name, args )
class DCOPServer(object):
def __init__( self, appid, addpid = 1):
self.app_id = pcop.register_as(appid, addpid)
def __init__( self, appid, addpid = 1):
self.app_id = pcop.register_as(appid, addpid)
class DCOPServerObject:
"""Inherit from this class to DCOP enabled your object.
Remember to call the base class constructor, and in your own constructor
you should called setMethods to set the methods to DCOP enable.
"""
def __init__(self, objName=None):
"""objName is the name of the object. If omitted, it will default to a hex
address. It is best to supply it."""
if objName:
self.dcop_obj = pcop.create_dcop_object(self, objName)
else:
self.dcop_obj = pcop.create_dcop_object(self)
def setMethods(self, methods):
"""Set the method list for this object.
methods is a list of tuple pairs. Each pair consists of the
method signature and the Python method that handles it.
For example, setMethods([ ('TQString cheeseType()', self.cheese_type),
('void setGreatWines(bool perthPink, bool hobartMuddy, bool chateauChunder)')
"""
pcop.set_method_list(self.dcop_obj, methods)
"""Inherit from this class to DCOP enabled your object.
Remember to call the base class constructor, and in your own constructor
you should called setMethods to set the methods to DCOP enable.
"""
def __init__(self, objName=None):
"""objName is the name of the object. If omitted, it will default to a hex
address. It is best to supply it."""
if objName:
self.dcop_obj = pcop.create_dcop_object(self, objName)
else:
self.dcop_obj = pcop.create_dcop_object(self)
def setMethods(self, methods):
"""Set the method list for this object.
methods is a list of tuple pairs. Each pair consists of the
method signature and the Python method that handles it.
For example, setMethods([ ('TQString cheeseType()', self.cheese_type),
('void setGreatWines(bool perthPink, bool hobartMuddy, bool chateauChunder)')
"""
pcop.set_method_list(self.dcop_obj, methods)

@ -33,13 +33,13 @@ class DictMaker:
def handle_string_marsh(self, attribute):
"""Handle marshalling of string item from the dictionary."""
return ["if (%s && !PyString_Check(%s)) return false;" % (attribute, attribute),
"if (%s) { qobj.%s(TQString(PyString_AsString(%s)));" % (attribute, set_method(attribute), attribute),
return ["if (%s && !PyBytes_Check(%s)) return false;" % (attribute, attribute),
"if (%s) { qobj.%s(TQString::fromUtf8(PyBytes_AS_STRING(%s)));" % (attribute, set_method(attribute), attribute),
"PyDict_DelItemString(dict,(char*)\"%s\"); } " % (attribute)]
def handle_string_demarsh(self, attribute):
"""Handle demarshalling of string items into the dictionary."""
return ["PyObject *%s = PyString_FromString(qobj.%s().utf8().data() );" % (attribute ,attribute),
return ["PyObject *%s = PyBytes_FromString(qobj.%s().utf8().data() );" % (attribute ,attribute),
"PyDict_SetItemString(dict, (char*)\"%s\", %s);" % (attribute, attribute)
]
@ -141,7 +141,7 @@ class DocType:
MARSHAL, DEMARSHAL, TOPYOBJ, FROMPYOBJ = 0,1,2,3
if len(sys.argv)!=4:
print "Use: gen_marshal_code.py <input file> <output file> <doc-xml-output file>"
print("Use: gen_marshal_code.py <input file> <output file> <doc-xml-output file>")
raise RuntimeError
nowt, in_name, code_name, doc_xml_name = tuple(sys.argv)
@ -267,10 +267,10 @@ out_file.writelines([x + '\n' for x in gen_code_comments])
out_file.writelines([x + '\n' for x in code])
out_file.close()
xml_file = file(doc_xml_name,"w")
print >>xml_file, '<?xml version="1.0" ?>'
print >>xml_file, '<!-- This file was auto-generated by gen_marshal_code.py. Changes will be lost! -->'
print >>xml_file, "<types>"
[ [xml_file.write(x+"\n") for x in doc.xml()] for doc in doc_types.values() ] # silly one-liner
print >>xml_file, "</types>"
xml_file = open(doc_xml_name,"w")
print('<?xml version="1.0" ?>', file=xml_file)
print('<!-- This file was auto-generated by gen_marshal_code.py. Changes will be lost! -->', file=xml_file)
print("<types>", file=xml_file)
[ [xml_file.write(x+"\n") for x in doc.xml()] for doc in list(doc_types.values()) ] # silly one-liner
print("</types>", file=xml_file)
xml_file.close()

@ -40,8 +40,8 @@ namespace PythonDCOP {
return 0;
PyObject* args = PyTuple_New( 2 );
PyTuple_SetItem( args, 0, PyString_FromString( appname ) );
PyTuple_SetItem( args, 1, PyString_FromString( objname ) );
PyTuple_SetItem( args, 0, PyBytes_FromString( appname ) );
PyTuple_SetItem( args, 1, PyBytes_FromString( objname ) );
return PyObject_CallObject( cl, args );
}

@ -46,7 +46,7 @@ type: bool
}
%% to_pyobj
{
return PyInt_FromLong(val ? 1 : 0);
return PyLong_FromLong(val ? 1 : 0);
}
%% marshal
{
@ -69,9 +69,9 @@ type:int
%doc as int i
%% marshal
{
if (!PyInt_Check(obj)) return false;
if (!PyLong_Check(obj)) return false;
if (str) {
(*str) << (TQ_INT32)PyInt_AsLong(obj);
(*str) << (TQ_INT32)PyLong_AsLong(obj);
}
return true;
}
@ -79,7 +79,7 @@ type:int
{
TQ_INT32 i;
(*str) >> i;
return PyInt_FromLong( (long)i );
return PyLong_FromLong( (long)i );
}
%%
@ -87,9 +87,9 @@ type:uint
%doc as int i
%% marshal
{
if (!PyInt_Check(obj)) return false;
if (!PyLong_Check(obj)) return false;
if (str) {
(*str) << (TQ_INT32)PyInt_AsLong(obj);
(*str) << (TQ_INT32)PyLong_AsLong(obj);
}
return true;
}
@ -97,7 +97,7 @@ type:uint
{
TQ_INT32 i;
(*str) >> i;
return PyInt_FromLong( (long)i );
return PyLong_FromLong( (long)i );
}
%%
@ -124,17 +124,17 @@ type:uchar
%doc as int c
%% marshal
{
if (PyString_Check(obj) && PyString_Size(obj)==1) {
if (PyBytes_Check(obj) && PyBytes_Size(obj)==1) {
if (str) {
char *c = PyString_AsString(obj);
char *c = PyBytes_AS_STRING(obj);
(*str) << (*c);
}
return true;
}
if (PyInt_Check(obj)) {
if (PyLong_Check(obj)) {
if (str) {
long l = PyInt_AsLong(obj);
long l = PyLong_AsLong(obj);
TQ_UINT8 c = (TQ_UINT8)(l & 0xff);
(*str) << c;
}
@ -147,7 +147,7 @@ type:uchar
{
TQ_UINT8 c;
(*str) >> c;
return PyString_FromStringAndSize((const char *)(&c),1);
return PyBytes_FromStringAndSize((const char *)(&c),1);
}
%%
@ -155,9 +155,9 @@ type:char
%doc as int c
%% marshal
{
if (PyInt_Check(obj)) {
if (PyLong_Check(obj)) {
if (str) {
long l = PyInt_AsLong(obj);
long l = PyLong_AsLong(obj);
TQ_INT8 c = (TQ_INT8)(l & 0xff);
(*str) << c;
}
@ -170,7 +170,7 @@ type:char
{
TQ_INT8 c;
(*str) >> c;
return PyInt_FromLong((long)c);
return PyLong_FromLong((long)c);
}
%%
@ -178,37 +178,29 @@ type:char
type:TQByteArray
%% marshal
{
PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
if ( pb && pb->bf_getreadbuffer && pb->bf_getsegcount )
Py_buffer view;
if (PyObject_GetBuffer(obj, &view, PyBUF_WRITABLE|PyBUF_SIMPLE))
{
// Get the number of buffer segments
int seg_count = (pb->bf_getsegcount)(obj, 0);
if ( seg_count != 1 )
// Can't handle more (or less) than 1 buffer segment
// at the moment
return false;
// Get buffer size and data
void *data;
int size;
if ( (size = (pb->bf_getreadbuffer)(obj, 0, &data)) < 0 )
return false;
return false;
}
if (str) {
TQByteArray a;
a.setRawData( (const char*)data, size );
(*str) << a;
a.resetRawData( (const char*)data, size );
}
int size = view.len;
if (size < 0)
{
PyBuffer_Release(&view);
return false;
}
return true;
if (str)
{
TQByteArray a;
a.setRawData((const char*)view.buf, size);
(*str) << a;
a.resetRawData((const char*)view.buf, size);
}
else
// obj does not implement the buffer interface
return false;
PyBuffer_Release(&view);
return true;
}
%% demarshal
{
@ -219,25 +211,8 @@ type:TQByteArray
uint size = a.size();
char *data = a.data();
// Create a new buffer object and copy the data.
// Don't use PyBuffer_FromMemory() and the likes since
// that wouldn't give correct allocation and deallocation.
PyObject *buffer_obj = PyBuffer_New( size );
if ( !buffer_obj )
return NULL;
PyBufferProcs *pb = buffer_obj->ob_type->tp_as_buffer;
void *buffer_data;
(pb->bf_getwritebuffer)( buffer_obj, 0, &buffer_data );
for ( uint i = 0; i < size; i++ )
((char*)buffer_data)[i] = data[i];
return buffer_obj;
// Demarshal to a writable buffer object
return PyBytes_FromStringAndSize(data, size);
}
%%
@ -245,9 +220,9 @@ type:TQString
%doc as str s
%% marshal
{
if (!PyString_Check(obj)) return false;
if (!PyBytes_Check(obj)) return false;
if (str) {
TQString s( PyString_AsString(obj) );
TQString s = TQString::fromUtf8(PyBytes_AS_STRING(obj));
(*str) << s;
}
return true;
@ -256,7 +231,7 @@ type:TQString
{
TQString s;
(*str) >> s;
return PyString_FromString( s.utf8().data() );
return PyBytes_FromString( s.utf8().data() );
}
%%
@ -264,9 +239,9 @@ type:TQCString
%doc as str s
%% marshal
{
if (!PyString_Check(obj)) return false;
if (!PyBytes_Check(obj)) return false;
if (str) {
TQCString s( PyString_AsString(obj) );
TQCString s( PyBytes_AS_STRING(obj) );
(*str) << s;
}
return true;
@ -275,7 +250,7 @@ type:TQCString
{
TQCString s;
(*str) >> s;
return PyString_FromString( s.data() );
return PyBytes_FromString( s.data() );
}
%%
@ -473,13 +448,6 @@ type:TQDateTime
return dt;
}
if (PyInt_Check(obj)) {
*ok=true;
TQDateTime dt;
dt.setTime_t( (uint)PyInt_AsLong(obj) );
return dt;
}
PyObject *date_tuple, *time_tuple;
if (PyArg_ParseTuple(obj, (char*)"OO", &date_tuple, &time_tuple)) {
TQDateTime dt;
@ -507,13 +475,13 @@ type:KURL
%% from_pyobj
{
*ok=false;
if (!PyString_Check(obj)) return KURL();
if (!PyBytes_Check(obj)) return KURL();
*ok=true;
return KURL( TQString(PyString_AsString(obj)) );
return KURL( TQString::fromUtf8(PyBytes_AS_STRING(obj)) );
}
%% to_pyobj
{
return PyString_FromString( val.prettyURL().utf8().data() );
return PyBytes_FromString( val.prettyURL().utf8().data() );
}
%% marshal
%defaultcode
@ -524,14 +492,14 @@ type:KURL
type:DCOPRef
%% from_pyobj
{
if (PyInstance_Check(obj) &&
if (PyType_Check(obj) &&
PyObject_HasAttrString(obj, (char*)"appname") &&
PyObject_HasAttrString(obj, (char*)"name")) {
PyObject *appname = PyObject_GetAttrString(obj, (char*)"appname");
PyObject *name = PyObject_GetAttrString(obj, (char*)"name");
if (PyString_Check(appname) && PyString_Check(name)) {
char *c_appname = PyString_AsString(appname);
char *c_name = PyString_AsString(name);
if (PyBytes_Check(appname) && PyBytes_Check(name)) {
char *c_appname = PyBytes_AS_STRING(appname);
char *c_name = PyBytes_AS_STRING(name);
DCOPRef ref;
ref.setRef(TQCString(c_appname), TQCString(c_name) );
Py_DECREF(appname);

@ -188,7 +188,7 @@ namespace PythonDCOP {
it.current(); ++it, ++c) {
PyObject *tuple = PyTuple_New(2);
PyList_SetItem(result, c, tuple);
PyTuple_SetItem(tuple, 0, PyString_FromString(it.currentKey() ) );
PyTuple_SetItem(tuple, 0, PyBytes_FromString(it.currentKey() ) );
PyTuple_SetItem(tuple, 1, it.current()->pythonMethod() );
}
return result;
@ -593,7 +593,7 @@ namespace PythonDCOP {
QCStringList::ConstIterator end = apps.end();
unsigned int i = 0;
for (; it != end; ++it, i++ )
PyList_SetItem( l, i, PyString_FromString( (*it).data() ) );
PyList_SetItem( l, i, PyBytes_FromString( (*it).data() ) );
return l;
}
@ -621,7 +621,7 @@ namespace PythonDCOP {
int add_pid = 1;
if (PyArg_ParseTuple(args, (char*)"s|i", &appid, &add_pid)) {
TQCString actual_appid = Client::instance()->dcop()->registerAs(TQCString(appid), add_pid!=0);
return PyString_FromString(actual_appid.data());
return PyBytes_FromString(actual_appid.data());
}
return NULL;
}
@ -632,7 +632,7 @@ namespace PythonDCOP {
if (PyArg_ParseTuple(args, (char*)"O|s", &py_dcop_object, &objid)) {
Py_INCREF(py_dcop_object);
PCOPObject *obj = objid ? new PCOPObject(py_dcop_object, objid) : new PCOPObject(py_dcop_object);
return PyCObject_FromVoidPtr( (void*)obj, delete_dcop_object );
return PyCapsule_New( (void*)obj, NULL, (PyCapsule_Destructor)delete_dcop_object );
}
return NULL;
}
@ -646,7 +646,7 @@ namespace PythonDCOP {
PyObject *c_obj;
PyObject *method_list;
if (PyArg_ParseTuple(args, (char*)"OO", &c_obj, &method_list) &&
PyCObject_Check(c_obj) &&
PyCapsule_CheckExact(c_obj) &&
PyList_Check(method_list)) {
// extract each tuple from the list, aborting if any is invalid
@ -662,7 +662,7 @@ namespace PythonDCOP {
meth_list.insert(method_signature, py_method);
}
PCOPObject *obj = (PCOPObject*)PyCObject_AsVoidPtr(c_obj);
PCOPObject *obj = (PCOPObject*)PyCapsule_GetPointer(c_obj, NULL);
if (obj) {
if (!obj->setMethodList(meth_list)) return NULL;
}
@ -675,8 +675,8 @@ namespace PythonDCOP {
PyObject *get_method_list(PyObject */*self*/, PyObject *args) {
PyObject *c_obj;
if (PyArg_ParseTuple(args, (char*)"O", &c_obj)) {
if (PyCObject_Check(c_obj)) {
PCOPObject *obj = (PCOPObject*)PyCObject_AsVoidPtr(c_obj);
if (PyCapsule_CheckExact(c_obj)) {
PCOPObject *obj = (PCOPObject*)PyCapsule_GetPointer(c_obj, NULL);
return obj->methodList();
}
}
@ -736,7 +736,7 @@ namespace PythonDCOP {
for(QCStringList::ConstIterator it = qt_list.begin();
it!=qt_list.end();
++it,c++)
PyList_SetItem(l, c, PyString_FromString( (*it).data() ) );
PyList_SetItem(l, c, PyBytes_FromString( (*it).data() ) );
return l;
}
@ -757,14 +757,20 @@ PyMethodDef PCOPMethods[] = {
{ NULL, NULL, 0, NULL } /* Sentinel */
};
static struct PyModuleDef pcopmodule = {
PyModuleDef_HEAD_INIT,
"pcop",
NULL,
-1,
PCOPMethods
};
extern "C"
{
void initpcop()
{
(void) Py_InitModule( (char*)"pcop", PCOPMethods );
}
PyMODINIT_FUNC PyInit_pcop(void)
{
return PyModule_Create(&pcopmodule);
}
}

@ -7,14 +7,14 @@ import pydcop
app = pydcop.anyAppCalled( "kpresenter" )
if not app: raise RuntimeError, "Couldn't find a running KPresenter"
if not app: raise RuntimeError("Couldn't find a running KPresenter")
doc = app.KoApplicationIface.getDocuments()[0]
view = doc.view(0)
startAction = view.action( "screen_start" )
print "Starting Presentation %s" % doc.url()
print("Starting Presentation %s" % doc.url())
startAction.activate()
@ -27,4 +27,4 @@ while startAction.enabled() == 0:
act.activate()
view.screenStop()
print "Presentation finished."
print("Presentation finished.")

@ -7,7 +7,7 @@ inc_exceptions = {'TQDate': None, 'TQTime': None, 'KURL' : 'kurl'}
iface_inc_list = ['dcopobject']
iface_inc_list += [ t.lower() for t in type_list if t[0]=='Q' and t not in inc_exceptions ]
iface_inc_list += inc_exceptions.values()
iface_inc_list += list(inc_exceptions.values())
iface_inc_1 = ['class DCOPDemoIface : virtual public DCOPObject {',
' K_DCOP',
@ -39,7 +39,7 @@ files = {'tdedcoptest_iface.h': iface_inc,
'cpp_inc.h': cpp_inc
}
for (fname,data) in files.items():
for (fname,data) in list(files.items()):
outf = file(fname,'w')
for d in data:
outf.write(d+'\n')

@ -36,7 +36,7 @@ class ParrotObject(pydcop.DCOPServerObject):
appid = pydcop.registerAs('petshop')
print "Server: %s starting" % appid
print("Server: %s starting" % appid)
parrot = ParrotObject()
another_parrot = ParrotObject('polly')

@ -19,10 +19,10 @@ class MyObject(pydcop.DCOPServerObject):
self.setMethods( [('void test(TQString)', self.test)])
def test(self, data):
print "New Weather for " + data
print("New Weather for " + data)
appid = pydcop.registerAs('dcopSignalTest')
print "Server: %s starting" % appid
print("Server: %s starting" % appid)
pytest = MyObject()

@ -4,12 +4,12 @@ import pydcop
#res = pcop.dcop_call( "kspread", "default", "getDocuments", () )
res = pydcop.anyAppCalled("kspread").default.getDocuments()
print res
print res[0].appname
print res[0].name
print(res)
print(res[0].appname)
print(res[0].name)
m = res[0].map()
print m.tableNames()
print(m.tableNames())
print "done"
print("done")

@ -6,23 +6,23 @@ app = pydcop.anyAppCalled( "kspread" );
res = app.default.getDocuments()
print res
print res[0].appname
print res[0].name
print(res)
print(res[0].appname)
print(res[0].name)
m = res[0].map()
print m.tableNames()
print(m.tableNames())
x = m.table('Sheet2')
if x:
print x
print "===================="
print x._name
print "===================="
print x._name()
print "===================="
else: print "Could not find sheet called Sheet2"
print "done"
print(x)
print("====================")
print(x._name)
print("====================")
print(x._name())
print("====================")
else: print("Could not find sheet called Sheet2")
print("done")

@ -9,6 +9,6 @@ table = app.default.getViews()[0]
table.setSelection( ( 2, 2, 4, 6 ) )
table.setSelectionBgColor( (100, 100, 240) )
print rect
print(rect)
print "done"
print("done")

Loading…
Cancel
Save