We do not need to check if the attribute exist to raise an exception, setattr() yet raise a well formatted expection in case of failure.
This way we avoid a dir() call and an IN check in a hot path.
The only drawback is that this change the raised exception in the case an attr not exist, from AssertionError to AttributeError... I hope none was using that eception explicitly.
A quote from Cython documentation:
"The other direction, i.e. automatic encoding to C strings, is only supported
for the ASCII codec (and the “default encoding”, which is runtime specific
and may or may not be ASCII). This is because CPython handles the memory
management in this case by keeping an encoded copy of the string alive
together with the original unicode string. Otherwise, there would be no way
to limit the lifetime of the encoded string in any sensible way, thus
rendering any attempt to extract a C string pointer from it a dangerous
endeavour."
Cython plays it safe and we can't live with ASCII-only; reverting to
our earlier "hacks" for string conversion.
This reverts commit b547ff2aa2.
Conflicts:
efl/elementary/entry.pyx
efl/elementary/object.pyx
Elm was lgpl3, COPYING was lgpl3, docs say lgpl3. So fix everything to be v3.
Also fix the COPING for Lesser: we must include gpl (in COPYING) AND lgpl (in COPYING.LESSER).
With "except *" a call is made to PyErr_Occurred on each call of a
function.
Adding a return value where possible and using an appropriate exception
value calls PyErr_Occurred only when that value is returned, ie.
an exception has been raised.
cdef void example_func() except *: <- PyErr_Occurred called on each call
cdef int example_func() except 0: <- PyErr_Occurred called only when
an exception has been raised (the function thus returns 0)
hasattr tries getattr which can be variedly slow, so check dict instead.
This also fixes it in cases where the property doesn't have a __get__
function.
Calling str() uses __repr__ when __str__ is not found.
__repr__ should return a string with angle brackets when the object
cannot be reconstructed with exec(repr(obj)).
Has two loggers: efl and efl.eo.
To test, add handlers, formatters etc. and change levels using
normal Python logging utilities. The test messages come from
efl.eo init and class registration.
Decorators implemented in a much more simple and generic
way than before, we can use them in other place too.
3 deco implemented:
@on_signal(emission, source)
@message_handler
@on_text_change
I choosed the 'strange' on_* naming convention to not
clash/confuse with normal callback functions, tell
me if you don't like.
__dealloc__ methods. Initializing them *seems* to be safe though.
And there's no need to initialize either the C objects to NULL nor
python objects to None, this gets done automatically by Cython, along
with initializing integers to 0.
Now you can write:
if not my_obj:
raise VeryBadError("My object is gone!")
and:
if my_obj:
my_obj.manipulate()
instead of:
if my_obj.is_deleted()
raise ErrorBadVery("Where did it go?")
and:
if not my_obj.is_deleted():
my_obj.manipulate()
But really, we should add NULL checks all over the place instead of
having the end developers checking for it.