[pypy-commit] pypy default: Fix for "assert isinstance(x, str)" in RPython, in case x is "str-or-None".
arigo
noreply at buildbot.pypy.org
Mon Aug 18 14:26:22 CEST 2014
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r72876:a24d530761ce
Date: 2014-08-18 14:25 +0200
http://bitbucket.org/pypy/pypy/changeset/a24d530761ce/
Log: Fix for "assert isinstance(x, str)" in RPython, in case x is "str-
or-None".
diff --git a/rpython/annotator/test/test_annrpython.py b/rpython/annotator/test/test_annrpython.py
--- a/rpython/annotator/test/test_annrpython.py
+++ b/rpython/annotator/test/test_annrpython.py
@@ -4301,6 +4301,38 @@
s = a.build_types(f, [])
assert isinstance(s, annmodel.SomeString)
+ def test_isinstance_str_1(self):
+ def g():
+ pass
+ def f(n):
+ if n > 5:
+ s = "foo"
+ else:
+ s = None
+ g()
+ return isinstance(s, str)
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [int])
+ assert isinstance(s, annmodel.SomeBool)
+ assert not s.is_constant()
+
+ def test_isinstance_str_2(self):
+ def g():
+ pass
+ def f(n):
+ if n > 5:
+ s = "foo"
+ else:
+ s = None
+ g()
+ if isinstance(s, str):
+ return s
+ return ""
+ a = self.RPythonAnnotator()
+ s = a.build_types(f, [int])
+ assert isinstance(s, annmodel.SomeString)
+ assert not s.can_be_none()
+
def g(n):
return [0, 1, 2, n]
diff --git a/rpython/rtyper/rbuiltin.py b/rpython/rtyper/rbuiltin.py
--- a/rpython/rtyper/rbuiltin.py
+++ b/rpython/rtyper/rbuiltin.py
@@ -683,13 +683,14 @@
if hop.s_result.is_constant():
return hop.inputconst(lltype.Bool, hop.s_result.const)
- if hop.args_s[1].is_constant() and hop.args_s[1].const == list:
- if hop.args_s[0].knowntype != list:
- raise TyperError("isinstance(x, list) expects x to be known statically to be a list or None")
- rlist = hop.args_r[0]
- vlist = hop.inputarg(rlist, arg=0)
- cnone = hop.inputconst(rlist, None)
- return hop.genop('ptr_ne', [vlist, cnone], resulttype=lltype.Bool)
+ if hop.args_s[1].is_constant() and hop.args_s[1].const in (str, list):
+ if hop.args_s[0].knowntype not in (str, list):
+ raise TyperError("isinstance(x, str/list) expects x to be known"
+ " statically to be a str/list or None")
+ rstrlist = hop.args_r[0]
+ vstrlist = hop.inputarg(rstrlist, arg=0)
+ cnone = hop.inputconst(rstrlist, None)
+ return hop.genop('ptr_ne', [vstrlist, cnone], resulttype=lltype.Bool)
assert isinstance(hop.args_r[0], rclass.InstanceRepr)
return hop.args_r[0].rtype_isinstance(hop)
diff --git a/rpython/rtyper/test/test_rbuiltin.py b/rpython/rtyper/test/test_rbuiltin.py
--- a/rpython/rtyper/test/test_rbuiltin.py
+++ b/rpython/rtyper/test/test_rbuiltin.py
@@ -364,17 +364,35 @@
assert res == isinstance([A(), B(), C()][x-1], [A, B, C][y-1]) * 3
def test_isinstance_list(self):
+ def g():
+ pass
def f(i):
if i == 0:
l = []
else:
l = None
+ g()
return isinstance(l, list)
res = self.interpret(f, [0])
assert res is True
res = self.interpret(f, [1])
assert res is False
+ def test_isinstance_str(self):
+ def g():
+ pass
+ def f(i):
+ if i == 0:
+ l = "foobar"
+ else:
+ l = None
+ g()
+ return isinstance(l, str)
+ res = self.interpret(f, [0])
+ assert res is True
+ res = self.interpret(f, [1])
+ assert res is False
+
def test_instantiate(self):
class A:
pass
More information about the pypy-commit
mailing list