<reponame>reingart/pypy<filename>pypy/module/micronumpy/flagsobj.py
from rpython.rlib import jit

from pypy.interpreter.baseobjspace import W_Root
from pypy.interpreter.error import OperationError
from pypy.interpreter.gateway import interp2app
from pypy.interpreter.typedef import TypeDef, GetSetProperty
from pypy.module.micronumpy import constants as NPY
from pypy.module.micronumpy.strides import is_c_contiguous, is_f_contiguous

def enable_flags(arr, flags):
    arr.flags |= flags

def clear_flags(arr, flags):
    arr.flags &= ~flags

def _update_contiguous_flags(arr):
    is_c_contig = is_c_contiguous(arr)
    if is_c_contig:
        enable_flags(arr, NPY.ARRAY_C_CONTIGUOUS)
    else:
        clear_flags(arr, NPY.ARRAY_C_CONTIGUOUS)

    is_f_contig = is_f_contiguous(arr)
    if is_f_contig:
        enable_flags(arr, NPY.ARRAY_F_CONTIGUOUS)
    else:
        clear_flags(arr, NPY.ARRAY_F_CONTIGUOUS)


class W_FlagsObject(W_Root):
    def __init__(self, arr):
        self.flags = 0

    def descr__new__(space, w_subtype):
        self = space.allocate_instance(W_FlagsObject, w_subtype)
        W_FlagsObject.__init__(self, None)
        return self

    def descr_get_contiguous(self, space):
        return space.w_True

    def descr_get_fortran(self, space):
        return space.w_False

    def descr_get_writeable(self, space):
        return space.w_True

    def descr_get_fnc(self, space):
        return space.wrap(
            space.is_true(self.descr_get_fortran(space)) and not
            space.is_true(self.descr_get_contiguous(space)))

    def descr_get_forc(self, space):
        return space.wrap(
            space.is_true(self.descr_get_fortran(space)) or
            space.is_true(self.descr_get_contiguous(space)))

    def descr_getitem(self, space, w_item):
        key = space.str_w(w_item)
        if key == "C" or key == "CONTIGUOUS" or key == "C_CONTIGUOUS":
            return self.descr_get_contiguous(space)
        if key == "F" or key == "FORTRAN" or key == "F_CONTIGUOUS":
            return self.descr_get_fortran(space)
        if key == "W" or key == "WRITEABLE":
            return self.descr_get_writeable(space)
        if key == "FNC":
            return self.descr_get_fnc(space)
        if key == "FORC":
            return self.descr_get_forc(space)
        raise OperationError(space.w_KeyError, space.wrap(
            "Unknown flag"))

    def descr_setitem(self, space, w_item, w_value):
        raise OperationError(space.w_KeyError, space.wrap(
            "Unknown flag"))

    def eq(self, space, w_other):
        if not isinstance(w_other, W_FlagsObject):
            return False
        return self.flags == w_other.flags

    def descr_eq(self, space, w_other):
        return space.wrap(self.eq(space, w_other))

    def descr_ne(self, space, w_other):
        return space.wrap(not self.eq(space, w_other))

W_FlagsObject.typedef = TypeDef("numpy.flagsobj",
    __new__ = interp2app(W_FlagsObject.descr__new__.im_func),

    __getitem__ = interp2app(W_FlagsObject.descr_getitem),
    __setitem__ = interp2app(W_FlagsObject.descr_setitem),
    __eq__ = interp2app(W_FlagsObject.descr_eq),
    __ne__ = interp2app(W_FlagsObject.descr_ne),

    contiguous = GetSetProperty(W_FlagsObject.descr_get_contiguous),
    c_contiguous = GetSetProperty(W_FlagsObject.descr_get_contiguous),
    f_contiguous = GetSetProperty(W_FlagsObject.descr_get_fortran),
    fortran = GetSetProperty(W_FlagsObject.descr_get_fortran),
    writeable = GetSetProperty(W_FlagsObject.descr_get_writeable),
    fnc = GetSetProperty(W_FlagsObject.descr_get_fnc),
    forc = GetSetProperty(W_FlagsObject.descr_get_forc),
)
