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
db97d4f4
Commit
db97d4f4
authored
Jan 08, 2017
by
ns-cweber
Committed by
Dylan Trotter
Jan 08, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Issue #12: Fix native attribute access (#41)
* Implemented via descriptors instead of overriding GetAttribute
parent
b0e8553c
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
70 additions
and
4 deletions
+70
-4
runtime/native.go
runtime/native.go
+32
-3
runtime/native_test.go
runtime/native_test.go
+28
-1
testing/native_test.py
testing/native_test.py
+10
-0
No files found.
runtime/native.go
View file @
db97d4f4
...
...
@@ -64,10 +64,10 @@ func toNativeMetaclassUnsafe(o *Object) *nativeMetaclass {
return
(
*
nativeMetaclass
)(
o
.
toPointer
())
}
func
newNativeType
(
rtype
reflect
.
Type
,
base
*
Type
,
d
*
Dict
)
*
nativeMetaclass
{
func
newNativeType
(
rtype
reflect
.
Type
,
base
*
Type
)
*
nativeMetaclass
{
return
&
nativeMetaclass
{
Type
{
Object
:
Object
{
typ
:
nativeMetaclassType
,
dict
:
d
},
Object
:
Object
{
typ
:
nativeMetaclassType
},
name
:
nativeTypeName
(
rtype
),
basis
:
base
.
basis
,
bases
:
[]
*
Type
{
base
},
...
...
@@ -337,7 +337,21 @@ func getNativeType(rtype reflect.Type) *Type {
d
[
meth
.
Name
]
=
newNativeMethod
(
meth
.
Name
,
meth
.
Func
)
}
}
t
=
&
newNativeType
(
rtype
,
base
,
newStringDict
(
d
))
.
Type
t
=
&
newNativeType
(
rtype
,
base
)
.
Type
derefed
:=
rtype
for
derefed
.
Kind
()
==
reflect
.
Ptr
{
derefed
=
derefed
.
Elem
()
}
if
derefed
.
Kind
()
==
reflect
.
Struct
{
for
i
:=
0
;
i
<
derefed
.
NumField
();
i
++
{
name
:=
derefed
.
Field
(
i
)
.
Name
d
[
name
]
=
newNativeField
(
name
,
i
,
t
)
}
}
t
.
dict
=
newStringDict
(
d
)
// This cannot fail since we're defining simple classes.
if
err
:=
prepareType
(
t
);
err
!=
""
{
logFatal
(
err
)
...
...
@@ -348,6 +362,21 @@ func getNativeType(rtype reflect.Type) *Type {
return
t
}
func
newNativeField
(
name
string
,
i
int
,
t
*
Type
)
*
Object
{
nativeFieldGet
:=
func
(
f
*
Frame
,
args
Args
,
_
KWArgs
)
(
*
Object
,
*
BaseException
)
{
if
raised
:=
checkFunctionArgs
(
f
,
name
,
args
,
t
);
raised
!=
nil
{
return
nil
,
raised
}
v
:=
toNativeUnsafe
(
args
[
0
])
.
value
for
v
.
Type
()
.
Kind
()
==
reflect
.
Ptr
{
v
=
v
.
Elem
()
}
return
WrapNative
(
f
,
v
.
Field
(
i
))
}
get
:=
newBuiltinFunction
(
name
,
nativeFieldGet
)
.
ToObject
()
return
newProperty
(
get
,
nil
,
nil
)
.
ToObject
()
}
func
newNativeMethod
(
name
string
,
fun
reflect
.
Value
)
*
Object
{
return
newBuiltinFunction
(
name
,
func
(
f
*
Frame
,
args
Args
,
kwargs
KWArgs
)
(
*
Object
,
*
BaseException
)
{
return
nativeInvoke
(
f
,
fun
,
args
)
...
...
runtime/native_test.go
View file @
db97d4f4
...
...
@@ -24,7 +24,7 @@ import (
func
TestNativeMetaclassNew
(
t
*
testing
.
T
)
{
var
i
int16
intType
:=
&
newNativeType
(
reflect
.
TypeOf
(
i
),
IntType
,
NewDict
()
)
.
Type
intType
:=
&
newNativeType
(
reflect
.
TypeOf
(
i
),
IntType
)
.
Type
fun
:=
wrapFuncForTest
(
func
(
f
*
Frame
,
args
...*
Object
)
*
BaseException
{
newFunc
,
raised
:=
GetAttr
(
f
,
intType
.
ToObject
(),
NewStr
(
"new"
),
nil
)
if
raised
!=
nil
{
...
...
@@ -413,6 +413,33 @@ func TestNativeTypeName(t *testing.T) {
}
}
func
TestNewNativeFieldChecksInstanceType
(
t
*
testing
.
T
)
{
f
:=
newFrame
(
nil
)
// Given a native object
native
,
raised
:=
WrapNative
(
f
,
reflect
.
ValueOf
(
struct
{
foo
string
}{}))
if
raised
!=
nil
{
t
.
Fatal
(
"Unexpected exception:"
,
raised
)
}
// When its field property is assigned to a different type
property
,
raised
:=
native
.
typ
.
dict
.
GetItemString
(
f
,
"foo"
)
if
raised
!=
nil
{
t
.
Fatal
(
"Unexpected exception:"
,
raised
)
}
if
raised
:=
IntType
.
dict
.
SetItemString
(
f
,
"foo"
,
property
);
raised
!=
nil
{
t
.
Fatal
(
"Unexpected exception:"
,
raised
)
}
// And we try to access that property on an object of the new type
_
,
raised
=
GetAttr
(
f
,
NewInt
(
1
)
.
ToObject
(),
NewStr
(
"foo"
),
nil
)
// Then expect a TypeError was raised
if
raised
==
nil
||
raised
.
Type
()
!=
TypeErrorType
{
t
.
Fatal
(
"Wanted TypeError; got:"
,
raised
)
}
}
func
wrapArgs
(
elems
...
interface
{})
Args
{
f
:=
NewRootFrame
()
argc
:=
len
(
elems
)
...
...
testing/native_test.py
View file @
db97d4f4
...
...
@@ -16,6 +16,9 @@
from
__go__.math
import
MaxInt32
,
Pow10
,
Signbit
from
__go__.strings
import
Count
,
IndexAny
,
Repeat
from
__go__.encoding.csv
import
NewReader
as
NewCSVReader
from
__go__.image
import
Pt
from
__go__.strings
import
NewReader
as
NewStringReader
assert
Count
(
'foo,bar,baz'
,
','
)
==
2
assert
IndexAny
(
'foobar'
,
'obr'
)
==
1
...
...
@@ -23,3 +26,10 @@ assert Repeat('foo', 3) == 'foofoofoo'
assert
MaxInt32
==
2147483647
assert
Pow10
(
2.0
)
==
100.0
assert
Signbit
(
-
42.0
)
==
True
# pylint: disable=g-explicit-bool-comparison
# Can access field on unreferenced struct (Pt returns an image.Point struct)
assert
Pt
(
1
,
0
).
X
==
1
# Can access field on pointer to struct (NewCSVReader returns a pointer to a
# csv.Reader struct)
assert
NewCSVReader
(
NewStringReader
(
"foo"
)).
LazyQuotes
==
False
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