[PyKDE] Incorrect line numbers in compiler error messages

2005-07-07 Thread Denis S. Otkidach
As I can see sip removes empty line when generating .cpp files.  This
causes incorrect line numbers in error messages from compiler calculated
from values in #line directives.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


[PyKDE] Bug in code for wrapped attributes

2005-07-02 Thread Denis S. Otkidach
Below is a code generated for wrapped attribute (PyObject* in original
class, SIP_PYOBJECT in SIP spec):

--8--
static PyObject *var_MyClass_myAttr(PyObject *sipSelf,PyObject *sipPy)
{
PyObject * sipVal;
MyClass *sipCpp = reinterpret_castMyClass *(sipGetCppPtr((sipWrapper 
*)sipSelf,sipClass_MyClass));

if (!sipCpp)
return NULL;

if (sipPy == NULL)
{
sipVal = sipCpp - myAttr;

Py_XINCREF(sipVal);

return sipVal;
}   

sipVal = sipPy;

if (PyErr_Occurred() != NULL)
{
sipBadSetType(sipNm_MyModule_MyClass,sipNm_MyModule_myAttr);
return NULL;
}

Py_INCREF(sipVal); // -- missed increment
sipCpp - myAttr = sipVal;

Py_INCREF(Py_None);
return Py_None;
}
--8--

There is no line marked with missed increment in generated code, so
attribute value has incorrect reference count causing strange behavior
and/or segmentation fault.

The story about how I discovered this bug is quite interesting.  I've
written test script looking like the following:

foo = MyModule.Foo()
foo.myAttr = lambda *args: args
bar = foo.createBar()  # bar constructor assignes foo.myAttr to bar.myAttr
def newMyAttr(*args):
print 'newMyAttr called with', args
bar.doSmth() # this method calls bar.myAttr

I defined newMyAttr as replacement for earlier assigned function. Then I
run the script and so expected output newMyAttr called with (2, 1, 2).
 Just a minute later I discovered that I'd actually forgotten to assign
newMyAttr to bar.myAttr!  Then why it's called?!  Did Python conjectured
that I wanted to assign newMyAttr itself?  Looked like a mistery.  I
added print bar.myAttr before and after newMyAttr definition and saw:

converter: function lambda at 0x30c994
converter: function newMyAttr at 0x30c994

Hey, these objects have the same address!  Farther experiments proved my
guess that lambda object was destroyed.  In fact, after changing

foo.myAttr = lambda *args: args

into

f = lambda *args: args
foo.myAttr = f

the problem disappeared.  Putting print sys.getrefcount(f) showed 2
when 3 expected (f itself, foo.myAttr, and argument to getrefcount).

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-07-01 Thread Denis S. Otkidach
On Thu, 30 Jun 2005 17:24:27 +0100
Phil Thompson [EMAIL PROTECTED] wrote:

  4) There are several standard exceptions which I always have to catch.
  Now I have a macro for them:
 
  #define CATCH_STD_EXCEPTIONS \
  catch (std::bad_alloc) {\
  PyErr_NoMemory(); \
  sipIsErr = 1; \
  } catch (std::exception exc) {\
  PyErr_SetString(PyExc_RuntimeError, exc.what()); \
  sipIsErr = 1; \
  } catch (...) {\
  PyErr_SetString(PyExc_RuntimeError, unknown); \
  sipIsErr = 1; \
  }
 
  used in %MethodCode:
 
  %MethodCode
  try {
  sipRes = someMethod(...);
  } CATCH_STD_EXCEPTIONS // sipIsErr - this comment is important hint to
  SIP! %End
 
 If your point is the need for the comment, then yes - consider it a feature.

No, I meant these exceptions must be caught almost everywhere.  So I
have to add %MethodCode to almost every method, which is annoying.  The
latest release of SIP always catch all exceptions with catch(...)
clause with -e option, but now it doesn't.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-07-01 Thread Denis S. Otkidach
On Thu, 30 Jun 2005 17:24:27 +0100
Phil Thompson [EMAIL PROTECTED] wrote:

  1) If sipExceptionRef is not used in RaiseCode we'll get a warning.
 
 Tonight's snapshot will only generate it if it is used.

Now I get no sipExceptionRef in catch clause even when it's used in
%RaiseCode.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-07-01 Thread Denis S. Otkidach
On Fri, 1 Jul 2005 08:54:19 +0100
Phil Thompson [EMAIL PROTECTED] wrote:

 Whoops. Change the argument to the strstr() call that checks for 
 sipExceptionRef from...
 
 xd-raisecode
 
 ...to...
 
 xd-raisecode-frag

Now it works fine, thanks.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-07-01 Thread Denis S. Otkidach
On Fri, 1 Jul 2005 17:37:44 +0100
Phil Thompson [EMAIL PROTECTED] wrote:

 If we solve the problem of how to specify ... then you could define 
 std::bad_alloc, std::exception, and (somehow) ... using %Exception and 
 then...
 
   void foo() throw (std::bad_alloc, std::exception, ...);
 
 If this is too much trouble, then I can only suggest implementing something 
 like %DefaultExceptionHandler than contains your code and is applied to 
 anything that has no throw specifier (so long as the -e option is used).

I think we need some more feedback from other SIP users before going farther.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-06-30 Thread Denis S. Otkidach
On Wed, 29 Jun 2005 15:59:08 +0100
Phil Thompson [EMAIL PROTECTED] wrote:

  sip command passes without error, but I have an error when linking:
  $OFILES in Makefile contains sipMyModuleMyException.o, while there is no
  corresponding .cpp file generated.
 
  BTW, when I use throw specifier in method signature without
  corresponding %Exception directive, sip exits with non-zero code, but
  reports no error message.
 
  All tests were done with sip-snapshot-20050626.
 
 Should be fixed in tonight's snapshot.

Simple examples work like a charm with sip-snapshot-20050629, thanks!
There are some points to discuss: 

1) If sipExceptionRef is not used in RaiseCode we'll get a warning. 

2) Exceptions that were not specified in throw are not caught and I see
no way to add catch(...) to generated code.

3) throw specifier has no effect on generated code when %MethodCode is
used, shouldn't it?

4) There are several standard exceptions which I always have to catch. 
Now I have a macro for them:

#define CATCH_STD_EXCEPTIONS \
catch (std::bad_alloc) {\
PyErr_NoMemory(); \
sipIsErr = 1; \
} catch (std::exception exc) {\
PyErr_SetString(PyExc_RuntimeError, exc.what()); \
sipIsErr = 1; \
} catch (...) {\
PyErr_SetString(PyExc_RuntimeError, unknown); \
sipIsErr = 1; \
}

used in %MethodCode:

%MethodCode
try {
sipRes = someMethod(...);
} CATCH_STD_EXCEPTIONS // sipIsErr - this comment is important hint to SIP!
%End

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-06-29 Thread Denis S. Otkidach
On Sun, 26 Jun 2005 23:05:33 +0100
Phil Thompson [EMAIL PROTECTED] wrote:

 Support for this is in tonight's snapshot - some changes to what I described 
 above, but nothing sigificant.
 
 Support for converting Python exceptions to C++ exceptions in Python 
 re-implementations of C++ virtuals not yet implemented.
 
 This hasn't been tested - feedback please.

sip command passes without error, but I have an error when linking:
$OFILES in Makefile contains sipMyModuleMyException.o, while there is no
corresponding .cpp file generated.

BTW, when I use throw specifier in method signature without
corresponding %Exception directive, sip exits with non-zero code, but
reports no error message.

All tests were done with sip-snapshot-20050626.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


[PyKDE] Docstrings with SIP

2005-06-21 Thread Denis S. Otkidach
Is there a way to provide docstrings for module, classes and their
methods without hacking generated structures?

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] SIP parse error

2005-06-21 Thread Denis S. Otkidach
On Sun, 19 Jun 2005 14:37:48 +0100
Phil Thompson [EMAIL PROTECTED] wrote:

 On Friday 17 June 2005 9:13 pm, James Emerton wrote:
  There is a small issue with the parsing code in SIP.  I get a parse
  error whenever a %MethodCode section contains a %, such as a printf()
  format string.
 
  My workaround right now is to use something like this...
  const char fmt[] = { 37, '0', '4', 'd', 37, '0', '2', 'd', 37, '0',
  '2', 'd', 0 };
 
 Should be fixed in tonight's snapshot.

I see some strange syntax errors with this snapshot for project
successfully built with sip-snapshot-20050605.  In all cases the error
is in %Included file and in one case the error is at line 271 of file
having 214 lines.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] SIP parse error

2005-06-21 Thread Denis S. Otkidach
On Tue, 21 Jun 2005 15:52:15 +0100 (BST)
Phil Thompson [EMAIL PROTECTED] wrote:

  I see some strange syntax errors with this snapshot for project
  successfully built with sip-snapshot-20050605.  In all cases the error
  is in %Included file and in one case the error is at line 271 of file
  having 214 lines.
 
 Can you send me a test case?

Looks like I've found one minimal example:
== sip_bug.sip ==
%Module sip_bug

%PostInitialisationCode
(void)0;
%End

%Include MyClass.sip
== MyClass.sip ==
%ModuleHeaderCode
class MyClass {
public:
void method() {};
};
// If you remove next line the error gone

%End

class MyClass {
public:
void method();
%MethodCode
(void)0;
%End
};
==
$ ./configure_sip_bug.py
sip -e -w -c . -b sip_bug.sbf sip_bug.sip
sip: MyClass.sip:20: syntax error

As you can see MyClass.sip consist of 16 lines only.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] SIP parse error

2005-06-18 Thread Denis S. Otkidach
On Fri, 17 Jun 2005 13:13:28 -0700
James Emerton [EMAIL PROTECTED] wrote:

 There is a small issue with the parsing code in SIP.  I get a parse
 error whenever a %MethodCode section contains a %, such as a printf()
 format string.
 
 My workaround right now is to use something like this...
 const char fmt[] = { 37, '0', '4', 'd', 37, '0', '2', 'd', 37, '0',
 '2', 'd', 0 };

I have the same issue when using modulo operator.  I've defined
alternative spelling for it in separate header file as workaround.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-06-18 Thread Denis S. Otkidach
On Thu, 9 Jun 2005 09:33:22 -0700
James Emerton [EMAIL PROTECTED] wrote:

 I think there is a need for biderectional conversion of exceptions. 
 I'd like to be able to throw them back into the C++.
 
 In fact, a mechanism that could be enable to check the Python error
 state after calling a Python method from C++ could throw the exception
 instead of returning to the C++.

Could you provide some examples?  I see 2 use cases:

1) Your C++ method accepts callback function implemented in Python.  SIP
translates C++ functions to Python, but it doesn't translate Python
callables to C++ ones.  You have to call it yourself.  There is no even
automatic argument translation for it.  Why do you think exception
should be translated automatically?  You can never trust user provided
Python code, you can't predict what exceptions it will ever raise, so
you have to handle all possible errors.  I even can't imaging syntax for
backward exception translation.

2) You overwrite virtual method of wrapped class in Python, so that
other methods (implemented in C++) use it instead of base.  This is more
interesting case, but I believe SIP can't handle it too.  Please correct
me if I'm wrong.

So far I don't see any need for automatic backward exception
translation, since you have to code mannually Python exception handling
anyway.

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


[PyKDE] Static (why?) PyDateTimeAPI and SIP

2005-06-18 Thread Denis S. Otkidach
I use datetime C API in extension module generated with SIP.  But SIP
break the code into several .cpp files compiled separately and
PyDateTimeAPI used by all macros constituting public interface is
declared static.

The current solution is to define my own functions in main module as
workaround:

%ModuleHeaderCode
PyObject * mxo_PyDateTime_FromDateAndTime(int year, int month, int day,
  int hour, int minute, int seconds,
  int usecs);
%End

%ModuleCode
PyObject * mxo_PyDateTime_FromDateAndTime(int year, int month, int day,
  int hour, int minute, int seconds,
  int usecs) {
return PyDateTime_FromDateAndTime(year, month, day, hour, minute, seconds,
  usecs);
}
// and so on for each macro used
%End

%PostInitialisationCode
PyDateTime_IMPORT;
%End

But I wonder why PyDateTimeAPI is declared static, and is the a better
solution?

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-06-07 Thread Denis S. Otkidach
On Mon, 6 Jun 2005 17:54:43 +0100
Phil Thompson [EMAIL PROTECTED] wrote:

 SIP's exception support was added by a user - I've never used it myself. 
 Suggestions for improvements always welcome.

I see the following scenario.  User creates exception class and expose
it in module namespace (Please correct me if there is a better way):

%ModuleCode
static PyObject *MyException_object;
%End

%PostInitialisationCode
MyException_object = PyErr_NewException(MyModule.MyException, 0, 0);
if (!MyException_object) return;
PyDict_SetItemString(sip_mdict, MyException, MyException_object);
%End

Then he has to define one way mapping for it (assuming MyException has
the same interface as std::exception):

%MappedType MyException
{

%ConvertFromTypeCode
return PyObject_CallFunction(MyException_object, S, sipCpp-what());
%End

%ConvertToTypeCode
// We don't need backward convertion, but SIP requires it.
*sipIsErr = 1;
return 0;
%End

};


That's all.  Now generated code for method with signature 
void error() throw (MyException); should be equivalent to 
something like the following:

try
{
sipCpp - Test::error();
}
catch (MyException e)
{
PyObject *MyException_instance = ... // %ConvertFromTypeCode
PyObject *MyException_object = PyObject_Type(MyException_instance);
PyErr_SetObject(MyException_object, MyException_instance);
return NULL;
}


-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Handling exceptions in SIP

2005-06-07 Thread Denis S. Otkidach
On Tue, 7 Jun 2005 13:30:29 +0100 (BST)
Phil Thompson [EMAIL PROTECTED] wrote:

 Ok. How about this...
 
 %Exception MyException - will be used with an externally defined
 exception. (Note, you will not be able to specify a base exception, but
 why would you want to?)
 
 %Exception MyException(Base) - will be used to specify a derived
 exception. SIP will recognise Exception as the standard Python
 exception, eg.
 
 %Exception MyBase(Exception)
 
 %Exception MyException(MyBase)

Looks a bit tricky, but it suites all possible cases I think.  Let it be
so.

 Or maybe an empty base exception should be interpreted as the standard
 Python exception, eg.
 
 %Exception MyBase()
 
 ???

It doesn't matter for me.

  Exactly.  Calling PyErr_SetString etc. is quite convenient for extension
  module authors vs. returning initialized exception instance.
 
 So we have...
 
 %RaiseCode
 // Raise a Python exception.  sipCpp will be the C++ pointer,
 // sipException_MyException will be the exception type (unless the
 // exception was defined externally).
 PyObject *val = PyObject_CallFunction(sipException_MyException,
   S, sipCpp-what());
 
 PyErr_SetObject(sipException_MyException, val);
 %End

In most cases it will be even simplier:

%RaiseCode
PyErr_SetString(sipException_MyException, sipCpp-what());
%End

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


Re: [PyKDE] Wrapped classes without constructor

2005-06-07 Thread Denis S. Otkidach
On Tue, 7 Jun 2005 15:20:40 +0100 (BST)
Phil Thompson [EMAIL PROTECTED] wrote:

  I have several classes which shouldn't be initialized by user.  Neither
  /Abstract/, nor declaring constructor private helps, since in both
  cases generated class doesn't have destructor, which in my case is
  mandatory.  I use the following code to clear constructor:
 
  %PreInitialisationCode
  sipType_MyClass.td_init = 0;
  %End
 
  Is there a better way I've missed?
 
 What version of SIP? 

$ sip -V
4.2.1 (4.2.1-297)

 The current snapshot *might* be more helpful as there
 have been changes in this area.

Thanks, after upgrade to recent snapshot wrapped class has destructor
with /Abstract/.  But the class is added to module namespace.  Could the
latter be controlled too?

-- 
Denis S. Otkidach
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde


[PyKDE] Handling exceptions in SIP

2005-06-06 Thread Denis S. Otkidach
I hope it's correct place to ask general questions about SIP.

Am I correct that automatic exception handling in SIP is useless?  I see
several problems with it.  First, the code for method with signature
void error() throw (exception); is:

try
{
sipCpp - Test::error();
}
catch (exception e)
{
/* Hope that there is a valid copy ctor. */ 
exception *sipCpp = new exception(e);

sipRaiseClassException(sipClass_exception,sipCpp);
return NULL;
} 

The copy of exception is generated and important information is lost (in
fact, std::exception used above is never raised itself, but holds what()
virtual method redefined in subclasses).

Second, the only way to map C++ exception to python object is wrapping
exception class, %MappedType doesn't work.  But then I see no way to
subclass standard Exception class.

Am I missing something?

-- 
Denis S. Otkidach 
http://www.python.ru/  [ru]

___
PyKDE mailing listPyKDE@mats.imk.fraunhofer.de
http://mats.imk.fraunhofer.de/mailman/listinfo/pykde