Commit c4fe264a authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #414 from undingen/fix_pip_search3

Misc fixes for pip part 3
parents 2c6722be d1387d74
......@@ -1218,8 +1218,13 @@ extern "C" PyObject* PyNumber_FloorDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_TrueDivide(PyObject*, PyObject*) noexcept {
Py_FatalError("unimplemented");
extern "C" PyObject* PyNumber_TrueDivide(PyObject* lhs, PyObject* rhs) noexcept {
try {
return binop(lhs, rhs, AST_TYPE::TrueDiv);
} catch (ExcInfo e) {
setCAPIException(e);
return NULL;
}
}
extern "C" PyObject* PyNumber_Remainder(PyObject* lhs, PyObject* rhs) noexcept {
......
......@@ -484,7 +484,7 @@ Value ASTInterpreter::visit_invoke(AST_Invoke* node) {
}
Value ASTInterpreter::visit_clsAttribute(AST_ClsAttribute* node) {
return getattr(visit_expr(node->value).o, node->attr.c_str());
return getclsattr(visit_expr(node->value).o, node->attr.c_str());
}
Value ASTInterpreter::visit_augBinOp(AST_AugBinOp* node) {
......
......@@ -450,7 +450,7 @@ Box* notimplementedRepr(Box* self) {
return boxStrConstant("NotImplemented");
}
Box* sorted(Box* obj, Box* key, Box* cmp, Box** args) {
Box* sorted(Box* obj, Box* cmp, Box* key, Box** args) {
Box* reverse = args[0];
BoxedList* rtn = new BoxedList();
......@@ -458,7 +458,7 @@ Box* sorted(Box* obj, Box* key, Box* cmp, Box** args) {
listAppendInternal(rtn, e);
}
listSort(rtn, key, cmp, reverse);
listSort(rtn, cmp, key, reverse);
return rtn;
}
......
......@@ -91,7 +91,13 @@ Box* seqiterNext(Box* s) {
BoxedSeqIter* self = static_cast<BoxedSeqIter*>(s);
if (!self->next) {
Box* hasnext = seqiterHasnext(s);
Box* hasnext = NULL;
if (s->cls == seqiter_cls)
hasnext = seqiterHasnext(s);
else if (s->cls == seqreviter_cls)
hasnext = seqreviterHasnext(s);
else
RELEASE_ASSERT(0, "");
if (hasnext == False)
raiseExcHelper(StopIteration, "");
}
......
......@@ -980,6 +980,44 @@ Box* longRdiv(BoxedLong* v1, Box* _v2) {
}
}
Box* longTrueDiv(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__truediv__' requires a 'long' object but received a '%s'",
getTypeName(v1));
// We only support args which fit into an int for now...
int overflow = 0;
long lhs = PyLong_AsLongAndOverflow(v1, &overflow);
if (overflow)
return NotImplemented;
long rhs = PyLong_AsLongAndOverflow(_v2, &overflow);
if (overflow)
return NotImplemented;
if (rhs == 0)
raiseExcHelper(ZeroDivisionError, "division by zero");
return boxFloat(lhs / (double)rhs);
}
Box* longRTrueDiv(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__rtruediv__' requires a 'long' object but received a '%s'",
getTypeName(v1));
// We only support args which fit into an int for now...
int overflow = 0;
long lhs = PyLong_AsLongAndOverflow(_v2, &overflow);
if (overflow)
return NotImplemented;
long rhs = PyLong_AsLongAndOverflow(v1, &overflow);
if (overflow)
return NotImplemented;
if (rhs == 0)
raiseExcHelper(ZeroDivisionError, "division by zero");
return boxFloat(lhs / (double)rhs);
}
Box* longPow(BoxedLong* v1, Box* _v2) {
if (!isSubclass(v1->cls, long_cls))
raiseExcHelper(TypeError, "descriptor '__pow__' requires a 'long' object but received a '%s'", getTypeName(v1));
......@@ -1074,6 +1112,8 @@ void setupLong() {
long_cls->giveAttr("__div__", new BoxedFunction(boxRTFunction((void*)longDiv, UNKNOWN, 2)));
long_cls->giveAttr("__rdiv__", new BoxedFunction(boxRTFunction((void*)longRdiv, UNKNOWN, 2)));
long_cls->giveAttr("__truediv__", new BoxedFunction(boxRTFunction((void*)longTrueDiv, UNKNOWN, 2)));
long_cls->giveAttr("__rtruediv__", new BoxedFunction(boxRTFunction((void*)longRTrueDiv, UNKNOWN, 2)));
long_cls->giveAttr("__divmod__", new BoxedFunction(boxRTFunction((void*)longDivmod, UNKNOWN, 2)));
......
......@@ -1206,6 +1206,13 @@ extern "C" Box* getclsattr(Box* obj, const char* attr) {
Box* gotten;
if (attr[0] == '_' && attr[1] == '_' && PyInstance_Check(obj)) {
// __enter__ and __exit__ need special treatment.
static std::string enter_str("__enter__"), exit_str("__exit__");
if (attr == enter_str || attr == exit_str)
return getattr(obj, attr);
}
#if 0
std::unique_ptr<Rewriter> rewriter(Rewriter::createRewriter(__builtin_extract_return_addr(__builtin_return_address(0)), 2, 1, "getclsattr"));
......@@ -2482,6 +2489,12 @@ extern "C" Box* callattr(Box* obj, const std::string* attr, CallattrFlags flags,
LookupScope scope = flags.cls_only ? CLASS_ONLY : CLASS_OR_INST;
if ((*attr)[0] == '_' && (*attr)[1] == '_' && PyInstance_Check(obj)) {
// __enter__ and __exit__ need special treatment.
if (*attr == "__enter__" || *attr == "__exit__")
scope = CLASS_OR_INST;
}
if (rewriter.get()) {
// TODO feel weird about doing this; it either isn't necessary
// or this kind of thing is necessary in a lot more places
......
......@@ -12,3 +12,5 @@ for i in xrange(10):
for it in its:
print it.next(),
print
print list(itertools.dropwhile(lambda x: x == 0, reversed((1, 2, 3))))
......@@ -31,10 +31,9 @@ for a in [-5, -1, 1, 5, -2L, -1L, 1L, 2L, 15L]:
test(1L, 2.0)
test(3.0, 2L)
print (2L).__rdiv__(-1)
print (2L).__rdiv__(-1L)
print (-2L).__rdiv__(1L)
print (-2L).__rdiv__(1)
for lhs in [2L, -2L]:
for rhs in [-1, -1L, 1, 2L]:
print lhs.__rdiv__(rhs), lhs.__truediv__(rhs), lhs.__rtruediv__(rhs)
print (1L) << (2L)
print (1L) << (2)
......
......@@ -20,3 +20,10 @@ print list(reversed(RevIterTest()))
# xrange and list have __reversed__ methods
print list(xrange(0,9).__reversed__())
print list([1,2,3,4,5,6].__reversed__())
r = reversed((1, 2, 3))
try:
while True:
print r.next(),
except StopIteration:
print ""
# Make sure __exit__ gets called in various exit scenarios:
class C(object):
class NewC(object):
def __enter__(self):
print "__enter__"
def __exit__(self, type, val, tb):
print "__exit__"
def f():
class OldC:
def __enter__(self):
print "__enter__"
def __exit__(self, type, val, tb):
print "__exit__"
def f(C):
with C():
pass
with C() as n:
......@@ -42,9 +49,10 @@ def f():
with C() as o:
return
f()
f(NewC)
f(OldC)
def f2(b):
def f2(b, C):
n = 2
while n:
print n
......@@ -56,6 +64,6 @@ def f2(b):
else:
return "b false"
print f2(False)
print f2(True)
print f2(False, NewC), f2(False, OldC)
print f2(True, NewC), f2(True, OldC)
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