Comments (20)
Shouldn't you be more interested in the Lua type of the object than the type of the Python wrapper? See
https://github.com/scoder/lupa#python-objects-in-lua
from lupa.
Thanks, it will work for my use case!
The problem with it is that "Python instincts" don't help here: from lua.eval("{}")
you get <Lua table at 0x7f813059ec40>
; you can get a class from this object (<type 'lupa._lupa._LuaTable'>
), but this class doesn't exist is not importable in Python land, so it is not obvious how to check for a type.
By doing isinstance
check one can confirm that an object conforms to a certain interface. Interface is provided by lupa wrapper, not by Lua language, so checking for Lua type is less explicit.
from lupa.
Faced another issue: you need a LuaRuntime instance to do a check. It may be hard to structure code in such way an instance is accessable everywhere; there could be many LuaRuntime instances managed by another part of the library, and no globally available runtime - it could be inconvenient to pass "lua" object through several layers to do a type check. Creating another Lua runtime just for type checking doesn't look good doesn't work.
from lupa.
Two ideas:
-
provide
_LuaObject
with a property.lua_type
that returns the Lua type name (as done in__repr__()
) -
provide a global function
lupa.lua_type()
that takes a_LuaObject
and returns its Lua type name (independent of a specific runtime instance)
I vote for 2) as it avoids adding a new attribute to wrapped Lua objects that risks shadowing a Lua object attribute or table key.
The type of the wrapper object should never be relevant. It's a pure implementation detail, as shown by the fact that the types are not exported by the module.
from lupa.
The type of the wrapper object should never be relevant. It's a pure implementation detail, as shown by the fact that the types are not exported by the module.
My use case is serializing/processing a dict which contains mixed values - some of them could be wrapped Lua objects, some of them could be Python objects. I want to expand tables to dicts, disallow (raise an exception) Lua functions and coroutines, stuff like that. Values are mixed because they are returned from Lua code which has an access to some of the Python objects and can put them to a table.
Is there a better way to distinguish between regular Python objects and wrapped Lua objects than doing an isinstance(obj, LuaObject)
type check? lupa.lua_type()
could help with that as it will return 'userdata' for regular Python objects, but if I'm not mistaken it could return 'userdata' for objects from Lua extensions as well.
What is an advantage of hiding these wrapper classes - do you have plans to change or remove them?
from lupa.
It keeps bothering me :) User should care about lua types in Lua code and about Python types in Python code, right?
In #34 you mentioned that it'd be good for _LuaTable to provide update
method; this method is to be used from Python code, Lua tables don't have this method, so checking for lua_type(obj) == "table" is less clear.
I propose to remove @cython.internal
from types that can be visible to Python: _LuaTable
, _LuaObject
, _LuaFunction
, _LuaCoroutineFunction
, _LuaThread
, _LuaIter
.
from lupa.
Counterproposal :)
We register them with the corresponding ABCs so that you can test isinstance(obj, Mapping)
, isinstance(x, Callable)
etc. Wouldn't that be enough?
from lupa.
Registering them with ABCs still won't allow to distinguish between "regular" Python objects and wrapped Lua types. lupa.lua_type()
cover most practical needs, but it doesn't provide a way to check if an object is a LuaObject or not.
from lupa.
Ok, but that can be helped with a global function lupa.is_lua_object(obj)
.
from lupa.
It looks like lupa.lua_type(obj)
+ lupa.is_lua_object(obj)
will cover all use cases.
I haven't understood yet why is this indirection needed - do you want to keep a possibility of changing/removing _Lua...
classes without breaking user code, is that what this indirection for?
from lupa.
And if this indirection is needed, why is it better to rely on strings like "table" instead of e.g. using custom ABCs, or classes directly?
from lupa.
I consider the concrete classes an implementation detail that code should not depend on. I don't see a need to depend on anything but a) the Lua type of the wrapped object and b) the protocol(s) that the object wrapper implements in Python. And I do encourage people to test for ABCs, thus my proposal to add support for them.
from lupa.
I agree that there is no need for anything but Lua type of a wrapped object and a protocol(s) that the object wrapper implement, they cover all use cases.
My point is that isinstance(obj, lupa.LuaTable)
also covers all use cases (it checks for both in a single call), and it provides some advantages:
- it is easier to implement - we need to remove some code instead of adding more code;
lupa.lua_type(obj) == "table"
doesn't check that"table"
is a valid value whileisinstance(obj, lupa.LuaTable)
will raise an AttributeError in case of incorrect/unavailable type;- from
repr(wrapped_object)
users can understand how to useisinstance(obj, lupa.LuaTable)
, but not how to uselupa.lua_type(obj)
.
from lupa.
I get the impression that you are confusing two levels here: the Python API and the Lua API. The fact that an object is a table in Lua doesn't necessarily mean it gets a mapping interface wrapper in Python. This may become configurable at some point, and users may be able to decide which interface to map a Lua object to (just like we have as_attrgetter() and as_itemgetter() now). A possible example would be to split up sequence and mapping support for tables and provide separate, distinct wrapper implementations for them. These interfaces may or may not reuse what the current Lupa wrapper classes provide (although they would most likely inherit from a Lupa wrapper base class in one way or another).
If your code relies on a specific Python interface, you should test for the ABC. If you rely on specific properties of the wrapped Lua object, you should test for that based on the Lua type. You should not test for a specific wrapper class.
from lupa.
I just realised that there is no need for is_lua_object()
if lua_type()
returns None for non-Lua objects.
from lupa.
hmm, github haven't displayed some of your comments before (#26 (comment), #26 (comment)).
What I really want to do is to get an object returned by Lua function and convert it to plain Python data structure which doesn't hold any reference to LuaRuntime, and can be e.g. serialized to JSON:
- (previously wrapped) Python objects should remain Python objects, they should be passed as-is;
- Lua tables should be copied to Python dicts (with keys and values converted from Lua recursively);
- exception should be raised for other wrapped Lua objects.
A possible example would be to split up sequence and mapping support for tables and provide separate, distinct wrapper implementations for them.
This is quite similar to what I'm doing - I want to expose _LuaTables as unrelated (copied) dicts. Checking for _LuaTable is exactly what the code wants to do; it doesn't care what is Lua type of the object or if object is a Mapping or not. If lupa returns some other wrapped Lua object then it is not known how to convert it to a primitive data type, so an exception should be raised; again, the code doesn't care about its Lua type or interfaces this object provides, what it cares about is if an object is _LuaObject or not.
I just realised that there is no need for is_lua_object() if lua_type() returns None for non-Lua objects.
This could become confusing with auto-conversion rules. I'd expect is_lua_object
to return False for Python ints, but lua_type
returns 'number' for ints. Should this new lua_type
return None or 'number' for a Python int?
from lupa.
See 9f12ac0
from lupa.
OK, it makes sense.
Maybe fix/change lua_type
example in README?
from lupa.
from lupa.
Thanks!
from lupa.
Related Issues (20)
- Error loading C modules in 2.x HOT 6
- Expose Lua load arguments (mode and chunkname) HOT 9
- Identity of wrapped Lua objects
- Deadlock involving __dealloc__ HOT 3
- [Feature Request] Async Overhaul
- [Feature Request] Expose Guts for better fine control.
- Ship Lua 5.1 with default lupa installation HOT 3
- pip install lupa fails on Windows HOT 2
- Terra HOT 1
- question: using python functions on lua tables HOT 2
- error lupa.lua54.LuaSyntaxError:
- Can Chinese name function functions be supported?
- Can't install lupa using pip HOT 3
- lua51 missing HOT 1
- 2.1 `pip install --upgrade lupa` not enough, `--force-reinstall` was needed HOT 4
- Unable to Import 'lua-utf8' in LuaJIT HOT 1
- 2.1: pytest fails in `lupa/tests/test.py::TestOverflowMixin::test_no_overflow` unit HOT 8
- Cython error: Lua "undeclared name not builtin: long" HOT 2
- 'popen' not supported
- How to pass a python dictionary as an argument into a function defined in LUA code? HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from lupa.