Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
grumpy
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
grumpy
Commits
53406932
Commit
53406932
authored
Jan 19, 2017
by
YOU
Committed by
Dylan Trotter
Jan 19, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix IndexError to TypeError (#155)
parent
93543941
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
81 additions
and
49 deletions
+81
-49
runtime/core.go
runtime/core.go
+17
-12
runtime/str.go
runtime/str.go
+21
-14
runtime/str_test.go
runtime/str_test.go
+25
-4
testing/str_test.py
testing/str_test.py
+18
-19
No files found.
runtime/core.go
View file @
53406932
...
...
@@ -487,21 +487,26 @@ func Index(f *Frame, o *Object) (*Object, *BaseException) {
// IndexInt returns the value of o converted to a Go int according to o's
// __index__ slot.
// It raises a TypeError if o doesn't have an __index__ method.
// If the returned value doesn't fit into an int, it raises an OverflowError.
func
IndexInt
(
f
*
Frame
,
o
*
Object
)
(
int
,
*
BaseException
)
{
i
,
raised
:=
Index
(
f
,
o
)
if
raised
!=
nil
{
return
0
,
raised
}
if
i
!=
nil
{
if
i
.
isInstance
(
IntType
)
{
return
toIntUnsafe
(
i
)
.
Value
(),
nil
func
IndexInt
(
f
*
Frame
,
o
*
Object
)
(
i
int
,
raised
*
BaseException
)
{
if
index
:=
o
.
typ
.
slots
.
Index
;
index
!=
nil
{
// Unwrap __index__ slot and fall through.
o
,
raised
=
index
.
Fn
(
f
,
o
)
if
raised
!=
nil
{
return
0
,
raised
}
if
l
:=
toLongUnsafe
(
i
)
.
Value
();
numInIntRange
(
l
)
{
return
int
(
l
.
Int64
()),
nil
}
if
o
.
isInstance
(
IntType
)
{
return
toIntUnsafe
(
o
)
.
Value
(),
nil
}
if
o
.
isInstance
(
LongType
)
{
l
:=
toLongUnsafe
(
o
)
.
Value
()
// Anything bigger than maxIntBig will treat as maxIntBig.
if
!
numInIntRange
(
l
)
{
l
=
maxIntBig
}
return
int
(
l
.
Int64
()),
nil
}
return
0
,
f
.
RaiseType
(
IndexErrorType
,
fmt
.
Sprintf
(
"cannot fit '%s' into an index-sized integer"
,
o
.
typ
)
)
return
0
,
f
.
RaiseType
(
TypeErrorType
,
errBadSliceIndex
)
}
// Invoke calls the given callable with the positional arguments given by args
...
...
runtime/str.go
View file @
53406932
...
...
@@ -221,13 +221,13 @@ func strFind(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
s
:=
toStrUnsafe
(
args
[
0
])
.
Value
()
l
:=
len
(
s
)
start
,
end
:=
0
,
l
if
argc
>=
3
{
if
argc
>=
3
&&
args
[
2
]
!=
None
{
start
,
raised
=
IndexInt
(
f
,
args
[
2
])
if
raised
!=
nil
{
return
nil
,
raised
}
}
if
argc
==
4
{
if
argc
==
4
&&
args
[
3
]
!=
None
{
end
,
raised
=
IndexInt
(
f
,
args
[
3
])
if
raised
!=
nil
{
return
nil
,
raised
...
...
@@ -236,7 +236,7 @@ func strFind(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) {
if
start
>
l
{
return
NewInt
(
-
1
)
.
ToObject
(),
nil
}
start
,
end
=
adjustIndex
(
start
,
l
),
adjustIndex
(
end
,
l
)
start
,
end
=
adjustIndex
(
start
,
end
,
l
)
if
start
>
end
{
return
NewInt
(
-
1
)
.
ToObject
(),
nil
}
...
...
@@ -750,16 +750,22 @@ func strRepeatCount(f *Frame, numChars int, mult *Object) (int, bool, *BaseExcep
return
n
,
true
,
nil
}
func
adjustIndex
(
i
,
l
int
)
int
{
switch
{
case
i
<=
-
l
:
i
=
0
case
i
<
0
:
i
+=
l
case
i
>
l
:
i
=
l
func
adjustIndex
(
start
,
end
,
length
int
)
(
int
,
int
)
{
if
end
>
length
{
end
=
length
}
else
if
end
<
0
{
end
+=
length
if
end
<
0
{
end
=
0
}
}
if
start
<
0
{
start
+=
length
if
start
<
0
{
start
=
0
}
}
return
i
return
start
,
end
}
func
strStartsEndsWith
(
f
*
Frame
,
method
string
,
args
Args
)
(
*
Object
,
*
BaseException
)
{
...
...
@@ -801,11 +807,12 @@ func strStartsEndsWith(f *Frame, method string, args Args) (*Object, *BaseExcept
l
:=
len
(
s
)
start
,
end
:=
0
,
l
if
argc
>=
3
{
start
=
adjustIndex
(
toIntUnsafe
(
args
[
2
])
.
Value
(),
l
)
start
=
toIntUnsafe
(
args
[
2
])
.
Value
(
)
}
if
argc
==
4
{
end
=
adjustIndex
(
toIntUnsafe
(
args
[
3
])
.
Value
(),
l
)
end
=
toIntUnsafe
(
args
[
3
])
.
Value
(
)
}
start
,
end
=
adjustIndex
(
start
,
end
,
l
)
if
start
>
end
{
// start == end may still return true when matching ''.
return
False
.
ToObject
(),
nil
...
...
runtime/str_test.go
View file @
53406932
...
...
@@ -247,6 +247,17 @@ func TestStrRepr(t *testing.T) {
}
func
TestStrMethods
(
t
*
testing
.
T
)
{
fooType
:=
newTestClass
(
"Foo"
,
[]
*
Type
{
ObjectType
},
newStringDict
(
map
[
string
]
*
Object
{
"bar"
:
None
}))
intIndexType
:=
newTestClass
(
"IntIndex"
,
[]
*
Type
{
ObjectType
},
newStringDict
(
map
[
string
]
*
Object
{
"__index__"
:
newBuiltinFunction
(
"__index__"
,
func
(
f
*
Frame
,
_
Args
,
_
KWArgs
)
(
*
Object
,
*
BaseException
)
{
return
NewInt
(
2
)
.
ToObject
(),
nil
})
.
ToObject
(),
}))
longIndexType
:=
newTestClass
(
"LongIndex"
,
[]
*
Type
{
ObjectType
},
newStringDict
(
map
[
string
]
*
Object
{
"__index__"
:
newBuiltinFunction
(
"__index__"
,
func
(
f
*
Frame
,
_
Args
,
_
KWArgs
)
(
*
Object
,
*
BaseException
)
{
return
NewLong
(
big
.
NewInt
(
2
))
.
ToObject
(),
nil
})
.
ToObject
(),
}))
cases
:=
[]
struct
{
methodName
string
args
Args
...
...
@@ -254,7 +265,7 @@ func TestStrMethods(t *testing.T) {
wantExc
*
BaseException
}{
{
"endswith"
,
wrapArgs
(
""
,
""
),
True
.
ToObject
(),
nil
},
{
"endswith"
,
wrapArgs
(
""
,
""
,
1
),
Tru
e
.
ToObject
(),
nil
},
{
"endswith"
,
wrapArgs
(
""
,
""
,
1
),
Fals
e
.
ToObject
(),
nil
},
{
"endswith"
,
wrapArgs
(
"foobar"
,
"bar"
),
True
.
ToObject
(),
nil
},
{
"endswith"
,
wrapArgs
(
"foobar"
,
"bar"
,
0
,
-
2
),
False
.
ToObject
(),
nil
},
{
"endswith"
,
wrapArgs
(
"foobar"
,
"foo"
,
0
,
3
),
True
.
ToObject
(),
nil
},
...
...
@@ -266,12 +277,22 @@ func TestStrMethods(t *testing.T) {
{
"endswith"
,
wrapArgs
(
"foo"
,
newTestTuple
(
123
)
.
ToObject
()),
nil
,
mustCreateException
(
TypeErrorType
,
"expected a str"
)},
{
"find"
,
wrapArgs
(
""
,
""
),
NewInt
(
0
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
""
,
""
,
1
),
NewInt
(
-
1
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
""
,
""
,
-
1
),
NewInt
(
0
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
""
,
""
,
None
,
-
1
),
NewInt
(
0
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
),
NewInt
(
3
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
fooType
),
nil
,
mustCreateException
(
TypeErrorType
,
"slice indices must be integers or None or have an __index__ method"
)},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
NewInt
(
MaxInt
)),
NewInt
(
-
1
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
None
,
NewInt
(
MaxInt
)),
NewInt
(
3
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
newObject
(
intIndexType
)),
NewInt
(
3
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
None
,
newObject
(
intIndexType
)),
NewInt
(
-
1
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
newObject
(
longIndexType
)),
NewInt
(
3
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
None
,
newObject
(
longIndexType
)),
NewInt
(
-
1
)
.
ToObject
(),
nil
},
// TODO: Support unicode substring.
{
"find"
,
wrapArgs
(
"foobar"
,
NewUnicode
(
"bar"
)),
nil
,
mustCreateException
(
TypeErrorType
,
"'find/index' requires a 'str' object but received a 'unicode'"
)},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
"baz"
),
nil
,
mustCreateException
(
IndexErrorType
,
"cannot fit '<type 'str'>' into an index-sized integer"
)},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
0
,
"baz"
),
nil
,
mustCreateException
(
IndexErrorType
,
"cannot fit '<type 'str'>' into an index-sized integer"
)},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
"baz"
),
nil
,
mustCreateException
(
TypeErrorType
,
"slice indices must be integers or None or have an __index__ method"
)},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
0
,
"baz"
),
nil
,
mustCreateException
(
TypeErrorType
,
"slice indices must be integers or None or have an __index__ method"
)},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
None
),
NewInt
(
3
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
0
,
None
),
NewInt
(
3
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"bar"
,
0
,
-
2
),
NewInt
(
-
1
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"foo"
,
0
,
3
),
NewInt
(
0
)
.
ToObject
(),
nil
},
{
"find"
,
wrapArgs
(
"foobar"
,
"foo"
,
10
),
NewInt
(
-
1
)
.
ToObject
(),
nil
},
...
...
@@ -321,7 +342,7 @@ func TestStrMethods(t *testing.T) {
{
"split"
,
wrapArgs
(
"foo"
,
1
),
nil
,
mustCreateException
(
TypeErrorType
,
"expected a str separator"
)},
{
"split"
,
wrapArgs
(
"foo"
,
""
),
nil
,
mustCreateException
(
ValueErrorType
,
"empty separator"
)},
{
"startswith"
,
wrapArgs
(
""
,
""
),
True
.
ToObject
(),
nil
},
{
"startswith"
,
wrapArgs
(
""
,
""
,
1
),
Tru
e
.
ToObject
(),
nil
},
{
"startswith"
,
wrapArgs
(
""
,
""
,
1
),
Fals
e
.
ToObject
(),
nil
},
{
"startswith"
,
wrapArgs
(
"foobar"
,
"foo"
),
True
.
ToObject
(),
nil
},
{
"startswith"
,
wrapArgs
(
"foobar"
,
"foo"
,
2
),
False
.
ToObject
(),
nil
},
{
"startswith"
,
wrapArgs
(
"foobar"
,
"bar"
,
3
),
True
.
ToObject
(),
nil
},
...
...
testing/str_test.py
View file @
53406932
...
...
@@ -24,11 +24,15 @@ assert "baz" + "" == "baz"
# Test find
assert
""
.
find
(
""
)
==
0
assert
""
.
find
(
""
,
1
)
==
-
1
assert
""
.
find
(
""
,
-
1
)
==
0
assert
""
.
find
(
""
,
None
,
-
1
)
==
0
assert
"foobar"
.
find
(
"bar"
)
==
3
assert
"foobar"
.
find
(
"bar"
,
0
,
-
2
)
==
-
1
assert
"foobar"
.
find
(
"foo"
,
0
,
3
)
==
0
assert
"foobar"
.
find
(
"bar"
,
3
,
5
)
==
-
1
assert
"foobar"
.
find
(
"bar"
,
5
,
3
)
==
-
1
assert
'foobar'
.
find
(
"bar"
,
None
)
==
3
assert
'foobar'
.
find
(
"bar"
,
0
,
None
)
==
3
assert
"bar"
.
find
(
"foobar"
)
==
-
1
assert
"bar"
.
find
(
"a"
,
0
,
-
1
)
==
1
assert
'abcdefghiabc'
.
find
(
'abc'
)
==
0
...
...
@@ -42,18 +46,17 @@ assert 'abc'.find('', 4) == -1
assert
'rrarrrrrrrrra'
.
find
(
'a'
)
==
2
assert
'rrarrrrrrrrra'
.
find
(
'a'
,
4
)
==
12
assert
'rrarrrrrrrrra'
.
find
(
'a'
,
4
,
6
)
==
-
1
assert
'rrarrrrrrrrra'
.
find
(
'a'
,
4
,
None
)
==
12
assert
'rrarrrrrrrrra'
.
find
(
'a'
,
None
,
6
)
==
2
assert
''
.
find
(
''
)
==
0
assert
''
.
find
(
''
,
1
,
1
)
==
-
1
assert
''
.
find
(
''
,
sys
.
maxint
,
0
)
==
-
1
assert
''
.
find
(
'xx'
)
==
-
1
assert
''
.
find
(
'xx'
,
1
,
1
)
==
-
1
assert
''
.
find
(
'xx'
,
sys
.
maxint
,
0
)
==
-
1
assert
'ab'
.
find
(
'xxx'
,
sys
.
maxsize
+
1
,
0
)
==
-
1
# TODO: Support unicode substring.
# assert "foobar".find(u"bar") == 3
# TODO: Support None.
# assert 'rrarrrrrrrrra'.find('a', 4, None) == 12
# assert 'rrarrrrrrrrra'.find('a', None, 6) == 2
class
Foo
(
object
):
...
...
@@ -61,8 +64,6 @@ class Foo(object):
return
3
assert
'abcd'
.
find
(
'a'
,
Foo
())
==
-
1
# TODO: This raises IndexError under Grumpy but returns -1 for CPython.
# 'ab'.find('xxx', sys.maxsize + 1, 0)
try
:
"foo"
.
find
(
123
)
...
...
@@ -82,19 +83,17 @@ try:
except
TypeError
:
pass
# TODO: Both of these test cases raise TypeError under CPython but raise
# IndexError under Grumpy.
#try:
# 'foobar'.find("bar", "baz")
# raise AssertionError
#except TypeError:
# pass
#try:
# 'foobar'.find("bar", 0, "baz")
# raise AssertionError
#except TypeError:
# pass
try
:
'foobar'
.
find
(
"bar"
,
"baz"
)
raise
AssertionError
except
TypeError
:
pass
try
:
'foobar'
.
find
(
"bar"
,
0
,
"baz"
)
raise
AssertionError
except
TypeError
:
pass
# Test Mod
assert
"%s"
%
42
==
"42"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment