Commit 93a9f529 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge branch 'master' into refcounting

parents d849bb93 c9268664
......@@ -38,6 +38,7 @@ addons:
- g++-4.8
- gdb
- libbz2-dev
- libgeoip-dev
- libgmp3-dev
- libmpfr-dev
- liblzma-dev
......
......@@ -28,6 +28,12 @@ sudo apt-get install -yq automake git cmake ninja-build ccache libncurses5-dev l
sudo yum install git make cmake clang gcc gcc-c++ ccache ninja-build xz-devel automake libtool gmp-devel mpfr-devel readline-devel openssl-devel sqlite-devel python-devel zlib-devel bzip2-devel ncurses-devel texlive-latex2man libffi-devel
```
### Additional prerequisites for running the integration tests
**Ubuntu**
```
sudo apt-get install libgeoip-dev
```
### Building and testing
```
git clone https://github.com/dropbox/pyston.git ~/pyston
......
......@@ -1947,15 +1947,15 @@ extern "C" PyObject* PyNumber_Positive(PyObject* o) noexcept {
}
extern "C" PyObject* PyNumber_Absolute(PyObject* o) noexcept {
if (o == Py_None)
return type_error("bad operand type for abs(): '%.200s'", o);
PyNumberMethods* m;
try {
return abs_(o);
} catch (ExcInfo e) {
fatalOrError(PyExc_NotImplementedError, "unimplemented");
return nullptr;
}
if (o == NULL)
return null_error();
m = o->cls->tp_as_number;
if (m && m->nb_absolute)
return m->nb_absolute(o);
return type_error("bad operand type for abs(): '%.200s'", o);
}
extern "C" PyObject* PyNumber_Invert(PyObject* o) noexcept {
......
......@@ -86,6 +86,7 @@ static PyObject* do_mklist(const char**, va_list*, int, int, int) noexcept;
static PyObject* do_mkdict(const char**, va_list*, int, int, int) noexcept;
static PyObject* do_mkvalue(const char**, va_list*, int) noexcept;
typedef double va_double;
static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noexcept {
for (;;) {
switch (*(*p_format)++) {
......@@ -124,8 +125,54 @@ static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noe
case 'l':
return PyInt_FromLong(va_arg(*p_va, long));
case 'k': {
unsigned long n;
n = va_arg(*p_va, unsigned long);
if (n > (unsigned long)PyInt_GetMax())
return PyLong_FromUnsignedLong(n);
else
return PyInt_FromLong(n);
}
#ifdef HAVE_LONG_LONG
case 'L':
return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG));
case 'K':
return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG));
#endif
#ifdef Py_USING_UNICODE
case 'u': {
PyObject* v;
Py_UNICODE* u = va_arg(*p_va, Py_UNICODE*);
Py_ssize_t n;
if (**p_format == '#') {
++*p_format;
if (flags & FLAG_SIZE_T)
n = va_arg(*p_va, Py_ssize_t);
else
n = va_arg(*p_va, int);
} else
n = -1;
if (u == NULL) {
v = Py_None;
Py_INCREF(v);
} else {
if (n < 0)
n = _ustrlen(u);
v = PyUnicode_FromUnicode(u, n);
}
return v;
}
#endif
case 'f':
case 'd':
return PyFloat_FromDouble(va_arg(*p_va, double));
return PyFloat_FromDouble((double)va_arg(*p_va, va_double));
#ifndef WITHOUT_COMPLEX
case 'D':
return PyComplex_FromCComplex(*((Py_complex*)va_arg(*p_va, Py_complex*)));
#endif /* WITHOUT_COMPLEX */
case 'c': {
char p[1];
......@@ -133,34 +180,6 @@ static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noe
return PyString_FromStringAndSize(p, 1);
}
case 'N':
case 'S':
case 'O':
if (**p_format == '&') {
typedef PyObject* (*converter)(void*);
converter func = va_arg(*p_va, converter);
void* arg = va_arg(*p_va, void*);
++*p_format;
return (*func)(arg);
} else {
PyObject* v;
v = va_arg(*p_va, PyObject*);
if (v != NULL) {
if (*(*p_format - 1) != 'N')
Py_INCREF(v);
} else if (!PyErr_Occurred())
/* If a NULL was passed
* because a call that should
* have constructed a value
* failed, that's OK, and we
* pass the error on; but if
* no error occurred it's not
* clear that the caller knew
* what she was doing. */
PyErr_SetString(PyExc_SystemError, "NULL object passed to Py_BuildValue");
return v;
}
case 's':
case 'z': {
PyObject* v;
......@@ -190,37 +209,34 @@ static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noe
}
return v;
}
#ifdef HAVE_LONG_LONG
case 'L':
return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG));
case 'K':
return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG));
#endif
#ifdef Py_USING_UNICODE
case 'u': {
PyObject* v;
Py_UNICODE* u = va_arg(*p_va, Py_UNICODE*);
Py_ssize_t n;
if (**p_format == '#') {
case 'N':
case 'S':
case 'O':
if (**p_format == '&') {
typedef PyObject* (*converter)(void*);
converter func = va_arg(*p_va, converter);
void* arg = va_arg(*p_va, void*);
++*p_format;
if (flags & FLAG_SIZE_T)
n = va_arg(*p_va, Py_ssize_t);
else
n = va_arg(*p_va, int);
} else
n = -1;
if (u == NULL) {
v = Py_None;
Py_INCREF(v);
return (*func)(arg);
} else {
if (n < 0)
n = _ustrlen(u);
v = PyUnicode_FromUnicode(u, n);
}
PyObject* v;
v = va_arg(*p_va, PyObject*);
if (v != NULL) {
if (*(*p_format - 1) != 'N')
Py_INCREF(v);
} else if (!PyErr_Occurred())
/* If a NULL was passed
* because a call that should
* have constructed a value
* failed, that's OK, and we
* pass the error on; but if
* no error occurred it's not
* clear that the caller knew
* what she was doing. */
PyErr_SetString(PyExc_SystemError, "NULL object passed to Py_BuildValue");
return v;
}
#endif
case ':':
case ',':
......@@ -229,7 +245,8 @@ static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noe
break;
default:
RELEASE_ASSERT(0, "%c", *((*p_format) - 1));
PyErr_SetString(PyExc_SystemError, "bad format char passed to Py_BuildValue");
return NULL;
}
}
abort();
......
......@@ -90,19 +90,10 @@ extern "C" Box* vars(Box* obj) {
}
extern "C" Box* abs_(Box* x) {
if (PyInt_Check(x)) {
i64 n = static_cast<BoxedInt*>(x)->n;
return boxInt(n >= 0 ? n : -n);
} else if (x->cls == float_cls) {
double d = static_cast<BoxedFloat*>(x)->d;
return boxFloat(std::abs(d));
} else if (x->cls == long_cls) {
return longAbs(static_cast<BoxedLong*>(x));
} else {
static BoxedString* abs_str = getStaticString("__abs__");
CallattrFlags callattr_flags{.cls_only = true, .null_on_nonexistent = false, .argspec = ArgPassSpec(0) };
return callattr(x, abs_str, callattr_flags, NULL, NULL, NULL, NULL, NULL);
}
Box* rtn = PyNumber_Absolute(x);
if (!rtn)
throwCAPIException();
return rtn;
}
extern "C" Box* binFunc(Box* x) {
......@@ -326,11 +317,12 @@ extern "C" Box* chr(Box* arg) {
}
extern "C" Box* unichr(Box* arg) {
if (arg->cls != int_cls)
raiseExcHelper(TypeError, "an integer is required");
int n = -1;
if (!PyArg_ParseSingle(arg, 0, "unichr", "i", &n))
throwCAPIException();
i64 n = static_cast<BoxedInt*>(arg)->n;
Box* rtn = PyUnicode_FromOrdinal(n);
if (!rtn)
checkAndThrowCAPIException();
return rtn;
}
......@@ -937,6 +929,111 @@ Fail_1:
return NULL;
}
static PyObject* filterunicode(PyObject* func, PyObject* strobj) {
PyObject* result;
Py_ssize_t i, j;
Py_ssize_t len = PyUnicode_GetSize(strobj);
Py_ssize_t outlen = len;
if (func == Py_None) {
/* If it's a real string we can return the original,
* as no character is ever false and __getitem__
* does return this character. If it's a subclass
* we must go through the __getitem__ loop */
if (PyUnicode_CheckExact(strobj)) {
Py_INCREF(strobj);
return strobj;
}
}
if ((result = PyUnicode_FromUnicode(NULL, len)) == NULL)
return NULL;
for (i = j = 0; i < len; ++i) {
PyObject* item, *arg, *good;
int ok;
item = (*strobj->cls->tp_as_sequence->sq_item)(strobj, i);
if (item == NULL)
goto Fail_1;
if (func == Py_None) {
ok = 1;
} else {
arg = PyTuple_Pack(1, item);
if (arg == NULL) {
Py_DECREF(item);
goto Fail_1;
}
good = PyEval_CallObject(func, arg);
Py_DECREF(arg);
if (good == NULL) {
Py_DECREF(item);
goto Fail_1;
}
ok = PyObject_IsTrue(good);
Py_DECREF(good);
}
if (ok > 0) {
Py_ssize_t reslen;
if (!PyUnicode_Check(item)) {
PyErr_SetString(PyExc_TypeError, "can't filter unicode to unicode:"
" __getitem__ returned different type");
Py_DECREF(item);
goto Fail_1;
}
reslen = PyUnicode_GET_SIZE(item);
if (reslen == 1)
PyUnicode_AS_UNICODE(result)[j++] = PyUnicode_AS_UNICODE(item)[0];
else {
/* do we need more space? */
Py_ssize_t need = j + reslen + len - i - 1;
/* check that didnt overflow */
if ((j > PY_SSIZE_T_MAX - reslen) || ((j + reslen) > PY_SSIZE_T_MAX - len) || ((j + reslen + len) < i)
|| ((j + reslen + len - i) <= 0)) {
Py_DECREF(item);
return NULL;
}
assert(need >= 0);
assert(outlen >= 0);
if (need > outlen) {
/* overallocate,
to avoid reallocations */
if (need < 2 * outlen) {
if (outlen > PY_SSIZE_T_MAX / 2) {
Py_DECREF(item);
return NULL;
} else {
need = 2 * outlen;
}
}
if (PyUnicode_Resize(&result, need) < 0) {
Py_DECREF(item);
goto Fail_1;
}
outlen = need;
}
memcpy(PyUnicode_AS_UNICODE(result) + j, PyUnicode_AS_UNICODE(item), reslen * sizeof(Py_UNICODE));
j += reslen;
}
}
Py_DECREF(item);
if (ok < 0)
goto Fail_1;
}
if (j < outlen)
PyUnicode_Resize(&result, j);
return result;
Fail_1:
Py_DECREF(result);
return NULL;
}
static PyObject* filtertuple(PyObject* func, PyObject* tuple) {
PyObject* result;
Py_ssize_t i, j;
......@@ -1013,7 +1110,6 @@ Box* filter2(Box* f, Box* container) {
f = bool_cls;
// Special cases depending on the type of container influences the return type
// TODO There are other special cases like this
if (PyTuple_Check(container)) {
Box* rtn = filtertuple(f, static_cast<BoxedTuple*>(container));
if (!rtn) {
......@@ -1030,6 +1126,14 @@ Box* filter2(Box* f, Box* container) {
return rtn;
}
if (PyUnicode_Check(container)) {
Box* rtn = filterunicode(f, container);
if (!rtn) {
throwCAPIException();
}
return rtn;
}
Box* rtn = new BoxedList();
for (Box* e : container->pyElements()) {
Box* r = runtimeCall(f, ArgPassSpec(1), e, NULL, NULL, NULL, NULL);
......@@ -1157,20 +1261,26 @@ class BoxedEnumerate : public Box {
private:
BoxIterator iterator, iterator_end;
int64_t idx;
BoxedLong* idx_long;
public:
BoxedEnumerate(BoxIterator iterator_begin, BoxIterator iterator_end, int64_t idx)
: iterator(iterator_begin), iterator_end(iterator_end), idx(idx) {}
BoxedEnumerate(BoxIterator iterator_begin, BoxIterator iterator_end, int64_t idx, BoxedLong* idx_long)
: iterator(iterator_begin), iterator_end(iterator_end), idx(idx), idx_long(idx_long) {}
DEFAULT_CLASS(enumerate_cls);
static Box* new_(Box* cls, Box* obj, Box* start) {
RELEASE_ASSERT(cls == enumerate_cls, "");
RELEASE_ASSERT(PyInt_Check(start), "");
int64_t idx = static_cast<BoxedInt*>(start)->n;
RELEASE_ASSERT(PyInt_Check(start) || PyLong_Check(start), "");
int64_t idx = PyInt_AsSsize_t(start);
BoxedLong* idx_long = NULL;
if (idx == -1 && PyErr_Occurred()) {
PyErr_Clear();
assert(PyLong_Check(start));
idx_long = (BoxedLong*)start;
}
llvm::iterator_range<BoxIterator> range = obj->pyElements();
return new BoxedEnumerate(range.begin(), range.end(), idx);
return new BoxedEnumerate(range.begin(), range.end(), idx, idx_long);
}
static Box* iter(Box* _self) noexcept {
......@@ -1184,7 +1294,19 @@ public:
BoxedEnumerate* self = static_cast<BoxedEnumerate*>(_self);
Box* val = *self->iterator;
++self->iterator;
return BoxedTuple::create({ boxInt(self->idx++), val });
Box* rtn = BoxedTuple::create({ self->idx_long ? self->idx_long : boxInt(self->idx), val });
// check if incrementing the counter would overflow it, if so switch to long counter
if (self->idx == PY_SSIZE_T_MAX) {
assert(!self->idx_long);
self->idx_long = boxLong(self->idx);
self->idx = -1;
}
if (self->idx_long)
self->idx_long = (BoxedLong*)longAdd(self->idx_long, boxInt(1));
else
++self->idx;
return rtn;
}
static Box* hasnext(Box* _self) {
......@@ -1512,7 +1634,7 @@ Box* input(Box* prompt) {
Box* builtinRound(Box* _number, Box* _ndigits) {
double x = PyFloat_AsDouble(_number);
if (PyErr_Occurred())
raiseExcHelper(TypeError, "a float is required");
throwCAPIException();
/* interpret 2nd argument as a Py_ssize_t; clip on overflow */
Py_ssize_t ndigits = PyNumber_AsSsize_t(_ndigits, NULL);
......@@ -2052,8 +2174,8 @@ void setupBuiltins() {
{ NULL, NULL }, NULL, range_doc);
builtins_module->giveAttr("range", range_obj);
auto* round_obj
= new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)builtinRound, BOXED_FLOAT, 2, false, false),
auto* round_obj = new BoxedBuiltinFunctionOrMethod(
FunctionMetadata::create((void*)builtinRound, BOXED_FLOAT, 2, ParamNames({ "number", "ndigits" }, "", "")),
"round", { autoDecref(boxInt(0)) }, NULL, round_doc);
builtins_module->giveAttr("round", round_obj);
......@@ -2164,7 +2286,7 @@ void setupBuiltins() {
FunctionMetadata::create((void*)builtinCmp, UNKNOWN, 2), "cmp", cmp_doc));
builtins_module->giveAttr(
"format", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)builtinFormat, UNKNOWN, 2), "format",
format_doc));
{ NULL }, NULL, format_doc));
static PyMethodDef builtin_methods[] = {
......
......@@ -14,6 +14,7 @@
#include "runtime/dict.h"
#include "capi/typeobject.h"
#include "capi/types.h"
#include "core/ast.h"
#include "core/common.h"
......@@ -923,6 +924,8 @@ void setupDict() {
dictiterkey_cls->instances_are_nonzero = dictitervalue_cls->instances_are_nonzero
= dictiteritem_cls->instances_are_nonzero = true;
dict_cls->tp_hash = PyObject_HashNotImplemented;
dict_cls->giveAttr("__len__", new BoxedFunction(FunctionMetadata::create((void*)dictLen, BOXED_INT, 1)));
dict_cls->giveAttr("__new__", new BoxedFunction(FunctionMetadata::create((void*)dictNew, UNKNOWN, 1, true, true)));
dict_cls->giveAttr("__init__", new BoxedFunction(FunctionMetadata::create((void*)dictInit, NONE, 1, true, true)));
......@@ -980,6 +983,7 @@ void setupDict() {
dict_cls->giveAttr("__nonzero__", new BoxedFunction(FunctionMetadata::create((void*)dictNonzero, BOXED_BOOL, 1)));
add_operators(dict_cls);
dict_cls->freeze();
// create the dictonary iterator types
......
......@@ -433,16 +433,20 @@ extern "C" Box* div_i64_i64(i64 lhs, i64 rhs) {
return boxInt(div_result);
}
extern "C" i64 mod_i64_i64(i64 lhs, i64 rhs) {
extern "C" Box* mod_i64_i64(i64 lhs, i64 rhs) {
if (rhs == 0) {
raiseExcHelper(ZeroDivisionError, "integer division or modulo by zero");
}
// I don't think this can overflow:
// this would overflow:
if (lhs == PYSTON_INT_MIN && rhs == -1)
return boxLong(0); // long because pypy and cpython both return a long
if (lhs < 0 && rhs > 0)
return ((lhs + 1) % rhs) + (rhs - 1);
return boxInt(((lhs + 1) % rhs) + (rhs - 1));
if (lhs > 0 && rhs < 0)
return ((lhs - 1) % rhs) + (rhs + 1);
return lhs % rhs;
return boxInt(((lhs - 1) % rhs) + (rhs + 1));
return boxInt(lhs % rhs);
}
extern "C" Box* pow_i64_i64(i64 lhs, i64 rhs, Box* mod) {
......@@ -777,7 +781,7 @@ Box* intRLShift(BoxedInt* lhs, Box* rhs) {
extern "C" Box* intModInt(BoxedInt* lhs, BoxedInt* rhs) {
assert(PyInt_Check(lhs));
assert(PyInt_Check(rhs));
return boxInt(mod_i64_i64(lhs->n, rhs->n));
return mod_i64_i64(lhs->n, rhs->n);
}
extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) {
......@@ -788,7 +792,7 @@ extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) {
return incref(NotImplemented);
}
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
return boxInt(mod_i64_i64(lhs->n, rhs_int->n));
return mod_i64_i64(lhs->n, rhs_int->n);
}
Box* intRMod(BoxedInt* lhs, Box* rhs) {
......@@ -800,7 +804,7 @@ Box* intRMod(BoxedInt* lhs, Box* rhs) {
return NotImplemented;
}
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs);
return boxInt(mod_i64_i64(rhs_int->n, lhs->n));
return mod_i64_i64(rhs_int->n, lhs->n);
}
extern "C" Box* intDivmod(BoxedInt* lhs, Box* rhs) {
......@@ -1082,6 +1086,9 @@ extern "C" Box* intHash(BoxedInt* self) {
raiseExcHelper(TypeError, "descriptor '__hash__' requires a 'int' object but received a '%s'",
getTypeName(self));
if (self->n == -1)
return boxInt(-2);
if (self->cls == int_cls)
return self;
return boxInt(self->n);
......@@ -1473,6 +1480,30 @@ extern "C" int PyInt_ClearFreeList() noexcept {
return freelist_size;
}
static Box* intFormat(PyObject* self, Box* format_spec) {
if (PyBytes_Check(format_spec)) {
Box* rtn = _PyInt_FormatAdvanced(self, PyBytes_AS_STRING(format_spec), PyBytes_GET_SIZE(format_spec));
if (!rtn)
throwCAPIException();
return rtn;
}
if (PyUnicode_Check(format_spec)) {
/* Convert format_spec to a str */
PyObject* result;
PyObject* str_spec = PyObject_Str(format_spec);
if (str_spec == NULL)
throwCAPIException();
result = _PyInt_FormatAdvanced(self, PyBytes_AS_STRING(str_spec), PyBytes_GET_SIZE(str_spec));
Py_DECREF(str_spec);
if (!result)
throwCAPIException();
return result;
}
raiseExcHelper(TypeError, "__format__ requires str or unicode");
}
void setupInt() {
static PyNumberMethods int_as_number;
int_cls->tp_as_number = &int_as_number;
......@@ -1492,7 +1523,7 @@ void setupInt() {
_addFuncIntFloatUnknown("__floordiv__", (void*)intFloordivInt, (void*)intFloordivFloat, (void*)intFloordiv);
_addFuncIntFloatUnknown("__truediv__", (void*)intTruedivInt, (void*)intTruedivFloat, (void*)intTruediv);
_addFuncIntFloatUnknown("__mul__", (void*)intMulInt, (void*)intMulFloat, (void*)intMul);
_addFuncIntUnknown("__mod__", BOXED_INT, (void*)intModInt, (void*)intMod);
_addFuncIntUnknown("__mod__", UNKNOWN, (void*)intModInt, (void*)intMod);
_addFuncPow("__pow__", BOXED_INT, (void*)intPowFloat, (void*)intPow);
int_cls->giveAttr("__radd__", new BoxedFunction(FunctionMetadata::create((void*)intRAdd, UNKNOWN, 2)));
......@@ -1538,6 +1569,8 @@ void setupInt() {
int_cls->giveAttr("__float__", new BoxedFunction(FunctionMetadata::create((void*)intFloat, BOXED_FLOAT, 1)));
int_cls->giveAttr("__long__", new BoxedFunction(FunctionMetadata::create((void*)intLong, LONG, 1)));
int_cls->giveAttr("__format__", new BoxedFunction(FunctionMetadata::create((void*)intFormat, STR, 2)));
int_cls->giveAttr("__doc__",
boxString("int(x=0) -> int or long\n"
"int(x, base=10) -> int or long\n"
......
......@@ -28,7 +28,7 @@ static_assert(sizeof(int64_t) == sizeof(long), "");
#define PYSTON_INT_MAX LONG_MAX
extern "C" Box* div_i64_i64(i64 lhs, i64 rhs);
extern "C" i64 mod_i64_i64(i64 lhs, i64 rhs);
extern "C" Box* mod_i64_i64(i64 lhs, i64 rhs);
extern "C" Box* add_i64_i64(i64 lhs, i64 rhs);
extern "C" Box* sub_i64_i64(i64 lhs, i64 rhs);
......
......@@ -1540,8 +1540,12 @@ Box* longHash(BoxedLong* self) {
getTypeName(self));
// If the long fits into an int we have to return the same hash in order that we can find the value in a dict.
if (mpz_fits_slong_p(self->n))
return boxInt(mpz_get_si(self->n));
if (mpz_fits_slong_p(self->n)) {
auto v = mpz_get_si(self->n);
if (v == -1)
v = -2;
return boxInt(v);
}
// CPython use the absolute value of self mod ULONG_MAX.
unsigned long remainder = mpz_tdiv_ui(self->n, ULONG_MAX);
......@@ -1556,6 +1560,14 @@ Box* longHash(BoxedLong* self) {
return boxInt(remainder);
}
long long_hash(PyObject* self) noexcept {
try {
return unboxInt(longHash((BoxedLong*)self));
} catch (ExcInfo e) {
RELEASE_ASSERT(0, "");
}
}
extern "C" Box* longTrunc(BoxedLong* self) {
if (!PyLong_Check(self))
raiseExcHelper(TypeError, "descriptor '__trunc__' requires a 'long' object but received a '%s'",
......@@ -1729,5 +1741,6 @@ void setupLong() {
long_cls->freeze();
long_cls->tp_as_number->nb_power = long_pow;
long_cls->tp_hash = long_hash;
}
}
import os, sys, subprocess, shutil
sys.path.append(os.path.dirname(__file__) + "/../lib")
from test_helper import create_virtenv, run_test
ENV_NAME = "geoip_test_env_" + os.path.basename(sys.executable)
SRC_DIR = os.path.abspath(os.path.join(ENV_NAME, "src"))
PYTHON_EXE = os.path.abspath(os.path.join(ENV_NAME, "bin", "python"))
pkg = ["-e", "git+https://github.com/maxmind/geoip-api-python.git@v1.3.2#egg=GeoIP"]
create_virtenv(ENV_NAME, pkg, force_create = True)
GEOIP_DIR = os.path.abspath(os.path.join(SRC_DIR, "geoip"))
expected = [{'ran': 10}]
run_test([PYTHON_EXE, "setup.py", "test"], cwd=GEOIP_DIR, expected=expected)
import sys
__builtins__.aoeu = 1
print aoeu
......@@ -37,10 +39,14 @@ print filter(lambda x: x % 2, xrange(20))
print type(enumerate([]))
print list(enumerate(xrange(5, 10)))
print list(enumerate(start=-42, sequence=xrange(5, 10)))
print list(enumerate(range(3), 2**128)) # tests long
print list(enumerate(range(3), 2**63-1)) # tests start with int and than switch to long
# If the first argument is None, filter calls checks for truthiness (ie is equivalent to passing 'bool')
print filter(None, xrange(-5, 5))
print filter(None, unicode("12"))
print isinstance(1, int)
print isinstance(1, (float, int))
print isinstance(1, (float, (), (int, 3), 4))
......@@ -79,6 +85,7 @@ print hex(12345)
print oct(234)
print hex(0)
print oct(0) # This should not add an additional leading 0, ie should return "0" not "00"
print abs((-sys.maxint)-1)
try:
print hex([])
......@@ -129,9 +136,24 @@ print apply(sorted, [l], { "reverse" : True })
print format(5.0, '+')
print format(5.011111111111, '+.6')
print format("abc", '')
print format(0, str(10))
print '{n}'.format(n=None)
print hash(1L)
def C(long):
def __hash__(self):
return self
print hash(2L)
try:
print hash({})
except TypeError as e:
print e
try:
print hash(set())
except TypeError as e:
print e
# Thankfully, setting __builtins__ has no effect:
__builtins__ = {'zzz': 2}
try:
......
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