Rather than just talking I prototyped my last suggestion about None 
behaviour, it is up in the -dagss branch:

http://hg.cython.org/cython-dagss/rev/4d543e06c926

Run the test "noneattributeacc" without cleanup and inspect the C file.

The exceptional circumstances under which it will work are too numerous 
too mention, I basically made a testcase and only did the very minimum 
for that to work (so this is only marginally better than just talking), 
but it does work and I kind of consider it proof of concept.

It is possible to improve it a lot, but it will likely never be able to 
optimize

flag = (x is not None)
if flag:
    ...

However, we can make it so that if you help it like this,

flag = (x is not None)
if flag:
    assert x is not None # or cython.check_None(x)

then things get optimized. So, in effect, I think this makes a case for 
steering Cython in a direction where _safe access for None is always 
enabled by default_.

Here's the result, my own comments after # sign.

   __pyx_1 = (__pyx_v_var != Py_None);
   if (__pyx_1) {

     /* "/home/dagss/cython/d/tests/run/noneattributeacc.pyx":49
  * def check_and_assign(MyClass var):
  *     if var is not None:
  *         print var.a             # <<<<<<<<<<<<<<
  *         var = None
  *         print var.a
  */

#
# No None check needed here
#

     __pyx_2 = PyInt_FromLong(((struct 
__pyx_obj_16noneattributeacc_MyClass *)__pyx_v_var)->a); if 
(unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 49; 
__pyx_clineno = __LINE__; goto __pyx_L1_error;}

     /* "/home/dagss/cython/d/tests/run/noneattributeacc.pyx":50
  *         var = None             # <<<<<<<<<<<<<<
  *
  */
     Py_INCREF(Py_None);
     Py_DECREF(__pyx_v_var);
     __pyx_v_var = Py_None;

     /* "/home/dagss/cython/d/tests/run/noneattributeacc.pyx":51
  *         print var.a
  *         var = None
  *         print var.a             # <<<<<<<<<<<<<<
  *
  */
#
# Note that a None-check is inserted.
#

     if (unlikely(__pyx_v_var == Py_None)) {
       __Pyx_RaiseNoneAttributeError("a");
       {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; __pyx_clineno = 
__LINE__; goto __pyx_L1_error;}
     }
     __pyx_2 = PyInt_FromLong(((struct 
__pyx_obj_16noneattributeacc_MyClass *)__pyx_v_var)->a); if 
(unlikely(!__pyx_2)) {__pyx_filename = __pyx_f[0]; __pyx_lineno = 51; 
__pyx_clineno = __LINE__; goto __pyx_L1_error;}
  ...

-- 
Dag Sverre
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to