[GRASS-SVN] r65968 - grass/trunk/lib/python/ctypes/ctypesgencore

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Aug 19 07:53:28 PDT 2015


Author: martinl
Date: 2015-08-19 07:53:28 -0700 (Wed, 19 Aug 2015)
New Revision: 65968

Modified:
   grass/trunk/lib/python/ctypes/ctypesgencore/expressions.py
Log:
Description: Enclose Python ternary in parenthesis.
 This fixes an issue with the C to Python conversion of the stat & stat64
 structs on GNU/Hurd. The structs define the final member conditionally:
 .
  #define _SPARE_SIZE     ((sizeof (__fsid_t) == sizeof (int)) ? 9 : 8)
      int st_spare[_SPARE_SIZE];  /* Room for future expansion.  */
  #undef _SPARE_SIZE
 .
 This gets converted by ctypesgen to:
 .
  ('st_spare', c_int * (sizeof(__fsid_t) == sizeof(c_int)) and 9 or 8),
 .
 Which causes a TypeError:
 .
  TypeError: second item in _fields_ tuple (index 17) must be a C type
 .
 Enclosing the Python expression in parenthesis to become:
 .
  ('st_spare', c_int * ((sizeof(__fsid_t) == sizeof(c_int)) and 9 or 8)),
 .
 fixes the TypeError.
 .
 While the and/or idiom is common it's also unsafe, because it can return
 wrong results when the "and" value has a false boolean value. See:
 .
 https://docs.python.org/3.4/faq/programming.html#is-there-an-equivalent-of-c-s-ternary-operator
 .
 In the st_spare case this is not a problem, but it can cause problems for
 other conversions in the future.
 .
 Instead of the and/or idiom the recommended if/else idiom is used.
 .
 The st_spare member thus becomes:
 .
  ('st_spare', c_int * (9 if (sizeof(__fsid_t) == sizeof(c_int)) else 8)),
 .
Author: Bas Couwenberg <sebastic at xs4all.nl>
Forwarded: https://trac.osgeo.org/grass/ticket/2581


Modified: grass/trunk/lib/python/ctypes/ctypesgencore/expressions.py
===================================================================
--- grass/trunk/lib/python/ctypes/ctypesgencore/expressions.py	2015-08-18 15:51:08 UTC (rev 65967)
+++ grass/trunk/lib/python/ctypes/ctypesgencore/expressions.py	2015-08-19 14:53:28 UTC (rev 65968)
@@ -208,9 +208,9 @@
             return self.no.evaluate(context)
 
     def py_string(self, can_be_ctype):
-        return "%s and %s or %s" % \
-            (self.cond.py_string(True),
-             self.yes.py_string(can_be_ctype),
+        return "(%s if %s else %s)" % \
+            (self.yes.py_string(can_be_ctype),
+             self.cond.py_string(True),
              self.no.py_string(can_be_ctype))
 
 class AttributeExpressionNode(ExpressionNode):



More information about the grass-commit mailing list