sethmlarson / virtualbox-python

Complete implementation of VirtualBox's COM API with a Pythonic interface.
https://pypi.org/project/virtualbox
Apache License 2.0
354 stars 75 forks source link

Dynamic module does not define module export function (PyInit_VBoxPython3_6m) #99

Closed larytet closed 6 years ago

larytet commented 6 years ago
ENVIRONMENT
SUMMARY

Following code fails

import virtualbox
vbox = virtualbox.VirtualBox()
vbox.compose_machine_filename("win8", "test", "", "")

with AttributeError: 'TypeError' object has no attribute 'message'

The full error


    def _call_method(self, method, in_p=None):
        if in_p is None:
            in_p = []
        in_params = [self._cast_to_valuetype(p) for p in in_p]
        try:
            ret = method(*in_params)
        except Exception as exc:
            errno = getattr(exc, 'errno', getattr(exc, 'hresult', -1))
            errno &= 0xFFFFFFFF
            errclass = vbox_error.get(errno, VBoxError)
            errobj = errclass()
            errobj.exc = exc
            errobj.value = errno
            # TODO: Is this the only way to get a message from exc...
            #       does this also vary between nix vs windows.
            errobj.msg = None
            if platform.system() == 'Windows':
                if hasattr(exc, 'args'):
                    errobj.msg = exc.args[2][2]
            # TODO: get the Linux/Darwin specific args struct

            if errobj.msg is None:
>               errobj.msg = getattr(exc, 'msg', getattr(exc, 'message'))
E               AttributeError: 'TypeError' object has no attribute 'message'
larytet commented 6 years ago

The following fails as well

import virtualbox
virtualbox.VirtualBox().find_machine("win8")

The whole output looks like

$ bpython3
bpython version 0.17 on top of Python 3.6.3 /usr/bin/python3
>>> import virtualbox
>>> virtualbox.VirtualBox().find_machine("win8")
m=VBoxPython3_6m x=dynamic module does not define module export function (PyInit_VBoxPython3_6m)
m=VBoxPython3m x=No module named 'VBoxPython3m'
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    virtualbox.VirtualBox().find_machine("win8")
  File "/usr/local/lib/python3.6/dist-packages/virtualbox/library.py", line 7280, in find_machine
    in_p=[name_or_id])
  File "/usr/local/lib/python3.6/dist-packages/virtualbox/library_base.py", line 186, in _call
    return self._call_method(method, in_p=in_p)
  File "/usr/local/lib/python3.6/dist-packages/virtualbox/library_base.py", line 212, in _call_method
    errobj.msg = getattr(exc, 'msg', getattr(exc, 'message'))
AttributeError: 'TypeError' object has no attribute 'message'

I suspect that I have a problem with the environment, but I can not figure out what the problem is

larytet commented 6 years ago

After some debugging: exc.dict is {} (instance exc does not contain any attributes) and errobj=0xffffffff (None)

larytet commented 6 years ago

In Python 2.7 I am getting

$ bpython
bpython version 0.17 on top of Python 2.7.14 /usr/bin/python
>>> import virtualbox
>>> virtualbox.VirtualBox().find_machine("win8")
m=VBoxPython2_7 x=No module named VBoxPython2_7
m=VBoxPython2 x=No module named VBoxPython2
m=VBoxPython x=/usr/lib/virtualbox/VBoxPython.so: undefined symbol: _Py_FalseStruct
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    virtualbox.VirtualBox().find_machine("win8")
  File "/usr/local/lib/python2.7/dist-packages/virtualbox/library_ext/vbox.py", line 22, in __init__
    manager = virtualbox.Manager()
  File "/usr/local/lib/python2.7/dist-packages/virtualbox/__init__.py", line 137, in __init__
    self.manager = vboxapi.VirtualBoxManager(mtype, mparams)
  File "/usr/local/lib/python2.7/dist-packages/vboxapi/__init__.py", line 989, in __init__
    self.platform = PlatformXPCOM(dPlatformParams)
  File "/usr/local/lib/python2.7/dist-packages/vboxapi/__init__.py", line 750, in __init__
    import xpcom.vboxxpcom
  File "/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/vboxxpcom.py", line 78, in <module>
    raise Exception('Cannot find VBoxPython module (tried: %s)' % (', '.join(_asVBoxPythons),))
Exception: Cannot find VBoxPython module (tried: VBoxPython2_7, VBoxPython2, VBoxPython)

I installed pyvbox using sudo pip install pyvbox

larytet commented 6 years ago

I tried to use vboxapi directly - this is about the wrong parameter for findMachine and broken exception handler.

import vboxapi
vboxapi.VirtualBoxManager(None, None).getVirtualBox().findMachine('win8')
import vboxapi
vboxMgr = vboxapi.VirtualBoxManager(None, None)
m=VBoxPython3_6m x=dynamic module does not define module export function (PyInit_VBoxPython3_6m)
m=VBoxPython3m x=No module named 'VBoxPython3m'
#  I hope I am doing it right 
vbox = vboxMgr.getVirtualBox()
vbox.findMachine('win8')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    vbox.findMachine('win8')
  File "<XPCOMObject method 'findMachine'>", line 3, in findMachine
TypeError: internal error in PyXPCOM, parameter must be a bytes object
larytet commented 6 years ago

I tried

import vboxapi
vboxMgr = vboxapi.VirtualBoxManager(None, None)
m=VBoxPython3_6m x=dynamic module does not define module export function (PyInit_VBoxPython3_6m)
m=VBoxPython3m x=No module named 'VBoxPython3m'
#  I hope I am doing it right 
vbox = vboxMgr.getVirtualBox()
 vbox.findMachine(u"win8".encode())
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    vbox.findMachine(u"win8".encode())
  File "<XPCOMObject method 'findMachine'>", line 3, in findMachine
TypeError: This parameter must be a unicode object
larytet commented 6 years ago

I suspect that Python3 binding is broken. In Python 2.7 I am getting Cannot find VBoxPython module (tried: VBoxPython2_7, VBoxPython2, VBoxPython)

I tried to set the path PYTHON_PATH=/usr/lib/virtualbox/sdk/bindings/xpcom/python:/usr/lib/virtualbox PYTHONPATH=/usr/lib/virtualbox/sdk/bindings/xpcom/python:/usr/lib/virtualbox

There is a file /usr/lib/virtualbox/VBoxPython.so

sethmlarson commented 6 years ago

Hello! Thanks for posting this issue and including all this information. Could you answer a few questions about your environment then I'll be able to help you a lot easier:

We'll get to the bottom of this!

larytet commented 6 years ago

I have downloaded VirtualBoxSDK-5.2.2-119230.zip from the VirtualBox website md5 d533c08e64f31e5cd7c886c906ed7d16

I am using system (Host machine) Python 3 to install everything unzip cd sdk/installer sudo VBOX_INSTALL_PATH=/usr/lib/virtualbox python3.6 vboxapisetup.py install sudo pip3 install vboxapi

It appears that I have /usr/local/lib/python3.6/dist-packages import vboxapi works fine as you see in my posts above

The issue is not with pyvbox, but with my installation of vboxapi. I guess pyvbox is not the right place to continue.

Would be nice to have an egg which installs everything in Ubuntu.

Meanwhile I switched to the VBoxManager shell for my project.

sethmlarson commented 6 years ago

I'll still try to recreate your issue as I have Ubuntu 17.10 installed.

larytet commented 6 years ago

I did

    # install VirtualBox SDK from https://www.virtualbox.org/wiki/Downloads
    # wget http://download.virtualbox.org/virtualbox/5.2.2/VirtualBoxSDK-5.2.2-119230.zip
    # unzip VirtualBoxSDK-5.2.2-119230.zip
    # cd sdk/installer/
    # sudo VBOX_INSTALL_PATH=/usr/lib/virtualboxpython3 python3.6 ./vboxapisetup.py install
noxdafox commented 6 years ago

I have the same issue on Debian Stretch, Python 3.5.

pyvbox was installed via pip.

sudo pip3 install pyvbox
In [1]: import virtualbox

In [2]: vbox = virtualbox.VirtualBox()
m=VBoxPython3_5m x=dynamic module does not define module export function (PyInit_VBoxPython3_5m)
m=VBoxPython3m x=No module named 'VBoxPython3m'

In [3]: vm = vbox.find_machine(vbox.machines[0].name)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    194         try:
--> 195             ret = method(*in_params)
    196         except Exception as exc:

/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py in findMachine(self, Param1)

TypeError: internal error in PyXPCOM, parameter must be a bytes object

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
<ipython-input-3-65f32237fea6> in <module>()
----> 1 vm = vbox.find_machine(vbox.machines[0].name)

/usr/local/lib/python3.5/dist-packages/virtualbox/library.py in find_machine(self, name_or_id)
   7278             raise TypeError("name_or_id can only be an instance of type basestring")
   7279         machine = self._call("findMachine",
-> 7280                      in_p=[name_or_id])
   7281         machine = IMachine(machine)
   7282         return machine

/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call(self, name, in_p)
    184         method = self._search_attr(name)
    185         if inspect.isfunction(method) or inspect.ismethod(method):
--> 186             return self._call_method(method, in_p=in_p)
    187         else:
    188             return method

/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    210 
    211             if errobj.msg is None:
--> 212                 errobj.msg = getattr(exc, 'msg', getattr(exc, 'message'))
    213             raise errobj
    214         return ret

AttributeError: 'TypeError' object has no attribute 'message'
sethmlarson commented 6 years ago

See issue #102.

noxdafox commented 6 years ago

Yes I was already reading through that issue, what is the recommended workaround?

I tried to copy the libfile but did not help.

cp /usr/lib/virtualbox/VBoxPython3_5m.so /usr/lib/virtualbox/VBoxPython3_5.so
sethmlarson commented 6 years ago

I'm not sure, upstream hasn't responded to the issue I raised with them. I was thinking of maybe writing some retry import logic that sets sys.abiflags() to return an empty string if the first import fails? Not sure.

sethmlarson commented 6 years ago

Actually setting sys.abiflags to an empty string before importing and then restoring after the import might just work! Since this import logic happens within xpcom.py not within our code.

noxdafox commented 6 years ago

Yup that works! Thanks!

sethmlarson commented 6 years ago

Now to codify it in our crazy import logic. :)

noxdafox commented 6 years ago

Actually it just fixed the vbox instance creation error, not the original one reported in this issue.

In [1]: import sys

In [2]: sys.abiflags = ''

In [3]: import virtualbox

In [4]: vbox = virtualbox.VirtualBox()

In [5]: vm = vbox.find_machine(vbox.machines[0].name)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    194         try:
--> 195             ret = method(*in_params)
    196         except Exception as exc:

/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/client/__init__.py in findMachine(self, Param1)

TypeError: internal error in PyXPCOM, parameter must be a bytes object

During handling of the above exception, another exception occurred:

AttributeError                            Traceback (most recent call last)
<ipython-input-5-65f32237fea6> in <module>()
----> 1 vm = vbox.find_machine(vbox.machines[0].name)

/usr/local/lib/python3.5/dist-packages/virtualbox/library.py in find_machine(self, name_or_id)
   7278             raise TypeError("name_or_id can only be an instance of type basestring")
   7279         machine = self._call("findMachine",
-> 7280                      in_p=[name_or_id])
   7281         machine = IMachine(machine)
   7282         return machine

/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call(self, name, in_p)
    184         method = self._search_attr(name)
    185         if inspect.isfunction(method) or inspect.ismethod(method):
--> 186             return self._call_method(method, in_p=in_p)
    187         else:
    188             return method

/usr/local/lib/python3.5/dist-packages/virtualbox/library_base.py in _call_method(self, method, in_p)
    210 
    211             if errobj.msg is None:
--> 212                 errobj.msg = getattr(exc, 'msg', getattr(exc, 'message'))
    213             raise errobj
    214         return ret

AttributeError: 'TypeError' object has no attribute 'message'
sethmlarson commented 6 years ago

Could you open up a separate issue?

noxdafox commented 6 years ago

106

lzwgiter commented 4 years ago

I have the same issue with python2.7:

>>> import virtualbox
>>> vbox = virtualbox.VirtualBox()
m=VBoxPython2_7 x=No module named VBoxPython2_7
m=VBoxPython2 x=No module named VBoxPython2
m=VBoxPython x=/usr/lib/virtualbox/VBoxPython.so: undefined symbol: _Py_FalseStruct
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/float/.local/lib/python2.7/site-packages/virtualbox/library_ext/vbox.py", line 22, in __init__
    manager = virtualbox.Manager()
  File "/home/float/.local/lib/python2.7/site-packages/virtualbox/__init__.py", line 145, in __init__
    self.manager = vboxapi.VirtualBoxManager(mtype, mparams)
  File "vboxapi/__init__.py", line 972, in __init__
    self.platform = PlatformXPCOM(dPlatformParams)
  File "vboxapi/__init__.py", line 732, in __init__
    import xpcom.vboxxpcom
  File "/usr/lib/virtualbox/sdk/bindings/xpcom/python/xpcom/vboxxpcom.py", line 78, in <module>
    raise Exception('Cannot find VBoxPython module (tried: %s)' % (', '.join(_asVBoxPythons),))
Exception: Cannot find VBoxPython module (tried: VBoxPython2_7, VBoxPython2, VBoxPython)