Commit a13fab25 authored by Haoyu Bai's avatar Haoyu Bai

improved the pure Python shadow module

parent f7d7598f
......@@ -2,13 +2,26 @@
compiled = False
def empty_decorator(x):
return x
_Unspecified = object()
# Function decorators
def _empty_decorator(x):
return x
def locals(**arg_types):
return empty_decorator
return _empty_decorator
def test_assert_path_exists(path):
return _empty_decorator
class _EmptyDecoratorAndManager(object):
def __call__(self, x):
return x
def __enter__(self):
pass
def __exit__(self, exc_type, exc_value, traceback):
pass
def inline(f, *args, **kwds):
if isinstance(f, basestring):
......@@ -38,11 +51,11 @@ def cmod(a, b):
# Emulated language constructs
def cast(type, arg):
def cast(type, *args):
if hasattr(type, '__call__'):
return type(arg)
return type(*args)
else:
return arg
return args[0]
def sizeof(arg):
return 1
......@@ -53,9 +66,9 @@ def typeof(arg):
def address(arg):
return pointer(type(arg))([arg])
def declare(type=None, value=None, **kwds):
def declare(type=None, value=_Unspecified, **kwds):
if type is not None and hasattr(type, '__call__'):
if value:
if value is not _Unspecified:
return type(value)
else:
return type()
......@@ -75,21 +88,24 @@ del _nogil
# Emulated types
class CythonType(object):
class CythonMetaType(type):
def __getitem__(type, ix):
return array(type, ix)
CythonTypeObject = CythonMetaType('CythonTypeObject', (object,), {})
class CythonType(CythonTypeObject):
def _pointer(self, n=1):
for i in range(n):
self = pointer(self)
return self
def __getitem__(self, ix):
return array(self, ix)
class PointerType(CythonType):
def __init__(self, value=None):
if isinstance(value, ArrayType):
if isinstance(value, (ArrayType, PointerType)):
self._items = [cast(self._basetype, a) for a in value._items]
elif isinstance(value, list):
self._items = [cast(self._basetype, a) for a in value]
......@@ -108,6 +124,14 @@ class PointerType(CythonType):
raise IndexError("negative indexing not allowed in C")
self._items[ix] = cast(self._basetype, value)
def __eq__(self, value):
if value is None and not self._items:
return True
elif type(self) != type(value):
return False
else:
return self._items == value._items
class ArrayType(PointerType):
def __init__(self):
......@@ -116,9 +140,18 @@ class ArrayType(PointerType):
class StructType(CythonType):
def __init__(self, **data):
for key, value in data.iteritems():
setattr(self, key, value)
def __init__(self, cast_from=_Unspecified, **data):
if cast_from is not _Unspecified:
# do cast
if len(data) > 0:
raise ValueError('Cannot accept keyword arguments when casting.')
if type(cast_from) is not type(self):
raise ValueError('Cannot cast from %s'%cast_from)
for key, value in cast_from.__dict__.items():
setattr(self, key, value)
else:
for key, value in data.iteritems():
setattr(self, key, value)
def __setattr__(self, key, value):
if key in self._members:
......@@ -129,10 +162,22 @@ class StructType(CythonType):
class UnionType(CythonType):
def __init__(self, **data):
if len(data) > 0:
def __init__(self, cast_from=_Unspecified, **data):
if cast_from is not _Unspecified:
# do type cast
if len(data) > 0:
raise ValueError('Cannot accept keyword arguments when casting.')
if isinstance(cast_from, dict):
datadict = cast_from
elif type(cast_from) is type(self):
datadict = cast_from.__dict__
else:
raise ValueError('Cannot cast from %s'%cast_from)
else:
datadict = data
if len(datadict) > 1:
raise AttributeError("Union can only store one field at a time.")
for key, value in data.iteritems():
for key, value in datadict.iteritems():
setattr(self, key, value)
def __setattr__(self, key, value):
......@@ -173,9 +218,8 @@ class typedef(CythonType):
def __init__(self, type):
self._basetype = type
def __call__(self, value=None):
if value is not None:
value = cast(self._basetype, value)
def __call__(self, *arg):
value = cast(self._basetype, *arg)
return value
......@@ -230,3 +274,4 @@ for t in int_types + float_types + complex_types + other_types:
void = typedef(None)
NULL = None
......@@ -19,26 +19,24 @@ def test_sizeof():
else:
print(cython.sizeof(cython.char) == 1)
## CURRENTLY BROKEN - FIXME!!
## def test_declare(n):
## """
## >>> test_declare(100)
## (100, 100)
## >>> test_declare(100.5)
## (100, 100)
## >>> test_declare(None)
## Traceback (most recent call last):
## ...
## TypeError: an integer is required
## """
## x = cython.declare(cython.int)
## y = cython.declare(cython.int, n)
## if cython.compiled:
## cython.declare(xx=cython.int, yy=cython.long)
## i = sizeof(xx)
## ptr = cython.declare(cython.p_int, cython.address(y))
## return y, ptr[0]
def test_declare(n):
"""
>>> test_declare(100)
(100, 100)
>>> test_declare(100.5)
(100, 100)
>>> test_declare(None) #doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: ...
"""
x = cython.declare(cython.int)
y = cython.declare(cython.int, n)
if cython.compiled:
cython.declare(xx=cython.int, yy=cython.long)
i = sizeof(xx)
ptr = cython.declare(cython.p_int, cython.address(y))
return y, ptr[0]
@cython.locals(x=cython.double, n=cython.int)
def test_cast(x):
......@@ -59,6 +57,7 @@ def test_address(x):
return y[0]
## CURRENTLY BROKEN - FIXME!!
## Is this test make sense? Implicit conversion in pure Python??
## @cython.locals(x=cython.int)
## @cython.locals(y=cython.bint)
......@@ -93,21 +92,19 @@ def test_with_nogil(nogil):
result = True
return result
## CURRENTLY BROKEN - FIXME!!
MyUnion = cython.union(n=cython.int, x=cython.double)
MyStruct = cython.struct(is_integral=cython.bint, data=MyUnion)
MyStruct2 = cython.typedef(MyStruct[2])
## MyUnion = cython.union(n=cython.int, x=cython.double)
## MyStruct = cython.struct(is_integral=cython.bint, data=MyUnion)
## MyStruct2 = cython.typedef(MyStruct[2])
## def test_struct(n, x):
## """
## >>> test_struct(389, 1.64493)
## (389, 1.64493)
## """
## a = cython.declare(MyStruct2)
## a[0] = MyStruct(True, data=MyUnion(n=n))
## a[1] = MyStruct(is_integral=False, data={'x': x})
## return a[0].data.n, a[1].data.x
def test_struct(n, x):
"""
>>> test_struct(389, 1.64493)
(389, 1.64493)
"""
a = cython.declare(MyStruct2)
a[0] = MyStruct(is_integral=True, data=MyUnion(n=n))
a[1] = MyStruct(is_integral=False, data={'x': x})
return a[0].data.n, a[1].data.x
import cython as cy
from cython import declare, cast, locals, address, typedef, p_void, compiled
......@@ -116,24 +113,21 @@ from cython import declare as my_declare, locals as my_locals, p_void as my_void
@my_locals(a=cython.p_void)
def test_imports():
"""
>>> test_imports() # (True, True)
True
>>> test_imports()
(True, True)
"""
a = cython.NULL
b = declare(p_void, cython.NULL)
c = my_declare(my_void_star, cython.NULL)
d = cy.declare(cy.p_void, cython.NULL)
## CURRENTLY BROKEN - FIXME!!
#return a == d, compiled == my_compiled
return compiled == my_compiled
return a == d, compiled == my_compiled
## CURRENTLY BROKEN - FIXME!!
## MyStruct3 = typedef(MyStruct[3])
## MyStruct4 = my_typedef(MyStruct[4])
## MyStruct5 = cy.typedef(MyStruct[5])
# MyStruct3 = typedef(MyStruct[3])
# MyStruct4 = my_typedef(MyStruct[4])
# MyStruct5 = cy.typedef(MyStruct[5])
def test_declare_c_types(n):
"""
......
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