Hi,

(Sent to both cython-devel and cython-users. However, I'm not subscribed to users I think, so please forward if it doesn't reach there).

On closer inspection I believe both are following Python behaviour (and thus behaving correctly). In Python any `__name_preceded_by_double_underscores` used within a class ends up looking up `_Classname__name_preceded_by_double_underscores`. Therefore in case 1 it's looking up `_Bar__foo` and not finding it.

Therefore, I think it is the "correct" thing to do.

This proved a pain with the `__pyx_unpickle` functions that Cython generates. In the end I just disabled it for `__pyx_` names, which I guess could be called hypocrisy .

David


On 23/04/2020 18:47, Stefan Behnel wrote:
Hi,

thanks for the very detailed report.

I'm CC-ing cython-devel, but let's keep the discussion for this on the
cython-users list.

The background here is Github issue 1382 and PR 3123

https://github.com/cython/cython/issues/1382

https://github.com/cython/cython/pull/3123

This was newly merged for alpha 2, and I consider it somewhat provisional.
It makes "private" Python names follow Python semantics, but if that poses
excessive breakage for existing code, then we'll have to find a pragmatic
way to deal with it.


'Toni Barth' via cython-users schrieb am 23.04.20 um 19:07:
I just updated Cython from 3.0a1 to 3.0a2 in one of my projects and
noticed that it seems to introduce issues with private
functions/methods, means methods with leading __.

I noticed two cases which now fail in my project. I'm however unsure if
thats supposed to happen or if its a problem with the new Cython build.


Case 1: private function not declared


crash.pxd:


cpdef __foo()

cdef class Bar:
   cpdef run(Bar self)


crash.pyx:


cpdef __foo():
   print("foo")

cdef class Bar:
   cpdef run(Bar self):
     __foo()

     print("bar")


Running this with the following command:

py -3 -c "import pyximport;pyximport.install();import
crash;crash.Bar().run()"


Result:

crash.c
C:\Program Files (x86)\Microsoft Visual
Studio\Shared\Python36_64\lib\site-packages\Cython\Compiler\Main.py:344:
FutureWarning: Cython directive 'language_level' not set, using '3str'
for now (Py3). This has changed from earlier releases! File:
D:\crash\crash.pxd
   tree = Parsing.p_module(s, pxd, full_module_name)

Error compiling Cython file:
------------------------------------------------------------
...
cpdef __foo():
   print("foo")

cdef class Bar:
   cpdef run(Bar self):
     __foo()
    ^
------------------------------------------------------------

crash.pyx:6:4: undeclared name not builtin: __foo
At least this looks like a bug to me. Global module names should not be
impacted by this change.


Error compiling Cython file:
------------------------------------------------------------
...
cpdef __foo():
   print("foo")

cdef class Bar:
   cpdef run(Bar self):
     __foo()
    ^
------------------------------------------------------------

crash.pyx:6:4: '__foo' redeclared

Error compiling Cython file:
------------------------------------------------------------
...
cpdef __foo()
            ^
------------------------------------------------------------

crash.pxd:1:12: Previous declaration is here
Lovely :)



Another problem, probably related, occurs when trying to override a
private method in a derived class:


Case 2: overriding private class methods


base.pxd:


cdef class Base:
   cdef void __foo(Base self)
   cpdef run(Base self)


base.pyx:


cdef class Base:

   cdef void __foo(Base self):
     print("foo!")
  cpdef run(Base self):
     self.__foo()


extend.pxd:


from base cimport Base

cdef class Extend(Base):
   pass


extend.pyx:


cdef class Extend(Base):

   cdef void __foo(Extend self):
     print("bar")

Running with the following command:

py -3 -c "import pyximport;pyximport.install();import
extend;extend.Extend().run()"


Results in the following output:


extend.c
C:\Program Files (x86)\Microsoft Visual
Studio\Shared\Python36_64\lib\site-packages\Cython\Compiler\Main.py:344:
FutureWarning: Cython directive 'language_level' not set, using '3str'
for now (Py3). This has changed from earlier releases! File:
D:\crash\extend.pxd
   tree = Parsing.p_module(s, pxd, full_module_name)

Error compiling Cython file:
------------------------------------------------------------
...
cdef class Extend(Base):

   cdef void __foo(Extend self):
       ^
------------------------------------------------------------

extend.pyx:3:7: C method '_Extend__foo' not previously declared in
definition part of extension type 'Extend'
This, OTOH, is intended. Private methods are not meant to be inherited and
overridden. That's what makes them "private" :) That's consistent with
Python semantics.

I think it's somewhat up for debate if this should apply in the same way to
cdef classes as for Python classes. But from a language design point of
view, having this kind of difference between the two seems a bad idea.

Do you feel like argueing against this? :)

Stefan
_______________________________________________
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel


_______________________________________________
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel

Reply via email to