Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
satella
Manage
Activity
Members
Labels
Plan
Issues
1
Issue boards
Milestones
Wiki
Code
Merge requests
0
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
public
satella
Commits
6e6d8506
Commit
6e6d8506
authored
8 years ago
by
Piotr Maślanka
Browse files
Options
Downloads
Patches
Plain Diff
some tests
parent
4db89f23
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
satella/coding/debug/typecheck.py
+173
-0
173 additions, 0 deletions
satella/coding/debug/typecheck.py
setup.py
+1
-0
1 addition, 0 deletions
setup.py
with
174 additions
and
0 deletions
satella/coding/debug/typecheck.py
+
173
−
0
View file @
6e6d8506
...
@@ -4,12 +4,185 @@ Decorator for debug-time typechecking
...
@@ -4,12 +4,185 @@ Decorator for debug-time typechecking
"""
"""
from
__future__
import
print_function
,
absolute_import
,
division
from
__future__
import
print_function
,
absolute_import
,
division
import
six
import
six
import
inspect
import
logging
import
logging
import
itertools
try
:
import
typing
except
ImportError
:
from
backports
import
typing
import
types
import
types
from
collections
import
namedtuple
import
functools
import
functools
logger
=
logging
.
getLogger
(
__name__
)
logger
=
logging
.
getLogger
(
__name__
)
List
=
typing
.
List
Tuple
=
typing
.
Tuple
Dict
=
typing
.
Dict
NewType
=
typing
.
NewType
Callable
=
typing
.
Callable
Sequence
=
typing
.
Sequence
TypeVar
=
typing
.
TypeVar
Generic
=
typing
.
Generic
Pair
=
typing
.
Pair
Mapping
=
typing
.
Mapping
Iterable
=
typing
.
Iterable
Union
=
typing
.
Union
Any
=
typing
.
Any
Optional
=
typing
.
Optional
# Internal tokens - only instances will be
class
_NotGiven
(
object
):
pass
class
_NoDefault
(
object
):
pass
_CSArgument
=
namedtuple
(
'
_CSArgument
'
,
(
'
name
'
,
'
required
'
,
'
default_value
'
))
class
CSArgument
(
_CSArgument
):
def
__str__
(
self
):
p
=
[
'
Argument
'
+
self
.
name
]
if
not
self
.
required
:
p
.
append
(
'
optional with default %s
'
%
(
self
.
default_value
,
))
return
'
'
.
join
(
p
)
class
CSVarargsPlaceholder
(
CSArgument
):
def
__init__
(
self
,
name
):
super
(
CSVarargsPlaceholder
,
self
).
__init__
(
'
name
'
,
False
,
())
class
CSKwargsPlaceholder
(
CSArgument
):
def
__init__
(
self
,
name
):
super
(
CSKwargsPlaceholder
,
self
).
__init__
(
'
name
'
,
False
,
{})
class
TypeErrorReason
(
object
):
pass
class
CSTypeError
(
TypeError
):
"""
A TypeError exception on steroids
"""
def
__str__
(
self
):
return
'
Problem with argument %s
'
%
(
arg
.
name
,
)
def
__init__
(
self
,
arg
):
"""
:param arg: Argument definition
:type arg: CSArgument
"""
super
(
CSTypeError
,
self
).
__init__
(
str
(
self
))
self
.
arg
=
arg
class
CSBadTypeError
(
CSTypeError
):
def
__init__
(
self
,
arg
,
expected
,
got
):
super
(
CSBadTypeError
,
self
).
__init__
(
arg
)
self
.
expected
=
expected
self
.
got
=
got
def
__str__
(
self
):
return
'
Bad type given for arg %s, expected %s got %s
'
%
(
self
.
arg
.
name
,
self
.
expected
,
self
.
got
)
class
CSNotGivenError
(
CSTypeError
):
def
__str__
(
self
):
return
'
Value for argument %s not given
'
%
(
self
.
arg
.
name
,
)
class
CSMultipleValuesGivenError
(
CSTypeError
):
def
__str__
(
self
):
return
'
Got multiple values for argument
'
%
(
self
.
arg
.
name
,
)
class
CallSignature
(
object
):
"""
Call signature of a callable.
Properties:
- has_varargs (Bool) - if has varargs
- has_kwargs (Bool) - if has kwargs
- locals (Dict[str => CSArgument]) - list of locals this function call will generate
- pos_args (List[CSArgument)] - list of positional arguments
- varargs_name (Union[str, None]) - name of varargs argument, or None if not present
- kwargs_name (Union[str, None]) - name of kwargs argument, or None if not present
"""
__slots__
=
(
'
has_varargs
'
,
'
has_kwargs
'
,
'
pos_args
'
,
'
locals
'
)
def
count_required_positionals
(
self
):
return
len
((
a
for
a
in
self
.
pos_args
if
a
.
required
))
def
__init__
(
self
,
callable
):
args
,
varargs
,
kwargs
,
defaults
=
inspect
.
getargspec
(
callable
)
# pad them
while
len
(
defaults
)
<
len
(
args
):
defaults
=
[
_NoDefault
]
+
list
(
defaults
)
# process positionals
self
.
pos_args
=
[]
self
.
locals
=
{}
for
arg
,
default
in
zip
(
args
,
defaults
):
cs_arg
=
CSArgument
(
arg
,
default
is
_NoDefault
,
default
)
self
.
pos_args
.
append
(
cs_arg
)
self
.
locals
[
arg
]
=
cs_arg
self
.
varargs_name
=
varargs
if
varargs
is
not
None
:
self
.
has_varargs
=
True
self
.
locals
[
self
.
varargs_name
]
=
CSVarargsPlaceholder
(
self
.
varargs_name
)
self
.
kwargs_name
=
kwargs
if
kwargs
is
not
None
:
self
.
has_kwargs
=
True
self
.
locals
[
self
.
kwargs_name
]
=
CSKwargsPlaceholder
(
self
.
kwargs_name
)
def
result
(
self
,
*
args
,
**
kwargs
):
"""
Simulate a function call, see what locals are defined
Return a dict of (local_variable_name => it
'
s value),
or TypeError
:param args: function call parameters
:param kwargs: function call parameters
:return: dict
:raise CSTypeError: call would raise a TypeError
"""
assert
len
(
args
)
>=
self
.
count_required_positionals
()
locals
=
{}
# positional
for
arg
,
value
in
itertools
.
izip_longest
(
self
.
pos_args
,
args
[:
len
(
self
.
pos_args
)],
fillvalue
=
_NotGiven
):
if
value
is
_NotGiven
:
if
arg
.
required
:
raise
CSNotGivenError
(
arg
)
else
:
value
=
arg
.
default_value
locals
[
arg
.
name
]
=
value
# varargs
if
self
.
has_varargs
:
locals
[
self
.
varargs_name
]
=
args
[
len
(
self
.
pos_args
):]
# kwargs
if
self
.
has_kwargs
:
locals
[
self
.
kwargs_name
]
=
kwargs
return
locals
def
typed
(
*
t_args
,
**
t_kwargs
):
def
typed
(
*
t_args
,
**
t_kwargs
):
...
...
This diff is collapsed.
Click to expand it.
setup.py
+
1
−
0
View file @
6e6d8506
...
@@ -16,6 +16,7 @@ setup(name='satella',
...
@@ -16,6 +16,7 @@ setup(name='satella',
install_requires
=
[
install_requires
=
[
"
six
"
,
"
six
"
,
"
monotonic
"
,
"
monotonic
"
,
"
typing
"
],
],
tests_require
=
[
tests_require
=
[
"
nose
"
"
nose
"
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment