コード例 #1
0
ファイル: int.cpp プロジェクト: guangwong/pyston
static Box* _intNew(Box* val, Box* base) {
    if (isSubclass(val->cls, int_cls)) {
        RELEASE_ASSERT(!base, "");
        BoxedInt* n = static_cast<BoxedInt*>(val);
        if (val->cls == int_cls)
            return n;
        return new BoxedInt(n->n);
    } else if (isSubclass(val->cls, str_cls)) {
        int base_n;
        if (!base)
            base_n = 10;
        else {
            RELEASE_ASSERT(base->cls == int_cls, "");
            base_n = static_cast<BoxedInt*>(base)->n;
        }

        BoxedString* s = static_cast<BoxedString*>(val);

        RELEASE_ASSERT(s->size() == strlen(s->data()), "");
        Box* r = PyInt_FromString(s->data(), NULL, base_n);
        if (!r)
            throwCAPIException();
        return r;
    } else if (isSubclass(val->cls, unicode_cls)) {
        int base_n;
        if (!base)
            base_n = 10;
        else {
            RELEASE_ASSERT(base->cls == int_cls, "");
            base_n = static_cast<BoxedInt*>(base)->n;
        }

        Box* r = PyInt_FromUnicode(PyUnicode_AS_UNICODE(val), PyUnicode_GET_SIZE(val), base_n);
        if (!r)
            throwCAPIException();
        return r;
    } else if (val->cls == float_cls) {
        RELEASE_ASSERT(!base, "");
        double d = static_cast<BoxedFloat*>(val)->d;
        return new BoxedInt(d);
    } else {
        RELEASE_ASSERT(!base, "");
        static const std::string int_str("__int__");
        Box* r = callattr(val, &int_str, CallattrFlags({.cls_only = true, .null_on_nonexistent = true }),
                          ArgPassSpec(0), NULL, NULL, NULL, NULL, NULL);

        if (!r) {
            fprintf(stderr, "TypeError: int() argument must be a string or a number, not '%s'\n", getTypeName(val));
            raiseExcHelper(TypeError, "");
        }

        if (!isSubclass(r->cls, int_cls) && !isSubclass(r->cls, long_cls)) {
            raiseExcHelper(TypeError, "__int__ returned non-int (type %s)", r->cls->tp_name);
        }
        return r;
    }
コード例 #2
0
ファイル: import.cpp プロジェクト: nanwu/pyston
/* Return the package that an import is being performed in.  If globals comes
   from the module foo.bar.bat (not itself a package), this returns the
   sys.modules entry for foo.bar.  If globals is from a package's __init__.py,
   the package's entry in sys.modules is returned, as a borrowed reference.

   The *name* of the returned package is returned in buf.

   If globals doesn't come from a package or a module in a package, or a
   corresponding entry is not found in sys.modules, Py_None is returned.
*/
static Box* getParent(Box* globals, int level, std::string& buf) {
    int orig_level = level;

    if (globals == NULL || globals == None || level == 0)
        return None;

    static BoxedString* package_str = internStringImmortal("__package__");
    BoxedString* pkgname = static_cast<BoxedString*>(getFromGlobals(globals, package_str));
    if (pkgname != NULL && pkgname != None) {
        /* __package__ is set, so use it */
        if (pkgname->cls != str_cls) {
            raiseExcHelper(ValueError, "__package__ set to non-string");
        }
        size_t len = pkgname->size();
        if (len == 0) {
            if (level > 0) {
                raiseExcHelper(ValueError, "Attempted relative import in non-package");
            }
            return None;
        }
        if (len > PATH_MAX) {
            raiseExcHelper(ValueError, "Package name too long");
        }
        buf += pkgname->s();
    } else {
        static BoxedString* name_str = internStringImmortal("__name__");

        /* __package__ not set, so figure it out and set it */
        BoxedString* modname = static_cast<BoxedString*>(getFromGlobals(globals, name_str));
        if (modname == NULL || modname->cls != str_cls)
            return None;

        static BoxedString* path_str = internStringImmortal("__path__");
        Box* modpath = getFromGlobals(globals, path_str);

        if (modpath != NULL) {
            /* __path__ is set, so modname is already the package name */
            if (modname->size() > PATH_MAX) {
                raiseExcHelper(ValueError, "Module name too long");
            }
            buf += modname->s();
            setGlobal(globals, package_str, modname);
        } else {
            /* Normal module, so work out the package name if any */
            size_t lastdot = modname->s().rfind('.');
            if (lastdot == std::string::npos && level > 0) {
                raiseExcHelper(ValueError, "Attempted relative import in non-package");
            }
            if (lastdot == std::string::npos) {
                setGlobal(globals, package_str, None);
                return None;
            }
            if (lastdot >= PATH_MAX) {
                raiseExcHelper(ValueError, "Module name too long");
            }

            buf = std::string(modname->s(), 0, lastdot);
            setGlobal(globals, package_str, boxString(buf));
        }
    }

    size_t dot = buf.size() - 1;
    while (--level > 0) {
        dot = buf.rfind('.', dot);
        if (dot == std::string::npos) {
            raiseExcHelper(ValueError, "Attempted relative import beyond toplevel package");
        }
        dot--;
    }

    buf = std::string(buf, 0, dot + 1);

    BoxedDict* sys_modules = getSysModulesDict();
    Box* boxed_name = boxString(buf);
    Box* parent = sys_modules->d.find(boxed_name) != sys_modules->d.end() ? sys_modules->d[boxed_name] : NULL;
    if (parent == NULL) {
        if (orig_level < 1) {
            printf("Warning: Parent module '%.200s' not found "
                   "while handling absolute import\n",
                   buf.c_str());
        } else {
            raiseExcHelper(SystemError, "Parent module '%.200s' not loaded, "
                                        "cannot perform relative import",
                           buf.c_str());
        }
    }
    return parent;
    /* We expect, but can't guarantee, if parent != None, that:
       - parent.__name__ == buf
       - parent.__dict__ is globals
       If this is violated...  Who cares? */
}