Commit 435cf875 authored by Marius Wachtler's avatar Marius Wachtler

fix a bunch of bugs which showed up in test_builtin.py

Unfortunately there are still a few hiding which means we can't yet run test_builtin.py right now
parent b3038205
...@@ -28,6 +28,12 @@ sudo apt-get install -yq automake git cmake ninja-build ccache libncurses5-dev l ...@@ -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 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 ### Building and testing
``` ```
git clone https://github.com/dropbox/pyston.git ~/pyston git clone https://github.com/dropbox/pyston.git ~/pyston
......
...@@ -1947,15 +1947,15 @@ extern "C" PyObject* PyNumber_Positive(PyObject* o) noexcept { ...@@ -1947,15 +1947,15 @@ extern "C" PyObject* PyNumber_Positive(PyObject* o) noexcept {
} }
extern "C" PyObject* PyNumber_Absolute(PyObject* o) noexcept { extern "C" PyObject* PyNumber_Absolute(PyObject* o) noexcept {
if (o == Py_None) PyNumberMethods* m;
return type_error("bad operand type for abs(): '%.200s'", o);
try { if (o == NULL)
return abs_(o); return null_error();
} catch (ExcInfo e) { m = o->cls->tp_as_number;
fatalOrError(PyExc_NotImplementedError, "unimplemented"); if (m && m->nb_absolute)
return nullptr; return m->nb_absolute(o);
}
return type_error("bad operand type for abs(): '%.200s'", o);
} }
extern "C" PyObject* PyNumber_Invert(PyObject* o) noexcept { extern "C" PyObject* PyNumber_Invert(PyObject* o) noexcept {
......
...@@ -90,19 +90,10 @@ extern "C" Box* vars(Box* obj) { ...@@ -90,19 +90,10 @@ extern "C" Box* vars(Box* obj) {
} }
extern "C" Box* abs_(Box* x) { extern "C" Box* abs_(Box* x) {
if (PyInt_Check(x)) { Box* rtn = PyNumber_Absolute(x);
i64 n = static_cast<BoxedInt*>(x)->n; if (!rtn)
return boxInt(n >= 0 ? n : -n); throwCAPIException();
} else if (x->cls == float_cls) { return rtn;
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 = internStringImmortal("__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);
}
} }
extern "C" Box* binFunc(Box* x) { extern "C" Box* binFunc(Box* x) {
...@@ -326,11 +317,12 @@ extern "C" Box* chr(Box* arg) { ...@@ -326,11 +317,12 @@ extern "C" Box* chr(Box* arg) {
} }
extern "C" Box* unichr(Box* arg) { extern "C" Box* unichr(Box* arg) {
if (arg->cls != int_cls) int n = -1;
raiseExcHelper(TypeError, "an integer is required"); if (!PyArg_ParseSingle(arg, 0, "unichr", "i", &n))
throwCAPIException();
i64 n = static_cast<BoxedInt*>(arg)->n;
Box* rtn = PyUnicode_FromOrdinal(n); Box* rtn = PyUnicode_FromOrdinal(n);
if (!rtn)
checkAndThrowCAPIException(); checkAndThrowCAPIException();
return rtn; return rtn;
} }
...@@ -936,6 +928,111 @@ Fail_1: ...@@ -936,6 +928,111 @@ Fail_1:
return NULL; 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) { static PyObject* filtertuple(PyObject* func, PyObject* tuple) {
PyObject* result; PyObject* result;
Py_ssize_t i, j; Py_ssize_t i, j;
...@@ -1012,7 +1109,6 @@ Box* filter2(Box* f, Box* container) { ...@@ -1012,7 +1109,6 @@ Box* filter2(Box* f, Box* container) {
f = bool_cls; f = bool_cls;
// Special cases depending on the type of container influences the return type // Special cases depending on the type of container influences the return type
// TODO There are other special cases like this
if (PyTuple_Check(container)) { if (PyTuple_Check(container)) {
Box* rtn = filtertuple(f, static_cast<BoxedTuple*>(container)); Box* rtn = filtertuple(f, static_cast<BoxedTuple*>(container));
if (!rtn) { if (!rtn) {
...@@ -1029,6 +1125,14 @@ Box* filter2(Box* f, Box* container) { ...@@ -1029,6 +1125,14 @@ Box* filter2(Box* f, Box* container) {
return rtn; return rtn;
} }
if (PyUnicode_Check(container)) {
Box* rtn = filterunicode(f, container);
if (!rtn) {
throwCAPIException();
}
return rtn;
}
Box* rtn = new BoxedList(); Box* rtn = new BoxedList();
for (Box* e : container->pyElements()) { for (Box* e : container->pyElements()) {
Box* r = runtimeCall(f, ArgPassSpec(1), e, NULL, NULL, NULL, NULL); Box* r = runtimeCall(f, ArgPassSpec(1), e, NULL, NULL, NULL, NULL);
...@@ -1511,7 +1615,7 @@ Box* input(Box* prompt) { ...@@ -1511,7 +1615,7 @@ Box* input(Box* prompt) {
Box* builtinRound(Box* _number, Box* _ndigits) { Box* builtinRound(Box* _number, Box* _ndigits) {
double x = PyFloat_AsDouble(_number); double x = PyFloat_AsDouble(_number);
if (PyErr_Occurred()) if (PyErr_Occurred())
raiseExcHelper(TypeError, "a float is required"); throwCAPIException();
/* interpret 2nd argument as a Py_ssize_t; clip on overflow */ /* interpret 2nd argument as a Py_ssize_t; clip on overflow */
Py_ssize_t ndigits = PyNumber_AsSsize_t(_ndigits, NULL); Py_ssize_t ndigits = PyNumber_AsSsize_t(_ndigits, NULL);
...@@ -2050,8 +2154,8 @@ void setupBuiltins() { ...@@ -2050,8 +2154,8 @@ void setupBuiltins() {
{ NULL, NULL }, NULL, range_doc); { NULL, NULL }, NULL, range_doc);
builtins_module->giveAttr("range", range_obj); builtins_module->giveAttr("range", range_obj);
auto* round_obj auto* round_obj = new BoxedBuiltinFunctionOrMethod(
= new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)builtinRound, BOXED_FLOAT, 2, false, false), FunctionMetadata::create((void*)builtinRound, BOXED_FLOAT, 2, ParamNames({ "number", "ndigits" }, "", "")),
"round", { boxInt(0) }, NULL, round_doc); "round", { boxInt(0) }, NULL, round_doc);
builtins_module->giveAttr("round", round_obj); builtins_module->giveAttr("round", round_obj);
...@@ -2161,7 +2265,7 @@ void setupBuiltins() { ...@@ -2161,7 +2265,7 @@ void setupBuiltins() {
FunctionMetadata::create((void*)builtinCmp, UNKNOWN, 2), "cmp", cmp_doc)); FunctionMetadata::create((void*)builtinCmp, UNKNOWN, 2), "cmp", cmp_doc));
builtins_module->giveAttr( builtins_module->giveAttr(
"format", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)builtinFormat, UNKNOWN, 2), "format", "format", new BoxedBuiltinFunctionOrMethod(FunctionMetadata::create((void*)builtinFormat, UNKNOWN, 2), "format",
format_doc)); { NULL }, NULL, format_doc));
static PyMethodDef builtin_methods[] = { static PyMethodDef builtin_methods[] = {
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "runtime/dict.h" #include "runtime/dict.h"
#include "capi/typeobject.h"
#include "capi/types.h" #include "capi/types.h"
#include "core/ast.h" #include "core/ast.h"
#include "core/common.h" #include "core/common.h"
...@@ -855,6 +856,7 @@ void setupDict() { ...@@ -855,6 +856,7 @@ void setupDict() {
= dictiteritem_cls->instances_are_nonzero = true; = dictiteritem_cls->instances_are_nonzero = true;
dict_cls->tp_dealloc = &BoxedDict::dealloc; dict_cls->tp_dealloc = &BoxedDict::dealloc;
dict_cls->tp_hash = PyObject_HashNotImplemented;
dict_cls->has_safe_tp_dealloc = true; dict_cls->has_safe_tp_dealloc = true;
dict_cls->giveAttr("__len__", new BoxedFunction(FunctionMetadata::create((void*)dictLen, BOXED_INT, 1))); dict_cls->giveAttr("__len__", new BoxedFunction(FunctionMetadata::create((void*)dictLen, BOXED_INT, 1)));
...@@ -913,6 +915,7 @@ void setupDict() { ...@@ -913,6 +915,7 @@ void setupDict() {
dict_cls->giveAttr("__nonzero__", new BoxedFunction(FunctionMetadata::create((void*)dictNonzero, BOXED_BOOL, 1))); dict_cls->giveAttr("__nonzero__", new BoxedFunction(FunctionMetadata::create((void*)dictNonzero, BOXED_BOOL, 1)));
add_operators(dict_cls);
dict_cls->freeze(); dict_cls->freeze();
// create the dictonary iterator types // create the dictonary iterator types
......
...@@ -365,16 +365,20 @@ extern "C" Box* div_i64_i64(i64 lhs, i64 rhs) { ...@@ -365,16 +365,20 @@ extern "C" Box* div_i64_i64(i64 lhs, i64 rhs) {
return boxInt(div_result); 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) { if (rhs == 0) {
raiseExcHelper(ZeroDivisionError, "integer division or modulo by zero"); 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) if (lhs < 0 && rhs > 0)
return ((lhs + 1) % rhs) + (rhs - 1); return boxInt(((lhs + 1) % rhs) + (rhs - 1));
if (lhs > 0 && rhs < 0) if (lhs > 0 && rhs < 0)
return ((lhs - 1) % rhs) + (rhs + 1); return boxInt(((lhs - 1) % rhs) + (rhs + 1));
return lhs % rhs; return boxInt(lhs % rhs);
} }
extern "C" Box* pow_i64_i64(i64 lhs, i64 rhs, Box* mod) { extern "C" Box* pow_i64_i64(i64 lhs, i64 rhs, Box* mod) {
...@@ -709,7 +713,7 @@ Box* intRLShift(BoxedInt* lhs, Box* rhs) { ...@@ -709,7 +713,7 @@ Box* intRLShift(BoxedInt* lhs, Box* rhs) {
extern "C" Box* intModInt(BoxedInt* lhs, BoxedInt* rhs) { extern "C" Box* intModInt(BoxedInt* lhs, BoxedInt* rhs) {
assert(PyInt_Check(lhs)); assert(PyInt_Check(lhs));
assert(PyInt_Check(rhs)); 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) { extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) {
...@@ -720,7 +724,7 @@ extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) { ...@@ -720,7 +724,7 @@ extern "C" Box* intMod(BoxedInt* lhs, Box* rhs) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); 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) { Box* intRMod(BoxedInt* lhs, Box* rhs) {
...@@ -732,7 +736,7 @@ Box* intRMod(BoxedInt* lhs, Box* rhs) { ...@@ -732,7 +736,7 @@ Box* intRMod(BoxedInt* lhs, Box* rhs) {
return NotImplemented; return NotImplemented;
} }
BoxedInt* rhs_int = static_cast<BoxedInt*>(rhs); 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) { extern "C" Box* intDivmod(BoxedInt* lhs, Box* rhs) {
...@@ -1010,6 +1014,9 @@ extern "C" Box* intHash(BoxedInt* self) { ...@@ -1010,6 +1014,9 @@ extern "C" Box* intHash(BoxedInt* self) {
raiseExcHelper(TypeError, "descriptor '__hash__' requires a 'int' object but received a '%s'", raiseExcHelper(TypeError, "descriptor '__hash__' requires a 'int' object but received a '%s'",
getTypeName(self)); getTypeName(self));
if (self->n == -1)
return boxInt(-2);
if (self->cls == int_cls) if (self->cls == int_cls)
return self; return self;
return boxInt(self->n); return boxInt(self->n);
...@@ -1355,6 +1362,30 @@ static PyObject* int_getnewargs(BoxedInt* v) noexcept { ...@@ -1355,6 +1362,30 @@ static PyObject* int_getnewargs(BoxedInt* v) noexcept {
return Py_BuildValue("(l)", v->n); return Py_BuildValue("(l)", v->n);
} }
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() { void setupInt() {
static PyNumberMethods int_as_number; static PyNumberMethods int_as_number;
int_cls->tp_as_number = &int_as_number; int_cls->tp_as_number = &int_as_number;
...@@ -1376,7 +1407,7 @@ void setupInt() { ...@@ -1376,7 +1407,7 @@ void setupInt() {
_addFuncIntFloatUnknown("__floordiv__", (void*)intFloordivInt, (void*)intFloordivFloat, (void*)intFloordiv); _addFuncIntFloatUnknown("__floordiv__", (void*)intFloordivInt, (void*)intFloordivFloat, (void*)intFloordiv);
_addFuncIntFloatUnknown("__truediv__", (void*)intTruedivInt, (void*)intTruedivFloat, (void*)intTruediv); _addFuncIntFloatUnknown("__truediv__", (void*)intTruedivInt, (void*)intTruedivFloat, (void*)intTruediv);
_addFuncIntFloatUnknown("__mul__", (void*)intMulInt, (void*)intMulFloat, (void*)intMul); _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); _addFuncPow("__pow__", BOXED_INT, (void*)intPowFloat, (void*)intPow);
int_cls->giveAttr("__radd__", new BoxedFunction(FunctionMetadata::create((void*)intRAdd, UNKNOWN, 2))); int_cls->giveAttr("__radd__", new BoxedFunction(FunctionMetadata::create((void*)intRAdd, UNKNOWN, 2)));
...@@ -1422,6 +1453,8 @@ void setupInt() { ...@@ -1422,6 +1453,8 @@ void setupInt() {
int_cls->giveAttr("__float__", new BoxedFunction(FunctionMetadata::create((void*)intFloat, BOXED_FLOAT, 1))); 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("__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__", int_cls->giveAttr("__doc__",
boxString("int(x=0) -> int or long\n" boxString("int(x=0) -> int or long\n"
"int(x, base=10) -> int or long\n" "int(x, base=10) -> int or long\n"
......
...@@ -28,7 +28,7 @@ static_assert(sizeof(int64_t) == sizeof(long), ""); ...@@ -28,7 +28,7 @@ static_assert(sizeof(int64_t) == sizeof(long), "");
#define PYSTON_INT_MAX LONG_MAX #define PYSTON_INT_MAX LONG_MAX
extern "C" Box* div_i64_i64(i64 lhs, i64 rhs); 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* add_i64_i64(i64 lhs, i64 rhs);
extern "C" Box* sub_i64_i64(i64 lhs, i64 rhs); extern "C" Box* sub_i64_i64(i64 lhs, i64 rhs);
......
...@@ -1531,8 +1531,12 @@ Box* longHash(BoxedLong* self) { ...@@ -1531,8 +1531,12 @@ Box* longHash(BoxedLong* self) {
getTypeName(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 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)) if (mpz_fits_slong_p(self->n)) {
return boxInt(mpz_get_si(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. // CPython use the absolute value of self mod ULONG_MAX.
unsigned long remainder = mpz_tdiv_ui(self->n, ULONG_MAX); unsigned long remainder = mpz_tdiv_ui(self->n, ULONG_MAX);
...@@ -1547,6 +1551,14 @@ Box* longHash(BoxedLong* self) { ...@@ -1547,6 +1551,14 @@ Box* longHash(BoxedLong* self) {
return boxInt(remainder); 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) { extern "C" Box* longTrunc(BoxedLong* self) {
if (!PyLong_Check(self)) if (!PyLong_Check(self))
raiseExcHelper(TypeError, "descriptor '__trunc__' requires a 'long' object but received a '%s'", raiseExcHelper(TypeError, "descriptor '__trunc__' requires a 'long' object but received a '%s'",
...@@ -1734,5 +1746,6 @@ void setupLong() { ...@@ -1734,5 +1746,6 @@ void setupLong() {
long_cls->freeze(); long_cls->freeze();
long_cls->tp_as_number->nb_power = long_pow; long_cls->tp_as_number->nb_power = long_pow;
long_cls->tp_hash = long_hash;
} }
} }
import sys
__builtins__.aoeu = 1 __builtins__.aoeu = 1
print aoeu print aoeu
...@@ -41,6 +43,8 @@ print list(enumerate(start=-42, sequence=xrange(5, 10))) ...@@ -41,6 +43,8 @@ print list(enumerate(start=-42, sequence=xrange(5, 10)))
# If the first argument is None, filter calls checks for truthiness (ie is equivalent to passing 'bool') # 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, xrange(-5, 5))
print filter(None, unicode("12"))
print isinstance(1, int) print isinstance(1, int)
print isinstance(1, (float, int)) print isinstance(1, (float, int))
print isinstance(1, (float, (), (int, 3), 4)) print isinstance(1, (float, (), (int, 3), 4))
...@@ -79,6 +83,7 @@ print hex(12345) ...@@ -79,6 +83,7 @@ print hex(12345)
print oct(234) print oct(234)
print hex(0) print hex(0)
print oct(0) # This should not add an additional leading 0, ie should return "0" not "00" print oct(0) # This should not add an additional leading 0, ie should return "0" not "00"
print abs((-sys.maxint)-1)
try: try:
print hex([]) print hex([])
...@@ -129,9 +134,24 @@ print apply(sorted, [l], { "reverse" : True }) ...@@ -129,9 +134,24 @@ print apply(sorted, [l], { "reverse" : True })
print format(5.0, '+') print format(5.0, '+')
print format(5.011111111111, '+.6') print format(5.011111111111, '+.6')
print format("abc", '') print format("abc", '')
print format(0, str(10))
print '{n}'.format(n=None) 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: # Thankfully, setting __builtins__ has no effect:
__builtins__ = {'zzz': 2} __builtins__ = {'zzz': 2}
try: 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