Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
P
Pyston
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
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Boxiang Sun
Pyston
Commits
039ea8f2
Commit
039ea8f2
authored
May 11, 2015
by
Kevin Modzelewski
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #518 from undingen/misc
Support for inspect.isgenerator, round(int), property.__doc__
parents
3dba07f5
bbb19558
Changes
16
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
53 additions
and
45 deletions
+53
-45
from_cpython/Include/pyconfig.h
from_cpython/Include/pyconfig.h
+1
-0
from_cpython/Lib/inspect.py
from_cpython/Lib/inspect.py
+1
-0
src/codegen/ast_interpreter.cpp
src/codegen/ast_interpreter.cpp
+2
-4
src/codegen/compvars.cpp
src/codegen/compvars.cpp
+4
-7
src/codegen/compvars.h
src/codegen/compvars.h
+2
-2
src/codegen/irgen/irgenerator.cpp
src/codegen/irgen/irgenerator.cpp
+2
-2
src/core/types.h
src/core/types.h
+6
-0
src/runtime/builtin_modules/builtins.cpp
src/runtime/builtin_modules/builtins.cpp
+2
-4
src/runtime/code.cpp
src/runtime/code.cpp
+5
-0
src/runtime/descr.cpp
src/runtime/descr.cpp
+1
-1
src/runtime/objmodel.cpp
src/runtime/objmodel.cpp
+5
-4
src/runtime/types.cpp
src/runtime/types.cpp
+9
-12
src/runtime/types.h
src/runtime/types.h
+4
-7
test/tests/builtins.py
test/tests/builtins.py
+1
-1
test/tests/inspect_test.py
test/tests/inspect_test.py
+6
-0
test/tests/property.py
test/tests/property.py
+2
-1
No files found.
from_cpython/Include/pyconfig.h
View file @
039ea8f2
...
...
@@ -129,6 +129,7 @@
#define HAVE_UNISTD_H 1
#define HAVE_UTIME_H 1
#define HAVE_WCHAR_H 1
#define HAVE_WORKING_TZSET 1
#define HAVE_PUTENV 1
// Added this for some Pyston modifications:
...
...
from_cpython/Lib/inspect.py
View file @
039ea8f2
...
...
@@ -44,6 +44,7 @@ from collections import namedtuple
# Pyston change: we don't support all of these flags yet, so just enable the ones that we do:
CO_VARARGS
=
0x4
CO_VARKEYWORDS
=
0x8
CO_GENERATOR
=
0x20
# These constants are from Include/code.h.
# CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 0x1, 0x2, 0x4, 0x8
# CO_NESTED, CO_GENERATOR, CO_NOFREE = 0x10, 0x20, 0x40
...
...
src/codegen/ast_interpreter.cpp
View file @
039ea8f2
...
...
@@ -759,8 +759,6 @@ Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::v
takes_closure
=
source_info
->
scoping
->
getScopeInfoForNode
(
node
)
->
takesClosure
();
}
bool
is_generator
=
cl
->
source
->
is_generator
;
BoxedClosure
*
closure
=
0
;
if
(
takes_closure
)
{
if
(
scope_info
->
createsClosure
())
{
...
...
@@ -775,7 +773,7 @@ Box* ASTInterpreter::createFunction(AST* node, AST_arguments* args, const std::v
Box
*
passed_globals
=
NULL
;
if
(
!
getCF
()
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
())
passed_globals
=
globals
;
return
boxCLFunction
(
cl
,
closure
,
is_generator
,
passed_globals
,
u
.
il
);
return
boxCLFunction
(
cl
,
closure
,
passed_globals
,
u
.
il
);
}
Value
ASTInterpreter
::
visit_makeFunction
(
AST_MakeFunction
*
mkfn
)
{
...
...
@@ -815,7 +813,7 @@ Value ASTInterpreter::visit_makeClass(AST_MakeClass* mkclass) {
Box
*
passed_globals
=
NULL
;
if
(
!
getCF
()
->
clfunc
->
source
->
scoping
->
areGlobalsFromModule
())
passed_globals
=
globals
;
Box
*
attrDict
=
runtimeCall
(
boxCLFunction
(
cl
,
closure
,
false
,
passed_globals
,
{}),
ArgPassSpec
(
0
),
0
,
0
,
0
,
0
,
0
);
Box
*
attrDict
=
runtimeCall
(
boxCLFunction
(
cl
,
closure
,
passed_globals
,
{}),
ArgPassSpec
(
0
),
0
,
0
,
0
,
0
,
0
);
Box
*
classobj
=
createUserClass
(
&
node
->
name
.
str
(),
basesTuple
,
attrDict
);
...
...
src/codegen/compvars.cpp
View file @
039ea8f2
...
...
@@ -723,8 +723,8 @@ ConcreteCompilerVariable* UnknownType::hasnext(IREmitter& emitter, const OpInfo&
return
boolFromI1
(
emitter
,
rtn_val
);
}
CompilerVariable
*
makeFunction
(
IREmitter
&
emitter
,
CLFunction
*
f
,
CompilerVariable
*
closure
,
bool
isGenerator
,
Box
*
globals
,
const
std
::
vector
<
ConcreteCompilerVariable
*>&
defaults
)
{
CompilerVariable
*
makeFunction
(
IREmitter
&
emitter
,
CLFunction
*
f
,
CompilerVariable
*
closure
,
Box
*
globals
,
const
std
::
vector
<
ConcreteCompilerVariable
*>&
defaults
)
{
// Unlike the CLFunction*, which can be shared between recompilations, the Box* around it
// should be created anew every time the functiondef is encountered
...
...
@@ -752,17 +752,14 @@ CompilerVariable* makeFunction(IREmitter& emitter, CLFunction* f, CompilerVariab
scratch
=
getNullPtr
(
g
.
llvm_value_type_ptr_ptr
);
}
llvm
::
Value
*
isGenerator_v
=
llvm
::
ConstantInt
::
get
(
g
.
i1
,
isGenerator
,
false
);
assert
(
globals
==
NULL
);
llvm
::
Value
*
globals_v
=
getNullPtr
(
g
.
llvm_value_type_ptr
);
// We know this function call can't throw, so it's safe to use emitter.getBuilder()->CreateCall() rather than
// emitter.createCall().
llvm
::
Value
*
boxed
=
emitter
.
getBuilder
()
->
CreateCall
(
g
.
funcs
.
boxCLFunction
,
std
::
vector
<
llvm
::
Value
*>
{
embedRelocatablePtr
(
f
,
g
.
llvm_clfunction_type_ptr
),
closure_v
,
isGenerator_v
,
globals_v
,
scratch
,
getConstantInt
(
defaults
.
size
(),
g
.
i64
)
});
g
.
funcs
.
boxCLFunction
,
std
::
vector
<
llvm
::
Value
*>
{
embedRelocatablePtr
(
f
,
g
.
llvm_clfunction_type_ptr
),
closure_v
,
globals_v
,
scratch
,
getConstantInt
(
defaults
.
size
(),
g
.
i64
)
});
if
(
convertedClosure
)
convertedClosure
->
decvref
(
emitter
);
...
...
src/codegen/compvars.h
View file @
039ea8f2
...
...
@@ -398,8 +398,8 @@ ConcreteCompilerVariable* makeLong(IREmitter& emitter, std::string&);
ConcreteCompilerVariable
*
makePureImaginary
(
IREmitter
&
emitter
,
double
imag
);
CompilerVariable
*
makeStr
(
const
std
::
string
*
);
CompilerVariable
*
makeUnicode
(
IREmitter
&
emitter
,
const
std
::
string
*
);
CompilerVariable
*
makeFunction
(
IREmitter
&
emitter
,
CLFunction
*
,
CompilerVariable
*
closure
,
bool
isGenerator
,
Box
*
globals
,
const
std
::
vector
<
ConcreteCompilerVariable
*>&
defaults
);
CompilerVariable
*
makeFunction
(
IREmitter
&
emitter
,
CLFunction
*
,
CompilerVariable
*
closure
,
Box
*
globals
,
const
std
::
vector
<
ConcreteCompilerVariable
*>&
defaults
);
ConcreteCompilerVariable
*
undefVariable
();
CompilerVariable
*
makeTuple
(
const
std
::
vector
<
CompilerVariable
*>&
elts
);
...
...
src/codegen/irgen/irgenerator.cpp
View file @
039ea8f2
...
...
@@ -1269,7 +1269,7 @@ private:
// but since the classdef can't create its own closure, shouldn't need to explicitly
// create that scope to pass the closure through.
assert
(
irstate
->
getSourceInfo
()
->
scoping
->
areGlobalsFromModule
());
CompilerVariable
*
func
=
makeFunction
(
emitter
,
cl
,
created_closure
,
false
,
NULL
,
{});
CompilerVariable
*
func
=
makeFunction
(
emitter
,
cl
,
created_closure
,
NULL
,
{});
CompilerVariable
*
attr_dict
=
func
->
call
(
emitter
,
getEmptyOpInfo
(
unw_info
),
ArgPassSpec
(
0
),
{},
NULL
);
...
...
@@ -1333,7 +1333,7 @@ private:
}
assert
(
irstate
->
getSourceInfo
()
->
scoping
->
areGlobalsFromModule
());
CompilerVariable
*
func
=
makeFunction
(
emitter
,
cl
,
created_closure
,
is_generator
,
NULL
,
defaults
);
CompilerVariable
*
func
=
makeFunction
(
emitter
,
cl
,
created_closure
,
NULL
,
defaults
);
for
(
auto
d
:
defaults
)
{
d
->
decvref
(
emitter
);
...
...
src/core/types.h
View file @
039ea8f2
...
...
@@ -322,6 +322,12 @@ public:
osr_versions
[
compiled
->
entry_descriptor
]
=
compiled
;
}
}
bool
isGenerator
()
const
{
if
(
source
)
return
source
->
is_generator
;
return
false
;
}
};
CLFunction
*
createRTFunction
(
int
num_args
,
int
num_defaults
,
bool
takes_varargs
,
bool
takes_kwargs
,
...
...
src/runtime/builtin_modules/builtins.cpp
View file @
039ea8f2
...
...
@@ -1017,12 +1017,10 @@ Box* input(Box* prompt) {
}
Box
*
builtinRound
(
Box
*
_number
,
Box
*
_ndigits
)
{
if
(
!
isSubclass
(
_number
->
cls
,
float_cls
))
double
x
=
PyFloat_AsDouble
(
_number
);
if
(
PyErr_Occurred
())
raiseExcHelper
(
TypeError
,
"a float is required"
);
BoxedFloat
*
number
=
(
BoxedFloat
*
)
_number
;
double
x
=
number
->
d
;
/* interpret 2nd argument as a Py_ssize_t; clip on overflow */
Py_ssize_t
ndigits
=
PyNumber_AsSsize_t
(
_ndigits
,
NULL
);
if
(
ndigits
==
-
1
&&
PyErr_Occurred
())
...
...
src/runtime/code.cpp
View file @
039ea8f2
...
...
@@ -62,6 +62,9 @@ public:
return
boxInt
(
-
1
);
}
if
(
cl
->
source
->
ast
->
lineno
==
(
uint32_t
)
-
1
)
return
boxInt
(
-
1
);
return
boxInt
(
cl
->
source
->
ast
->
lineno
);
}
...
...
@@ -98,6 +101,8 @@ public:
flags
|=
CO_VARARGS
;
if
(
code
->
f
->
param_names
.
kwarg
.
size
())
flags
|=
CO_VARKEYWORDS
;
if
(
code
->
f
->
isGenerator
())
flags
|=
CO_GENERATOR
;
return
boxInt
(
flags
);
}
};
...
...
src/runtime/descr.cpp
View file @
039ea8f2
...
...
@@ -188,7 +188,7 @@ void setupDescr() {
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
offsetof
(
BoxedProperty
,
prop_set
)));
property_cls
->
giveAttr
(
"fdel"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
offsetof
(
BoxedProperty
,
prop_del
)));
property_cls
->
giveAttr
(
"
fdoc
"
,
property_cls
->
giveAttr
(
"
__doc__
"
,
new
BoxedMemberDescriptor
(
BoxedMemberDescriptor
::
OBJECT
,
offsetof
(
BoxedProperty
,
prop_doc
)));
property_cls
->
freeze
();
...
...
src/runtime/objmodel.cpp
View file @
039ea8f2
...
...
@@ -2112,7 +2112,8 @@ extern "C" bool nonzero(Box* obj) {
ASSERT
(
isUserDefined
(
obj
->
cls
)
||
obj
->
cls
==
classobj_cls
||
obj
->
cls
==
type_cls
||
isSubclass
(
obj
->
cls
,
Exception
)
||
obj
->
cls
==
file_cls
||
obj
->
cls
==
traceback_cls
||
obj
->
cls
==
instancemethod_cls
||
obj
->
cls
==
module_cls
||
obj
->
cls
==
capifunc_cls
||
obj
->
cls
==
builtin_function_or_method_cls
||
obj
->
cls
==
method_cls
,
||
obj
->
cls
==
builtin_function_or_method_cls
||
obj
->
cls
==
method_cls
||
obj
->
cls
==
frame_cls
||
obj
->
cls
==
capi_getset_cls
||
obj
->
cls
==
pyston_getset_cls
,
"%s.__nonzero__"
,
getTypeName
(
obj
));
// TODO
// TODO should rewrite these?
...
...
@@ -2845,7 +2846,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
int
num_output_args
=
f
->
numReceivedArgs
();
int
num_passed_args
=
argspec
.
totalPassed
();
if
(
argspec
.
has_starargs
||
argspec
.
has_kwargs
||
f
unc
->
isGenerator
)
{
if
(
argspec
.
has_starargs
||
argspec
.
has_kwargs
||
f
->
isGenerator
()
)
{
rewrite_args
=
NULL
;
REWRITE_ABORTED
(
""
);
}
...
...
@@ -2879,7 +2880,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
// Fast path: if it's a simple-enough call, we don't have to do anything special. On a simple
// django-admin test this covers something like 93% of all calls to callFunc.
if
(
!
f
unc
->
isGenerator
)
{
if
(
!
f
->
isGenerator
()
)
{
if
(
argspec
.
num_keywords
==
0
&&
!
argspec
.
has_starargs
&&
!
argspec
.
has_kwargs
&&
argspec
.
num_args
==
f
->
num_args
&&
!
f
->
takes_varargs
&&
!
f
->
takes_kwargs
)
{
return
callCLFunc
(
f
,
rewrite_args
,
argspec
.
num_args
,
closure
,
NULL
,
func
->
globals
,
arg1
,
arg2
,
arg3
,
args
);
...
...
@@ -3166,7 +3167,7 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
// special handling for generators:
// the call to function containing a yield should just create a new generator object.
Box
*
res
;
if
(
f
unc
->
isGenerator
)
{
if
(
f
->
isGenerator
()
)
{
res
=
createGenerator
(
func
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
}
else
{
res
=
callCLFunc
(
f
,
rewrite_args
,
num_output_args
,
closure
,
NULL
,
func
->
globals
,
oarg1
,
oarg2
,
oarg3
,
oargs
);
...
...
src/runtime/types.cpp
View file @
039ea8f2
...
...
@@ -287,8 +287,7 @@ Box* Box::nextIC() {
std
::
string
builtinStr
(
"__builtin__"
);
extern
"C"
BoxedFunctionBase
::
BoxedFunctionBase
(
CLFunction
*
f
)
:
in_weakreflist
(
NULL
),
f
(
f
),
closure
(
NULL
),
isGenerator
(
false
),
ndefaults
(
0
),
defaults
(
NULL
),
modname
(
NULL
),
name
(
NULL
),
doc
(
NULL
)
{
:
in_weakreflist
(
NULL
),
f
(
f
),
closure
(
NULL
),
ndefaults
(
0
),
defaults
(
NULL
),
modname
(
NULL
),
name
(
NULL
),
doc
(
NULL
)
{
if
(
f
->
source
)
{
this
->
modname
=
PyDict_GetItemString
(
getGlobalsDict
(),
"__name__"
);
this
->
doc
=
f
->
source
->
getDocString
();
...
...
@@ -301,9 +300,8 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f)
}
extern
"C"
BoxedFunctionBase
::
BoxedFunctionBase
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
,
bool
isGenerator
)
:
in_weakreflist
(
NULL
),
f
(
f
),
closure
(
closure
),
isGenerator
(
isGenerator
),
ndefaults
(
0
),
defaults
(
NULL
),
modname
(
NULL
),
name
(
NULL
),
doc
(
NULL
)
{
BoxedClosure
*
closure
)
:
in_weakreflist
(
NULL
),
f
(
f
),
closure
(
closure
),
ndefaults
(
0
),
defaults
(
NULL
),
modname
(
NULL
),
name
(
NULL
),
doc
(
NULL
)
{
if
(
defaults
.
size
())
{
// make sure to initialize defaults first, since the GC behavior is triggered by ndefaults,
// and a GC can happen within this constructor:
...
...
@@ -326,9 +324,8 @@ extern "C" BoxedFunctionBase::BoxedFunctionBase(CLFunction* f, std::initializer_
BoxedFunction
::
BoxedFunction
(
CLFunction
*
f
)
:
BoxedFunction
(
f
,
{})
{
}
BoxedFunction
::
BoxedFunction
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
,
bool
isGenerator
,
Box
*
globals
)
:
BoxedFunctionBase
(
f
,
defaults
,
closure
,
isGenerator
)
{
BoxedFunction
::
BoxedFunction
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
,
Box
*
globals
)
:
BoxedFunctionBase
(
f
,
defaults
,
closure
)
{
assert
((
!
globals
)
==
(
!
f
->
source
||
f
->
source
->
scoping
->
areGlobalsFromModule
()));
this
->
globals
=
globals
;
...
...
@@ -349,8 +346,8 @@ BoxedBuiltinFunctionOrMethod::BoxedBuiltinFunctionOrMethod(CLFunction* f, const
BoxedBuiltinFunctionOrMethod
::
BoxedBuiltinFunctionOrMethod
(
CLFunction
*
f
,
const
char
*
name
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
,
bool
isGenerator
,
const
char
*
doc
)
:
BoxedFunctionBase
(
f
,
defaults
,
closure
,
isGenerator
)
{
const
char
*
doc
)
:
BoxedFunctionBase
(
f
,
defaults
,
closure
)
{
assert
(
name
);
this
->
name
=
static_cast
<
BoxedString
*>
(
boxString
(
name
));
...
...
@@ -429,12 +426,12 @@ extern "C" void moduleGCHandler(GCVisitor* v, Box* b) {
// This mustn't throw; our IR generator generates calls to it without "invoke" even when there are exception handlers /
// finally-blocks in scope.
// TODO: should we use C++11 `noexcept' here?
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
bool
isGenerator
,
Box
*
globals
,
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
Box
*
globals
,
std
::
initializer_list
<
Box
*>
defaults
)
{
if
(
closure
)
assert
(
closure
->
cls
==
closure_cls
);
return
new
BoxedFunction
(
f
,
defaults
,
closure
,
isGenerator
,
globals
);
return
new
BoxedFunction
(
f
,
defaults
,
closure
,
globals
);
}
extern
"C"
CLFunction
*
unboxCLFunction
(
Box
*
b
)
{
...
...
src/runtime/types.h
View file @
039ea8f2
...
...
@@ -129,8 +129,7 @@ char* getWriteableStringContents(BoxedString* s);
extern
"C"
void
listAppendInternal
(
Box
*
self
,
Box
*
v
);
extern
"C"
void
listAppendArrayInternal
(
Box
*
self
,
Box
**
v
,
int
nelts
);
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
bool
isGenerator
,
Box
*
globals
,
std
::
initializer_list
<
Box
*>
defaults
);
extern
"C"
Box
*
boxCLFunction
(
CLFunction
*
f
,
BoxedClosure
*
closure
,
Box
*
globals
,
std
::
initializer_list
<
Box
*>
defaults
);
extern
"C"
CLFunction
*
unboxCLFunction
(
Box
*
b
);
extern
"C"
Box
*
createUserClass
(
const
std
::
string
*
name
,
Box
*
base
,
Box
*
attr_dict
);
extern
"C"
double
unboxFloat
(
Box
*
b
);
...
...
@@ -663,7 +662,6 @@ public:
BoxedClosure
*
closure
;
Box
*
globals
;
bool
isGenerator
;
int
ndefaults
;
GCdArray
*
defaults
;
...
...
@@ -675,8 +673,7 @@ public:
Box
*
doc
;
// __doc__
BoxedFunctionBase
(
CLFunction
*
f
);
BoxedFunctionBase
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
=
NULL
,
bool
isGenerator
=
false
);
BoxedFunctionBase
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
=
NULL
);
};
class
BoxedFunction
:
public
BoxedFunctionBase
{
...
...
@@ -685,7 +682,7 @@ public:
BoxedFunction
(
CLFunction
*
f
);
BoxedFunction
(
CLFunction
*
f
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
=
NULL
,
bool
isGenerator
=
false
,
Box
*
globals
=
NULL
);
Box
*
globals
=
NULL
);
DEFAULT_CLASS
(
function_cls
);
};
...
...
@@ -694,7 +691,7 @@ class BoxedBuiltinFunctionOrMethod : public BoxedFunctionBase {
public:
BoxedBuiltinFunctionOrMethod
(
CLFunction
*
f
,
const
char
*
name
,
const
char
*
doc
=
NULL
);
BoxedBuiltinFunctionOrMethod
(
CLFunction
*
f
,
const
char
*
name
,
std
::
initializer_list
<
Box
*>
defaults
,
BoxedClosure
*
closure
=
NULL
,
bool
isGenerator
=
false
,
const
char
*
doc
=
NULL
);
BoxedClosure
*
closure
=
NULL
,
const
char
*
doc
=
NULL
);
DEFAULT_CLASS
(
builtin_function_or_method_cls
);
};
...
...
test/tests/builtins.py
View file @
039ea8f2
...
...
@@ -108,7 +108,7 @@ print callable(lambda: 1)
print
range
(
5L
,
7L
)
for
n
in
[
0
,
1
,
2
,
3
,
4
,
5
]:
print
round
(
-
1.1
,
n
),
round
(
-
1.9
,
n
),
round
(
0.5
,
n
),
round
(
-
0.5
,
n
),
round
(
-
0.123456789
,
n
)
print
round
(
-
1.1
,
n
),
round
(
-
1.9
,
n
),
round
(
0.5
,
n
),
round
(
-
0.5
,
n
),
round
(
-
0.123456789
,
n
)
,
round
(
1
,
n
)
print
list
(
iter
(
xrange
(
100
).
__iter__
().
next
,
20
))
...
...
test/tests/inspect_test.py
View file @
039ea8f2
...
...
@@ -8,3 +8,9 @@ def f2():
print
inspect
.
getargspec
(
f1
)
print
inspect
.
getargspec
(
f2
)
def
G
():
yield
1
print
inspect
.
isgenerator
(
f1
)
print
inspect
.
isgenerator
(
G
)
print
inspect
.
isgenerator
(
G
())
test/tests/property.py
View file @
039ea8f2
...
...
@@ -8,7 +8,7 @@ class C(object):
def
fset
(
self
,
val
):
print
'in fset, val ='
,
val
x
=
property
(
fget
,
fset
)
x
=
property
(
fget
,
fset
,
None
,
"Doc String"
)
c
=
C
()
print
c
.
x
...
...
@@ -16,6 +16,7 @@ print C.x.__get__(c, C)
print
type
(
C
.
x
.
__get__
(
None
,
C
))
c
.
x
=
7
print
c
.
x
print
C
.
x
.
__doc__
class
C2
(
object
):
@
property
...
...
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