Recently I used cython in my project and I came with idea that sometimes virtual methods are overkill. What's about adding non-virtual decorator for c[p]def methods? cdef class Foo: @cython.nonvirtual cpdef int is_active(self): return clib.obj_is_active(self._cobj) -- vitja.
Vitja Makarov, 24.08.2011 21:00:
Recently I used cython in my project and I came with idea that sometimes virtual methods are overkill.
What's about adding non-virtual decorator for c[p]def methods?
cdef class Foo: @cython.nonvirtual cpdef int is_active(self): return clib.obj_is_active(self._cobj)
How does that differ from the "final" decorator? Stefan
2011/8/24 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 24.08.2011 21:00:
Recently I used cython in my project and I came with idea that sometimes virtual methods are overkill.
What's about adding non-virtual decorator for c[p]def methods?
cdef class Foo: @cython.nonvirtual cpdef int is_active(self): return clib.obj_is_active(self._cobj)
How does that differ from the "final" decorator?
I tried final classes: 1. Final decorator doesn't work at pxd level (compiler crash) 2. In this example foo call is done through virtual table cimport cython @cython.final cdef class Foo: cdef foo(self): print 'haha' def test(): cdef Foo a = Foo() a.foo() __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;} 3. I can't use final decorator for methods (error reported) -- vitja.
On Wed, Aug 24, 2011 at 12:17 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/24 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 24.08.2011 21:00:
Recently I used cython in my project and I came with idea that sometimes virtual methods are overkill.
What's about adding non-virtual decorator for c[p]def methods?
cdef class Foo: @cython.nonvirtual cpdef int is_active(self): return clib.obj_is_active(self._cobj)
How does that differ from the "final" decorator?
I tried final classes: 1. Final decorator doesn't work at pxd level (compiler crash) 2. In this example foo call is done through virtual table
cimport cython
@cython.final cdef class Foo: cdef foo(self): print 'haha'
def test(): cdef Foo a = Foo() a.foo()
__pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
3. I can't use final decorator for methods (error reported)
I don't think "final methods" were actually implemented, it's just a question of naming. - Robert
2011/8/24 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/24 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 24.08.2011 21:00:
Recently I used cython in my project and I came with idea that sometimes virtual methods are overkill.
What's about adding non-virtual decorator for c[p]def methods?
cdef class Foo: @cython.nonvirtual cpdef int is_active(self): return clib.obj_is_active(self._cobj)
How does that differ from the "final" decorator?
I tried final classes: 1. Final decorator doesn't work at pxd level (compiler crash) 2. In this example foo call is done through virtual table
cimport cython
@cython.final cdef class Foo: cdef foo(self): print 'haha'
def test(): cdef Foo a = Foo() a.foo()
__pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
3. I can't use final decorator for methods (error reported)
I think this ticket is about it http://trac.cython.org/cython_trac/ticket/586 -- vitja.
Vitja Makarov, 24.08.2011 21:17:
2011/8/24 Stefan Behnel:
Vitja Makarov, 24.08.2011 21:00:
Recently I used cython in my project and I came with idea that sometimes virtual methods are overkill.
What's about adding non-virtual decorator for c[p]def methods?
cdef class Foo: @cython.nonvirtual cpdef int is_active(self): return clib.obj_is_active(self._cobj)
How does that differ from the "final" decorator?
I tried final classes: 1. Final decorator doesn't work at pxd level (compiler crash)
Sounds like a bug.
2. In this example foo call is done through virtual table
cimport cython
@cython.final cdef class Foo: cdef foo(self): print 'haha'
def test(): cdef Foo a = Foo() a.foo()
__pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
Right, this is not implemented yet. Feel free to do so. Also see http://trac.cython.org/cython_trac/ticket/474
3. I can't use final decorator for methods (error reported)
2011/8/24 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 24.08.2011 21:17:
2011/8/24 Stefan Behnel:
Vitja Makarov, 24.08.2011 21:00:
Recently I used cython in my project and I came with idea that sometimes virtual methods are overkill.
What's about adding non-virtual decorator for c[p]def methods?
cdef class Foo: @cython.nonvirtual cpdef int is_active(self): return clib.obj_is_active(self._cobj)
How does that differ from the "final" decorator?
I tried final classes: 1. Final decorator doesn't work at pxd level (compiler crash)
Sounds like a bug.
2. In this example foo call is done through virtual table
cimport cython
@cython.final cdef class Foo: cdef foo(self): print 'haha'
def test(): cdef Foo a = Foo() a.foo()
__pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
Right, this is not implemented yet. Feel free to do so. Also see
http://trac.cython.org/cython_trac/ticket/474
3. I can't use final decorator for methods (error reported)
What is the prefered syntax keyword inline or final decorator? -- vitja.
Vitja Makarov, 25.08.2011 18:11:
2011/8/24 Stefan Behnel:
Vitja Makarov, 24.08.2011 21:17:
I tried final classes: 2. In this example foo call is done through virtual table
cimport cython
@cython.final cdef class Foo: cdef foo(self): print 'haha'
def test(): cdef Foo a = Foo() a.foo()
__pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
Right, this is not implemented yet. Feel free to do so. Also see
http://trac.cython.org/cython_trac/ticket/474
3. I can't use final decorator for methods (error reported)
What is the prefered syntax keyword inline or final decorator?
"final" is the right option here. They are orthogonal concepts. Only because you declare a method "final" does not mean you want to inline it, and just because you declare it "inline" does not (necessarily) mean that you cannot override it. Admittedly, the semantics of an overridable inline method may turn out to be somewhat obscure and error prone, so I think it's a good idea to let "inline" imply "final". But not the other way round. Stefan
2011/8/25 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 18:11:
2011/8/24 Stefan Behnel:
Vitja Makarov, 24.08.2011 21:17:
I tried final classes: 2. In this example foo call is done through virtual table
cimport cython
@cython.final cdef class Foo: cdef foo(self): print 'haha'
def test(): cdef Foo a = Foo() a.foo()
__pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
Right, this is not implemented yet. Feel free to do so. Also see
http://trac.cython.org/cython_trac/ticket/474
3. I can't use final decorator for methods (error reported)
What is the prefered syntax keyword inline or final decorator?
"final" is the right option here.
They are orthogonal concepts. Only because you declare a method "final" does not mean you want to inline it, and just because you declare it "inline" does not (necessarily) mean that you cannot override it. Admittedly, the semantics of an overridable inline method may turn out to be somewhat obscure and error prone, so I think it's a good idea to let "inline" imply "final". But not the other way round.
But both inline and final methods should bypass vtab, right? Also I'm not sure about C inline qualifier here. I see three options: - non-virtual: bypass vtab - final: non-virtual, non-overridable - inline: non-virtual, C inline qualifier is used -- vitja.
Vitja Makarov, 25.08.2011 20:32:
2011/8/25 Stefan Behnel<stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 18:11:
2011/8/24 Stefan Behnel:
Vitja Makarov, 24.08.2011 21:17:
I tried final classes: 2. In this example foo call is done through virtual table
cimport cython
@cython.final cdef class Foo: cdef foo(self): print 'haha'
def test(): cdef Foo a = Foo() a.foo()
__pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
Right, this is not implemented yet. Feel free to do so. Also see
http://trac.cython.org/cython_trac/ticket/474
3. I can't use final decorator for methods (error reported)
What is the prefered syntax keyword inline or final decorator?
"final" is the right option here.
They are orthogonal concepts. Only because you declare a method "final" does not mean you want to inline it, and just because you declare it "inline" does not (necessarily) mean that you cannot override it. Admittedly, the semantics of an overridable inline method may turn out to be somewhat obscure and error prone, so I think it's a good idea to let "inline" imply "final". But not the other way round.
But both inline and final methods should bypass vtab, right?
Yes. But in the "final" case, it's always clear which method implementation to use - it's not overridable, so there is only one choice. In the "inline" case, it could still be overridable and we may have a subtype of the declared type in our hands at runtime, thus choosing the wrong method at compile time. That's why only the "final" case is safe. Note that I'm only talking about the semantics of the qualifier themselves here. If we allow "inline" methods, I think we should force them to be "final" as well. But that's a practical choice, not a semantic implication.
Also I'm not sure about C inline qualifier here.
That's what "inline" requests.
I see three options:
- non-virtual: bypass vtab - final: non-virtual, non-overridable
How would you want to bypass the vtable in the "non-virtual" case if the method is overridable?
- inline: non-virtual, C inline qualifier is used
Correct. Stefan
2011/8/25 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 20:32:
2011/8/25 Stefan Behnel<stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 18:11:
2011/8/24 Stefan Behnel:
Vitja Makarov, 24.08.2011 21:17:
I tried final classes: 2. In this example foo call is done through virtual table
cimport cython
@cython.final cdef class Foo: cdef foo(self): print 'haha'
def test(): cdef Foo a = Foo() a.foo()
__pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = __LINE__; goto __pyx_L1_error;}
Right, this is not implemented yet. Feel free to do so. Also see
http://trac.cython.org/cython_trac/ticket/474
3. I can't use final decorator for methods (error reported)
What is the prefered syntax keyword inline or final decorator?
"final" is the right option here.
They are orthogonal concepts. Only because you declare a method "final" does not mean you want to inline it, and just because you declare it "inline" does not (necessarily) mean that you cannot override it. Admittedly, the semantics of an overridable inline method may turn out to be somewhat obscure and error prone, so I think it's a good idea to let "inline" imply "final". But not the other way round.
But both inline and final methods should bypass vtab, right?
Yes. But in the "final" case, it's always clear which method implementation to use - it's not overridable, so there is only one choice. In the "inline" case, it could still be overridable and we may have a subtype of the declared type in our hands at runtime, thus choosing the wrong method at compile time. That's why only the "final" case is safe.
Note that I'm only talking about the semantics of the qualifier themselves here. If we allow "inline" methods, I think we should force them to be "final" as well. But that's a practical choice, not a semantic implication.
Also I'm not sure about C inline qualifier here.
That's what "inline" requests.
I see three options:
- non-virtual: bypass vtab - final: non-virtual, non-overridable
How would you want to bypass the vtable in the "non-virtual" case if the method is overridable?
- inline: non-virtual, C inline qualifier is used
Correct.
Ok. I think it's better to implement final method then user could choose to use inline qualifier or not. -- vitja.
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 20:32:
2011/8/25 Stefan Behnel<stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 18:11:
2011/8/24 Stefan Behnel:
Vitja Makarov, 24.08.2011 21:17: > > I tried final classes: > 2. In this example foo call is done through virtual table > > cimport cython > > @cython.final > cdef class Foo: > cdef foo(self): > print 'haha' > > def test(): > cdef Foo a = Foo() > a.foo() > > __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo > *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) > {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = > __LINE__; goto __pyx_L1_error;}
Right, this is not implemented yet. Feel free to do so. Also see
http://trac.cython.org/cython_trac/ticket/474
> 3. I can't use final decorator for methods (error reported)
What is the prefered syntax keyword inline or final decorator?
"final" is the right option here.
They are orthogonal concepts. Only because you declare a method "final" does not mean you want to inline it, and just because you declare it "inline" does not (necessarily) mean that you cannot override it. Admittedly, the semantics of an overridable inline method may turn out to be somewhat obscure and error prone, so I think it's a good idea to let "inline" imply "final". But not the other way round.
But both inline and final methods should bypass vtab, right?
Yes. But in the "final" case, it's always clear which method implementation to use - it's not overridable, so there is only one choice. In the "inline" case, it could still be overridable and we may have a subtype of the declared type in our hands at runtime, thus choosing the wrong method at compile time. That's why only the "final" case is safe.
Note that I'm only talking about the semantics of the qualifier themselves here. If we allow "inline" methods, I think we should force them to be "final" as well. But that's a practical choice, not a semantic implication.
Also I'm not sure about C inline qualifier here.
That's what "inline" requests.
I see three options:
- non-virtual: bypass vtab - final: non-virtual, non-overridable
How would you want to bypass the vtable in the "non-virtual" case if the method is overridable?
- inline: non-virtual, C inline qualifier is used
Correct.
Ok.
I think it's better to implement final method then user could choose to use inline qualifier or not.
I tried it here: https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d... There is one problem: vtab bypassing should be enabled if final method is defined in the same module. I don't know how to check that final method comes from cimport (it's okay with pxd, the problem is pyx) -- vitja.
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 20:32:
2011/8/25 Stefan Behnel<stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 18:11:
2011/8/24 Stefan Behnel: > > Vitja Makarov, 24.08.2011 21:17: >> >> I tried final classes: >> 2. In this example foo call is done through virtual table >> >> cimport cython >> >> @cython.final >> cdef class Foo: >> cdef foo(self): >> print 'haha' >> >> def test(): >> cdef Foo a = Foo() >> a.foo() >> >> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >> __LINE__; goto __pyx_L1_error;} > > Right, this is not implemented yet. Feel free to do so. Also see > > http://trac.cython.org/cython_trac/ticket/474 > > >> 3. I can't use final decorator for methods (error reported) > > http://trac.cython.org/cython_trac/ticket/586
What is the prefered syntax keyword inline or final decorator?
"final" is the right option here.
They are orthogonal concepts. Only because you declare a method "final" does not mean you want to inline it, and just because you declare it "inline" does not (necessarily) mean that you cannot override it. Admittedly, the semantics of an overridable inline method may turn out to be somewhat obscure and error prone, so I think it's a good idea to let "inline" imply "final". But not the other way round.
But both inline and final methods should bypass vtab, right?
Yes. But in the "final" case, it's always clear which method implementation to use - it's not overridable, so there is only one choice. In the "inline" case, it could still be overridable and we may have a subtype of the declared type in our hands at runtime, thus choosing the wrong method at compile time. That's why only the "final" case is safe.
Note that I'm only talking about the semantics of the qualifier themselves here. If we allow "inline" methods, I think we should force them to be "final" as well. But that's a practical choice, not a semantic implication.
Also I'm not sure about C inline qualifier here.
That's what "inline" requests.
I see three options:
- non-virtual: bypass vtab - final: non-virtual, non-overridable
How would you want to bypass the vtable in the "non-virtual" case if the method is overridable?
- inline: non-virtual, C inline qualifier is used
Correct.
Ok.
I think it's better to implement final method then user could choose to use inline qualifier or not.
I tried it here: https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d...
There is one problem: vtab bypassing should be enabled if final method is defined in the same module. I don't know how to check that final method comes from cimport (it's okay with pxd, the problem is pyx)
https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef... Here is update version. I've add tree asserts and final method's prototypes. -- vitja.
2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 20:32:
2011/8/25 Stefan Behnel<stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 18:11: > > 2011/8/24 Stefan Behnel: >> >> Vitja Makarov, 24.08.2011 21:17: >>> >>> I tried final classes: >>> 2. In this example foo call is done through virtual table >>> >>> cimport cython >>> >>> @cython.final >>> cdef class Foo: >>> cdef foo(self): >>> print 'haha' >>> >>> def test(): >>> cdef Foo a = Foo() >>> a.foo() >>> >>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>> __LINE__; goto __pyx_L1_error;} >> >> Right, this is not implemented yet. Feel free to do so. Also see >> >> http://trac.cython.org/cython_trac/ticket/474 >> >> >>> 3. I can't use final decorator for methods (error reported) >> >> http://trac.cython.org/cython_trac/ticket/586 > > What is the prefered syntax keyword inline or final decorator?
"final" is the right option here.
They are orthogonal concepts. Only because you declare a method "final" does not mean you want to inline it, and just because you declare it "inline" does not (necessarily) mean that you cannot override it. Admittedly, the semantics of an overridable inline method may turn out to be somewhat obscure and error prone, so I think it's a good idea to let "inline" imply "final". But not the other way round.
But both inline and final methods should bypass vtab, right?
Yes. But in the "final" case, it's always clear which method implementation to use - it's not overridable, so there is only one choice. In the "inline" case, it could still be overridable and we may have a subtype of the declared type in our hands at runtime, thus choosing the wrong method at compile time. That's why only the "final" case is safe.
Note that I'm only talking about the semantics of the qualifier themselves here. If we allow "inline" methods, I think we should force them to be "final" as well. But that's a practical choice, not a semantic implication.
Also I'm not sure about C inline qualifier here.
That's what "inline" requests.
I see three options:
- non-virtual: bypass vtab - final: non-virtual, non-overridable
How would you want to bypass the vtable in the "non-virtual" case if the method is overridable?
- inline: non-virtual, C inline qualifier is used
Correct.
Ok.
I think it's better to implement final method then user could choose to use inline qualifier or not.
I tried it here: https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d...
There is one problem: vtab bypassing should be enabled if final method is defined in the same module. I don't know how to check that final method comes from cimport (it's okay with pxd, the problem is pyx)
https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef...
Here is update version. I've add tree asserts and final method's prototypes.
-- vitja.
I've created ticket for compiler crash when cython.final is used inside pxd file: http://trac.cython.org/cython_trac/ticket/722 Also I've updated final methods test case (added tree path assertions) https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4... About declaration origin detection may be it's a good idea to have a flag at scope level something like is_pxd_scope or is_declaration_scope? -- vitja.
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 20:32:
2011/8/25 Stefan Behnel<stefan_ml@behnel.de>: > > Vitja Makarov, 25.08.2011 18:11: >> >> 2011/8/24 Stefan Behnel: >>> >>> Vitja Makarov, 24.08.2011 21:17: >>>> >>>> I tried final classes: >>>> 2. In this example foo call is done through virtual table >>>> >>>> cimport cython >>>> >>>> @cython.final >>>> cdef class Foo: >>>> cdef foo(self): >>>> print 'haha' >>>> >>>> def test(): >>>> cdef Foo a = Foo() >>>> a.foo() >>>> >>>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>>> __LINE__; goto __pyx_L1_error;} >>> >>> Right, this is not implemented yet. Feel free to do so. Also see >>> >>> http://trac.cython.org/cython_trac/ticket/474 >>> >>> >>>> 3. I can't use final decorator for methods (error reported) >>> >>> http://trac.cython.org/cython_trac/ticket/586 >> >> What is the prefered syntax keyword inline or final decorator? > > "final" is the right option here. > > They are orthogonal concepts. Only because you declare a method "final" > does > not mean you want to inline it, and just because you declare it "inline" > does not (necessarily) mean that you cannot override it. Admittedly, the > semantics of an overridable inline method may turn out to be somewhat > obscure and error prone, so I think it's a good idea to let "inline" > imply > "final". But not the other way round.
But both inline and final methods should bypass vtab, right?
Yes. But in the "final" case, it's always clear which method implementation to use - it's not overridable, so there is only one choice. In the "inline" case, it could still be overridable and we may have a subtype of the declared type in our hands at runtime, thus choosing the wrong method at compile time. That's why only the "final" case is safe.
Note that I'm only talking about the semantics of the qualifier themselves here. If we allow "inline" methods, I think we should force them to be "final" as well. But that's a practical choice, not a semantic implication.
Also I'm not sure about C inline qualifier here.
That's what "inline" requests.
I see three options:
- non-virtual: bypass vtab - final: non-virtual, non-overridable
How would you want to bypass the vtable in the "non-virtual" case if the method is overridable?
- inline: non-virtual, C inline qualifier is used
Correct.
Ok.
I think it's better to implement final method then user could choose to use inline qualifier or not.
I tried it here: https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d...
There is one problem: vtab bypassing should be enabled if final method is defined in the same module. I don't know how to check that final method comes from cimport (it's okay with pxd, the problem is pyx)
https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef...
Here is update version. I've add tree asserts and final method's prototypes.
-- vitja.
I've created ticket for compiler crash when cython.final is used inside pxd file:
http://trac.cython.org/cython_trac/ticket/722
Also I've updated final methods test case (added tree path assertions) https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4...
About declaration origin detection may be it's a good idea to have a flag at scope level something like is_pxd_scope or is_declaration_scope?
It seems to me that I found a way to fix pxd/pyx cimport problem. I've created pull request: https://github.com/cython/cython/pull/59 -- vitja.
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 25.08.2011 20:32: > > 2011/8/25 Stefan Behnel<stefan_ml@behnel.de>: >> >> Vitja Makarov, 25.08.2011 18:11: >>> >>> 2011/8/24 Stefan Behnel: >>>> >>>> Vitja Makarov, 24.08.2011 21:17: >>>>> >>>>> I tried final classes: >>>>> 2. In this example foo call is done through virtual table >>>>> >>>>> cimport cython >>>>> >>>>> @cython.final >>>>> cdef class Foo: >>>>> cdef foo(self): >>>>> print 'haha' >>>>> >>>>> def test(): >>>>> cdef Foo a = Foo() >>>>> a.foo() >>>>> >>>>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>>>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>>>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>>>> __LINE__; goto __pyx_L1_error;} >>>> >>>> Right, this is not implemented yet. Feel free to do so. Also see >>>> >>>> http://trac.cython.org/cython_trac/ticket/474 >>>> >>>> >>>>> 3. I can't use final decorator for methods (error reported) >>>> >>>> http://trac.cython.org/cython_trac/ticket/586 >>> >>> What is the prefered syntax keyword inline or final decorator? >> >> "final" is the right option here. >> >> They are orthogonal concepts. Only because you declare a method "final" >> does >> not mean you want to inline it, and just because you declare it "inline" >> does not (necessarily) mean that you cannot override it. Admittedly, the >> semantics of an overridable inline method may turn out to be somewhat >> obscure and error prone, so I think it's a good idea to let "inline" >> imply >> "final". But not the other way round. > > But both inline and final methods should bypass vtab, right?
Yes. But in the "final" case, it's always clear which method implementation to use - it's not overridable, so there is only one choice. In the "inline" case, it could still be overridable and we may have a subtype of the declared type in our hands at runtime, thus choosing the wrong method at compile time. That's why only the "final" case is safe.
Note that I'm only talking about the semantics of the qualifier themselves here. If we allow "inline" methods, I think we should force them to be "final" as well. But that's a practical choice, not a semantic implication.
> Also I'm not sure about C inline qualifier here.
That's what "inline" requests.
> I see three options: > > - non-virtual: bypass vtab > - final: non-virtual, non-overridable
How would you want to bypass the vtable in the "non-virtual" case if the method is overridable?
> - inline: non-virtual, C inline qualifier is used
Correct.
Ok.
I think it's better to implement final method then user could choose to use inline qualifier or not.
I tried it here: https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d...
There is one problem: vtab bypassing should be enabled if final method is defined in the same module. I don't know how to check that final method comes from cimport (it's okay with pxd, the problem is pyx)
https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef...
Here is update version. I've add tree asserts and final method's prototypes.
-- vitja.
I've created ticket for compiler crash when cython.final is used inside pxd file:
http://trac.cython.org/cython_trac/ticket/722
Also I've updated final methods test case (added tree path assertions) https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4...
About declaration origin detection may be it's a good idea to have a flag at scope level something like is_pxd_scope or is_declaration_scope?
It seems to me that I found a way to fix pxd/pyx cimport problem. I've created pull request:
I've add support for inline methods, now you can declare inline method in pxd file: cdef class Foo: cdef inline foo(self): return 1 -- vitja.
On Sun, Aug 28, 2011 at 4:00 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Stefan Behnel <stefan_ml@behnel.de>: > Vitja Makarov, 25.08.2011 20:32: >> >> 2011/8/25 Stefan Behnel<stefan_ml@behnel.de>: >>> >>> Vitja Makarov, 25.08.2011 18:11: >>>> >>>> 2011/8/24 Stefan Behnel: >>>>> >>>>> Vitja Makarov, 24.08.2011 21:17: >>>>>> >>>>>> I tried final classes: >>>>>> 2. In this example foo call is done through virtual table >>>>>> >>>>>> cimport cython >>>>>> >>>>>> @cython.final >>>>>> cdef class Foo: >>>>>> cdef foo(self): >>>>>> print 'haha' >>>>>> >>>>>> def test(): >>>>>> cdef Foo a = Foo() >>>>>> a.foo() >>>>>> >>>>>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>>>>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>>>>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>>>>> __LINE__; goto __pyx_L1_error;} >>>>> >>>>> Right, this is not implemented yet. Feel free to do so. Also see >>>>> >>>>> http://trac.cython.org/cython_trac/ticket/474 >>>>> >>>>> >>>>>> 3. I can't use final decorator for methods (error reported) >>>>> >>>>> http://trac.cython.org/cython_trac/ticket/586 >>>> >>>> What is the prefered syntax keyword inline or final decorator? >>> >>> "final" is the right option here. >>> >>> They are orthogonal concepts. Only because you declare a method "final" >>> does >>> not mean you want to inline it, and just because you declare it "inline" >>> does not (necessarily) mean that you cannot override it. Admittedly, the >>> semantics of an overridable inline method may turn out to be somewhat >>> obscure and error prone, so I think it's a good idea to let "inline" >>> imply >>> "final". But not the other way round. >> >> But both inline and final methods should bypass vtab, right? > > Yes. But in the "final" case, it's always clear which method implementation > to use - it's not overridable, so there is only one choice. In the "inline" > case, it could still be overridable and we may have a subtype of the > declared type in our hands at runtime, thus choosing the wrong method at > compile time. That's why only the "final" case is safe. > > Note that I'm only talking about the semantics of the qualifier themselves > here. If we allow "inline" methods, I think we should force them to be > "final" as well. But that's a practical choice, not a semantic implication. > > >> Also I'm not sure about C inline qualifier here. > > That's what "inline" requests. > > >> I see three options: >> >> - non-virtual: bypass vtab >> - final: non-virtual, non-overridable > > How would you want to bypass the vtable in the "non-virtual" case if the > method is overridable? > > >> - inline: non-virtual, C inline qualifier is used > > Correct. >
Ok.
I think it's better to implement final method then user could choose to use inline qualifier or not.
I tried it here: https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d...
There is one problem: vtab bypassing should be enabled if final method is defined in the same module. I don't know how to check that final method comes from cimport (it's okay with pxd, the problem is pyx)
https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef...
Here is update version. I've add tree asserts and final method's prototypes.
-- vitja.
I've created ticket for compiler crash when cython.final is used inside pxd file:
http://trac.cython.org/cython_trac/ticket/722
Also I've updated final methods test case (added tree path assertions) https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4...
About declaration origin detection may be it's a good idea to have a flag at scope level something like is_pxd_scope or is_declaration_scope?
It seems to me that I found a way to fix pxd/pyx cimport problem. I've created pull request:
I've add support for inline methods, now you can declare inline method in pxd file:
cdef class Foo: cdef inline foo(self): return 1
Cool. I suppose for cross-module calls, non-inline methods vtables are best one can do short of actually linking the modules together. One question about your code--I'm not seeing how you're disallowing overriding final cpdef methods from Python. (Should we even allow final cpdef methods on non-final classes?) - Robert
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Sun, Aug 28, 2011 at 4:00 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: > 2011/8/25 Stefan Behnel <stefan_ml@behnel.de>: >> Vitja Makarov, 25.08.2011 20:32: >>> >>> 2011/8/25 Stefan Behnel<stefan_ml@behnel.de>: >>>> >>>> Vitja Makarov, 25.08.2011 18:11: >>>>> >>>>> 2011/8/24 Stefan Behnel: >>>>>> >>>>>> Vitja Makarov, 24.08.2011 21:17: >>>>>>> >>>>>>> I tried final classes: >>>>>>> 2. In this example foo call is done through virtual table >>>>>>> >>>>>>> cimport cython >>>>>>> >>>>>>> @cython.final >>>>>>> cdef class Foo: >>>>>>> cdef foo(self): >>>>>>> print 'haha' >>>>>>> >>>>>>> def test(): >>>>>>> cdef Foo a = Foo() >>>>>>> a.foo() >>>>>>> >>>>>>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>>>>>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>>>>>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>>>>>> __LINE__; goto __pyx_L1_error;} >>>>>> >>>>>> Right, this is not implemented yet. Feel free to do so. Also see >>>>>> >>>>>> http://trac.cython.org/cython_trac/ticket/474 >>>>>> >>>>>> >>>>>>> 3. I can't use final decorator for methods (error reported) >>>>>> >>>>>> http://trac.cython.org/cython_trac/ticket/586 >>>>> >>>>> What is the prefered syntax keyword inline or final decorator? >>>> >>>> "final" is the right option here. >>>> >>>> They are orthogonal concepts. Only because you declare a method "final" >>>> does >>>> not mean you want to inline it, and just because you declare it "inline" >>>> does not (necessarily) mean that you cannot override it. Admittedly, the >>>> semantics of an overridable inline method may turn out to be somewhat >>>> obscure and error prone, so I think it's a good idea to let "inline" >>>> imply >>>> "final". But not the other way round. >>> >>> But both inline and final methods should bypass vtab, right? >> >> Yes. But in the "final" case, it's always clear which method implementation >> to use - it's not overridable, so there is only one choice. In the "inline" >> case, it could still be overridable and we may have a subtype of the >> declared type in our hands at runtime, thus choosing the wrong method at >> compile time. That's why only the "final" case is safe. >> >> Note that I'm only talking about the semantics of the qualifier themselves >> here. If we allow "inline" methods, I think we should force them to be >> "final" as well. But that's a practical choice, not a semantic implication. >> >> >>> Also I'm not sure about C inline qualifier here. >> >> That's what "inline" requests. >> >> >>> I see three options: >>> >>> - non-virtual: bypass vtab >>> - final: non-virtual, non-overridable >> >> How would you want to bypass the vtable in the "non-virtual" case if the >> method is overridable? >> >> >>> - inline: non-virtual, C inline qualifier is used >> >> Correct. >> > > Ok. > > I think it's better to implement final method then user could choose > to use inline qualifier or not. >
I tried it here: https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d...
There is one problem: vtab bypassing should be enabled if final method is defined in the same module. I don't know how to check that final method comes from cimport (it's okay with pxd, the problem is pyx)
https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef...
Here is update version. I've add tree asserts and final method's prototypes.
-- vitja.
I've created ticket for compiler crash when cython.final is used inside pxd file:
http://trac.cython.org/cython_trac/ticket/722
Also I've updated final methods test case (added tree path assertions) https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4...
About declaration origin detection may be it's a good idea to have a flag at scope level something like is_pxd_scope or is_declaration_scope?
It seems to me that I found a way to fix pxd/pyx cimport problem. I've created pull request:
I've add support for inline methods, now you can declare inline method in pxd file:
cdef class Foo: cdef inline foo(self): return 1
Cool.
I suppose for cross-module calls, non-inline methods vtables are best one can do short of actually linking the modules together.
Sure. This is how it works now. But noitice that final isn't supported now at pxd scope. So it might not work. https://github.com/cython/cython/pull/59/files#L5R1888 For subclassing I check that both 3parent and children are in the same scope. When pxd is cimported vtable bypassing should be disabled in case it's cimported from anpther module. Not sure how to implement this. I think we should first fix final at pxd.
One question about your code--I'm not seeing how you're disallowing overriding final cpdef methods from Python. (Should we even allow final cpdef methods on non-final classes?)
I think it's hard and tricky to disallow cpdef overriding but I think it's better to have cpdef final methods. And I wouldn't argue if you say that final cpdef methods shouldn't be allowed at all. -- vitja.
On Mon, Aug 29, 2011 at 10:57 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Sun, Aug 28, 2011 at 4:00 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: > 2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: >> 2011/8/25 Stefan Behnel <stefan_ml@behnel.de>: >>> Vitja Makarov, 25.08.2011 20:32: >>>> >>>> 2011/8/25 Stefan Behnel<stefan_ml@behnel.de>: >>>>> >>>>> Vitja Makarov, 25.08.2011 18:11: >>>>>> >>>>>> 2011/8/24 Stefan Behnel: >>>>>>> >>>>>>> Vitja Makarov, 24.08.2011 21:17: >>>>>>>> >>>>>>>> I tried final classes: >>>>>>>> 2. In this example foo call is done through virtual table >>>>>>>> >>>>>>>> cimport cython >>>>>>>> >>>>>>>> @cython.final >>>>>>>> cdef class Foo: >>>>>>>> cdef foo(self): >>>>>>>> print 'haha' >>>>>>>> >>>>>>>> def test(): >>>>>>>> cdef Foo a = Foo() >>>>>>>> a.foo() >>>>>>>> >>>>>>>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>>>>>>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>>>>>>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>>>>>>> __LINE__; goto __pyx_L1_error;} >>>>>>> >>>>>>> Right, this is not implemented yet. Feel free to do so. Also see >>>>>>> >>>>>>> http://trac.cython.org/cython_trac/ticket/474 >>>>>>> >>>>>>> >>>>>>>> 3. I can't use final decorator for methods (error reported) >>>>>>> >>>>>>> http://trac.cython.org/cython_trac/ticket/586 >>>>>> >>>>>> What is the prefered syntax keyword inline or final decorator? >>>>> >>>>> "final" is the right option here. >>>>> >>>>> They are orthogonal concepts. Only because you declare a method "final" >>>>> does >>>>> not mean you want to inline it, and just because you declare it "inline" >>>>> does not (necessarily) mean that you cannot override it. Admittedly, the >>>>> semantics of an overridable inline method may turn out to be somewhat >>>>> obscure and error prone, so I think it's a good idea to let "inline" >>>>> imply >>>>> "final". But not the other way round. >>>> >>>> But both inline and final methods should bypass vtab, right? >>> >>> Yes. But in the "final" case, it's always clear which method implementation >>> to use - it's not overridable, so there is only one choice. In the "inline" >>> case, it could still be overridable and we may have a subtype of the >>> declared type in our hands at runtime, thus choosing the wrong method at >>> compile time. That's why only the "final" case is safe. >>> >>> Note that I'm only talking about the semantics of the qualifier themselves >>> here. If we allow "inline" methods, I think we should force them to be >>> "final" as well. But that's a practical choice, not a semantic implication. >>> >>> >>>> Also I'm not sure about C inline qualifier here. >>> >>> That's what "inline" requests. >>> >>> >>>> I see three options: >>>> >>>> - non-virtual: bypass vtab >>>> - final: non-virtual, non-overridable >>> >>> How would you want to bypass the vtable in the "non-virtual" case if the >>> method is overridable? >>> >>> >>>> - inline: non-virtual, C inline qualifier is used >>> >>> Correct. >>> >> >> Ok. >> >> I think it's better to implement final method then user could choose >> to use inline qualifier or not. >> > > I tried it here: > https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d... > > There is one problem: vtab bypassing should be enabled if final method > is defined in the same module. > I don't know how to check that final method comes from cimport (it's > okay with pxd, the problem is pyx) >
https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef...
Here is update version. I've add tree asserts and final method's prototypes.
-- vitja.
I've created ticket for compiler crash when cython.final is used inside pxd file:
http://trac.cython.org/cython_trac/ticket/722
Also I've updated final methods test case (added tree path assertions) https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4...
About declaration origin detection may be it's a good idea to have a flag at scope level something like is_pxd_scope or is_declaration_scope?
It seems to me that I found a way to fix pxd/pyx cimport problem. I've created pull request:
I've add support for inline methods, now you can declare inline method in pxd file:
cdef class Foo: cdef inline foo(self): return 1
Cool.
I suppose for cross-module calls, non-inline methods vtables are best one can do short of actually linking the modules together.
Sure. This is how it works now. But noitice that final isn't supported now at pxd scope. So it might not work.
https://github.com/cython/cython/pull/59/files#L5R1888
For subclassing I check that both 3parent and children are in the same scope. When pxd is cimported vtable bypassing should be disabled in case it's cimported from anpther module. Not sure how to implement this. I think we should first fix final at pxd.
One question about your code--I'm not seeing how you're disallowing overriding final cpdef methods from Python. (Should we even allow final cpdef methods on non-final classes?)
I think it's hard and tricky to disallow cpdef overriding but I think it's better to have cpdef final methods. And I wouldn't argue if you say that final cpdef methods shouldn't be allowed at all.
Yes, disallowing it with an explicit compile-time error was what I was thinking. - Robert
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Mon, Aug 29, 2011 at 10:57 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Sun, Aug 28, 2011 at 4:00 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>: > 2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: >> 2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: >>> 2011/8/25 Stefan Behnel <stefan_ml@behnel.de>: >>>> Vitja Makarov, 25.08.2011 20:32: >>>>> >>>>> 2011/8/25 Stefan Behnel<stefan_ml@behnel.de>: >>>>>> >>>>>> Vitja Makarov, 25.08.2011 18:11: >>>>>>> >>>>>>> 2011/8/24 Stefan Behnel: >>>>>>>> >>>>>>>> Vitja Makarov, 24.08.2011 21:17: >>>>>>>>> >>>>>>>>> I tried final classes: >>>>>>>>> 2. In this example foo call is done through virtual table >>>>>>>>> >>>>>>>>> cimport cython >>>>>>>>> >>>>>>>>> @cython.final >>>>>>>>> cdef class Foo: >>>>>>>>> cdef foo(self): >>>>>>>>> print 'haha' >>>>>>>>> >>>>>>>>> def test(): >>>>>>>>> cdef Foo a = Foo() >>>>>>>>> a.foo() >>>>>>>>> >>>>>>>>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>>>>>>>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>>>>>>>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>>>>>>>> __LINE__; goto __pyx_L1_error;} >>>>>>>> >>>>>>>> Right, this is not implemented yet. Feel free to do so. Also see >>>>>>>> >>>>>>>> http://trac.cython.org/cython_trac/ticket/474 >>>>>>>> >>>>>>>> >>>>>>>>> 3. I can't use final decorator for methods (error reported) >>>>>>>> >>>>>>>> http://trac.cython.org/cython_trac/ticket/586 >>>>>>> >>>>>>> What is the prefered syntax keyword inline or final decorator? >>>>>> >>>>>> "final" is the right option here. >>>>>> >>>>>> They are orthogonal concepts. Only because you declare a method "final" >>>>>> does >>>>>> not mean you want to inline it, and just because you declare it "inline" >>>>>> does not (necessarily) mean that you cannot override it. Admittedly, the >>>>>> semantics of an overridable inline method may turn out to be somewhat >>>>>> obscure and error prone, so I think it's a good idea to let "inline" >>>>>> imply >>>>>> "final". But not the other way round. >>>>> >>>>> But both inline and final methods should bypass vtab, right? >>>> >>>> Yes. But in the "final" case, it's always clear which method implementation >>>> to use - it's not overridable, so there is only one choice. In the "inline" >>>> case, it could still be overridable and we may have a subtype of the >>>> declared type in our hands at runtime, thus choosing the wrong method at >>>> compile time. That's why only the "final" case is safe. >>>> >>>> Note that I'm only talking about the semantics of the qualifier themselves >>>> here. If we allow "inline" methods, I think we should force them to be >>>> "final" as well. But that's a practical choice, not a semantic implication. >>>> >>>> >>>>> Also I'm not sure about C inline qualifier here. >>>> >>>> That's what "inline" requests. >>>> >>>> >>>>> I see three options: >>>>> >>>>> - non-virtual: bypass vtab >>>>> - final: non-virtual, non-overridable >>>> >>>> How would you want to bypass the vtable in the "non-virtual" case if the >>>> method is overridable? >>>> >>>> >>>>> - inline: non-virtual, C inline qualifier is used >>>> >>>> Correct. >>>> >>> >>> Ok. >>> >>> I think it's better to implement final method then user could choose >>> to use inline qualifier or not. >>> >> >> I tried it here: >> https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d... >> >> There is one problem: vtab bypassing should be enabled if final method >> is defined in the same module. >> I don't know how to check that final method comes from cimport (it's >> okay with pxd, the problem is pyx) >> > > > https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef... > > Here is update version. I've add tree asserts and final method's prototypes. > > -- > vitja. >
I've created ticket for compiler crash when cython.final is used inside pxd file:
http://trac.cython.org/cython_trac/ticket/722
Also I've updated final methods test case (added tree path assertions) https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4...
About declaration origin detection may be it's a good idea to have a flag at scope level something like is_pxd_scope or is_declaration_scope?
It seems to me that I found a way to fix pxd/pyx cimport problem. I've created pull request:
I've add support for inline methods, now you can declare inline method in pxd file:
cdef class Foo: cdef inline foo(self): return 1
Cool.
I suppose for cross-module calls, non-inline methods vtables are best one can do short of actually linking the modules together.
Sure. This is how it works now. But noitice that final isn't supported now at pxd scope. So it might not work.
https://github.com/cython/cython/pull/59/files#L5R1888
For subclassing I check that both 3parent and children are in the same scope. When pxd is cimported vtable bypassing should be disabled in case it's cimported from anpther module. Not sure how to implement this. I think we should first fix final at pxd.
One question about your code--I'm not seeing how you're disallowing overriding final cpdef methods from Python. (Should we even allow final cpdef methods on non-final classes?)
I think it's hard and tricky to disallow cpdef overriding but I think it's better to have cpdef final methods. And I wouldn't argue if you say that final cpdef methods shouldn't be allowed at all.
Yes, disallowing it with an explicit compile-time error was what I was thinking.
What about final classes with cpdef methods? @cython.final class Foo: cpdef bar(self): pass Should that raise an error? -- vitja.
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Mon, Aug 29, 2011 at 10:57 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Sun, Aug 28, 2011 at 4:00 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>: > 2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>: >> 2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: >>> 2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: >>>> 2011/8/25 Stefan Behnel <stefan_ml@behnel.de>: >>>>> Vitja Makarov, 25.08.2011 20:32: >>>>>> >>>>>> 2011/8/25 Stefan Behnel<stefan_ml@behnel.de>: >>>>>>> >>>>>>> Vitja Makarov, 25.08.2011 18:11: >>>>>>>> >>>>>>>> 2011/8/24 Stefan Behnel: >>>>>>>>> >>>>>>>>> Vitja Makarov, 24.08.2011 21:17: >>>>>>>>>> >>>>>>>>>> I tried final classes: >>>>>>>>>> 2. In this example foo call is done through virtual table >>>>>>>>>> >>>>>>>>>> cimport cython >>>>>>>>>> >>>>>>>>>> @cython.final >>>>>>>>>> cdef class Foo: >>>>>>>>>> cdef foo(self): >>>>>>>>>> print 'haha' >>>>>>>>>> >>>>>>>>>> def test(): >>>>>>>>>> cdef Foo a = Foo() >>>>>>>>>> a.foo() >>>>>>>>>> >>>>>>>>>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>>>>>>>>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>>>>>>>>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>>>>>>>>> __LINE__; goto __pyx_L1_error;} >>>>>>>>> >>>>>>>>> Right, this is not implemented yet. Feel free to do so. Also see >>>>>>>>> >>>>>>>>> http://trac.cython.org/cython_trac/ticket/474 >>>>>>>>> >>>>>>>>> >>>>>>>>>> 3. I can't use final decorator for methods (error reported) >>>>>>>>> >>>>>>>>> http://trac.cython.org/cython_trac/ticket/586 >>>>>>>> >>>>>>>> What is the prefered syntax keyword inline or final decorator? >>>>>>> >>>>>>> "final" is the right option here. >>>>>>> >>>>>>> They are orthogonal concepts. Only because you declare a method "final" >>>>>>> does >>>>>>> not mean you want to inline it, and just because you declare it "inline" >>>>>>> does not (necessarily) mean that you cannot override it. Admittedly, the >>>>>>> semantics of an overridable inline method may turn out to be somewhat >>>>>>> obscure and error prone, so I think it's a good idea to let "inline" >>>>>>> imply >>>>>>> "final". But not the other way round. >>>>>> >>>>>> But both inline and final methods should bypass vtab, right? >>>>> >>>>> Yes. But in the "final" case, it's always clear which method implementation >>>>> to use - it's not overridable, so there is only one choice. In the "inline" >>>>> case, it could still be overridable and we may have a subtype of the >>>>> declared type in our hands at runtime, thus choosing the wrong method at >>>>> compile time. That's why only the "final" case is safe. >>>>> >>>>> Note that I'm only talking about the semantics of the qualifier themselves >>>>> here. If we allow "inline" methods, I think we should force them to be >>>>> "final" as well. But that's a practical choice, not a semantic implication. >>>>> >>>>> >>>>>> Also I'm not sure about C inline qualifier here. >>>>> >>>>> That's what "inline" requests. >>>>> >>>>> >>>>>> I see three options: >>>>>> >>>>>> - non-virtual: bypass vtab >>>>>> - final: non-virtual, non-overridable >>>>> >>>>> How would you want to bypass the vtable in the "non-virtual" case if the >>>>> method is overridable? >>>>> >>>>> >>>>>> - inline: non-virtual, C inline qualifier is used >>>>> >>>>> Correct. >>>>> >>>> >>>> Ok. >>>> >>>> I think it's better to implement final method then user could choose >>>> to use inline qualifier or not. >>>> >>> >>> I tried it here: >>> https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d... >>> >>> There is one problem: vtab bypassing should be enabled if final method >>> is defined in the same module. >>> I don't know how to check that final method comes from cimport (it's >>> okay with pxd, the problem is pyx) >>> >> >> >> https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef... >> >> Here is update version. I've add tree asserts and final method's prototypes. >> >> -- >> vitja. >> > > I've created ticket for compiler crash when cython.final is used > inside pxd file: > > http://trac.cython.org/cython_trac/ticket/722 > > Also I've updated final methods test case (added tree path assertions) > https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4... > > > About declaration origin detection may be it's a good idea to have a > flag at scope level something like is_pxd_scope or > is_declaration_scope? >
It seems to me that I found a way to fix pxd/pyx cimport problem. I've created pull request:
I've add support for inline methods, now you can declare inline method in pxd file:
cdef class Foo: cdef inline foo(self): return 1
Cool.
I suppose for cross-module calls, non-inline methods vtables are best one can do short of actually linking the modules together.
Sure. This is how it works now. But noitice that final isn't supported now at pxd scope. So it might not work.
https://github.com/cython/cython/pull/59/files#L5R1888
For subclassing I check that both 3parent and children are in the same scope. When pxd is cimported vtable bypassing should be disabled in case it's cimported from anpther module. Not sure how to implement this. I think we should first fix final at pxd.
One question about your code--I'm not seeing how you're disallowing overriding final cpdef methods from Python. (Should we even allow final cpdef methods on non-final classes?)
I think it's hard and tricky to disallow cpdef overriding but I think it's better to have cpdef final methods. And I wouldn't argue if you say that final cpdef methods shouldn't be allowed at all.
Yes, disallowing it with an explicit compile-time error was what I was thinking.
What about final classes with cpdef methods?
@cython.final class Foo: cpdef bar(self): pass
Should that raise an error?
That should be perfectly fine. - Robert
Robert Bradshaw, 30.08.2011 18:18:
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov wrote:
What about final classes with cpdef methods?
@cython.final class Foo: cpdef bar(self): pass
Should that raise an error?
That should be perfectly fine.
Well, the 'final' decorator shouldn't work on normal Python classes. Regarding extension types, CPython has a way of declaring them 'final' with a type flag, which effectively prevents them from being subclassed in Python. So the above works as just fine for cdef classes. Stefan
2011/8/30 Stefan Behnel <stefan_ml@behnel.de>:
Robert Bradshaw, 30.08.2011 18:18:
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov wrote:
What about final classes with cpdef methods?
@cython.final class Foo: cpdef bar(self): pass
Should that raise an error?
That should be perfectly fine.
Well, the 'final' decorator shouldn't work on normal Python classes.
Regarding extension types, CPython has a way of declaring them 'final' with a type flag, which effectively prevents them from being subclassed in Python. So the above works as just fine for cdef classes.
Ok. So final class could have cpdef methods but non-final extension type couldn't, am I right? -- vitja.
Vitja Makarov, 30.08.2011 18:39:
2011/8/30 Stefan Behnel:
Robert Bradshaw, 30.08.2011 18:18:
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov wrote:
What about final classes with cpdef methods?
@cython.final class Foo: cpdef bar(self): pass
Should that raise an error?
That should be perfectly fine.
Well, the 'final' decorator shouldn't work on normal Python classes.
Regarding extension types, CPython has a way of declaring them 'final' with a type flag, which effectively prevents them from being subclassed in Python. So the above works as just fine for cdef classes.
Ok. So final class could have cpdef methods but non-final extension type couldn't, am I right?
All extension types can have cpdef methods, be they final or not. For final classes, cpdef methods simply mean that they have a Python wrapper and will otherwise be called directly when called from Cython. Actually, for cpdef methods in final classes, we can even drop the override check in the DefNode wrapper. I don't think that currently happens. Stefan
2011/8/30 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 30.08.2011 18:39:
2011/8/30 Stefan Behnel:
Robert Bradshaw, 30.08.2011 18:18:
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov wrote:
What about final classes with cpdef methods?
@cython.final class Foo: cpdef bar(self): pass
Should that raise an error?
That should be perfectly fine.
Well, the 'final' decorator shouldn't work on normal Python classes.
Regarding extension types, CPython has a way of declaring them 'final' with a type flag, which effectively prevents them from being subclassed in Python. So the above works as just fine for cdef classes.
Ok. So final class could have cpdef methods but non-final extension type couldn't, am I right?
All extension types can have cpdef methods, be they final or not. For final classes, cpdef methods simply mean that they have a Python wrapper and will otherwise be called directly when called from Cython.
Actually, for cpdef methods in final classes, we can even drop the override check in the DefNode wrapper. I don't think that currently happens.
Currently I drop OverrideCheckNode for all final cpdef methods, see https://github.com/cython/cython/pull/59/files#L2R1751 Final classes can have cpdef method that's ok. Could non-final classes have final-cpdef methods? Currently final class means that all its c[p]def methods are final too. -- vitja.
On Tue, Aug 30, 2011 at 10:19 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/30 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 30.08.2011 18:39:
2011/8/30 Stefan Behnel:
Robert Bradshaw, 30.08.2011 18:18:
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov wrote:
What about final classes with cpdef methods?
@cython.final class Foo: cpdef bar(self): pass
Should that raise an error?
That should be perfectly fine.
Well, the 'final' decorator shouldn't work on normal Python classes.
Regarding extension types, CPython has a way of declaring them 'final' with a type flag, which effectively prevents them from being subclassed in Python. So the above works as just fine for cdef classes.
Ok. So final class could have cpdef methods but non-final extension type couldn't, am I right?
All extension types can have cpdef methods, be they final or not. For final classes, cpdef methods simply mean that they have a Python wrapper and will otherwise be called directly when called from Cython.
Actually, for cpdef methods in final classes, we can even drop the override check in the DefNode wrapper. I don't think that currently happens.
Currently I drop OverrideCheckNode for all final cpdef methods, see https://github.com/cython/cython/pull/59/files#L2R1751
Final classes can have cpdef method that's ok. Could non-final classes have final-cpdef methods?
No, as we can't prevent them from being overridden (violating the semantics of final). We should raise an error when trying to declare final cpdef methods in non-final classes.
Currently final class means that all its c[p]def methods are final too.
Good point. - Robert
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Tue, Aug 30, 2011 at 10:19 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/30 Stefan Behnel <stefan_ml@behnel.de>:
Vitja Makarov, 30.08.2011 18:39:
2011/8/30 Stefan Behnel:
Robert Bradshaw, 30.08.2011 18:18:
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov wrote: > > What about final classes with cpdef methods? > > @cython.final > class Foo: > cpdef bar(self): > pass > > Should that raise an error?
That should be perfectly fine.
Well, the 'final' decorator shouldn't work on normal Python classes.
Regarding extension types, CPython has a way of declaring them 'final' with a type flag, which effectively prevents them from being subclassed in Python. So the above works as just fine for cdef classes.
Ok. So final class could have cpdef methods but non-final extension type couldn't, am I right?
All extension types can have cpdef methods, be they final or not. For final classes, cpdef methods simply mean that they have a Python wrapper and will otherwise be called directly when called from Cython.
Actually, for cpdef methods in final classes, we can even drop the override check in the DefNode wrapper. I don't think that currently happens.
Currently I drop OverrideCheckNode for all final cpdef methods, see https://github.com/cython/cython/pull/59/files#L2R1751
Final classes can have cpdef method that's ok. Could non-final classes have final-cpdef methods?
No, as we can't prevent them from being overridden (violating the semantics of final). We should raise an error when trying to declare final cpdef methods in non-final classes.
Ok. I get it!
Currently final class means that all its c[p]def methods are final too.
Good point.
I've updated my branch. Please review: https://github.com/cython/cython/pull/59 I've also added PyrexType.is_final_type attribute so now it should be used to check whether type is final or not. -- vitja.
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Mon, Aug 29, 2011 at 10:57 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/30 Robert Bradshaw <robertwb@math.washington.edu>:
On Sun, Aug 28, 2011 at 4:00 AM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>: > 2011/8/27 Vitja Makarov <vitja.makarov@gmail.com>: >> 2011/8/26 Vitja Makarov <vitja.makarov@gmail.com>: >>> 2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: >>>> 2011/8/25 Vitja Makarov <vitja.makarov@gmail.com>: >>>>> 2011/8/25 Stefan Behnel <stefan_ml@behnel.de>: >>>>>> Vitja Makarov, 25.08.2011 20:32: >>>>>>> >>>>>>> 2011/8/25 Stefan Behnel<stefan_ml@behnel.de>: >>>>>>>> >>>>>>>> Vitja Makarov, 25.08.2011 18:11: >>>>>>>>> >>>>>>>>> 2011/8/24 Stefan Behnel: >>>>>>>>>> >>>>>>>>>> Vitja Makarov, 24.08.2011 21:17: >>>>>>>>>>> >>>>>>>>>>> I tried final classes: >>>>>>>>>>> 2. In this example foo call is done through virtual table >>>>>>>>>>> >>>>>>>>>>> cimport cython >>>>>>>>>>> >>>>>>>>>>> @cython.final >>>>>>>>>>> cdef class Foo: >>>>>>>>>>> cdef foo(self): >>>>>>>>>>> print 'haha' >>>>>>>>>>> >>>>>>>>>>> def test(): >>>>>>>>>>> cdef Foo a = Foo() >>>>>>>>>>> a.foo() >>>>>>>>>>> >>>>>>>>>>> __pyx_t_1 = ((struct __pyx_vtabstruct_3yyy_Foo >>>>>>>>>>> *)__pyx_v_a->__pyx_vtab)->foo(__pyx_v_a); if (unlikely(!__pyx_t_1)) >>>>>>>>>>> {__pyx_filename = __pyx_f[0]; __pyx_lineno = 12; __pyx_clineno = >>>>>>>>>>> __LINE__; goto __pyx_L1_error;} >>>>>>>>>> >>>>>>>>>> Right, this is not implemented yet. Feel free to do so. Also see >>>>>>>>>> >>>>>>>>>> http://trac.cython.org/cython_trac/ticket/474 >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> 3. I can't use final decorator for methods (error reported) >>>>>>>>>> >>>>>>>>>> http://trac.cython.org/cython_trac/ticket/586 >>>>>>>>> >>>>>>>>> What is the prefered syntax keyword inline or final decorator? >>>>>>>> >>>>>>>> "final" is the right option here. >>>>>>>> >>>>>>>> They are orthogonal concepts. Only because you declare a method "final" >>>>>>>> does >>>>>>>> not mean you want to inline it, and just because you declare it "inline" >>>>>>>> does not (necessarily) mean that you cannot override it. Admittedly, the >>>>>>>> semantics of an overridable inline method may turn out to be somewhat >>>>>>>> obscure and error prone, so I think it's a good idea to let "inline" >>>>>>>> imply >>>>>>>> "final". But not the other way round. >>>>>>> >>>>>>> But both inline and final methods should bypass vtab, right? >>>>>> >>>>>> Yes. But in the "final" case, it's always clear which method implementation >>>>>> to use - it's not overridable, so there is only one choice. In the "inline" >>>>>> case, it could still be overridable and we may have a subtype of the >>>>>> declared type in our hands at runtime, thus choosing the wrong method at >>>>>> compile time. That's why only the "final" case is safe. >>>>>> >>>>>> Note that I'm only talking about the semantics of the qualifier themselves >>>>>> here. If we allow "inline" methods, I think we should force them to be >>>>>> "final" as well. But that's a practical choice, not a semantic implication. >>>>>> >>>>>> >>>>>>> Also I'm not sure about C inline qualifier here. >>>>>> >>>>>> That's what "inline" requests. >>>>>> >>>>>> >>>>>>> I see three options: >>>>>>> >>>>>>> - non-virtual: bypass vtab >>>>>>> - final: non-virtual, non-overridable >>>>>> >>>>>> How would you want to bypass the vtable in the "non-virtual" case if the >>>>>> method is overridable? >>>>>> >>>>>> >>>>>>> - inline: non-virtual, C inline qualifier is used >>>>>> >>>>>> Correct. >>>>>> >>>>> >>>>> Ok. >>>>> >>>>> I think it's better to implement final method then user could choose >>>>> to use inline qualifier or not. >>>>> >>>> >>>> I tried it here: >>>> https://github.com/vitek/cython/commit/ddf80a80dc75aced2cd92dc32afa77a7bcf2d... >>>> >>>> There is one problem: vtab bypassing should be enabled if final method >>>> is defined in the same module. >>>> I don't know how to check that final method comes from cimport (it's >>>> okay with pxd, the problem is pyx) >>>> >>> >>> >>> https://github.com/vitek/cython/commit/6e91fc257a683018ba6be340d384f9a7c34ef... >>> >>> Here is update version. I've add tree asserts and final method's prototypes. >>> >>> -- >>> vitja. >>> >> >> I've created ticket for compiler crash when cython.final is used >> inside pxd file: >> >> http://trac.cython.org/cython_trac/ticket/722 >> >> Also I've updated final methods test case (added tree path assertions) >> https://github.com/vitek/cython/commit/92edb09419c9b77a792f7c43e6ddd760b00c4... >> >> >> About declaration origin detection may be it's a good idea to have a >> flag at scope level something like is_pxd_scope or >> is_declaration_scope? >> > > It seems to me that I found a way to fix pxd/pyx cimport problem. I've > created pull request: > > https://github.com/cython/cython/pull/59 >
I've add support for inline methods, now you can declare inline method in pxd file:
cdef class Foo: cdef inline foo(self): return 1
Cool.
I suppose for cross-module calls, non-inline methods vtables are best one can do short of actually linking the modules together.
Sure. This is how it works now. But noitice that final isn't supported now at pxd scope. So it might not work.
https://github.com/cython/cython/pull/59/files#L5R1888
For subclassing I check that both 3parent and children are in the same scope. When pxd is cimported vtable bypassing should be disabled in case it's cimported from anpther module. Not sure how to implement this. I think we should first fix final at pxd.
One question about your code--I'm not seeing how you're disallowing overriding final cpdef methods from Python. (Should we even allow final cpdef methods on non-final classes?)
I think it's hard and tricky to disallow cpdef overriding but I think it's better to have cpdef final methods. And I wouldn't argue if you say that final cpdef methods shouldn't be allowed at all.
Yes, disallowing it with an explicit compile-time error was what I was thinking.
What about final classes with cpdef methods?
@cython.final class Foo: cpdef bar(self): pass
Should that raise an error?
That should be perfectly fine.
I'm not sure here. This would make users write code like this: @final cdef class Foo: cdef _is_foo(self): return self._foo def is_foo(self): return self._is_foo() cpdef is more convinient here. Also note that final class couldn't subclass types with cpdef methods. -- vitja.
Vitja Makarov, 30.08.2011 18:36:
2011/8/30 Robert Bradshaw:
On Tue, Aug 30, 2011 at 9:14 AM, Vitja Makarov wrote:
What about final classes with cpdef methods?
@cython.final class Foo: cpdef bar(self): pass
Should that raise an error?
That should be perfectly fine.
Robert meant to say that the above code is fine and should *not* raise an error.
I'm not sure here. This would make users write code like this:
@final cdef class Foo: cdef _is_foo(self): return self._foo
def is_foo(self): return self._is_foo()
cpdef is more convinient here. Also note that final class couldn't subclass types with cpdef methods.
Right. Stefan
Robert Bradshaw, 30.08.2011 07:32:
On Sun, Aug 28, 2011 at 4:00 AM, Vitja Makarov wrote:
I've created pull request:
I've add support for inline methods, now you can declare inline method in pxd file:
cdef class Foo: cdef inline foo(self): return 1
Cool.
+1 :)
I'm not seeing how you're disallowing overriding final cpdef methods from Python.
We could check for an override in the DefNode wrapper code at runtime. However, if it has been overridden, we won't even get there when called from Python, so we will never know if it has been overridden (well, we could add a check to tp_new(), but that would only catch overrides at class instantiation time, not attribute assignments). It's certainly easier and safer to reject this case at compile time, providing a very specific error message. Stefan
On Wed, Aug 24, 2011 at 12:00 PM, Vitja Makarov <vitja.makarov@gmail.com> wrote:
Recently I used cython in my project and I came with idea that sometimes virtual methods are overkill.
What's about adding non-virtual decorator for c[p]def methods?
cdef class Foo: @cython.nonvirtual cpdef int is_active(self): return clib.obj_is_active(self._cobj)
We have toyed with the idea of using a "final" modifier. Note that this would only work for a final class or a pure cdef method. - Robert
participants (3)
-
Robert Bradshaw -
Stefan Behnel -
Vitja Makarov