Mercurial > cpython-lru_cache-weakref
comparison Python/structmember.c @ 61467:f197407bdba2 3.1
Recorded merge of revisions 81032 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k
................
r81032 | antoine.pitrou | 2010-05-09 17:52:27 +0200 (dim., 09 mai 2010) | 9 lines
Recorded merge of revisions 81029 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r81029 | antoine.pitrou | 2010-05-09 16:46:46 +0200 (dim., 09 mai 2010) | 3 lines
Untabify C files. Will watch buildbots.
........
................
| author | Antoine Pitrou <solipsis@pitrou.net> |
|---|---|
| date | Sun, 09 May 2010 16:14:21 +0000 |
| parents | 64fdf66f69b0 |
| children | 3c9232a684ae |
comparison
equal
deleted
inserted
replaced
| 61459:f8c19c5f5dd2 | 61467:f197407bdba2 |
|---|---|
| 6 #include "structmember.h" | 6 #include "structmember.h" |
| 7 | 7 |
| 8 PyObject * | 8 PyObject * |
| 9 PyMember_GetOne(const char *addr, PyMemberDef *l) | 9 PyMember_GetOne(const char *addr, PyMemberDef *l) |
| 10 { | 10 { |
| 11 PyObject *v; | 11 PyObject *v; |
| 12 | 12 |
| 13 addr += l->offset; | 13 addr += l->offset; |
| 14 switch (l->type) { | 14 switch (l->type) { |
| 15 case T_BOOL: | 15 case T_BOOL: |
| 16 v = PyBool_FromLong(*(char*)addr); | 16 v = PyBool_FromLong(*(char*)addr); |
| 17 break; | 17 break; |
| 18 case T_BYTE: | 18 case T_BYTE: |
| 19 v = PyLong_FromLong(*(char*)addr); | 19 v = PyLong_FromLong(*(char*)addr); |
| 20 break; | 20 break; |
| 21 case T_UBYTE: | 21 case T_UBYTE: |
| 22 v = PyLong_FromUnsignedLong(*(unsigned char*)addr); | 22 v = PyLong_FromUnsignedLong(*(unsigned char*)addr); |
| 23 break; | 23 break; |
| 24 case T_SHORT: | 24 case T_SHORT: |
| 25 v = PyLong_FromLong(*(short*)addr); | 25 v = PyLong_FromLong(*(short*)addr); |
| 26 break; | 26 break; |
| 27 case T_USHORT: | 27 case T_USHORT: |
| 28 v = PyLong_FromUnsignedLong(*(unsigned short*)addr); | 28 v = PyLong_FromUnsignedLong(*(unsigned short*)addr); |
| 29 break; | 29 break; |
| 30 case T_INT: | 30 case T_INT: |
| 31 v = PyLong_FromLong(*(int*)addr); | 31 v = PyLong_FromLong(*(int*)addr); |
| 32 break; | 32 break; |
| 33 case T_UINT: | 33 case T_UINT: |
| 34 v = PyLong_FromUnsignedLong(*(unsigned int*)addr); | 34 v = PyLong_FromUnsignedLong(*(unsigned int*)addr); |
| 35 break; | 35 break; |
| 36 case T_LONG: | 36 case T_LONG: |
| 37 v = PyLong_FromLong(*(long*)addr); | 37 v = PyLong_FromLong(*(long*)addr); |
| 38 break; | 38 break; |
| 39 case T_ULONG: | 39 case T_ULONG: |
| 40 v = PyLong_FromUnsignedLong(*(unsigned long*)addr); | 40 v = PyLong_FromUnsignedLong(*(unsigned long*)addr); |
| 41 break; | 41 break; |
| 42 case T_PYSSIZET: | 42 case T_PYSSIZET: |
| 43 v = PyLong_FromSsize_t(*(Py_ssize_t*)addr); | 43 v = PyLong_FromSsize_t(*(Py_ssize_t*)addr); |
| 44 break; | 44 break; |
| 45 case T_FLOAT: | 45 case T_FLOAT: |
| 46 v = PyFloat_FromDouble((double)*(float*)addr); | 46 v = PyFloat_FromDouble((double)*(float*)addr); |
| 47 break; | 47 break; |
| 48 case T_DOUBLE: | 48 case T_DOUBLE: |
| 49 v = PyFloat_FromDouble(*(double*)addr); | 49 v = PyFloat_FromDouble(*(double*)addr); |
| 50 break; | 50 break; |
| 51 case T_STRING: | 51 case T_STRING: |
| 52 if (*(char**)addr == NULL) { | 52 if (*(char**)addr == NULL) { |
| 53 Py_INCREF(Py_None); | 53 Py_INCREF(Py_None); |
| 54 v = Py_None; | 54 v = Py_None; |
| 55 } | 55 } |
| 56 else | 56 else |
| 57 v = PyUnicode_FromString(*(char**)addr); | 57 v = PyUnicode_FromString(*(char**)addr); |
| 58 break; | 58 break; |
| 59 case T_STRING_INPLACE: | 59 case T_STRING_INPLACE: |
| 60 v = PyUnicode_FromString((char*)addr); | 60 v = PyUnicode_FromString((char*)addr); |
| 61 break; | 61 break; |
| 62 case T_CHAR: | 62 case T_CHAR: |
| 63 v = PyUnicode_FromStringAndSize((char*)addr, 1); | 63 v = PyUnicode_FromStringAndSize((char*)addr, 1); |
| 64 break; | 64 break; |
| 65 case T_OBJECT: | 65 case T_OBJECT: |
| 66 v = *(PyObject **)addr; | 66 v = *(PyObject **)addr; |
| 67 if (v == NULL) | 67 if (v == NULL) |
| 68 v = Py_None; | 68 v = Py_None; |
| 69 Py_INCREF(v); | 69 Py_INCREF(v); |
| 70 break; | 70 break; |
| 71 case T_OBJECT_EX: | 71 case T_OBJECT_EX: |
| 72 v = *(PyObject **)addr; | 72 v = *(PyObject **)addr; |
| 73 if (v == NULL) | 73 if (v == NULL) |
| 74 PyErr_SetString(PyExc_AttributeError, l->name); | 74 PyErr_SetString(PyExc_AttributeError, l->name); |
| 75 Py_XINCREF(v); | 75 Py_XINCREF(v); |
| 76 break; | 76 break; |
| 77 #ifdef HAVE_LONG_LONG | 77 #ifdef HAVE_LONG_LONG |
| 78 case T_LONGLONG: | 78 case T_LONGLONG: |
| 79 v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr); | 79 v = PyLong_FromLongLong(*(PY_LONG_LONG *)addr); |
| 80 break; | 80 break; |
| 81 case T_ULONGLONG: | 81 case T_ULONGLONG: |
| 82 v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr); | 82 v = PyLong_FromUnsignedLongLong(*(unsigned PY_LONG_LONG *)addr); |
| 83 break; | 83 break; |
| 84 #endif /* HAVE_LONG_LONG */ | 84 #endif /* HAVE_LONG_LONG */ |
| 85 case T_NONE: | 85 case T_NONE: |
| 86 v = Py_None; | 86 v = Py_None; |
| 87 Py_INCREF(v); | 87 Py_INCREF(v); |
| 88 break; | 88 break; |
| 89 default: | 89 default: |
| 90 PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); | 90 PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); |
| 91 v = NULL; | 91 v = NULL; |
| 92 } | 92 } |
| 93 return v; | 93 return v; |
| 94 } | 94 } |
| 95 | 95 |
| 96 #define WARN(msg) \ | 96 #define WARN(msg) \ |
| 97 do { \ | 97 do { \ |
| 98 if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) \ | 98 if (PyErr_WarnEx(PyExc_RuntimeWarning, msg, 1) < 0) \ |
| 99 return -1; \ | 99 return -1; \ |
| 100 } while (0) | 100 } while (0) |
| 101 | 101 |
| 102 int | 102 int |
| 103 PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) | 103 PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) |
| 104 { | 104 { |
| 105 PyObject *oldv; | 105 PyObject *oldv; |
| 106 | 106 |
| 107 addr += l->offset; | 107 addr += l->offset; |
| 108 | 108 |
| 109 if ((l->flags & READONLY)) | 109 if ((l->flags & READONLY)) |
| 110 { | 110 { |
| 111 PyErr_SetString(PyExc_AttributeError, "readonly attribute"); | 111 PyErr_SetString(PyExc_AttributeError, "readonly attribute"); |
| 112 return -1; | 112 return -1; |
| 113 } | 113 } |
| 114 if (v == NULL) { | 114 if (v == NULL) { |
| 115 if (l->type == T_OBJECT_EX) { | 115 if (l->type == T_OBJECT_EX) { |
| 116 /* Check if the attribute is set. */ | 116 /* Check if the attribute is set. */ |
| 117 if (*(PyObject **)addr == NULL) { | 117 if (*(PyObject **)addr == NULL) { |
| 118 PyErr_SetString(PyExc_AttributeError, l->name); | 118 PyErr_SetString(PyExc_AttributeError, l->name); |
| 119 return -1; | 119 return -1; |
| 120 } | 120 } |
| 121 } | 121 } |
| 122 else if (l->type != T_OBJECT) { | 122 else if (l->type != T_OBJECT) { |
| 123 PyErr_SetString(PyExc_TypeError, | 123 PyErr_SetString(PyExc_TypeError, |
| 124 "can't delete numeric/char attribute"); | 124 "can't delete numeric/char attribute"); |
| 125 return -1; | 125 return -1; |
| 126 } | 126 } |
| 127 } | 127 } |
| 128 switch (l->type) { | 128 switch (l->type) { |
| 129 case T_BOOL:{ | 129 case T_BOOL:{ |
| 130 if (!PyBool_Check(v)) { | 130 if (!PyBool_Check(v)) { |
| 131 PyErr_SetString(PyExc_TypeError, | 131 PyErr_SetString(PyExc_TypeError, |
| 132 "attribute value type must be bool"); | 132 "attribute value type must be bool"); |
| 133 return -1; | 133 return -1; |
| 134 } | 134 } |
| 135 if (v == Py_True) | 135 if (v == Py_True) |
| 136 *(char*)addr = (char) 1; | 136 *(char*)addr = (char) 1; |
| 137 else | 137 else |
| 138 *(char*)addr = (char) 0; | 138 *(char*)addr = (char) 0; |
| 139 break; | 139 break; |
| 140 } | 140 } |
| 141 case T_BYTE:{ | 141 case T_BYTE:{ |
| 142 long long_val = PyLong_AsLong(v); | 142 long long_val = PyLong_AsLong(v); |
| 143 if ((long_val == -1) && PyErr_Occurred()) | 143 if ((long_val == -1) && PyErr_Occurred()) |
| 144 return -1; | 144 return -1; |
| 145 *(char*)addr = (char)long_val; | 145 *(char*)addr = (char)long_val; |
| 146 /* XXX: For compatibility, only warn about truncations | 146 /* XXX: For compatibility, only warn about truncations |
| 147 for now. */ | 147 for now. */ |
| 148 if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN)) | 148 if ((long_val > CHAR_MAX) || (long_val < CHAR_MIN)) |
| 149 WARN("Truncation of value to char"); | 149 WARN("Truncation of value to char"); |
| 150 break; | 150 break; |
| 151 } | 151 } |
| 152 case T_UBYTE:{ | 152 case T_UBYTE:{ |
| 153 long long_val = PyLong_AsLong(v); | 153 long long_val = PyLong_AsLong(v); |
| 154 if ((long_val == -1) && PyErr_Occurred()) | 154 if ((long_val == -1) && PyErr_Occurred()) |
| 155 return -1; | 155 return -1; |
| 156 *(unsigned char*)addr = (unsigned char)long_val; | 156 *(unsigned char*)addr = (unsigned char)long_val; |
| 157 if ((long_val > UCHAR_MAX) || (long_val < 0)) | 157 if ((long_val > UCHAR_MAX) || (long_val < 0)) |
| 158 WARN("Truncation of value to unsigned char"); | 158 WARN("Truncation of value to unsigned char"); |
| 159 break; | 159 break; |
| 160 } | 160 } |
| 161 case T_SHORT:{ | 161 case T_SHORT:{ |
| 162 long long_val = PyLong_AsLong(v); | 162 long long_val = PyLong_AsLong(v); |
| 163 if ((long_val == -1) && PyErr_Occurred()) | 163 if ((long_val == -1) && PyErr_Occurred()) |
| 164 return -1; | 164 return -1; |
| 165 *(short*)addr = (short)long_val; | 165 *(short*)addr = (short)long_val; |
| 166 if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN)) | 166 if ((long_val > SHRT_MAX) || (long_val < SHRT_MIN)) |
| 167 WARN("Truncation of value to short"); | 167 WARN("Truncation of value to short"); |
| 168 break; | 168 break; |
| 169 } | 169 } |
| 170 case T_USHORT:{ | 170 case T_USHORT:{ |
| 171 long long_val = PyLong_AsLong(v); | 171 long long_val = PyLong_AsLong(v); |
| 172 if ((long_val == -1) && PyErr_Occurred()) | 172 if ((long_val == -1) && PyErr_Occurred()) |
| 173 return -1; | 173 return -1; |
| 174 *(unsigned short*)addr = (unsigned short)long_val; | 174 *(unsigned short*)addr = (unsigned short)long_val; |
| 175 if ((long_val > USHRT_MAX) || (long_val < 0)) | 175 if ((long_val > USHRT_MAX) || (long_val < 0)) |
| 176 WARN("Truncation of value to unsigned short"); | 176 WARN("Truncation of value to unsigned short"); |
| 177 break; | 177 break; |
| 178 } | 178 } |
| 179 case T_INT:{ | 179 case T_INT:{ |
| 180 long long_val = PyLong_AsLong(v); | 180 long long_val = PyLong_AsLong(v); |
| 181 if ((long_val == -1) && PyErr_Occurred()) | 181 if ((long_val == -1) && PyErr_Occurred()) |
| 182 return -1; | 182 return -1; |
| 183 *(int *)addr = (int)long_val; | 183 *(int *)addr = (int)long_val; |
| 184 if ((long_val > INT_MAX) || (long_val < INT_MIN)) | 184 if ((long_val > INT_MAX) || (long_val < INT_MIN)) |
| 185 WARN("Truncation of value to int"); | 185 WARN("Truncation of value to int"); |
| 186 break; | 186 break; |
| 187 } | 187 } |
| 188 case T_UINT:{ | 188 case T_UINT:{ |
| 189 unsigned long ulong_val = PyLong_AsUnsignedLong(v); | 189 unsigned long ulong_val = PyLong_AsUnsignedLong(v); |
| 190 if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) { | 190 if ((ulong_val == (unsigned long)-1) && PyErr_Occurred()) { |
| 191 /* XXX: For compatibility, accept negative int values | 191 /* XXX: For compatibility, accept negative int values |
| 192 as well. */ | 192 as well. */ |
| 193 PyErr_Clear(); | 193 PyErr_Clear(); |
| 194 ulong_val = PyLong_AsLong(v); | 194 ulong_val = PyLong_AsLong(v); |
| 195 if ((ulong_val == (unsigned long)-1) && | 195 if ((ulong_val == (unsigned long)-1) && |
| 196 PyErr_Occurred()) | 196 PyErr_Occurred()) |
| 197 return -1; | 197 return -1; |
| 198 *(unsigned int *)addr = (unsigned int)ulong_val; | 198 *(unsigned int *)addr = (unsigned int)ulong_val; |
| 199 WARN("Writing negative value into unsigned field"); | 199 WARN("Writing negative value into unsigned field"); |
| 200 } else | 200 } else |
| 201 *(unsigned int *)addr = (unsigned int)ulong_val; | 201 *(unsigned int *)addr = (unsigned int)ulong_val; |
| 202 if (ulong_val > UINT_MAX) | 202 if (ulong_val > UINT_MAX) |
| 203 WARN("Truncation of value to unsigned int"); | 203 WARN("Truncation of value to unsigned int"); |
| 204 break; | 204 break; |
| 205 } | 205 } |
| 206 case T_LONG:{ | 206 case T_LONG:{ |
| 207 *(long*)addr = PyLong_AsLong(v); | 207 *(long*)addr = PyLong_AsLong(v); |
| 208 if ((*(long*)addr == -1) && PyErr_Occurred()) | 208 if ((*(long*)addr == -1) && PyErr_Occurred()) |
| 209 return -1; | 209 return -1; |
| 210 break; | 210 break; |
| 211 } | 211 } |
| 212 case T_ULONG:{ | 212 case T_ULONG:{ |
| 213 *(unsigned long*)addr = PyLong_AsUnsignedLong(v); | 213 *(unsigned long*)addr = PyLong_AsUnsignedLong(v); |
| 214 if ((*(unsigned long*)addr == (unsigned long)-1) | 214 if ((*(unsigned long*)addr == (unsigned long)-1) |
| 215 && PyErr_Occurred()) { | 215 && PyErr_Occurred()) { |
| 216 /* XXX: For compatibility, accept negative int values | 216 /* XXX: For compatibility, accept negative int values |
| 217 as well. */ | 217 as well. */ |
| 218 PyErr_Clear(); | 218 PyErr_Clear(); |
| 219 *(unsigned long*)addr = PyLong_AsLong(v); | 219 *(unsigned long*)addr = PyLong_AsLong(v); |
| 220 if ((*(unsigned long*)addr == (unsigned long)-1) | 220 if ((*(unsigned long*)addr == (unsigned long)-1) |
| 221 && PyErr_Occurred()) | 221 && PyErr_Occurred()) |
| 222 return -1; | 222 return -1; |
| 223 WARN("Writing negative value into unsigned field"); | 223 WARN("Writing negative value into unsigned field"); |
| 224 } | 224 } |
| 225 break; | 225 break; |
| 226 } | 226 } |
| 227 case T_PYSSIZET:{ | 227 case T_PYSSIZET:{ |
| 228 *(Py_ssize_t*)addr = PyLong_AsSsize_t(v); | 228 *(Py_ssize_t*)addr = PyLong_AsSsize_t(v); |
| 229 if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1) | 229 if ((*(Py_ssize_t*)addr == (Py_ssize_t)-1) |
| 230 && PyErr_Occurred()) | 230 && PyErr_Occurred()) |
| 231 return -1; | 231 return -1; |
| 232 break; | 232 break; |
| 233 } | 233 } |
| 234 case T_FLOAT:{ | 234 case T_FLOAT:{ |
| 235 double double_val = PyFloat_AsDouble(v); | 235 double double_val = PyFloat_AsDouble(v); |
| 236 if ((double_val == -1) && PyErr_Occurred()) | 236 if ((double_val == -1) && PyErr_Occurred()) |
| 237 return -1; | 237 return -1; |
| 238 *(float*)addr = (float)double_val; | 238 *(float*)addr = (float)double_val; |
| 239 break; | 239 break; |
| 240 } | 240 } |
| 241 case T_DOUBLE: | 241 case T_DOUBLE: |
| 242 *(double*)addr = PyFloat_AsDouble(v); | 242 *(double*)addr = PyFloat_AsDouble(v); |
| 243 if ((*(double*)addr == -1) && PyErr_Occurred()) | 243 if ((*(double*)addr == -1) && PyErr_Occurred()) |
| 244 return -1; | 244 return -1; |
| 245 break; | 245 break; |
| 246 case T_OBJECT: | 246 case T_OBJECT: |
| 247 case T_OBJECT_EX: | 247 case T_OBJECT_EX: |
| 248 Py_XINCREF(v); | 248 Py_XINCREF(v); |
| 249 oldv = *(PyObject **)addr; | 249 oldv = *(PyObject **)addr; |
| 250 *(PyObject **)addr = v; | 250 *(PyObject **)addr = v; |
| 251 Py_XDECREF(oldv); | 251 Py_XDECREF(oldv); |
| 252 break; | 252 break; |
| 253 case T_CHAR: { | 253 case T_CHAR: { |
| 254 char *string; | 254 char *string; |
| 255 Py_ssize_t len; | 255 Py_ssize_t len; |
| 256 | 256 |
| 257 if (!PyUnicode_Check(v)) { | 257 if (!PyUnicode_Check(v)) { |
| 258 PyErr_BadArgument(); | 258 PyErr_BadArgument(); |
| 259 return -1; | 259 return -1; |
| 260 } | 260 } |
| 261 string = _PyUnicode_AsStringAndSize(v, &len); | 261 string = _PyUnicode_AsStringAndSize(v, &len); |
| 262 if (len != 1) { | 262 if (len != 1) { |
| 263 PyErr_BadArgument(); | 263 PyErr_BadArgument(); |
| 264 return -1; | 264 return -1; |
| 265 } | 265 } |
| 266 *(char*)addr = string[0]; | 266 *(char*)addr = string[0]; |
| 267 break; | 267 break; |
| 268 } | 268 } |
| 269 case T_STRING: | 269 case T_STRING: |
| 270 case T_STRING_INPLACE: | 270 case T_STRING_INPLACE: |
| 271 PyErr_SetString(PyExc_TypeError, "readonly attribute"); | 271 PyErr_SetString(PyExc_TypeError, "readonly attribute"); |
| 272 return -1; | 272 return -1; |
| 273 #ifdef HAVE_LONG_LONG | 273 #ifdef HAVE_LONG_LONG |
| 274 case T_LONGLONG:{ | 274 case T_LONGLONG:{ |
| 275 PY_LONG_LONG value; | 275 PY_LONG_LONG value; |
| 276 *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v); | 276 *(PY_LONG_LONG*)addr = value = PyLong_AsLongLong(v); |
| 277 if ((value == -1) && PyErr_Occurred()) | 277 if ((value == -1) && PyErr_Occurred()) |
| 278 return -1; | 278 return -1; |
| 279 break; | 279 break; |
| 280 } | 280 } |
| 281 case T_ULONGLONG:{ | 281 case T_ULONGLONG:{ |
| 282 unsigned PY_LONG_LONG value; | 282 unsigned PY_LONG_LONG value; |
| 283 /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong | 283 /* ??? PyLong_AsLongLong accepts an int, but PyLong_AsUnsignedLongLong |
| 284 doesn't ??? */ | 284 doesn't ??? */ |
| 285 if (PyLong_Check(v)) | 285 if (PyLong_Check(v)) |
| 286 *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v); | 286 *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsUnsignedLongLong(v); |
| 287 else | 287 else |
| 288 *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsLong(v); | 288 *(unsigned PY_LONG_LONG*)addr = value = PyLong_AsLong(v); |
| 289 if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred()) | 289 if ((value == (unsigned PY_LONG_LONG)-1) && PyErr_Occurred()) |
| 290 return -1; | 290 return -1; |
| 291 break; | 291 break; |
| 292 } | 292 } |
| 293 #endif /* HAVE_LONG_LONG */ | 293 #endif /* HAVE_LONG_LONG */ |
| 294 default: | 294 default: |
| 295 PyErr_Format(PyExc_SystemError, | 295 PyErr_Format(PyExc_SystemError, |
| 296 "bad memberdescr type for %s", l->name); | 296 "bad memberdescr type for %s", l->name); |
| 297 return -1; | 297 return -1; |
| 298 } | 298 } |
| 299 return 0; | 299 return 0; |
| 300 } | 300 } |
