Recursively convert Python object to a Lua data structure. Parts that can't be converted to Lua types are passed as-is. For Lua runtimes with restrictive attribute filters it means such values are passed as "capsules" which Lua code can send back to Python as-is, but can't acce
(lua, obj, max_depth=100, encoding='utf8', keep_tuples=True)
| 210 | |
| 211 | |
| 212 | def python2lua(lua, obj, max_depth=100, encoding='utf8', keep_tuples=True): |
| 213 | """ |
| 214 | Recursively convert Python object to a Lua data structure. |
| 215 | Parts that can't be converted to Lua types are passed as-is. |
| 216 | |
| 217 | For Lua runtimes with restrictive attribute filters it means such values |
| 218 | are passed as "capsules" which Lua code can send back to Python as-is, but |
| 219 | can't access otherwise. |
| 220 | """ |
| 221 | |
| 222 | def p2l(obj, depth): |
| 223 | if depth <= 0: |
| 224 | raise ValueError("Can't convert Python object to Lua: depth limit is reached") |
| 225 | |
| 226 | if isinstance(obj, PyResult): |
| 227 | return tuple(p2l(elt, depth-1) for elt in obj.result) |
| 228 | |
| 229 | if isinstance(obj, dict): |
| 230 | return lua.table_from({ |
| 231 | p2l(key, depth-1): p2l(value, depth-1) |
| 232 | for key, value in obj.items() |
| 233 | }) |
| 234 | |
| 235 | if isinstance(obj, tuple) and keep_tuples: |
| 236 | return tuple(p2l(el, depth-1) for el in obj) |
| 237 | |
| 238 | if isinstance(obj, (list, tuple)): |
| 239 | tbl = lua.table_from([p2l(el, depth-1) for el in obj]) |
| 240 | return _mark_table_as_array(lua, tbl) |
| 241 | |
| 242 | if isinstance(obj, str): |
| 243 | return obj.encode(encoding) |
| 244 | |
| 245 | if isinstance(obj, datetime.datetime): |
| 246 | return to_bytes(obj.isoformat() + 'Z', encoding) |
| 247 | # XXX: maybe return datetime encoded to Lua standard? E.g.: |
| 248 | |
| 249 | # tm = obj.timetuple() |
| 250 | # return python2lua(lua, { |
| 251 | # '_jstype': 'Date', |
| 252 | # 'year': tm.tm_year, |
| 253 | # 'month': tm.tm_mon, |
| 254 | # 'day': tm.tm_mday, |
| 255 | # 'yday': tm.tm_yday, |
| 256 | # 'wday': tm.tm_wday, # fixme: in Lua Sunday is 1, in Python Monday is 0 |
| 257 | # 'hour': tm.tm_hour, |
| 258 | # 'min': tm.tm_min, |
| 259 | # 'sec': tm.tm_sec, |
| 260 | # 'isdst': tm.tm_isdst, # fixme: isdst can be -1 in Python |
| 261 | # }, max_depth) |
| 262 | |
| 263 | return obj |
| 264 | |
| 265 | return p2l(obj, depth=max_depth) |
| 266 | |
| 267 | |
| 268 |