To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 2d2c1536 authored by Kunshan Wang's avatar Kunshan Wang
Browse files

Support both Python 2 and 3

parent d93b1068
# Python Binding of the Mu Client API
The Python binding allows the client to be written in Python. This binding is
based on the `ctypes` module. Currently only the Python 2 binding is available.
based on the `ctypes` module and is tested on Python 2, Python 3, PyPy and
PyPy3.
It depends on the C binding. You need to build the C binding in the
`../cbinding` directory before using this Python binding.
# How to use
See the docstring in `libmupython2.py`
See the docstring in `libmu.py`
<!--
vim: tw=80 spell
......
from __future__ import division, absolute_import, print_function, unicode_literals
def _assert_instance(obj, *tys):
if not any(isinstance(obj, ty) for ty in tys):
raise AssertionError("{} is not an instance of {}".format(obj,
" or ".join(map(str,tys))))
from __future__ import division, absolute_import, print_function, unicode_literals
from _libmuprivcommon import _assert_instance
def _is_str_like(v):
return isinstance(v, str) or isinstance(v, unicode)
def _encode_ascii(v):
_assert_instance(v, str, unicode)
if isinstance(v, unicode):
return v.encode("ascii")
else:
return v
def _decode_ascii(v):
_assert_instance(v, str, unicode)
if isinstance(v, str):
return v.decode("ascii")
else:
return v
def _assert_int_like(v):
_assert_instance(v, int, long)
from _libmuprivcommon import _assert_instance
def _is_str_like(v):
return isinstance(v, str) or isinstance(v, bytes)
def _encode_ascii(v):
_assert_instance(v, bytes, str)
if isinstance(v, str):
return v.encode("ascii")
else:
return v
def _decode_ascii(v):
_assert_instance(v, bytes, str)
if isinstance(v, bytes):
return v.decode("ascii")
else:
return v
def _assert_int_like(v):
_assert_instance(v, int)
......@@ -3,7 +3,7 @@ from __future__ import division, absolute_import, print_function, unicode_litera
import sys
import ctypes, ctypes.util
from libmupython2 import *
from libmu import *
def slurp(filename):
with open(filename) as t:
......
"""
libmupython2: Python2 binding for the Mu-client API.
libmu: Python binding for the Mu-client API.
This module works for both Python 2 and Python 3.
For PyPy users: This module is not RPython!
......@@ -147,6 +149,13 @@ It is recommended to read the docstrings in the following types: ``MuVM``,
from __future__ import division, absolute_import, print_function, unicode_literals
import sys
if sys.version_info[0] == 2:
import _libmuprivpython2 as _priv
else:
import _libmuprivpython3 as _priv
import ctypes, ctypes.util
_libc = ctypes.CDLL(ctypes.util.find_library("c"))
......@@ -165,10 +174,7 @@ def _assert_range(v, lb, ub):
if not (lb <= v <= ub):
raise AssertionError("{} is not between {} and {}".format(v, lb, ub))
def _assert_instance(obj, *tys):
if not any(isinstance(obj, ty) for ty in tys):
raise AssertionError("{} is not an instance of {}".format(obj,
" or ".join(tys)))
from _libmuprivcommon import _assert_instance
#### Low-level C types counterpart
......@@ -664,8 +670,8 @@ class MuCtx(_StructOfMethodsWrapper):
Arguments:
bundle_str: a str or unicode as the text-based bundle.
"""
_assert_instance(bundle_str, str, unicode)
return self.load_bundle_(bundle_str, len(bundle_str))
ascii_bundle = _priv._encode_ascii(bundle_str)
return self.load_bundle_(ascii_bundle, len(ascii_bundle))
def load_hail(self, hail_str):
"""Load a HAIL script.
......@@ -673,8 +679,8 @@ class MuCtx(_StructOfMethodsWrapper):
Arguments:
bundle_str: a str or unicode as the text-based HAIL script.
"""
_assert_instance(hail_str, str, unicode)
return self.load_hail_(hail_str, len(hail_str))
ascii_bundle = _priv._encode_ascii(hail_str)
return self.load_hail_(ascii_bundle, len(ascii_bundle))
def handle_from_int(self, value, length):
"""Convert a Python int to a Mu handle.
......@@ -688,7 +694,7 @@ class MuCtx(_StructOfMethodsWrapper):
Returns:
a MuIntValue
"""
_assert_instance(value, int, long)
_priv._assert_int_like(value)
_assert_range(length, 0, 64)
if _MIN_SINT64 <= value <= _MAX_SINT64:
return self.handle_from_sint64_(value, length)
......@@ -837,13 +843,15 @@ def _to_low_level_type(ty):
ty)
def _to_low_level_arg(arg):
return (arg._to_low_level_arg() if isinstance(arg, _LowLevelTypeWrapper)
else arg)
return (arg._to_low_level_arg() if isinstance(arg, _LowLevelTypeWrapper) else
_priv._encode_ascii(arg) if _priv._is_str_like(arg) else
arg)
def _from_low_level_retval(restype, low_level_rv, self):
return (restype._from_low_level_retval(low_level_rv, self)
if isinstance(restype, type) and issubclass(restype, _LowLevelTypeWrapper)
else low_level_rv)
if isinstance(restype, type) and issubclass(restype, _LowLevelTypeWrapper) else
_priv._decode_ascii(low_level_rv) if _priv._is_str_like(low_level_rv) else
low_level_rv)
def _make_high_level_method(name, expected_nargs, restype, argtypes):
def wrapper(self, *args):
......@@ -1104,7 +1112,7 @@ class MuRefImpl2StartDLL(object):
dll is a CDLL object of the "libmurefimpl2start.so" library, or a
pathname to it. In the latter case, a CDLL will be created.
"""
if isinstance(dll, str) or isinstance(dll, unicode):
if _priv._is_str_like(dll):
dll = ctypes.CDLL(dll)
dll.mu_refimpl2_new.restype = CPtrMuVM
......
#!/usr/bin/env python2
from __future__ import division, absolute_import, print_function, unicode_literals
import unittest
from libmupython2 import *
from libmu import *
dll = MuRefImpl2StartDLL(u"../cbinding/libmurefimpl2start.so")
mu = dll.mu_refimpl2_new()
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment