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
