8th day of python challenges 111-117
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
from astroid import MANAGER, arguments, nodes, inference_tip, UseInferenceDefault
|
||||
|
||||
|
||||
def infer_namespace(node, context=None):
|
||||
callsite = arguments.CallSite.from_call(node)
|
||||
if not callsite.keyword_arguments:
|
||||
# Cannot make sense of it.
|
||||
raise UseInferenceDefault()
|
||||
|
||||
class_node = nodes.ClassDef("Namespace", "docstring")
|
||||
class_node.parent = node.parent
|
||||
for attr in set(callsite.keyword_arguments):
|
||||
fake_node = nodes.EmptyNode()
|
||||
fake_node.parent = class_node
|
||||
fake_node.attrname = attr
|
||||
class_node.instance_attrs[attr] = [fake_node]
|
||||
return iter((class_node.instantiate_class(),))
|
||||
|
||||
|
||||
def _looks_like_namespace(node):
|
||||
func = node.func
|
||||
if isinstance(func, nodes.Attribute):
|
||||
return (
|
||||
func.attrname == "Namespace"
|
||||
and isinstance(func.expr, nodes.Name)
|
||||
and func.expr.name == "argparse"
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
MANAGER.register_transform(
|
||||
nodes.Call, inference_tip(infer_namespace), _looks_like_namespace
|
||||
)
|
@@ -0,0 +1,59 @@
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
"""
|
||||
Astroid hook for the attrs library
|
||||
|
||||
Without this hook pylint reports unsupported-assignment-operation
|
||||
for attrs classes
|
||||
"""
|
||||
|
||||
import astroid
|
||||
from astroid import MANAGER
|
||||
|
||||
|
||||
ATTRIB_NAMES = frozenset(("attr.ib", "attrib", "attr.attrib"))
|
||||
ATTRS_NAMES = frozenset(("attr.s", "attrs", "attr.attrs", "attr.attributes"))
|
||||
|
||||
|
||||
def is_decorated_with_attrs(node, decorator_names=ATTRS_NAMES):
|
||||
"""Return True if a decorated node has
|
||||
an attr decorator applied."""
|
||||
if not node.decorators:
|
||||
return False
|
||||
for decorator_attribute in node.decorators.nodes:
|
||||
if isinstance(decorator_attribute, astroid.Call): # decorator with arguments
|
||||
decorator_attribute = decorator_attribute.func
|
||||
if decorator_attribute.as_string() in decorator_names:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def attr_attributes_transform(node):
|
||||
"""Given that the ClassNode has an attr decorator,
|
||||
rewrite class attributes as instance attributes
|
||||
"""
|
||||
# Astroid can't infer this attribute properly
|
||||
# Prevents https://github.com/PyCQA/pylint/issues/1884
|
||||
node.locals["__attrs_attrs__"] = [astroid.Unknown(parent=node)]
|
||||
|
||||
for cdefbodynode in node.body:
|
||||
if not isinstance(cdefbodynode, astroid.Assign):
|
||||
continue
|
||||
if isinstance(cdefbodynode.value, astroid.Call):
|
||||
if cdefbodynode.value.func.as_string() not in ATTRIB_NAMES:
|
||||
continue
|
||||
else:
|
||||
continue
|
||||
for target in cdefbodynode.targets:
|
||||
|
||||
rhs_node = astroid.Unknown(
|
||||
lineno=cdefbodynode.lineno,
|
||||
col_offset=cdefbodynode.col_offset,
|
||||
parent=cdefbodynode,
|
||||
)
|
||||
node.locals[target.name] = [rhs_node]
|
||||
|
||||
|
||||
MANAGER.register_transform(
|
||||
astroid.ClassDef, attr_attributes_transform, is_decorated_with_attrs
|
||||
)
|
@@ -0,0 +1,822 @@
|
||||
# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2014-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
||||
# Copyright (c) 2015 Rene Zhang <rz99@cornell.edu>
|
||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid hooks for various builtins."""
|
||||
|
||||
from functools import partial
|
||||
from textwrap import dedent
|
||||
|
||||
import six
|
||||
from astroid import (
|
||||
MANAGER,
|
||||
Instance,
|
||||
UseInferenceDefault,
|
||||
AttributeInferenceError,
|
||||
inference_tip,
|
||||
InferenceError,
|
||||
NameInferenceError,
|
||||
AstroidTypeError,
|
||||
MroError,
|
||||
)
|
||||
from astroid import arguments
|
||||
from astroid.builder import AstroidBuilder
|
||||
from astroid import helpers
|
||||
from astroid import nodes
|
||||
from astroid import objects
|
||||
from astroid import scoped_nodes
|
||||
from astroid import util
|
||||
|
||||
|
||||
OBJECT_DUNDER_NEW = "object.__new__"
|
||||
|
||||
|
||||
def _extend_str(class_node, rvalue):
|
||||
"""function to extend builtin str/unicode class"""
|
||||
code = dedent(
|
||||
"""
|
||||
class whatever(object):
|
||||
def join(self, iterable):
|
||||
return {rvalue}
|
||||
def replace(self, old, new, count=None):
|
||||
return {rvalue}
|
||||
def format(self, *args, **kwargs):
|
||||
return {rvalue}
|
||||
def encode(self, encoding='ascii', errors=None):
|
||||
return ''
|
||||
def decode(self, encoding='ascii', errors=None):
|
||||
return u''
|
||||
def capitalize(self):
|
||||
return {rvalue}
|
||||
def title(self):
|
||||
return {rvalue}
|
||||
def lower(self):
|
||||
return {rvalue}
|
||||
def upper(self):
|
||||
return {rvalue}
|
||||
def swapcase(self):
|
||||
return {rvalue}
|
||||
def index(self, sub, start=None, end=None):
|
||||
return 0
|
||||
def find(self, sub, start=None, end=None):
|
||||
return 0
|
||||
def count(self, sub, start=None, end=None):
|
||||
return 0
|
||||
def strip(self, chars=None):
|
||||
return {rvalue}
|
||||
def lstrip(self, chars=None):
|
||||
return {rvalue}
|
||||
def rstrip(self, chars=None):
|
||||
return {rvalue}
|
||||
def rjust(self, width, fillchar=None):
|
||||
return {rvalue}
|
||||
def center(self, width, fillchar=None):
|
||||
return {rvalue}
|
||||
def ljust(self, width, fillchar=None):
|
||||
return {rvalue}
|
||||
"""
|
||||
)
|
||||
code = code.format(rvalue=rvalue)
|
||||
fake = AstroidBuilder(MANAGER).string_build(code)["whatever"]
|
||||
for method in fake.mymethods():
|
||||
method.parent = class_node
|
||||
method.lineno = None
|
||||
method.col_offset = None
|
||||
if "__class__" in method.locals:
|
||||
method.locals["__class__"] = [class_node]
|
||||
class_node.locals[method.name] = [method]
|
||||
method.parent = class_node
|
||||
|
||||
|
||||
def _extend_builtins(class_transforms):
|
||||
builtin_ast = MANAGER.builtins_module
|
||||
for class_name, transform in class_transforms.items():
|
||||
transform(builtin_ast[class_name])
|
||||
|
||||
|
||||
_extend_builtins(
|
||||
{
|
||||
"bytes": partial(_extend_str, rvalue="b''"),
|
||||
"str": partial(_extend_str, rvalue="''"),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _builtin_filter_predicate(node, builtin_name):
|
||||
if isinstance(node.func, nodes.Name) and node.func.name == builtin_name:
|
||||
return True
|
||||
if isinstance(node.func, nodes.Attribute):
|
||||
return (
|
||||
node.func.attrname == "fromkeys"
|
||||
and isinstance(node.func.expr, nodes.Name)
|
||||
and node.func.expr.name == "dict"
|
||||
)
|
||||
return False
|
||||
|
||||
|
||||
def register_builtin_transform(transform, builtin_name):
|
||||
"""Register a new transform function for the given *builtin_name*.
|
||||
|
||||
The transform function must accept two parameters, a node and
|
||||
an optional context.
|
||||
"""
|
||||
|
||||
def _transform_wrapper(node, context=None):
|
||||
result = transform(node, context=context)
|
||||
if result:
|
||||
if not result.parent:
|
||||
# Let the transformation function determine
|
||||
# the parent for its result. Otherwise,
|
||||
# we set it to be the node we transformed from.
|
||||
result.parent = node
|
||||
|
||||
if result.lineno is None:
|
||||
result.lineno = node.lineno
|
||||
if result.col_offset is None:
|
||||
result.col_offset = node.col_offset
|
||||
return iter([result])
|
||||
|
||||
MANAGER.register_transform(
|
||||
nodes.Call,
|
||||
inference_tip(_transform_wrapper),
|
||||
partial(_builtin_filter_predicate, builtin_name=builtin_name),
|
||||
)
|
||||
|
||||
|
||||
def _generic_inference(node, context, node_type, transform):
|
||||
args = node.args
|
||||
if not args:
|
||||
return node_type()
|
||||
if len(node.args) > 1:
|
||||
raise UseInferenceDefault()
|
||||
|
||||
arg, = args
|
||||
transformed = transform(arg)
|
||||
if not transformed:
|
||||
try:
|
||||
inferred = next(arg.infer(context=context))
|
||||
except (InferenceError, StopIteration):
|
||||
raise UseInferenceDefault()
|
||||
if inferred is util.Uninferable:
|
||||
raise UseInferenceDefault()
|
||||
transformed = transform(inferred)
|
||||
if not transformed or transformed is util.Uninferable:
|
||||
raise UseInferenceDefault()
|
||||
return transformed
|
||||
|
||||
|
||||
def _generic_transform(arg, klass, iterables, build_elts):
|
||||
if isinstance(arg, klass):
|
||||
return arg
|
||||
elif isinstance(arg, iterables):
|
||||
if not all(isinstance(elt, nodes.Const) for elt in arg.elts):
|
||||
raise UseInferenceDefault()
|
||||
elts = [elt.value for elt in arg.elts]
|
||||
elif isinstance(arg, nodes.Dict):
|
||||
if not all(isinstance(elt[0], nodes.Const) for elt in arg.items):
|
||||
raise UseInferenceDefault()
|
||||
elts = [item[0].value for item in arg.items]
|
||||
elif isinstance(arg, nodes.Const) and isinstance(
|
||||
arg.value, (six.string_types, six.binary_type)
|
||||
):
|
||||
elts = arg.value
|
||||
else:
|
||||
return
|
||||
return klass.from_constants(elts=build_elts(elts))
|
||||
|
||||
|
||||
def _infer_builtin(node, context, klass=None, iterables=None, build_elts=None):
|
||||
transform_func = partial(
|
||||
_generic_transform, klass=klass, iterables=iterables, build_elts=build_elts
|
||||
)
|
||||
|
||||
return _generic_inference(node, context, klass, transform_func)
|
||||
|
||||
|
||||
# pylint: disable=invalid-name
|
||||
infer_tuple = partial(
|
||||
_infer_builtin,
|
||||
klass=nodes.Tuple,
|
||||
iterables=(
|
||||
nodes.List,
|
||||
nodes.Set,
|
||||
objects.FrozenSet,
|
||||
objects.DictItems,
|
||||
objects.DictKeys,
|
||||
objects.DictValues,
|
||||
),
|
||||
build_elts=tuple,
|
||||
)
|
||||
|
||||
infer_list = partial(
|
||||
_infer_builtin,
|
||||
klass=nodes.List,
|
||||
iterables=(
|
||||
nodes.Tuple,
|
||||
nodes.Set,
|
||||
objects.FrozenSet,
|
||||
objects.DictItems,
|
||||
objects.DictKeys,
|
||||
objects.DictValues,
|
||||
),
|
||||
build_elts=list,
|
||||
)
|
||||
|
||||
infer_set = partial(
|
||||
_infer_builtin,
|
||||
klass=nodes.Set,
|
||||
iterables=(nodes.List, nodes.Tuple, objects.FrozenSet, objects.DictKeys),
|
||||
build_elts=set,
|
||||
)
|
||||
|
||||
infer_frozenset = partial(
|
||||
_infer_builtin,
|
||||
klass=objects.FrozenSet,
|
||||
iterables=(nodes.List, nodes.Tuple, nodes.Set, objects.FrozenSet, objects.DictKeys),
|
||||
build_elts=frozenset,
|
||||
)
|
||||
|
||||
|
||||
def _get_elts(arg, context):
|
||||
is_iterable = lambda n: isinstance(n, (nodes.List, nodes.Tuple, nodes.Set))
|
||||
try:
|
||||
inferred = next(arg.infer(context))
|
||||
except (InferenceError, NameInferenceError):
|
||||
raise UseInferenceDefault()
|
||||
if isinstance(inferred, nodes.Dict):
|
||||
items = inferred.items
|
||||
elif is_iterable(inferred):
|
||||
items = []
|
||||
for elt in inferred.elts:
|
||||
# If an item is not a pair of two items,
|
||||
# then fallback to the default inference.
|
||||
# Also, take in consideration only hashable items,
|
||||
# tuples and consts. We are choosing Names as well.
|
||||
if not is_iterable(elt):
|
||||
raise UseInferenceDefault()
|
||||
if len(elt.elts) != 2:
|
||||
raise UseInferenceDefault()
|
||||
if not isinstance(elt.elts[0], (nodes.Tuple, nodes.Const, nodes.Name)):
|
||||
raise UseInferenceDefault()
|
||||
items.append(tuple(elt.elts))
|
||||
else:
|
||||
raise UseInferenceDefault()
|
||||
return items
|
||||
|
||||
|
||||
def infer_dict(node, context=None):
|
||||
"""Try to infer a dict call to a Dict node.
|
||||
|
||||
The function treats the following cases:
|
||||
|
||||
* dict()
|
||||
* dict(mapping)
|
||||
* dict(iterable)
|
||||
* dict(iterable, **kwargs)
|
||||
* dict(mapping, **kwargs)
|
||||
* dict(**kwargs)
|
||||
|
||||
If a case can't be inferred, we'll fallback to default inference.
|
||||
"""
|
||||
call = arguments.CallSite.from_call(node)
|
||||
if call.has_invalid_arguments() or call.has_invalid_keywords():
|
||||
raise UseInferenceDefault
|
||||
|
||||
args = call.positional_arguments
|
||||
kwargs = list(call.keyword_arguments.items())
|
||||
|
||||
if not args and not kwargs:
|
||||
# dict()
|
||||
return nodes.Dict()
|
||||
elif kwargs and not args:
|
||||
# dict(a=1, b=2, c=4)
|
||||
items = [(nodes.Const(key), value) for key, value in kwargs]
|
||||
elif len(args) == 1 and kwargs:
|
||||
# dict(some_iterable, b=2, c=4)
|
||||
elts = _get_elts(args[0], context)
|
||||
keys = [(nodes.Const(key), value) for key, value in kwargs]
|
||||
items = elts + keys
|
||||
elif len(args) == 1:
|
||||
items = _get_elts(args[0], context)
|
||||
else:
|
||||
raise UseInferenceDefault()
|
||||
|
||||
value = nodes.Dict(
|
||||
col_offset=node.col_offset, lineno=node.lineno, parent=node.parent
|
||||
)
|
||||
value.postinit(items)
|
||||
return value
|
||||
|
||||
|
||||
def infer_super(node, context=None):
|
||||
"""Understand super calls.
|
||||
|
||||
There are some restrictions for what can be understood:
|
||||
|
||||
* unbounded super (one argument form) is not understood.
|
||||
|
||||
* if the super call is not inside a function (classmethod or method),
|
||||
then the default inference will be used.
|
||||
|
||||
* if the super arguments can't be inferred, the default inference
|
||||
will be used.
|
||||
"""
|
||||
if len(node.args) == 1:
|
||||
# Ignore unbounded super.
|
||||
raise UseInferenceDefault
|
||||
|
||||
scope = node.scope()
|
||||
if not isinstance(scope, nodes.FunctionDef):
|
||||
# Ignore non-method uses of super.
|
||||
raise UseInferenceDefault
|
||||
if scope.type not in ("classmethod", "method"):
|
||||
# Not interested in staticmethods.
|
||||
raise UseInferenceDefault
|
||||
|
||||
cls = scoped_nodes.get_wrapping_class(scope)
|
||||
if not len(node.args):
|
||||
mro_pointer = cls
|
||||
# In we are in a classmethod, the interpreter will fill
|
||||
# automatically the class as the second argument, not an instance.
|
||||
if scope.type == "classmethod":
|
||||
mro_type = cls
|
||||
else:
|
||||
mro_type = cls.instantiate_class()
|
||||
else:
|
||||
try:
|
||||
mro_pointer = next(node.args[0].infer(context=context))
|
||||
except InferenceError:
|
||||
raise UseInferenceDefault
|
||||
try:
|
||||
mro_type = next(node.args[1].infer(context=context))
|
||||
except InferenceError:
|
||||
raise UseInferenceDefault
|
||||
|
||||
if mro_pointer is util.Uninferable or mro_type is util.Uninferable:
|
||||
# No way we could understand this.
|
||||
raise UseInferenceDefault
|
||||
|
||||
super_obj = objects.Super(
|
||||
mro_pointer=mro_pointer, mro_type=mro_type, self_class=cls, scope=scope
|
||||
)
|
||||
super_obj.parent = node
|
||||
return super_obj
|
||||
|
||||
|
||||
def _infer_getattr_args(node, context):
|
||||
if len(node.args) not in (2, 3):
|
||||
# Not a valid getattr call.
|
||||
raise UseInferenceDefault
|
||||
|
||||
try:
|
||||
obj = next(node.args[0].infer(context=context))
|
||||
attr = next(node.args[1].infer(context=context))
|
||||
except InferenceError:
|
||||
raise UseInferenceDefault
|
||||
|
||||
if obj is util.Uninferable or attr is util.Uninferable:
|
||||
# If one of the arguments is something we can't infer,
|
||||
# then also make the result of the getattr call something
|
||||
# which is unknown.
|
||||
return util.Uninferable, util.Uninferable
|
||||
|
||||
is_string = isinstance(attr, nodes.Const) and isinstance(
|
||||
attr.value, six.string_types
|
||||
)
|
||||
if not is_string:
|
||||
raise UseInferenceDefault
|
||||
|
||||
return obj, attr.value
|
||||
|
||||
|
||||
def infer_getattr(node, context=None):
|
||||
"""Understand getattr calls
|
||||
|
||||
If one of the arguments is an Uninferable object, then the
|
||||
result will be an Uninferable object. Otherwise, the normal attribute
|
||||
lookup will be done.
|
||||
"""
|
||||
obj, attr = _infer_getattr_args(node, context)
|
||||
if (
|
||||
obj is util.Uninferable
|
||||
or attr is util.Uninferable
|
||||
or not hasattr(obj, "igetattr")
|
||||
):
|
||||
return util.Uninferable
|
||||
|
||||
try:
|
||||
return next(obj.igetattr(attr, context=context))
|
||||
except (StopIteration, InferenceError, AttributeInferenceError):
|
||||
if len(node.args) == 3:
|
||||
# Try to infer the default and return it instead.
|
||||
try:
|
||||
return next(node.args[2].infer(context=context))
|
||||
except InferenceError:
|
||||
raise UseInferenceDefault
|
||||
|
||||
raise UseInferenceDefault
|
||||
|
||||
|
||||
def infer_hasattr(node, context=None):
|
||||
"""Understand hasattr calls
|
||||
|
||||
This always guarantees three possible outcomes for calling
|
||||
hasattr: Const(False) when we are sure that the object
|
||||
doesn't have the intended attribute, Const(True) when
|
||||
we know that the object has the attribute and Uninferable
|
||||
when we are unsure of the outcome of the function call.
|
||||
"""
|
||||
try:
|
||||
obj, attr = _infer_getattr_args(node, context)
|
||||
if (
|
||||
obj is util.Uninferable
|
||||
or attr is util.Uninferable
|
||||
or not hasattr(obj, "getattr")
|
||||
):
|
||||
return util.Uninferable
|
||||
obj.getattr(attr, context=context)
|
||||
except UseInferenceDefault:
|
||||
# Can't infer something from this function call.
|
||||
return util.Uninferable
|
||||
except AttributeInferenceError:
|
||||
# Doesn't have it.
|
||||
return nodes.Const(False)
|
||||
return nodes.Const(True)
|
||||
|
||||
|
||||
def infer_callable(node, context=None):
|
||||
"""Understand callable calls
|
||||
|
||||
This follows Python's semantics, where an object
|
||||
is callable if it provides an attribute __call__,
|
||||
even though that attribute is something which can't be
|
||||
called.
|
||||
"""
|
||||
if len(node.args) != 1:
|
||||
# Invalid callable call.
|
||||
raise UseInferenceDefault
|
||||
|
||||
argument = node.args[0]
|
||||
try:
|
||||
inferred = next(argument.infer(context=context))
|
||||
except InferenceError:
|
||||
return util.Uninferable
|
||||
if inferred is util.Uninferable:
|
||||
return util.Uninferable
|
||||
return nodes.Const(inferred.callable())
|
||||
|
||||
|
||||
def infer_bool(node, context=None):
|
||||
"""Understand bool calls."""
|
||||
if len(node.args) > 1:
|
||||
# Invalid bool call.
|
||||
raise UseInferenceDefault
|
||||
|
||||
if not node.args:
|
||||
return nodes.Const(False)
|
||||
|
||||
argument = node.args[0]
|
||||
try:
|
||||
inferred = next(argument.infer(context=context))
|
||||
except InferenceError:
|
||||
return util.Uninferable
|
||||
if inferred is util.Uninferable:
|
||||
return util.Uninferable
|
||||
|
||||
bool_value = inferred.bool_value()
|
||||
if bool_value is util.Uninferable:
|
||||
return util.Uninferable
|
||||
return nodes.Const(bool_value)
|
||||
|
||||
|
||||
def infer_type(node, context=None):
|
||||
"""Understand the one-argument form of *type*."""
|
||||
if len(node.args) != 1:
|
||||
raise UseInferenceDefault
|
||||
|
||||
return helpers.object_type(node.args[0], context)
|
||||
|
||||
|
||||
def infer_slice(node, context=None):
|
||||
"""Understand `slice` calls."""
|
||||
args = node.args
|
||||
if not 0 < len(args) <= 3:
|
||||
raise UseInferenceDefault
|
||||
|
||||
infer_func = partial(helpers.safe_infer, context=context)
|
||||
args = [infer_func(arg) for arg in args]
|
||||
for arg in args:
|
||||
if not arg or arg is util.Uninferable:
|
||||
raise UseInferenceDefault
|
||||
if not isinstance(arg, nodes.Const):
|
||||
raise UseInferenceDefault
|
||||
if not isinstance(arg.value, (type(None), int)):
|
||||
raise UseInferenceDefault
|
||||
|
||||
if len(args) < 3:
|
||||
# Make sure we have 3 arguments.
|
||||
args.extend([None] * (3 - len(args)))
|
||||
|
||||
slice_node = nodes.Slice(
|
||||
lineno=node.lineno, col_offset=node.col_offset, parent=node.parent
|
||||
)
|
||||
slice_node.postinit(*args)
|
||||
return slice_node
|
||||
|
||||
|
||||
def _infer_object__new__decorator(node, context=None):
|
||||
# Instantiate class immediately
|
||||
# since that's what @object.__new__ does
|
||||
return iter((node.instantiate_class(),))
|
||||
|
||||
|
||||
def _infer_object__new__decorator_check(node):
|
||||
"""Predicate before inference_tip
|
||||
|
||||
Check if the given ClassDef has an @object.__new__ decorator
|
||||
"""
|
||||
if not node.decorators:
|
||||
return False
|
||||
|
||||
for decorator in node.decorators.nodes:
|
||||
if isinstance(decorator, nodes.Attribute):
|
||||
if decorator.as_string() == OBJECT_DUNDER_NEW:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def infer_issubclass(callnode, context=None):
|
||||
"""Infer issubclass() calls
|
||||
|
||||
:param nodes.Call callnode: an `issubclass` call
|
||||
:param InferenceContext: the context for the inference
|
||||
:rtype nodes.Const: Boolean Const value of the `issubclass` call
|
||||
:raises UseInferenceDefault: If the node cannot be inferred
|
||||
"""
|
||||
call = arguments.CallSite.from_call(callnode)
|
||||
if call.keyword_arguments:
|
||||
# issubclass doesn't support keyword arguments
|
||||
raise UseInferenceDefault("TypeError: issubclass() takes no keyword arguments")
|
||||
if len(call.positional_arguments) != 2:
|
||||
raise UseInferenceDefault(
|
||||
"Expected two arguments, got {count}".format(
|
||||
count=len(call.positional_arguments)
|
||||
)
|
||||
)
|
||||
# The left hand argument is the obj to be checked
|
||||
obj_node, class_or_tuple_node = call.positional_arguments
|
||||
|
||||
try:
|
||||
obj_type = next(obj_node.infer(context=context))
|
||||
except InferenceError as exc:
|
||||
raise UseInferenceDefault from exc
|
||||
if not isinstance(obj_type, nodes.ClassDef):
|
||||
raise UseInferenceDefault("TypeError: arg 1 must be class")
|
||||
|
||||
# The right hand argument is the class(es) that the given
|
||||
# object is to be checked against.
|
||||
try:
|
||||
class_container = _class_or_tuple_to_container(
|
||||
class_or_tuple_node, context=context
|
||||
)
|
||||
except InferenceError as exc:
|
||||
raise UseInferenceDefault from exc
|
||||
try:
|
||||
issubclass_bool = helpers.object_issubclass(obj_type, class_container, context)
|
||||
except AstroidTypeError as exc:
|
||||
raise UseInferenceDefault("TypeError: " + str(exc)) from exc
|
||||
except MroError as exc:
|
||||
raise UseInferenceDefault from exc
|
||||
return nodes.Const(issubclass_bool)
|
||||
|
||||
|
||||
def infer_isinstance(callnode, context=None):
|
||||
"""Infer isinstance calls
|
||||
|
||||
:param nodes.Call callnode: an isinstance call
|
||||
:param InferenceContext: context for call
|
||||
(currently unused but is a common interface for inference)
|
||||
:rtype nodes.Const: Boolean Const value of isinstance call
|
||||
|
||||
:raises UseInferenceDefault: If the node cannot be inferred
|
||||
"""
|
||||
call = arguments.CallSite.from_call(callnode)
|
||||
if call.keyword_arguments:
|
||||
# isinstance doesn't support keyword arguments
|
||||
raise UseInferenceDefault("TypeError: isinstance() takes no keyword arguments")
|
||||
if len(call.positional_arguments) != 2:
|
||||
raise UseInferenceDefault(
|
||||
"Expected two arguments, got {count}".format(
|
||||
count=len(call.positional_arguments)
|
||||
)
|
||||
)
|
||||
# The left hand argument is the obj to be checked
|
||||
obj_node, class_or_tuple_node = call.positional_arguments
|
||||
# The right hand argument is the class(es) that the given
|
||||
# obj is to be check is an instance of
|
||||
try:
|
||||
class_container = _class_or_tuple_to_container(
|
||||
class_or_tuple_node, context=context
|
||||
)
|
||||
except InferenceError:
|
||||
raise UseInferenceDefault
|
||||
try:
|
||||
isinstance_bool = helpers.object_isinstance(obj_node, class_container, context)
|
||||
except AstroidTypeError as exc:
|
||||
raise UseInferenceDefault("TypeError: " + str(exc))
|
||||
except MroError as exc:
|
||||
raise UseInferenceDefault from exc
|
||||
if isinstance_bool is util.Uninferable:
|
||||
raise UseInferenceDefault
|
||||
return nodes.Const(isinstance_bool)
|
||||
|
||||
|
||||
def _class_or_tuple_to_container(node, context=None):
|
||||
# Move inferences results into container
|
||||
# to simplify later logic
|
||||
# raises InferenceError if any of the inferences fall through
|
||||
node_infer = next(node.infer(context=context))
|
||||
# arg2 MUST be a type or a TUPLE of types
|
||||
# for isinstance
|
||||
if isinstance(node_infer, nodes.Tuple):
|
||||
class_container = [
|
||||
next(node.infer(context=context)) for node in node_infer.elts
|
||||
]
|
||||
class_container = [
|
||||
klass_node for klass_node in class_container if klass_node is not None
|
||||
]
|
||||
else:
|
||||
class_container = [node_infer]
|
||||
return class_container
|
||||
|
||||
|
||||
def infer_len(node, context=None):
|
||||
"""Infer length calls
|
||||
|
||||
:param nodes.Call node: len call to infer
|
||||
:param context.InferenceContext: node context
|
||||
:rtype nodes.Const: a Const node with the inferred length, if possible
|
||||
"""
|
||||
call = arguments.CallSite.from_call(node)
|
||||
if call.keyword_arguments:
|
||||
raise UseInferenceDefault("TypeError: len() must take no keyword arguments")
|
||||
if len(call.positional_arguments) != 1:
|
||||
raise UseInferenceDefault(
|
||||
"TypeError: len() must take exactly one argument "
|
||||
"({len}) given".format(len=len(call.positional_arguments))
|
||||
)
|
||||
[argument_node] = call.positional_arguments
|
||||
try:
|
||||
return nodes.Const(helpers.object_len(argument_node))
|
||||
except (AstroidTypeError, InferenceError) as exc:
|
||||
raise UseInferenceDefault(str(exc)) from exc
|
||||
|
||||
|
||||
def infer_str(node, context=None):
|
||||
"""Infer str() calls
|
||||
|
||||
:param nodes.Call node: str() call to infer
|
||||
:param context.InferenceContext: node context
|
||||
:rtype nodes.Const: a Const containing an empty string
|
||||
"""
|
||||
call = arguments.CallSite.from_call(node)
|
||||
if call.keyword_arguments:
|
||||
raise UseInferenceDefault("TypeError: str() must take no keyword arguments")
|
||||
try:
|
||||
return nodes.Const("")
|
||||
except (AstroidTypeError, InferenceError) as exc:
|
||||
raise UseInferenceDefault(str(exc)) from exc
|
||||
|
||||
|
||||
def infer_int(node, context=None):
|
||||
"""Infer int() calls
|
||||
|
||||
:param nodes.Call node: int() call to infer
|
||||
:param context.InferenceContext: node context
|
||||
:rtype nodes.Const: a Const containing the integer value of the int() call
|
||||
"""
|
||||
call = arguments.CallSite.from_call(node)
|
||||
if call.keyword_arguments:
|
||||
raise UseInferenceDefault("TypeError: int() must take no keyword arguments")
|
||||
|
||||
if call.positional_arguments:
|
||||
try:
|
||||
first_value = next(call.positional_arguments[0].infer(context=context))
|
||||
except InferenceError as exc:
|
||||
raise UseInferenceDefault(str(exc)) from exc
|
||||
|
||||
if first_value is util.Uninferable:
|
||||
raise UseInferenceDefault
|
||||
|
||||
if isinstance(first_value, nodes.Const) and isinstance(
|
||||
first_value.value, (int, str)
|
||||
):
|
||||
try:
|
||||
actual_value = int(first_value.value)
|
||||
except ValueError:
|
||||
return nodes.Const(0)
|
||||
return nodes.Const(actual_value)
|
||||
|
||||
return nodes.Const(0)
|
||||
|
||||
|
||||
def infer_dict_fromkeys(node, context=None):
|
||||
"""Infer dict.fromkeys
|
||||
|
||||
:param nodes.Call node: dict.fromkeys() call to infer
|
||||
:param context.InferenceContext: node context
|
||||
:rtype nodes.Dict:
|
||||
a Dictionary containing the values that astroid was able to infer.
|
||||
In case the inference failed for any reason, an empty dictionary
|
||||
will be inferred instead.
|
||||
"""
|
||||
|
||||
def _build_dict_with_elements(elements):
|
||||
new_node = nodes.Dict(
|
||||
col_offset=node.col_offset, lineno=node.lineno, parent=node.parent
|
||||
)
|
||||
new_node.postinit(elements)
|
||||
return new_node
|
||||
|
||||
call = arguments.CallSite.from_call(node)
|
||||
if call.keyword_arguments:
|
||||
raise UseInferenceDefault("TypeError: int() must take no keyword arguments")
|
||||
if len(call.positional_arguments) not in {1, 2}:
|
||||
raise UseInferenceDefault(
|
||||
"TypeError: Needs between 1 and 2 positional arguments"
|
||||
)
|
||||
|
||||
default = nodes.Const(None)
|
||||
values = call.positional_arguments[0]
|
||||
try:
|
||||
inferred_values = next(values.infer(context=context))
|
||||
except InferenceError:
|
||||
return _build_dict_with_elements([])
|
||||
if inferred_values is util.Uninferable:
|
||||
return _build_dict_with_elements([])
|
||||
|
||||
# Limit to a couple of potential values, as this can become pretty complicated
|
||||
accepted_iterable_elements = (nodes.Const,)
|
||||
if isinstance(inferred_values, (nodes.List, nodes.Set, nodes.Tuple)):
|
||||
elements = inferred_values.elts
|
||||
for element in elements:
|
||||
if not isinstance(element, accepted_iterable_elements):
|
||||
# Fallback to an empty dict
|
||||
return _build_dict_with_elements([])
|
||||
|
||||
elements_with_value = [(element, default) for element in elements]
|
||||
return _build_dict_with_elements(elements_with_value)
|
||||
|
||||
elif isinstance(inferred_values, nodes.Const) and isinstance(
|
||||
inferred_values.value, (str, bytes)
|
||||
):
|
||||
elements = [
|
||||
(nodes.Const(element), default) for element in inferred_values.value
|
||||
]
|
||||
return _build_dict_with_elements(elements)
|
||||
elif isinstance(inferred_values, nodes.Dict):
|
||||
keys = inferred_values.itered()
|
||||
for key in keys:
|
||||
if not isinstance(key, accepted_iterable_elements):
|
||||
# Fallback to an empty dict
|
||||
return _build_dict_with_elements([])
|
||||
|
||||
elements_with_value = [(element, default) for element in keys]
|
||||
return _build_dict_with_elements(elements_with_value)
|
||||
|
||||
# Fallback to an empty dictionary
|
||||
return _build_dict_with_elements([])
|
||||
|
||||
|
||||
# Builtins inference
|
||||
register_builtin_transform(infer_bool, "bool")
|
||||
register_builtin_transform(infer_super, "super")
|
||||
register_builtin_transform(infer_callable, "callable")
|
||||
register_builtin_transform(infer_getattr, "getattr")
|
||||
register_builtin_transform(infer_hasattr, "hasattr")
|
||||
register_builtin_transform(infer_tuple, "tuple")
|
||||
register_builtin_transform(infer_set, "set")
|
||||
register_builtin_transform(infer_list, "list")
|
||||
register_builtin_transform(infer_dict, "dict")
|
||||
register_builtin_transform(infer_frozenset, "frozenset")
|
||||
register_builtin_transform(infer_type, "type")
|
||||
register_builtin_transform(infer_slice, "slice")
|
||||
register_builtin_transform(infer_isinstance, "isinstance")
|
||||
register_builtin_transform(infer_issubclass, "issubclass")
|
||||
register_builtin_transform(infer_len, "len")
|
||||
register_builtin_transform(infer_str, "str")
|
||||
register_builtin_transform(infer_int, "int")
|
||||
register_builtin_transform(infer_dict_fromkeys, "dict.fromkeys")
|
||||
|
||||
|
||||
# Infer object.__new__ calls
|
||||
MANAGER.register_transform(
|
||||
nodes.ClassDef,
|
||||
inference_tip(_infer_object__new__decorator),
|
||||
_infer_object__new__decorator_check,
|
||||
)
|
@@ -0,0 +1,82 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2016-2017 Łukasz Rogalski <rogalski.91@gmail.com>
|
||||
# Copyright (c) 2017 Derek Gustafson <degustaf@gmail.com>
|
||||
# Copyright (c) 2018 Ioana Tagirta <ioana.tagirta@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
import sys
|
||||
|
||||
import astroid
|
||||
|
||||
PY34 = sys.version_info >= (3, 4)
|
||||
PY35 = sys.version_info >= (3, 5)
|
||||
|
||||
|
||||
def _collections_transform():
|
||||
return astroid.parse(
|
||||
"""
|
||||
class defaultdict(dict):
|
||||
default_factory = None
|
||||
def __missing__(self, key): pass
|
||||
def __getitem__(self, key): return default_factory
|
||||
|
||||
"""
|
||||
+ _deque_mock()
|
||||
+ _ordered_dict_mock()
|
||||
)
|
||||
|
||||
|
||||
def _deque_mock():
|
||||
base_deque_class = """
|
||||
class deque(object):
|
||||
maxlen = 0
|
||||
def __init__(self, iterable=None, maxlen=None):
|
||||
self.iterable = iterable or []
|
||||
def append(self, x): pass
|
||||
def appendleft(self, x): pass
|
||||
def clear(self): pass
|
||||
def count(self, x): return 0
|
||||
def extend(self, iterable): pass
|
||||
def extendleft(self, iterable): pass
|
||||
def pop(self): return self.iterable[0]
|
||||
def popleft(self): return self.iterable[0]
|
||||
def remove(self, value): pass
|
||||
def reverse(self): return reversed(self.iterable)
|
||||
def rotate(self, n=1): return self
|
||||
def __iter__(self): return self
|
||||
def __reversed__(self): return self.iterable[::-1]
|
||||
def __getitem__(self, index): return self.iterable[index]
|
||||
def __setitem__(self, index, value): pass
|
||||
def __delitem__(self, index): pass
|
||||
def __bool__(self): return bool(self.iterable)
|
||||
def __nonzero__(self): return bool(self.iterable)
|
||||
def __contains__(self, o): return o in self.iterable
|
||||
def __len__(self): return len(self.iterable)
|
||||
def __copy__(self): return deque(self.iterable)"""
|
||||
if PY35:
|
||||
base_deque_class += """
|
||||
def copy(self): return deque(self.iterable)
|
||||
def index(self, x, start=0, end=0): return 0
|
||||
def insert(self, x, i): pass
|
||||
def __add__(self, other): pass
|
||||
def __iadd__(self, other): pass
|
||||
def __mul__(self, other): pass
|
||||
def __imul__(self, other): pass
|
||||
def __rmul__(self, other): pass"""
|
||||
return base_deque_class
|
||||
|
||||
|
||||
def _ordered_dict_mock():
|
||||
base_ordered_dict_class = """
|
||||
class OrderedDict(dict):
|
||||
def __reversed__(self): return self[::-1]
|
||||
"""
|
||||
if PY34:
|
||||
base_ordered_dict_class += """
|
||||
def move_to_end(self, key, last=False): pass"""
|
||||
return base_ordered_dict_class
|
||||
|
||||
|
||||
astroid.register_module_extender(astroid.MANAGER, "collections", _collections_transform)
|
179
venv/lib/python3.6/site-packages/astroid/brain/brain_curses.py
Normal file
179
venv/lib/python3.6/site-packages/astroid/brain/brain_curses.py
Normal file
@@ -0,0 +1,179 @@
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
import astroid
|
||||
|
||||
|
||||
def _curses_transform():
|
||||
return astroid.parse(
|
||||
"""
|
||||
A_ALTCHARSET = 1
|
||||
A_BLINK = 1
|
||||
A_BOLD = 1
|
||||
A_DIM = 1
|
||||
A_INVIS = 1
|
||||
A_ITALIC = 1
|
||||
A_NORMAL = 1
|
||||
A_PROTECT = 1
|
||||
A_REVERSE = 1
|
||||
A_STANDOUT = 1
|
||||
A_UNDERLINE = 1
|
||||
A_HORIZONTAL = 1
|
||||
A_LEFT = 1
|
||||
A_LOW = 1
|
||||
A_RIGHT = 1
|
||||
A_TOP = 1
|
||||
A_VERTICAL = 1
|
||||
A_CHARTEXT = 1
|
||||
A_ATTRIBUTES = 1
|
||||
A_CHARTEXT = 1
|
||||
A_COLOR = 1
|
||||
KEY_MIN = 1
|
||||
KEY_BREAK = 1
|
||||
KEY_DOWN = 1
|
||||
KEY_UP = 1
|
||||
KEY_LEFT = 1
|
||||
KEY_RIGHT = 1
|
||||
KEY_HOME = 1
|
||||
KEY_BACKSPACE = 1
|
||||
KEY_F0 = 1
|
||||
KEY_Fn = 1
|
||||
KEY_DL = 1
|
||||
KEY_IL = 1
|
||||
KEY_DC = 1
|
||||
KEY_IC = 1
|
||||
KEY_EIC = 1
|
||||
KEY_CLEAR = 1
|
||||
KEY_EOS = 1
|
||||
KEY_EOL = 1
|
||||
KEY_SF = 1
|
||||
KEY_SR = 1
|
||||
KEY_NPAGE = 1
|
||||
KEY_PPAGE = 1
|
||||
KEY_STAB = 1
|
||||
KEY_CTAB = 1
|
||||
KEY_CATAB = 1
|
||||
KEY_ENTER = 1
|
||||
KEY_SRESET = 1
|
||||
KEY_RESET = 1
|
||||
KEY_PRINT = 1
|
||||
KEY_LL = 1
|
||||
KEY_A1 = 1
|
||||
KEY_A3 = 1
|
||||
KEY_B2 = 1
|
||||
KEY_C1 = 1
|
||||
KEY_C3 = 1
|
||||
KEY_BTAB = 1
|
||||
KEY_BEG = 1
|
||||
KEY_CANCEL = 1
|
||||
KEY_CLOSE = 1
|
||||
KEY_COMMAND = 1
|
||||
KEY_COPY = 1
|
||||
KEY_CREATE = 1
|
||||
KEY_END = 1
|
||||
KEY_EXIT = 1
|
||||
KEY_FIND = 1
|
||||
KEY_HELP = 1
|
||||
KEY_MARK = 1
|
||||
KEY_MESSAGE = 1
|
||||
KEY_MOVE = 1
|
||||
KEY_NEXT = 1
|
||||
KEY_OPEN = 1
|
||||
KEY_OPTIONS = 1
|
||||
KEY_PREVIOUS = 1
|
||||
KEY_REDO = 1
|
||||
KEY_REFERENCE = 1
|
||||
KEY_REFRESH = 1
|
||||
KEY_REPLACE = 1
|
||||
KEY_RESTART = 1
|
||||
KEY_RESUME = 1
|
||||
KEY_SAVE = 1
|
||||
KEY_SBEG = 1
|
||||
KEY_SCANCEL = 1
|
||||
KEY_SCOMMAND = 1
|
||||
KEY_SCOPY = 1
|
||||
KEY_SCREATE = 1
|
||||
KEY_SDC = 1
|
||||
KEY_SDL = 1
|
||||
KEY_SELECT = 1
|
||||
KEY_SEND = 1
|
||||
KEY_SEOL = 1
|
||||
KEY_SEXIT = 1
|
||||
KEY_SFIND = 1
|
||||
KEY_SHELP = 1
|
||||
KEY_SHOME = 1
|
||||
KEY_SIC = 1
|
||||
KEY_SLEFT = 1
|
||||
KEY_SMESSAGE = 1
|
||||
KEY_SMOVE = 1
|
||||
KEY_SNEXT = 1
|
||||
KEY_SOPTIONS = 1
|
||||
KEY_SPREVIOUS = 1
|
||||
KEY_SPRINT = 1
|
||||
KEY_SREDO = 1
|
||||
KEY_SREPLACE = 1
|
||||
KEY_SRIGHT = 1
|
||||
KEY_SRSUME = 1
|
||||
KEY_SSAVE = 1
|
||||
KEY_SSUSPEND = 1
|
||||
KEY_SUNDO = 1
|
||||
KEY_SUSPEND = 1
|
||||
KEY_UNDO = 1
|
||||
KEY_MOUSE = 1
|
||||
KEY_RESIZE = 1
|
||||
KEY_MAX = 1
|
||||
ACS_BBSS = 1
|
||||
ACS_BLOCK = 1
|
||||
ACS_BOARD = 1
|
||||
ACS_BSBS = 1
|
||||
ACS_BSSB = 1
|
||||
ACS_BSSS = 1
|
||||
ACS_BTEE = 1
|
||||
ACS_BULLET = 1
|
||||
ACS_CKBOARD = 1
|
||||
ACS_DARROW = 1
|
||||
ACS_DEGREE = 1
|
||||
ACS_DIAMOND = 1
|
||||
ACS_GEQUAL = 1
|
||||
ACS_HLINE = 1
|
||||
ACS_LANTERN = 1
|
||||
ACS_LARROW = 1
|
||||
ACS_LEQUAL = 1
|
||||
ACS_LLCORNER = 1
|
||||
ACS_LRCORNER = 1
|
||||
ACS_LTEE = 1
|
||||
ACS_NEQUAL = 1
|
||||
ACS_PI = 1
|
||||
ACS_PLMINUS = 1
|
||||
ACS_PLUS = 1
|
||||
ACS_RARROW = 1
|
||||
ACS_RTEE = 1
|
||||
ACS_S1 = 1
|
||||
ACS_S3 = 1
|
||||
ACS_S7 = 1
|
||||
ACS_S9 = 1
|
||||
ACS_SBBS = 1
|
||||
ACS_SBSB = 1
|
||||
ACS_SBSS = 1
|
||||
ACS_SSBB = 1
|
||||
ACS_SSBS = 1
|
||||
ACS_SSSB = 1
|
||||
ACS_SSSS = 1
|
||||
ACS_STERLING = 1
|
||||
ACS_TTEE = 1
|
||||
ACS_UARROW = 1
|
||||
ACS_ULCORNER = 1
|
||||
ACS_URCORNER = 1
|
||||
ACS_VLINE = 1
|
||||
COLOR_BLACK = 1
|
||||
COLOR_BLUE = 1
|
||||
COLOR_CYAN = 1
|
||||
COLOR_GREEN = 1
|
||||
COLOR_MAGENTA = 1
|
||||
COLOR_RED = 1
|
||||
COLOR_WHITE = 1
|
||||
COLOR_YELLOW = 1
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
astroid.register_module_extender(astroid.MANAGER, "curses", _curses_transform)
|
@@ -0,0 +1,28 @@
|
||||
# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2015 raylu <lurayl@gmail.com>
|
||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid hooks for dateutil"""
|
||||
|
||||
import textwrap
|
||||
|
||||
from astroid import MANAGER, register_module_extender
|
||||
from astroid.builder import AstroidBuilder
|
||||
|
||||
|
||||
def dateutil_transform():
|
||||
return AstroidBuilder(MANAGER).string_build(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
import datetime
|
||||
def parse(timestr, parserinfo=None, **kwargs):
|
||||
return datetime.datetime()
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
register_module_extender(MANAGER, "dateutil.parser", dateutil_transform)
|
@@ -0,0 +1,51 @@
|
||||
# Copyright (c) 2017 Claudiu Popa <pcmanticore@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
import collections
|
||||
import sys
|
||||
|
||||
import astroid
|
||||
|
||||
|
||||
def _clone_node_with_lineno(node, parent, lineno):
|
||||
cls = node.__class__
|
||||
other_fields = node._other_fields
|
||||
_astroid_fields = node._astroid_fields
|
||||
init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent}
|
||||
postinit_params = {param: getattr(node, param) for param in _astroid_fields}
|
||||
if other_fields:
|
||||
init_params.update({param: getattr(node, param) for param in other_fields})
|
||||
new_node = cls(**init_params)
|
||||
if hasattr(node, "postinit") and _astroid_fields:
|
||||
for param, child in postinit_params.items():
|
||||
if child and not isinstance(child, collections.Sequence):
|
||||
cloned_child = _clone_node_with_lineno(
|
||||
node=child, lineno=new_node.lineno, parent=new_node
|
||||
)
|
||||
postinit_params[param] = cloned_child
|
||||
new_node.postinit(**postinit_params)
|
||||
return new_node
|
||||
|
||||
|
||||
def _transform_formatted_value(node):
|
||||
if node.value and node.value.lineno == 1:
|
||||
if node.lineno != node.value.lineno:
|
||||
new_node = astroid.FormattedValue(
|
||||
lineno=node.lineno, col_offset=node.col_offset, parent=node.parent
|
||||
)
|
||||
new_value = _clone_node_with_lineno(
|
||||
node=node.value, lineno=node.lineno, parent=new_node
|
||||
)
|
||||
new_node.postinit(value=new_value, format_spec=node.format_spec)
|
||||
return new_node
|
||||
|
||||
|
||||
if sys.version_info[:2] >= (3, 6):
|
||||
# TODO: this fix tries to *patch* http://bugs.python.org/issue29051
|
||||
# The problem is that FormattedValue.value, which is a Name node,
|
||||
# has wrong line numbers, usually 1. This creates problems for pylint,
|
||||
# which expects correct line numbers for things such as message control.
|
||||
astroid.MANAGER.register_transform(
|
||||
astroid.FormattedValue, _transform_formatted_value
|
||||
)
|
@@ -0,0 +1,157 @@
|
||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
||||
|
||||
"""Astroid hooks for understanding functools library module."""
|
||||
from functools import partial
|
||||
from itertools import chain
|
||||
|
||||
import astroid
|
||||
from astroid import arguments
|
||||
from astroid import BoundMethod
|
||||
from astroid import extract_node
|
||||
from astroid import helpers
|
||||
from astroid.interpreter import objectmodel
|
||||
from astroid import MANAGER
|
||||
from astroid import objects
|
||||
|
||||
|
||||
LRU_CACHE = "functools.lru_cache"
|
||||
|
||||
|
||||
class LruWrappedModel(objectmodel.FunctionModel):
|
||||
"""Special attribute model for functions decorated with functools.lru_cache.
|
||||
|
||||
The said decorators patches at decoration time some functions onto
|
||||
the decorated function.
|
||||
"""
|
||||
|
||||
@property
|
||||
def attr___wrapped__(self):
|
||||
return self._instance
|
||||
|
||||
@property
|
||||
def attr_cache_info(self):
|
||||
cache_info = extract_node(
|
||||
"""
|
||||
from functools import _CacheInfo
|
||||
_CacheInfo(0, 0, 0, 0)
|
||||
"""
|
||||
)
|
||||
|
||||
class CacheInfoBoundMethod(BoundMethod):
|
||||
def infer_call_result(self, caller, context=None):
|
||||
yield helpers.safe_infer(cache_info)
|
||||
|
||||
return CacheInfoBoundMethod(proxy=self._instance, bound=self._instance)
|
||||
|
||||
@property
|
||||
def attr_cache_clear(self):
|
||||
node = extract_node("""def cache_clear(self): pass""")
|
||||
return BoundMethod(proxy=node, bound=self._instance.parent.scope())
|
||||
|
||||
|
||||
def _transform_lru_cache(node, context=None):
|
||||
# TODO: this is not ideal, since the node should be immutable,
|
||||
# but due to https://github.com/PyCQA/astroid/issues/354,
|
||||
# there's not much we can do now.
|
||||
# Replacing the node would work partially, because,
|
||||
# in pylint, the old node would still be available, leading
|
||||
# to spurious false positives.
|
||||
node.special_attributes = LruWrappedModel()(node)
|
||||
return
|
||||
|
||||
|
||||
def _functools_partial_inference(node, context=None):
|
||||
call = arguments.CallSite.from_call(node)
|
||||
number_of_positional = len(call.positional_arguments)
|
||||
if number_of_positional < 1:
|
||||
raise astroid.UseInferenceDefault(
|
||||
"functools.partial takes at least one argument"
|
||||
)
|
||||
if number_of_positional == 1 and not call.keyword_arguments:
|
||||
raise astroid.UseInferenceDefault(
|
||||
"functools.partial needs at least to have some filled arguments"
|
||||
)
|
||||
|
||||
partial_function = call.positional_arguments[0]
|
||||
try:
|
||||
inferred_wrapped_function = next(partial_function.infer(context=context))
|
||||
except astroid.InferenceError as exc:
|
||||
raise astroid.UseInferenceDefault from exc
|
||||
if inferred_wrapped_function is astroid.Uninferable:
|
||||
raise astroid.UseInferenceDefault("Cannot infer the wrapped function")
|
||||
if not isinstance(inferred_wrapped_function, astroid.FunctionDef):
|
||||
raise astroid.UseInferenceDefault("The wrapped function is not a function")
|
||||
|
||||
# Determine if the passed keywords into the callsite are supported
|
||||
# by the wrapped function.
|
||||
function_parameters = chain(
|
||||
inferred_wrapped_function.args.args or (),
|
||||
inferred_wrapped_function.args.kwonlyargs or (),
|
||||
)
|
||||
parameter_names = set(
|
||||
param.name
|
||||
for param in function_parameters
|
||||
if isinstance(param, astroid.AssignName)
|
||||
)
|
||||
if set(call.keyword_arguments) - parameter_names:
|
||||
raise astroid.UseInferenceDefault(
|
||||
"wrapped function received unknown parameters"
|
||||
)
|
||||
|
||||
partial_function = objects.PartialFunction(
|
||||
call,
|
||||
name=inferred_wrapped_function.name,
|
||||
doc=inferred_wrapped_function.doc,
|
||||
lineno=inferred_wrapped_function.lineno,
|
||||
col_offset=inferred_wrapped_function.col_offset,
|
||||
parent=inferred_wrapped_function.parent,
|
||||
)
|
||||
partial_function.postinit(
|
||||
args=inferred_wrapped_function.args,
|
||||
body=inferred_wrapped_function.body,
|
||||
decorators=inferred_wrapped_function.decorators,
|
||||
returns=inferred_wrapped_function.returns,
|
||||
type_comment_returns=inferred_wrapped_function.type_comment_returns,
|
||||
type_comment_args=inferred_wrapped_function.type_comment_args,
|
||||
)
|
||||
return iter((partial_function,))
|
||||
|
||||
|
||||
def _looks_like_lru_cache(node):
|
||||
"""Check if the given function node is decorated with lru_cache."""
|
||||
if not node.decorators:
|
||||
return False
|
||||
for decorator in node.decorators.nodes:
|
||||
if not isinstance(decorator, astroid.Call):
|
||||
continue
|
||||
if _looks_like_functools_member(decorator, "lru_cache"):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _looks_like_functools_member(node, member):
|
||||
"""Check if the given Call node is a functools.partial call"""
|
||||
if isinstance(node.func, astroid.Name):
|
||||
return node.func.name == member
|
||||
elif isinstance(node.func, astroid.Attribute):
|
||||
return (
|
||||
node.func.attrname == member
|
||||
and isinstance(node.func.expr, astroid.Name)
|
||||
and node.func.expr.name == "functools"
|
||||
)
|
||||
|
||||
|
||||
_looks_like_partial = partial(_looks_like_functools_member, member="partial")
|
||||
|
||||
|
||||
MANAGER.register_transform(
|
||||
astroid.FunctionDef, _transform_lru_cache, _looks_like_lru_cache
|
||||
)
|
||||
|
||||
|
||||
MANAGER.register_transform(
|
||||
astroid.Call,
|
||||
astroid.inference_tip(_functools_partial_inference),
|
||||
_looks_like_partial,
|
||||
)
|
220
venv/lib/python3.6/site-packages/astroid/brain/brain_gi.py
Normal file
220
venv/lib/python3.6/site-packages/astroid/brain/brain_gi.py
Normal file
@@ -0,0 +1,220 @@
|
||||
# Copyright (c) 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
||||
# Copyright (c) 2014 Google, Inc.
|
||||
# Copyright (c) 2014 Cole Robinson <crobinso@redhat.com>
|
||||
# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
||||
# Copyright (c) 2015 David Shea <dshea@redhat.com>
|
||||
# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net>
|
||||
# Copyright (c) 2016 Giuseppe Scrivano <gscrivan@redhat.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid hooks for the Python 2 GObject introspection bindings.
|
||||
|
||||
Helps with understanding everything imported from 'gi.repository'
|
||||
"""
|
||||
|
||||
import inspect
|
||||
import itertools
|
||||
import sys
|
||||
import re
|
||||
import warnings
|
||||
|
||||
from astroid import MANAGER, AstroidBuildingError, nodes
|
||||
from astroid.builder import AstroidBuilder
|
||||
|
||||
|
||||
_inspected_modules = {}
|
||||
|
||||
_identifier_re = r"^[A-Za-z_]\w*$"
|
||||
|
||||
|
||||
def _gi_build_stub(parent):
|
||||
"""
|
||||
Inspect the passed module recursively and build stubs for functions,
|
||||
classes, etc.
|
||||
"""
|
||||
classes = {}
|
||||
functions = {}
|
||||
constants = {}
|
||||
methods = {}
|
||||
for name in dir(parent):
|
||||
if name.startswith("__"):
|
||||
continue
|
||||
|
||||
# Check if this is a valid name in python
|
||||
if not re.match(_identifier_re, name):
|
||||
continue
|
||||
|
||||
try:
|
||||
obj = getattr(parent, name)
|
||||
except:
|
||||
continue
|
||||
|
||||
if inspect.isclass(obj):
|
||||
classes[name] = obj
|
||||
elif inspect.isfunction(obj) or inspect.isbuiltin(obj):
|
||||
functions[name] = obj
|
||||
elif inspect.ismethod(obj) or inspect.ismethoddescriptor(obj):
|
||||
methods[name] = obj
|
||||
elif (
|
||||
str(obj).startswith("<flags")
|
||||
or str(obj).startswith("<enum ")
|
||||
or str(obj).startswith("<GType ")
|
||||
or inspect.isdatadescriptor(obj)
|
||||
):
|
||||
constants[name] = 0
|
||||
elif isinstance(obj, (int, str)):
|
||||
constants[name] = obj
|
||||
elif callable(obj):
|
||||
# Fall back to a function for anything callable
|
||||
functions[name] = obj
|
||||
else:
|
||||
# Assume everything else is some manner of constant
|
||||
constants[name] = 0
|
||||
|
||||
ret = ""
|
||||
|
||||
if constants:
|
||||
ret += "# %s constants\n\n" % parent.__name__
|
||||
for name in sorted(constants):
|
||||
if name[0].isdigit():
|
||||
# GDK has some busted constant names like
|
||||
# Gdk.EventType.2BUTTON_PRESS
|
||||
continue
|
||||
|
||||
val = constants[name]
|
||||
|
||||
strval = str(val)
|
||||
if isinstance(val, str):
|
||||
strval = '"%s"' % str(val).replace("\\", "\\\\")
|
||||
ret += "%s = %s\n" % (name, strval)
|
||||
|
||||
if ret:
|
||||
ret += "\n\n"
|
||||
if functions:
|
||||
ret += "# %s functions\n\n" % parent.__name__
|
||||
for name in sorted(functions):
|
||||
ret += "def %s(*args, **kwargs):\n" % name
|
||||
ret += " pass\n"
|
||||
|
||||
if ret:
|
||||
ret += "\n\n"
|
||||
if methods:
|
||||
ret += "# %s methods\n\n" % parent.__name__
|
||||
for name in sorted(methods):
|
||||
ret += "def %s(self, *args, **kwargs):\n" % name
|
||||
ret += " pass\n"
|
||||
|
||||
if ret:
|
||||
ret += "\n\n"
|
||||
if classes:
|
||||
ret += "# %s classes\n\n" % parent.__name__
|
||||
for name, obj in sorted(classes.items()):
|
||||
base = "object"
|
||||
if issubclass(obj, Exception):
|
||||
base = "Exception"
|
||||
ret += "class %s(%s):\n" % (name, base)
|
||||
|
||||
classret = _gi_build_stub(obj)
|
||||
if not classret:
|
||||
classret = "pass\n"
|
||||
|
||||
for line in classret.splitlines():
|
||||
ret += " " + line + "\n"
|
||||
ret += "\n"
|
||||
|
||||
return ret
|
||||
|
||||
|
||||
def _import_gi_module(modname):
|
||||
# we only consider gi.repository submodules
|
||||
if not modname.startswith("gi.repository."):
|
||||
raise AstroidBuildingError(modname=modname)
|
||||
# build astroid representation unless we already tried so
|
||||
if modname not in _inspected_modules:
|
||||
modnames = [modname]
|
||||
optional_modnames = []
|
||||
|
||||
# GLib and GObject may have some special case handling
|
||||
# in pygobject that we need to cope with. However at
|
||||
# least as of pygobject3-3.13.91 the _glib module doesn't
|
||||
# exist anymore, so if treat these modules as optional.
|
||||
if modname == "gi.repository.GLib":
|
||||
optional_modnames.append("gi._glib")
|
||||
elif modname == "gi.repository.GObject":
|
||||
optional_modnames.append("gi._gobject")
|
||||
|
||||
try:
|
||||
modcode = ""
|
||||
for m in itertools.chain(modnames, optional_modnames):
|
||||
try:
|
||||
with warnings.catch_warnings():
|
||||
# Just inspecting the code can raise gi deprecation
|
||||
# warnings, so ignore them.
|
||||
try:
|
||||
from gi import PyGIDeprecationWarning, PyGIWarning
|
||||
|
||||
warnings.simplefilter("ignore", PyGIDeprecationWarning)
|
||||
warnings.simplefilter("ignore", PyGIWarning)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
__import__(m)
|
||||
modcode += _gi_build_stub(sys.modules[m])
|
||||
except ImportError:
|
||||
if m not in optional_modnames:
|
||||
raise
|
||||
except ImportError:
|
||||
astng = _inspected_modules[modname] = None
|
||||
else:
|
||||
astng = AstroidBuilder(MANAGER).string_build(modcode, modname)
|
||||
_inspected_modules[modname] = astng
|
||||
else:
|
||||
astng = _inspected_modules[modname]
|
||||
if astng is None:
|
||||
raise AstroidBuildingError(modname=modname)
|
||||
return astng
|
||||
|
||||
|
||||
def _looks_like_require_version(node):
|
||||
# Return whether this looks like a call to gi.require_version(<name>, <version>)
|
||||
# Only accept function calls with two constant arguments
|
||||
if len(node.args) != 2:
|
||||
return False
|
||||
|
||||
if not all(isinstance(arg, nodes.Const) for arg in node.args):
|
||||
return False
|
||||
|
||||
func = node.func
|
||||
if isinstance(func, nodes.Attribute):
|
||||
if func.attrname != "require_version":
|
||||
return False
|
||||
if isinstance(func.expr, nodes.Name) and func.expr.name == "gi":
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
if isinstance(func, nodes.Name):
|
||||
return func.name == "require_version"
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def _register_require_version(node):
|
||||
# Load the gi.require_version locally
|
||||
try:
|
||||
import gi
|
||||
|
||||
gi.require_version(node.args[0].value, node.args[1].value)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return node
|
||||
|
||||
|
||||
MANAGER.register_failed_import_hook(_import_gi_module)
|
||||
MANAGER.register_transform(
|
||||
nodes.Call, _register_require_version, _looks_like_require_version
|
||||
)
|
@@ -0,0 +1,67 @@
|
||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2018 Ioana Tagirta <ioana.tagirta@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
import sys
|
||||
|
||||
import six
|
||||
|
||||
import astroid
|
||||
|
||||
PY36 = sys.version_info >= (3, 6)
|
||||
|
||||
|
||||
def _hashlib_transform():
|
||||
signature = "value=''"
|
||||
template = """
|
||||
class %(name)s(object):
|
||||
def __init__(self, %(signature)s): pass
|
||||
def digest(self):
|
||||
return %(digest)s
|
||||
def copy(self):
|
||||
return self
|
||||
def update(self, value): pass
|
||||
def hexdigest(self):
|
||||
return ''
|
||||
@property
|
||||
def name(self):
|
||||
return %(name)r
|
||||
@property
|
||||
def block_size(self):
|
||||
return 1
|
||||
@property
|
||||
def digest_size(self):
|
||||
return 1
|
||||
"""
|
||||
algorithms_with_signature = dict.fromkeys(
|
||||
["md5", "sha1", "sha224", "sha256", "sha384", "sha512"], signature
|
||||
)
|
||||
if PY36:
|
||||
blake2b_signature = "data=b'', *, digest_size=64, key=b'', salt=b'', \
|
||||
person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \
|
||||
node_depth=0, inner_size=0, last_node=False"
|
||||
blake2s_signature = "data=b'', *, digest_size=32, key=b'', salt=b'', \
|
||||
person=b'', fanout=1, depth=1, leaf_size=0, node_offset=0, \
|
||||
node_depth=0, inner_size=0, last_node=False"
|
||||
new_algorithms = dict.fromkeys(
|
||||
["sha3_224", "sha3_256", "sha3_384", "sha3_512", "shake_128", "shake_256"],
|
||||
signature,
|
||||
)
|
||||
algorithms_with_signature.update(new_algorithms)
|
||||
algorithms_with_signature.update(
|
||||
{"blake2b": blake2b_signature, "blake2s": blake2s_signature}
|
||||
)
|
||||
classes = "".join(
|
||||
template
|
||||
% {
|
||||
"name": hashfunc,
|
||||
"digest": 'b""' if six.PY3 else '""',
|
||||
"signature": signature,
|
||||
}
|
||||
for hashfunc, signature in algorithms_with_signature.items()
|
||||
)
|
||||
return astroid.parse(classes)
|
||||
|
||||
|
||||
astroid.register_module_extender(astroid.MANAGER, "hashlib", _hashlib_transform)
|
81
venv/lib/python3.6/site-packages/astroid/brain/brain_http.py
Normal file
81
venv/lib/python3.6/site-packages/astroid/brain/brain_http.py
Normal file
@@ -0,0 +1,81 @@
|
||||
# Copyright (c) 2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid brain hints for some of the `http` module."""
|
||||
import textwrap
|
||||
|
||||
import astroid
|
||||
from astroid.builder import AstroidBuilder
|
||||
|
||||
|
||||
def _http_transform():
|
||||
return AstroidBuilder(astroid.MANAGER).string_build(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
from http import HTTPStatus
|
||||
|
||||
CONTINUE = HTTPStatus.CONTINUE
|
||||
SWITCHING_PROTOCOLS = HTTPStatus.SWITCHING_PROTOCOLS
|
||||
PROCESSING = HTTPStatus.PROCESSING
|
||||
OK = HTTPStatus.OK
|
||||
CREATED = HTTPStatus.CREATED
|
||||
ACCEPTED = HTTPStatus.ACCEPTED
|
||||
NON_AUTHORITATIVE_INFORMATION = HTTPStatus.NON_AUTHORITATIVE_INFORMATION
|
||||
NO_CONTENT = HTTPStatus.NO_CONTENT
|
||||
RESET_CONTENT = HTTPStatus.RESET_CONTENT
|
||||
PARTIAL_CONTENT = HTTPStatus.PARTIAL_CONTENT
|
||||
MULTI_STATUS = HTTPStatus.MULTI_STATUS
|
||||
ALREADY_REPORTED = HTTPStatus.ALREADY_REPORTED
|
||||
IM_USED = HTTPStatus.IM_USED
|
||||
MULTIPLE_CHOICES = HTTPStatus.MULTIPLE_CHOICES
|
||||
MOVED_PERMANENTLY = HTTPStatus.MOVED_PERMANENTLY
|
||||
FOUND = HTTPStatus.FOUND
|
||||
SEE_OTHER = HTTPStatus.SEE_OTHER
|
||||
NOT_MODIFIED = HTTPStatus.NOT_MODIFIED
|
||||
USE_PROXY = HTTPStatus.USE_PROXY
|
||||
TEMPORARY_REDIRECT = HTTPStatus.TEMPORARY_REDIRECT
|
||||
PERMANENT_REDIRECT = HTTPStatus.PERMANENT_REDIRECT
|
||||
BAD_REQUEST = HTTPStatus.BAD_REQUEST
|
||||
UNAUTHORIZED = HTTPStatus.UNAUTHORIZED
|
||||
PAYMENT_REQUIRED = HTTPStatus.PAYMENT_REQUIRED
|
||||
FORBIDDEN = HTTPStatus.FORBIDDEN
|
||||
NOT_FOUND = HTTPStatus.NOT_FOUND
|
||||
METHOD_NOT_ALLOWED = HTTPStatus.METHOD_NOT_ALLOWED
|
||||
NOT_ACCEPTABLE = HTTPStatus.NOT_ACCEPTABLE
|
||||
PROXY_AUTHENTICATION_REQUIRED = HTTPStatus.PROXY_AUTHENTICATION_REQUIRED
|
||||
REQUEST_TIMEOUT = HTTPStatus.REQUEST_TIMEOUT
|
||||
CONFLICT = HTTPStatus.CONFLICT
|
||||
GONE = HTTPStatus.GONE
|
||||
LENGTH_REQUIRED = HTTPStatus.LENGTH_REQUIRED
|
||||
PRECONDITION_FAILED = HTTPStatus.PRECONDITION_FAILED
|
||||
REQUEST_ENTITY_TOO_LARGE = HTTPStatus.REQUEST_ENTITY_TOO_LARGE
|
||||
REQUEST_URI_TOO_LONG = HTTPStatus.REQUEST_URI_TOO_LONG
|
||||
UNSUPPORTED_MEDIA_TYPE = HTTPStatus.UNSUPPORTED_MEDIA_TYPE
|
||||
REQUESTED_RANGE_NOT_SATISFIABLE = HTTPStatus.REQUESTED_RANGE_NOT_SATISFIABLE
|
||||
EXPECTATION_FAILED = HTTPStatus.EXPECTATION_FAILED
|
||||
UNPROCESSABLE_ENTITY = HTTPStatus.UNPROCESSABLE_ENTITY
|
||||
LOCKED = HTTPStatus.LOCKED
|
||||
FAILED_DEPENDENCY = HTTPStatus.FAILED_DEPENDENCY
|
||||
UPGRADE_REQUIRED = HTTPStatus.UPGRADE_REQUIRED
|
||||
PRECONDITION_REQUIRED = HTTPStatus.PRECONDITION_REQUIRED
|
||||
TOO_MANY_REQUESTS = HTTPStatus.TOO_MANY_REQUESTS
|
||||
REQUEST_HEADER_FIELDS_TOO_LARGE = HTTPStatus.REQUEST_HEADER_FIELDS_TOO_LARGE
|
||||
INTERNAL_SERVER_ERROR = HTTPStatus.INTERNAL_SERVER_ERROR
|
||||
NOT_IMPLEMENTED = HTTPStatus.NOT_IMPLEMENTED
|
||||
BAD_GATEWAY = HTTPStatus.BAD_GATEWAY
|
||||
SERVICE_UNAVAILABLE = HTTPStatus.SERVICE_UNAVAILABLE
|
||||
GATEWAY_TIMEOUT = HTTPStatus.GATEWAY_TIMEOUT
|
||||
HTTP_VERSION_NOT_SUPPORTED = HTTPStatus.HTTP_VERSION_NOT_SUPPORTED
|
||||
VARIANT_ALSO_NEGOTIATES = HTTPStatus.VARIANT_ALSO_NEGOTIATES
|
||||
INSUFFICIENT_STORAGE = HTTPStatus.INSUFFICIENT_STORAGE
|
||||
LOOP_DETECTED = HTTPStatus.LOOP_DETECTED
|
||||
NOT_EXTENDED = HTTPStatus.NOT_EXTENDED
|
||||
NETWORK_AUTHENTICATION_REQUIRED = HTTPStatus.NETWORK_AUTHENTICATION_REQUIRED
|
||||
"""
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
astroid.register_module_extender(astroid.MANAGER, "http.client", _http_transform)
|
45
venv/lib/python3.6/site-packages/astroid/brain/brain_io.py
Normal file
45
venv/lib/python3.6/site-packages/astroid/brain/brain_io.py
Normal file
@@ -0,0 +1,45 @@
|
||||
# Copyright (c) 2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid brain hints for some of the _io C objects."""
|
||||
|
||||
import astroid
|
||||
|
||||
|
||||
BUFFERED = {"BufferedWriter", "BufferedReader"}
|
||||
TextIOWrapper = "TextIOWrapper"
|
||||
FileIO = "FileIO"
|
||||
BufferedWriter = "BufferedWriter"
|
||||
|
||||
|
||||
def _generic_io_transform(node, name, cls):
|
||||
"""Transform the given name, by adding the given *class* as a member of the node."""
|
||||
|
||||
io_module = astroid.MANAGER.ast_from_module_name("_io")
|
||||
attribute_object = io_module[cls]
|
||||
instance = attribute_object.instantiate_class()
|
||||
node.locals[name] = [instance]
|
||||
|
||||
|
||||
def _transform_text_io_wrapper(node):
|
||||
# This is not always correct, since it can vary with the type of the descriptor,
|
||||
# being stdout, stderr or stdin. But we cannot get access to the name of the
|
||||
# stream, which is why we are using the BufferedWriter class as a default
|
||||
# value
|
||||
return _generic_io_transform(node, name="buffer", cls=BufferedWriter)
|
||||
|
||||
|
||||
def _transform_buffered(node):
|
||||
return _generic_io_transform(node, name="raw", cls=FileIO)
|
||||
|
||||
|
||||
astroid.MANAGER.register_transform(
|
||||
astroid.ClassDef, _transform_buffered, lambda node: node.name in BUFFERED
|
||||
)
|
||||
astroid.MANAGER.register_transform(
|
||||
astroid.ClassDef,
|
||||
_transform_text_io_wrapper,
|
||||
lambda node: node.name == TextIOWrapper,
|
||||
)
|
@@ -0,0 +1,29 @@
|
||||
# Copyright (c) 2012-2013 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
||||
# Copyright (c) 2014 Google, Inc.
|
||||
# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
from astroid import MANAGER, register_module_extender
|
||||
from astroid.builder import AstroidBuilder
|
||||
|
||||
|
||||
def mechanize_transform():
|
||||
return AstroidBuilder(MANAGER).string_build(
|
||||
"""
|
||||
|
||||
class Browser(object):
|
||||
def open(self, url, data=None, timeout=None):
|
||||
return None
|
||||
def open_novisit(self, url, data=None, timeout=None):
|
||||
return None
|
||||
def open_local_file(self, filename):
|
||||
return None
|
||||
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
register_module_extender(MANAGER, "mechanize", mechanize_transform)
|
@@ -0,0 +1,112 @@
|
||||
# Copyright (c) 2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
import sys
|
||||
|
||||
import astroid
|
||||
from astroid import exceptions
|
||||
|
||||
|
||||
PY34 = sys.version_info >= (3, 4)
|
||||
|
||||
|
||||
def _multiprocessing_transform():
|
||||
module = astroid.parse(
|
||||
"""
|
||||
from multiprocessing.managers import SyncManager
|
||||
def Manager():
|
||||
return SyncManager()
|
||||
"""
|
||||
)
|
||||
if not PY34:
|
||||
return module
|
||||
|
||||
# On Python 3.4, multiprocessing uses a getattr lookup inside contexts,
|
||||
# in order to get the attributes they need. Since it's extremely
|
||||
# dynamic, we use this approach to fake it.
|
||||
node = astroid.parse(
|
||||
"""
|
||||
from multiprocessing.context import DefaultContext, BaseContext
|
||||
default = DefaultContext()
|
||||
base = BaseContext()
|
||||
"""
|
||||
)
|
||||
try:
|
||||
context = next(node["default"].infer())
|
||||
base = next(node["base"].infer())
|
||||
except exceptions.InferenceError:
|
||||
return module
|
||||
|
||||
for node in (context, base):
|
||||
for key, value in node.locals.items():
|
||||
if key.startswith("_"):
|
||||
continue
|
||||
|
||||
value = value[0]
|
||||
if isinstance(value, astroid.FunctionDef):
|
||||
# We need to rebound this, since otherwise
|
||||
# it will have an extra argument (self).
|
||||
value = astroid.BoundMethod(value, node)
|
||||
module[key] = value
|
||||
return module
|
||||
|
||||
|
||||
def _multiprocessing_managers_transform():
|
||||
return astroid.parse(
|
||||
"""
|
||||
import array
|
||||
import threading
|
||||
import multiprocessing.pool as pool
|
||||
|
||||
import six
|
||||
|
||||
class Namespace(object):
|
||||
pass
|
||||
|
||||
class Value(object):
|
||||
def __init__(self, typecode, value, lock=True):
|
||||
self._typecode = typecode
|
||||
self._value = value
|
||||
def get(self):
|
||||
return self._value
|
||||
def set(self, value):
|
||||
self._value = value
|
||||
def __repr__(self):
|
||||
return '%s(%r, %r)'%(type(self).__name__, self._typecode, self._value)
|
||||
value = property(get, set)
|
||||
|
||||
def Array(typecode, sequence, lock=True):
|
||||
return array.array(typecode, sequence)
|
||||
|
||||
class SyncManager(object):
|
||||
Queue = JoinableQueue = six.moves.queue.Queue
|
||||
Event = threading.Event
|
||||
RLock = threading.RLock
|
||||
BoundedSemaphore = threading.BoundedSemaphore
|
||||
Condition = threading.Condition
|
||||
Barrier = threading.Barrier
|
||||
Pool = pool.Pool
|
||||
list = list
|
||||
dict = dict
|
||||
Value = Value
|
||||
Array = Array
|
||||
Namespace = Namespace
|
||||
__enter__ = lambda self: self
|
||||
__exit__ = lambda *args: args
|
||||
|
||||
def start(self, initializer=None, initargs=None):
|
||||
pass
|
||||
def shutdown(self):
|
||||
pass
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
astroid.register_module_extender(
|
||||
astroid.MANAGER, "multiprocessing.managers", _multiprocessing_managers_transform
|
||||
)
|
||||
astroid.register_module_extender(
|
||||
astroid.MANAGER, "multiprocessing", _multiprocessing_transform
|
||||
)
|
@@ -0,0 +1,440 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2012-2015 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
|
||||
# Copyright (c) 2013-2014 Google, Inc.
|
||||
# Copyright (c) 2014-2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2014 Eevee (Alex Munroe) <amunroe@yelp.com>
|
||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
||||
# Copyright (c) 2015 Dmitry Pribysh <dmand@yandex.ru>
|
||||
# Copyright (c) 2015 David Shea <dshea@redhat.com>
|
||||
# Copyright (c) 2015 Philip Lorenz <philip@bithub.de>
|
||||
# Copyright (c) 2016 Jakub Wilk <jwilk@jwilk.net>
|
||||
# Copyright (c) 2016 Mateusz Bysiek <mb@mbdev.pl>
|
||||
# Copyright (c) 2017 Hugo <hugovk@users.noreply.github.com>
|
||||
# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid hooks for the Python standard library."""
|
||||
|
||||
import functools
|
||||
import keyword
|
||||
from textwrap import dedent
|
||||
|
||||
from astroid import MANAGER, UseInferenceDefault, inference_tip, InferenceError
|
||||
from astroid import arguments
|
||||
from astroid import exceptions
|
||||
from astroid import nodes
|
||||
from astroid.builder import AstroidBuilder, extract_node
|
||||
from astroid import util
|
||||
|
||||
|
||||
TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"}
|
||||
ENUM_BASE_NAMES = {
|
||||
"Enum",
|
||||
"IntEnum",
|
||||
"enum.Enum",
|
||||
"enum.IntEnum",
|
||||
"IntFlag",
|
||||
"enum.IntFlag",
|
||||
}
|
||||
|
||||
|
||||
def _infer_first(node, context):
|
||||
if node is util.Uninferable:
|
||||
raise UseInferenceDefault
|
||||
try:
|
||||
value = next(node.infer(context=context))
|
||||
if value is util.Uninferable:
|
||||
raise UseInferenceDefault()
|
||||
else:
|
||||
return value
|
||||
except StopIteration:
|
||||
raise InferenceError()
|
||||
|
||||
|
||||
def _find_func_form_arguments(node, context):
|
||||
def _extract_namedtuple_arg_or_keyword(position, key_name=None):
|
||||
|
||||
if len(args) > position:
|
||||
return _infer_first(args[position], context)
|
||||
if key_name and key_name in found_keywords:
|
||||
return _infer_first(found_keywords[key_name], context)
|
||||
|
||||
args = node.args
|
||||
keywords = node.keywords
|
||||
found_keywords = (
|
||||
{keyword.arg: keyword.value for keyword in keywords} if keywords else {}
|
||||
)
|
||||
|
||||
name = _extract_namedtuple_arg_or_keyword(position=0, key_name="typename")
|
||||
names = _extract_namedtuple_arg_or_keyword(position=1, key_name="field_names")
|
||||
if name and names:
|
||||
return name.value, names
|
||||
|
||||
raise UseInferenceDefault()
|
||||
|
||||
|
||||
def infer_func_form(node, base_type, context=None, enum=False):
|
||||
"""Specific inference function for namedtuple or Python 3 enum. """
|
||||
# node is a Call node, class name as first argument and generated class
|
||||
# attributes as second argument
|
||||
|
||||
# namedtuple or enums list of attributes can be a list of strings or a
|
||||
# whitespace-separate string
|
||||
try:
|
||||
name, names = _find_func_form_arguments(node, context)
|
||||
try:
|
||||
attributes = names.value.replace(",", " ").split()
|
||||
except AttributeError:
|
||||
if not enum:
|
||||
attributes = [
|
||||
_infer_first(const, context).value for const in names.elts
|
||||
]
|
||||
else:
|
||||
# Enums supports either iterator of (name, value) pairs
|
||||
# or mappings.
|
||||
if hasattr(names, "items") and isinstance(names.items, list):
|
||||
attributes = [
|
||||
_infer_first(const[0], context).value
|
||||
for const in names.items
|
||||
if isinstance(const[0], nodes.Const)
|
||||
]
|
||||
elif hasattr(names, "elts"):
|
||||
# Enums can support either ["a", "b", "c"]
|
||||
# or [("a", 1), ("b", 2), ...], but they can't
|
||||
# be mixed.
|
||||
if all(isinstance(const, nodes.Tuple) for const in names.elts):
|
||||
attributes = [
|
||||
_infer_first(const.elts[0], context).value
|
||||
for const in names.elts
|
||||
if isinstance(const, nodes.Tuple)
|
||||
]
|
||||
else:
|
||||
attributes = [
|
||||
_infer_first(const, context).value for const in names.elts
|
||||
]
|
||||
else:
|
||||
raise AttributeError
|
||||
if not attributes:
|
||||
raise AttributeError
|
||||
except (AttributeError, exceptions.InferenceError):
|
||||
raise UseInferenceDefault()
|
||||
|
||||
# If we can't infer the name of the class, don't crash, up to this point
|
||||
# we know it is a namedtuple anyway.
|
||||
name = name or "Uninferable"
|
||||
# we want to return a Class node instance with proper attributes set
|
||||
class_node = nodes.ClassDef(name, "docstring")
|
||||
class_node.parent = node.parent
|
||||
# set base class=tuple
|
||||
class_node.bases.append(base_type)
|
||||
# XXX add __init__(*attributes) method
|
||||
for attr in attributes:
|
||||
fake_node = nodes.EmptyNode()
|
||||
fake_node.parent = class_node
|
||||
fake_node.attrname = attr
|
||||
class_node.instance_attrs[attr] = [fake_node]
|
||||
return class_node, name, attributes
|
||||
|
||||
|
||||
def _has_namedtuple_base(node):
|
||||
"""Predicate for class inference tip
|
||||
|
||||
:type node: ClassDef
|
||||
:rtype: bool
|
||||
"""
|
||||
return set(node.basenames) & TYPING_NAMEDTUPLE_BASENAMES
|
||||
|
||||
|
||||
def _looks_like(node, name):
|
||||
func = node.func
|
||||
if isinstance(func, nodes.Attribute):
|
||||
return func.attrname == name
|
||||
if isinstance(func, nodes.Name):
|
||||
return func.name == name
|
||||
return False
|
||||
|
||||
|
||||
_looks_like_namedtuple = functools.partial(_looks_like, name="namedtuple")
|
||||
_looks_like_enum = functools.partial(_looks_like, name="Enum")
|
||||
_looks_like_typing_namedtuple = functools.partial(_looks_like, name="NamedTuple")
|
||||
|
||||
|
||||
def infer_named_tuple(node, context=None):
|
||||
"""Specific inference function for namedtuple Call node"""
|
||||
tuple_base_name = nodes.Name(name="tuple", parent=node.root())
|
||||
class_node, name, attributes = infer_func_form(
|
||||
node, tuple_base_name, context=context
|
||||
)
|
||||
call_site = arguments.CallSite.from_call(node)
|
||||
func = next(extract_node("import collections; collections.namedtuple").infer())
|
||||
try:
|
||||
rename = next(call_site.infer_argument(func, "rename", context)).bool_value()
|
||||
except InferenceError:
|
||||
rename = False
|
||||
|
||||
if rename:
|
||||
attributes = _get_renamed_namedtuple_attributes(attributes)
|
||||
|
||||
replace_args = ", ".join("{arg}=None".format(arg=arg) for arg in attributes)
|
||||
field_def = (
|
||||
" {name} = property(lambda self: self[{index:d}], "
|
||||
"doc='Alias for field number {index:d}')"
|
||||
)
|
||||
field_defs = "\n".join(
|
||||
field_def.format(name=name, index=index)
|
||||
for index, name in enumerate(attributes)
|
||||
)
|
||||
fake = AstroidBuilder(MANAGER).string_build(
|
||||
"""
|
||||
class %(name)s(tuple):
|
||||
__slots__ = ()
|
||||
_fields = %(fields)r
|
||||
def _asdict(self):
|
||||
return self.__dict__
|
||||
@classmethod
|
||||
def _make(cls, iterable, new=tuple.__new__, len=len):
|
||||
return new(cls, iterable)
|
||||
def _replace(self, %(replace_args)s):
|
||||
return self
|
||||
def __getnewargs__(self):
|
||||
return tuple(self)
|
||||
%(field_defs)s
|
||||
"""
|
||||
% {
|
||||
"name": name,
|
||||
"fields": attributes,
|
||||
"field_defs": field_defs,
|
||||
"replace_args": replace_args,
|
||||
}
|
||||
)
|
||||
class_node.locals["_asdict"] = fake.body[0].locals["_asdict"]
|
||||
class_node.locals["_make"] = fake.body[0].locals["_make"]
|
||||
class_node.locals["_replace"] = fake.body[0].locals["_replace"]
|
||||
class_node.locals["_fields"] = fake.body[0].locals["_fields"]
|
||||
for attr in attributes:
|
||||
class_node.locals[attr] = fake.body[0].locals[attr]
|
||||
# we use UseInferenceDefault, we can't be a generator so return an iterator
|
||||
return iter([class_node])
|
||||
|
||||
|
||||
def _get_renamed_namedtuple_attributes(field_names):
|
||||
names = list(field_names)
|
||||
seen = set()
|
||||
for i, name in enumerate(field_names):
|
||||
if (
|
||||
not all(c.isalnum() or c == "_" for c in name)
|
||||
or keyword.iskeyword(name)
|
||||
or not name
|
||||
or name[0].isdigit()
|
||||
or name.startswith("_")
|
||||
or name in seen
|
||||
):
|
||||
names[i] = "_%d" % i
|
||||
seen.add(name)
|
||||
return tuple(names)
|
||||
|
||||
|
||||
def infer_enum(node, context=None):
|
||||
""" Specific inference function for enum Call node. """
|
||||
enum_meta = extract_node(
|
||||
"""
|
||||
class EnumMeta(object):
|
||||
'docstring'
|
||||
def __call__(self, node):
|
||||
class EnumAttribute(object):
|
||||
name = ''
|
||||
value = 0
|
||||
return EnumAttribute()
|
||||
def __iter__(self):
|
||||
class EnumAttribute(object):
|
||||
name = ''
|
||||
value = 0
|
||||
return [EnumAttribute()]
|
||||
def __reversed__(self):
|
||||
class EnumAttribute(object):
|
||||
name = ''
|
||||
value = 0
|
||||
return (EnumAttribute, )
|
||||
def __next__(self):
|
||||
return next(iter(self))
|
||||
def __getitem__(self, attr):
|
||||
class Value(object):
|
||||
@property
|
||||
def name(self):
|
||||
return ''
|
||||
@property
|
||||
def value(self):
|
||||
return attr
|
||||
|
||||
return Value()
|
||||
__members__ = ['']
|
||||
"""
|
||||
)
|
||||
class_node = infer_func_form(node, enum_meta, context=context, enum=True)[0]
|
||||
return iter([class_node.instantiate_class()])
|
||||
|
||||
|
||||
INT_FLAG_ADDITION_METHODS = """
|
||||
def __or__(self, other):
|
||||
return {name}(self.value | other.value)
|
||||
def __and__(self, other):
|
||||
return {name}(self.value & other.value)
|
||||
def __xor__(self, other):
|
||||
return {name}(self.value ^ other.value)
|
||||
def __add__(self, other):
|
||||
return {name}(self.value + other.value)
|
||||
def __div__(self, other):
|
||||
return {name}(self.value / other.value)
|
||||
def __invert__(self):
|
||||
return {name}(~self.value)
|
||||
def __mul__(self, other):
|
||||
return {name}(self.value * other.value)
|
||||
"""
|
||||
|
||||
|
||||
def infer_enum_class(node):
|
||||
""" Specific inference for enums. """
|
||||
for basename in node.basenames:
|
||||
# TODO: doesn't handle subclasses yet. This implementation
|
||||
# is a hack to support enums.
|
||||
if basename not in ENUM_BASE_NAMES:
|
||||
continue
|
||||
if node.root().name == "enum":
|
||||
# Skip if the class is directly from enum module.
|
||||
break
|
||||
for local, values in node.locals.items():
|
||||
if any(not isinstance(value, nodes.AssignName) for value in values):
|
||||
continue
|
||||
|
||||
targets = []
|
||||
stmt = values[0].statement()
|
||||
if isinstance(stmt, nodes.Assign):
|
||||
if isinstance(stmt.targets[0], nodes.Tuple):
|
||||
targets = stmt.targets[0].itered()
|
||||
else:
|
||||
targets = stmt.targets
|
||||
elif isinstance(stmt, nodes.AnnAssign):
|
||||
targets = [stmt.target]
|
||||
|
||||
inferred_return_value = None
|
||||
if isinstance(stmt, nodes.Assign):
|
||||
if isinstance(stmt.value, nodes.Const):
|
||||
if isinstance(stmt.value.value, str):
|
||||
inferred_return_value = repr(stmt.value.value)
|
||||
else:
|
||||
inferred_return_value = stmt.value.value
|
||||
else:
|
||||
inferred_return_value = stmt.value.as_string()
|
||||
|
||||
new_targets = []
|
||||
for target in targets:
|
||||
# Replace all the assignments with our mocked class.
|
||||
classdef = dedent(
|
||||
"""
|
||||
class {name}({types}):
|
||||
@property
|
||||
def value(self):
|
||||
return {return_value}
|
||||
@property
|
||||
def name(self):
|
||||
return "{name}"
|
||||
""".format(
|
||||
name=target.name,
|
||||
types=", ".join(node.basenames),
|
||||
return_value=inferred_return_value,
|
||||
)
|
||||
)
|
||||
if "IntFlag" in basename:
|
||||
# Alright, we need to add some additional methods.
|
||||
# Unfortunately we still can't infer the resulting objects as
|
||||
# Enum members, but once we'll be able to do that, the following
|
||||
# should result in some nice symbolic execution
|
||||
classdef += INT_FLAG_ADDITION_METHODS.format(name=target.name)
|
||||
|
||||
fake = AstroidBuilder(MANAGER).string_build(classdef)[target.name]
|
||||
fake.parent = target.parent
|
||||
for method in node.mymethods():
|
||||
fake.locals[method.name] = [method]
|
||||
new_targets.append(fake.instantiate_class())
|
||||
node.locals[local] = new_targets
|
||||
break
|
||||
return node
|
||||
|
||||
|
||||
def infer_typing_namedtuple_class(class_node, context=None):
|
||||
"""Infer a subclass of typing.NamedTuple"""
|
||||
# Check if it has the corresponding bases
|
||||
annassigns_fields = [
|
||||
annassign.target.name
|
||||
for annassign in class_node.body
|
||||
if isinstance(annassign, nodes.AnnAssign)
|
||||
]
|
||||
code = dedent(
|
||||
"""
|
||||
from collections import namedtuple
|
||||
namedtuple({typename!r}, {fields!r})
|
||||
"""
|
||||
).format(typename=class_node.name, fields=",".join(annassigns_fields))
|
||||
node = extract_node(code)
|
||||
generated_class_node = next(infer_named_tuple(node, context))
|
||||
for method in class_node.mymethods():
|
||||
generated_class_node.locals[method.name] = [method]
|
||||
return iter((generated_class_node,))
|
||||
|
||||
|
||||
def infer_typing_namedtuple(node, context=None):
|
||||
"""Infer a typing.NamedTuple(...) call."""
|
||||
# This is essentially a namedtuple with different arguments
|
||||
# so we extract the args and infer a named tuple.
|
||||
try:
|
||||
func = next(node.func.infer())
|
||||
except InferenceError:
|
||||
raise UseInferenceDefault
|
||||
|
||||
if func.qname() != "typing.NamedTuple":
|
||||
raise UseInferenceDefault
|
||||
|
||||
if len(node.args) != 2:
|
||||
raise UseInferenceDefault
|
||||
|
||||
if not isinstance(node.args[1], (nodes.List, nodes.Tuple)):
|
||||
raise UseInferenceDefault
|
||||
|
||||
names = []
|
||||
for elt in node.args[1].elts:
|
||||
if not isinstance(elt, (nodes.List, nodes.Tuple)):
|
||||
raise UseInferenceDefault
|
||||
if len(elt.elts) != 2:
|
||||
raise UseInferenceDefault
|
||||
names.append(elt.elts[0].as_string())
|
||||
|
||||
typename = node.args[0].as_string()
|
||||
if names:
|
||||
field_names = "({},)".format(",".join(names))
|
||||
else:
|
||||
field_names = "''"
|
||||
node = extract_node(
|
||||
"namedtuple({typename}, {fields})".format(typename=typename, fields=field_names)
|
||||
)
|
||||
return infer_named_tuple(node, context)
|
||||
|
||||
|
||||
MANAGER.register_transform(
|
||||
nodes.Call, inference_tip(infer_named_tuple), _looks_like_namedtuple
|
||||
)
|
||||
MANAGER.register_transform(nodes.Call, inference_tip(infer_enum), _looks_like_enum)
|
||||
MANAGER.register_transform(
|
||||
nodes.ClassDef,
|
||||
infer_enum_class,
|
||||
predicate=lambda cls: any(
|
||||
basename for basename in cls.basenames if basename in ENUM_BASE_NAMES
|
||||
),
|
||||
)
|
||||
MANAGER.register_transform(
|
||||
nodes.ClassDef, inference_tip(infer_typing_namedtuple_class), _has_namedtuple_base
|
||||
)
|
||||
MANAGER.register_transform(
|
||||
nodes.Call, inference_tip(infer_typing_namedtuple), _looks_like_typing_namedtuple
|
||||
)
|
77
venv/lib/python3.6/site-packages/astroid/brain/brain_nose.py
Normal file
77
venv/lib/python3.6/site-packages/astroid/brain/brain_nose.py
Normal file
@@ -0,0 +1,77 @@
|
||||
# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
|
||||
"""Hooks for nose library."""
|
||||
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
import astroid
|
||||
import astroid.builder
|
||||
|
||||
_BUILDER = astroid.builder.AstroidBuilder(astroid.MANAGER)
|
||||
|
||||
|
||||
def _pep8(name, caps=re.compile("([A-Z])")):
|
||||
return caps.sub(lambda m: "_" + m.groups()[0].lower(), name)
|
||||
|
||||
|
||||
def _nose_tools_functions():
|
||||
"""Get an iterator of names and bound methods."""
|
||||
module = _BUILDER.string_build(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
import unittest
|
||||
|
||||
class Test(unittest.TestCase):
|
||||
pass
|
||||
a = Test()
|
||||
"""
|
||||
)
|
||||
)
|
||||
try:
|
||||
case = next(module["a"].infer())
|
||||
except astroid.InferenceError:
|
||||
return
|
||||
for method in case.methods():
|
||||
if method.name.startswith("assert") and "_" not in method.name:
|
||||
pep8_name = _pep8(method.name)
|
||||
yield pep8_name, astroid.BoundMethod(method, case)
|
||||
if method.name == "assertEqual":
|
||||
# nose also exports assert_equals.
|
||||
yield "assert_equals", astroid.BoundMethod(method, case)
|
||||
|
||||
|
||||
def _nose_tools_transform(node):
|
||||
for method_name, method in _nose_tools_functions():
|
||||
node.locals[method_name] = [method]
|
||||
|
||||
|
||||
def _nose_tools_trivial_transform():
|
||||
"""Custom transform for the nose.tools module."""
|
||||
stub = _BUILDER.string_build("""__all__ = []""")
|
||||
all_entries = ["ok_", "eq_"]
|
||||
|
||||
for pep8_name, method in _nose_tools_functions():
|
||||
all_entries.append(pep8_name)
|
||||
stub[pep8_name] = method
|
||||
|
||||
# Update the __all__ variable, since nose.tools
|
||||
# does this manually with .append.
|
||||
all_assign = stub["__all__"].parent
|
||||
all_object = astroid.List(all_entries)
|
||||
all_object.parent = all_assign
|
||||
all_assign.value = all_object
|
||||
return stub
|
||||
|
||||
|
||||
astroid.register_module_extender(
|
||||
astroid.MANAGER, "nose.tools.trivial", _nose_tools_trivial_transform
|
||||
)
|
||||
astroid.MANAGER.register_transform(
|
||||
astroid.Module, _nose_tools_transform, lambda n: n.name == "nose.tools"
|
||||
)
|
557
venv/lib/python3.6/site-packages/astroid/brain/brain_numpy.py
Normal file
557
venv/lib/python3.6/site-packages/astroid/brain/brain_numpy.py
Normal file
@@ -0,0 +1,557 @@
|
||||
# Copyright (c) 2015-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
||||
# Copyright (c) 2017-2018 hippo91 <guillaume.peillex@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
|
||||
"""Astroid hooks for numpy."""
|
||||
|
||||
import functools
|
||||
import astroid
|
||||
|
||||
|
||||
def numpy_random_mtrand_transform():
|
||||
return astroid.parse(
|
||||
"""
|
||||
def beta(a, b, size=None): return uninferable
|
||||
def binomial(n, p, size=None): return uninferable
|
||||
def bytes(length): return uninferable
|
||||
def chisquare(df, size=None): return uninferable
|
||||
def choice(a, size=None, replace=True, p=None): return uninferable
|
||||
def dirichlet(alpha, size=None): return uninferable
|
||||
def exponential(scale=1.0, size=None): return uninferable
|
||||
def f(dfnum, dfden, size=None): return uninferable
|
||||
def gamma(shape, scale=1.0, size=None): return uninferable
|
||||
def geometric(p, size=None): return uninferable
|
||||
def get_state(): return uninferable
|
||||
def gumbel(loc=0.0, scale=1.0, size=None): return uninferable
|
||||
def hypergeometric(ngood, nbad, nsample, size=None): return uninferable
|
||||
def laplace(loc=0.0, scale=1.0, size=None): return uninferable
|
||||
def logistic(loc=0.0, scale=1.0, size=None): return uninferable
|
||||
def lognormal(mean=0.0, sigma=1.0, size=None): return uninferable
|
||||
def logseries(p, size=None): return uninferable
|
||||
def multinomial(n, pvals, size=None): return uninferable
|
||||
def multivariate_normal(mean, cov, size=None): return uninferable
|
||||
def negative_binomial(n, p, size=None): return uninferable
|
||||
def noncentral_chisquare(df, nonc, size=None): return uninferable
|
||||
def noncentral_f(dfnum, dfden, nonc, size=None): return uninferable
|
||||
def normal(loc=0.0, scale=1.0, size=None): return uninferable
|
||||
def pareto(a, size=None): return uninferable
|
||||
def permutation(x): return uninferable
|
||||
def poisson(lam=1.0, size=None): return uninferable
|
||||
def power(a, size=None): return uninferable
|
||||
def rand(*args): return uninferable
|
||||
def randint(low, high=None, size=None, dtype='l'): return uninferable
|
||||
def randn(*args): return uninferable
|
||||
def random_integers(low, high=None, size=None): return uninferable
|
||||
def random_sample(size=None): return uninferable
|
||||
def rayleigh(scale=1.0, size=None): return uninferable
|
||||
def seed(seed=None): return uninferable
|
||||
def set_state(state): return uninferable
|
||||
def shuffle(x): return uninferable
|
||||
def standard_cauchy(size=None): return uninferable
|
||||
def standard_exponential(size=None): return uninferable
|
||||
def standard_gamma(shape, size=None): return uninferable
|
||||
def standard_normal(size=None): return uninferable
|
||||
def standard_t(df, size=None): return uninferable
|
||||
def triangular(left, mode, right, size=None): return uninferable
|
||||
def uniform(low=0.0, high=1.0, size=None): return uninferable
|
||||
def vonmises(mu, kappa, size=None): return uninferable
|
||||
def wald(mean, scale, size=None): return uninferable
|
||||
def weibull(a, size=None): return uninferable
|
||||
def zipf(a, size=None): return uninferable
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def numpy_core_umath_transform():
|
||||
ufunc_optional_keyword_arguments = (
|
||||
"""out=None, where=True, casting='same_kind', order='K', """
|
||||
"""dtype=None, subok=True"""
|
||||
)
|
||||
return astroid.parse(
|
||||
"""
|
||||
# Constants
|
||||
e = 2.718281828459045
|
||||
euler_gamma = 0.5772156649015329
|
||||
|
||||
# No arg functions
|
||||
def geterrobj(): return uninferable
|
||||
|
||||
# One arg functions
|
||||
def seterrobj(errobj): return uninferable
|
||||
|
||||
# One arg functions with optional kwargs
|
||||
def arccos(x, {opt_args:s}): return uninferable
|
||||
def arccosh(x, {opt_args:s}): return uninferable
|
||||
def arcsin(x, {opt_args:s}): return uninferable
|
||||
def arcsinh(x, {opt_args:s}): return uninferable
|
||||
def arctan(x, {opt_args:s}): return uninferable
|
||||
def arctanh(x, {opt_args:s}): return uninferable
|
||||
def cbrt(x, {opt_args:s}): return uninferable
|
||||
def conj(x, {opt_args:s}): return uninferable
|
||||
def conjugate(x, {opt_args:s}): return uninferable
|
||||
def cosh(x, {opt_args:s}): return uninferable
|
||||
def deg2rad(x, {opt_args:s}): return uninferable
|
||||
def degrees(x, {opt_args:s}): return uninferable
|
||||
def exp2(x, {opt_args:s}): return uninferable
|
||||
def expm1(x, {opt_args:s}): return uninferable
|
||||
def fabs(x, {opt_args:s}): return uninferable
|
||||
def frexp(x, {opt_args:s}): return uninferable
|
||||
def isfinite(x, {opt_args:s}): return uninferable
|
||||
def isinf(x, {opt_args:s}): return uninferable
|
||||
def log(x, {opt_args:s}): return uninferable
|
||||
def log1p(x, {opt_args:s}): return uninferable
|
||||
def log2(x, {opt_args:s}): return uninferable
|
||||
def logical_not(x, {opt_args:s}): return uninferable
|
||||
def modf(x, {opt_args:s}): return uninferable
|
||||
def negative(x, {opt_args:s}): return uninferable
|
||||
def rad2deg(x, {opt_args:s}): return uninferable
|
||||
def radians(x, {opt_args:s}): return uninferable
|
||||
def reciprocal(x, {opt_args:s}): return uninferable
|
||||
def rint(x, {opt_args:s}): return uninferable
|
||||
def sign(x, {opt_args:s}): return uninferable
|
||||
def signbit(x, {opt_args:s}): return uninferable
|
||||
def sinh(x, {opt_args:s}): return uninferable
|
||||
def spacing(x, {opt_args:s}): return uninferable
|
||||
def square(x, {opt_args:s}): return uninferable
|
||||
def tan(x, {opt_args:s}): return uninferable
|
||||
def tanh(x, {opt_args:s}): return uninferable
|
||||
def trunc(x, {opt_args:s}): return uninferable
|
||||
|
||||
# Two args functions with optional kwargs
|
||||
def bitwise_and(x1, x2, {opt_args:s}): return uninferable
|
||||
def bitwise_or(x1, x2, {opt_args:s}): return uninferable
|
||||
def bitwise_xor(x1, x2, {opt_args:s}): return uninferable
|
||||
def copysign(x1, x2, {opt_args:s}): return uninferable
|
||||
def divide(x1, x2, {opt_args:s}): return uninferable
|
||||
def equal(x1, x2, {opt_args:s}): return uninferable
|
||||
def float_power(x1, x2, {opt_args:s}): return uninferable
|
||||
def floor_divide(x1, x2, {opt_args:s}): return uninferable
|
||||
def fmax(x1, x2, {opt_args:s}): return uninferable
|
||||
def fmin(x1, x2, {opt_args:s}): return uninferable
|
||||
def fmod(x1, x2, {opt_args:s}): return uninferable
|
||||
def greater(x1, x2, {opt_args:s}): return uninferable
|
||||
def hypot(x1, x2, {opt_args:s}): return uninferable
|
||||
def ldexp(x1, x2, {opt_args:s}): return uninferable
|
||||
def left_shift(x1, x2, {opt_args:s}): return uninferable
|
||||
def less(x1, x2, {opt_args:s}): return uninferable
|
||||
def logaddexp(x1, x2, {opt_args:s}): return uninferable
|
||||
def logaddexp2(x1, x2, {opt_args:s}): return uninferable
|
||||
def logical_and(x1, x2, {opt_args:s}): return uninferable
|
||||
def logical_or(x1, x2, {opt_args:s}): return uninferable
|
||||
def logical_xor(x1, x2, {opt_args:s}): return uninferable
|
||||
def maximum(x1, x2, {opt_args:s}): return uninferable
|
||||
def minimum(x1, x2, {opt_args:s}): return uninferable
|
||||
def nextafter(x1, x2, {opt_args:s}): return uninferable
|
||||
def not_equal(x1, x2, {opt_args:s}): return uninferable
|
||||
def power(x1, x2, {opt_args:s}): return uninferable
|
||||
def remainder(x1, x2, {opt_args:s}): return uninferable
|
||||
def right_shift(x1, x2, {opt_args:s}): return uninferable
|
||||
def subtract(x1, x2, {opt_args:s}): return uninferable
|
||||
def true_divide(x1, x2, {opt_args:s}): return uninferable
|
||||
""".format(
|
||||
opt_args=ufunc_optional_keyword_arguments
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
def numpy_core_numerictypes_transform():
|
||||
return astroid.parse(
|
||||
"""
|
||||
# different types defined in numerictypes.py
|
||||
class generic(object):
|
||||
def __init__(self, value):
|
||||
self.T = None
|
||||
self.base = None
|
||||
self.data = None
|
||||
self.dtype = None
|
||||
self.flags = None
|
||||
self.flat = None
|
||||
self.imag = None
|
||||
self.itemsize = None
|
||||
self.nbytes = None
|
||||
self.ndim = None
|
||||
self.real = None
|
||||
self.size = None
|
||||
self.strides = None
|
||||
|
||||
def all(self): return uninferable
|
||||
def any(self): return uninferable
|
||||
def argmax(self): return uninferable
|
||||
def argmin(self): return uninferable
|
||||
def argsort(self): return uninferable
|
||||
def astype(self): return uninferable
|
||||
def base(self): return uninferable
|
||||
def byteswap(self): return uninferable
|
||||
def choose(self): return uninferable
|
||||
def clip(self): return uninferable
|
||||
def compress(self): return uninferable
|
||||
def conj(self): return uninferable
|
||||
def conjugate(self): return uninferable
|
||||
def copy(self): return uninferable
|
||||
def cumprod(self): return uninferable
|
||||
def cumsum(self): return uninferable
|
||||
def data(self): return uninferable
|
||||
def diagonal(self): return uninferable
|
||||
def dtype(self): return uninferable
|
||||
def dump(self): return uninferable
|
||||
def dumps(self): return uninferable
|
||||
def fill(self): return uninferable
|
||||
def flags(self): return uninferable
|
||||
def flat(self): return uninferable
|
||||
def flatten(self): return uninferable
|
||||
def getfield(self): return uninferable
|
||||
def imag(self): return uninferable
|
||||
def item(self): return uninferable
|
||||
def itemset(self): return uninferable
|
||||
def itemsize(self): return uninferable
|
||||
def max(self): return uninferable
|
||||
def mean(self): return uninferable
|
||||
def min(self): return uninferable
|
||||
def nbytes(self): return uninferable
|
||||
def ndim(self): return uninferable
|
||||
def newbyteorder(self): return uninferable
|
||||
def nonzero(self): return uninferable
|
||||
def prod(self): return uninferable
|
||||
def ptp(self): return uninferable
|
||||
def put(self): return uninferable
|
||||
def ravel(self): return uninferable
|
||||
def real(self): return uninferable
|
||||
def repeat(self): return uninferable
|
||||
def reshape(self): return uninferable
|
||||
def resize(self): return uninferable
|
||||
def round(self): return uninferable
|
||||
def searchsorted(self): return uninferable
|
||||
def setfield(self): return uninferable
|
||||
def setflags(self): return uninferable
|
||||
def shape(self): return uninferable
|
||||
def size(self): return uninferable
|
||||
def sort(self): return uninferable
|
||||
def squeeze(self): return uninferable
|
||||
def std(self): return uninferable
|
||||
def strides(self): return uninferable
|
||||
def sum(self): return uninferable
|
||||
def swapaxes(self): return uninferable
|
||||
def take(self): return uninferable
|
||||
def tobytes(self): return uninferable
|
||||
def tofile(self): return uninferable
|
||||
def tolist(self): return uninferable
|
||||
def tostring(self): return uninferable
|
||||
def trace(self): return uninferable
|
||||
def transpose(self): return uninferable
|
||||
def var(self): return uninferable
|
||||
def view(self): return uninferable
|
||||
|
||||
|
||||
class dtype(object):
|
||||
def __init__(self, obj, align=False, copy=False):
|
||||
self.alignment = None
|
||||
self.base = None
|
||||
self.byteorder = None
|
||||
self.char = None
|
||||
self.descr = None
|
||||
self.fields = None
|
||||
self.flags = None
|
||||
self.hasobject = None
|
||||
self.isalignedstruct = None
|
||||
self.isbuiltin = None
|
||||
self.isnative = None
|
||||
self.itemsize = None
|
||||
self.kind = None
|
||||
self.metadata = None
|
||||
self.name = None
|
||||
self.names = None
|
||||
self.num = None
|
||||
self.shape = None
|
||||
self.str = None
|
||||
self.subdtype = None
|
||||
self.type = None
|
||||
|
||||
def newbyteorder(self, new_order='S'): return uninferable
|
||||
def __neg__(self): return uninferable
|
||||
|
||||
|
||||
class ndarray(object):
|
||||
def __init__(self, shape, dtype=float, buffer=None, offset=0,
|
||||
strides=None, order=None):
|
||||
self.T = None
|
||||
self.base = None
|
||||
self.ctypes = None
|
||||
self.data = None
|
||||
self.dtype = None
|
||||
self.flags = None
|
||||
self.flat = None
|
||||
self.imag = None
|
||||
self.itemsize = None
|
||||
self.nbytes = None
|
||||
self.ndim = None
|
||||
self.real = None
|
||||
self.shape = None
|
||||
self.size = None
|
||||
self.strides = None
|
||||
|
||||
def __neg__(self): return uninferable
|
||||
def __inv__(self): return uninferable
|
||||
def __invert__(self): return uninferable
|
||||
def all(self): return uninferable
|
||||
def any(self): return uninferable
|
||||
def argmax(self): return uninferable
|
||||
def argmin(self): return uninferable
|
||||
def argpartition(self): return uninferable
|
||||
def argsort(self): return uninferable
|
||||
def astype(self): return uninferable
|
||||
def byteswap(self): return uninferable
|
||||
def choose(self): return uninferable
|
||||
def clip(self): return uninferable
|
||||
def compress(self): return uninferable
|
||||
def conj(self): return uninferable
|
||||
def conjugate(self): return uninferable
|
||||
def copy(self): return uninferable
|
||||
def cumprod(self): return uninferable
|
||||
def cumsum(self): return uninferable
|
||||
def diagonal(self): return uninferable
|
||||
def dot(self): return uninferable
|
||||
def dump(self): return uninferable
|
||||
def dumps(self): return uninferable
|
||||
def fill(self): return uninferable
|
||||
def flatten(self): return uninferable
|
||||
def getfield(self): return uninferable
|
||||
def item(self): return uninferable
|
||||
def itemset(self): return uninferable
|
||||
def max(self): return uninferable
|
||||
def mean(self): return uninferable
|
||||
def min(self): return uninferable
|
||||
def newbyteorder(self): return uninferable
|
||||
def nonzero(self): return uninferable
|
||||
def partition(self): return uninferable
|
||||
def prod(self): return uninferable
|
||||
def ptp(self): return uninferable
|
||||
def put(self): return uninferable
|
||||
def ravel(self): return uninferable
|
||||
def repeat(self): return uninferable
|
||||
def reshape(self): return uninferable
|
||||
def resize(self): return uninferable
|
||||
def round(self): return uninferable
|
||||
def searchsorted(self): return uninferable
|
||||
def setfield(self): return uninferable
|
||||
def setflags(self): return uninferable
|
||||
def sort(self): return uninferable
|
||||
def squeeze(self): return uninferable
|
||||
def std(self): return uninferable
|
||||
def sum(self): return uninferable
|
||||
def swapaxes(self): return uninferable
|
||||
def take(self): return uninferable
|
||||
def tobytes(self): return uninferable
|
||||
def tofile(self): return uninferable
|
||||
def tolist(self): return uninferable
|
||||
def tostring(self): return uninferable
|
||||
def trace(self): return uninferable
|
||||
def transpose(self): return uninferable
|
||||
def var(self): return uninferable
|
||||
def view(self): return uninferable
|
||||
|
||||
|
||||
class busdaycalendar(object):
|
||||
def __init__(self, weekmask='1111100', holidays=None):
|
||||
self.holidays = None
|
||||
self.weekmask = None
|
||||
|
||||
class flexible(generic): pass
|
||||
class bool_(generic): pass
|
||||
class number(generic):
|
||||
def __neg__(self): return uninferable
|
||||
class datetime64(generic): pass
|
||||
|
||||
|
||||
class void(flexible):
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.base = None
|
||||
self.dtype = None
|
||||
self.flags = None
|
||||
def getfield(self): return uninferable
|
||||
def setfield(self): return uninferable
|
||||
|
||||
|
||||
class character(flexible): pass
|
||||
|
||||
|
||||
class integer(number):
|
||||
def __init__(self, value):
|
||||
self.denominator = None
|
||||
self.numerator = None
|
||||
|
||||
|
||||
class inexact(number): pass
|
||||
|
||||
|
||||
class str_(str, character):
|
||||
def maketrans(self, x, y=None, z=None): return uninferable
|
||||
|
||||
|
||||
class bytes_(bytes, character):
|
||||
def fromhex(self, string): return uninferable
|
||||
def maketrans(self, frm, to): return uninferable
|
||||
|
||||
|
||||
class signedinteger(integer): pass
|
||||
|
||||
|
||||
class unsignedinteger(integer): pass
|
||||
|
||||
|
||||
class complexfloating(inexact): pass
|
||||
|
||||
|
||||
class floating(inexact): pass
|
||||
|
||||
|
||||
class float64(floating, float):
|
||||
def fromhex(self, string): return uninferable
|
||||
|
||||
|
||||
class uint64(unsignedinteger): pass
|
||||
class complex64(complexfloating): pass
|
||||
class int16(signedinteger): pass
|
||||
class float96(floating): pass
|
||||
class int8(signedinteger): pass
|
||||
class uint32(unsignedinteger): pass
|
||||
class uint8(unsignedinteger): pass
|
||||
class _typedict(dict): pass
|
||||
class complex192(complexfloating): pass
|
||||
class timedelta64(signedinteger): pass
|
||||
class int32(signedinteger): pass
|
||||
class uint16(unsignedinteger): pass
|
||||
class float32(floating): pass
|
||||
class complex128(complexfloating, complex): pass
|
||||
class float16(floating): pass
|
||||
class int64(signedinteger): pass
|
||||
|
||||
buffer_type = memoryview
|
||||
bool8 = bool_
|
||||
byte = int8
|
||||
bytes0 = bytes_
|
||||
cdouble = complex128
|
||||
cfloat = complex128
|
||||
clongdouble = complex192
|
||||
clongfloat = complex192
|
||||
complex_ = complex128
|
||||
csingle = complex64
|
||||
double = float64
|
||||
float_ = float64
|
||||
half = float16
|
||||
int0 = int32
|
||||
int_ = int32
|
||||
intc = int32
|
||||
intp = int32
|
||||
long = int32
|
||||
longcomplex = complex192
|
||||
longdouble = float96
|
||||
longfloat = float96
|
||||
longlong = int64
|
||||
object0 = object_
|
||||
object_ = object_
|
||||
short = int16
|
||||
single = float32
|
||||
singlecomplex = complex64
|
||||
str0 = str_
|
||||
string_ = bytes_
|
||||
ubyte = uint8
|
||||
uint = uint32
|
||||
uint0 = uint32
|
||||
uintc = uint32
|
||||
uintp = uint32
|
||||
ulonglong = uint64
|
||||
unicode = str_
|
||||
unicode_ = str_
|
||||
ushort = uint16
|
||||
void0 = void
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def numpy_funcs():
|
||||
return astroid.parse(
|
||||
"""
|
||||
import builtins
|
||||
def sum(a, axis=None, dtype=None, out=None, keepdims=None):
|
||||
return builtins.sum(a)
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
def _looks_like_numpy_function(func_name, numpy_module_name, node):
|
||||
"""
|
||||
Return True if the current node correspond to the function inside
|
||||
the numpy module in parameters
|
||||
|
||||
:param node: the current node
|
||||
:type node: FunctionDef
|
||||
:param func_name: name of the function
|
||||
:type func_name: str
|
||||
:param numpy_module_name: name of the numpy module
|
||||
:type numpy_module_name: str
|
||||
:return: True if the current node correspond to the function looked for
|
||||
:rtype: bool
|
||||
"""
|
||||
return node.name == func_name and node.parent.name == numpy_module_name
|
||||
|
||||
|
||||
def numpy_function_infer_call_result(node):
|
||||
"""
|
||||
A wrapper around infer_call_result method bounded to the node.
|
||||
|
||||
:param node: the node which infer_call_result should be filtered
|
||||
:type node: FunctionDef
|
||||
:return: a function that filter the results of the call to node.infer_call_result
|
||||
:rtype: function
|
||||
"""
|
||||
# Put the origin infer_call_result method into the closure
|
||||
origin_infer_call_result = node.infer_call_result
|
||||
|
||||
def infer_call_result_wrapper(caller=None, context=None):
|
||||
"""
|
||||
Call the origin infer_call_result method bounded to the node instance and
|
||||
filter the results to remove List and Tuple instances
|
||||
"""
|
||||
unfiltered_infer_call_result = origin_infer_call_result(caller, context)
|
||||
return (
|
||||
x
|
||||
for x in unfiltered_infer_call_result
|
||||
if not isinstance(x, (astroid.List, astroid.Tuple))
|
||||
)
|
||||
|
||||
return infer_call_result_wrapper
|
||||
|
||||
|
||||
def _replace_numpy_function_infer_call_result(node, context=None):
|
||||
node.infer_call_result = numpy_function_infer_call_result(node)
|
||||
return
|
||||
|
||||
|
||||
astroid.MANAGER.register_transform(
|
||||
astroid.FunctionDef,
|
||||
_replace_numpy_function_infer_call_result,
|
||||
functools.partial(
|
||||
_looks_like_numpy_function, "linspace", "numpy.core.function_base"
|
||||
),
|
||||
)
|
||||
|
||||
astroid.MANAGER.register_transform(
|
||||
astroid.FunctionDef,
|
||||
_replace_numpy_function_infer_call_result,
|
||||
functools.partial(_looks_like_numpy_function, "array", "numpy.core.records"),
|
||||
)
|
||||
|
||||
astroid.register_module_extender(
|
||||
astroid.MANAGER, "numpy.core.umath", numpy_core_umath_transform
|
||||
)
|
||||
astroid.register_module_extender(
|
||||
astroid.MANAGER, "numpy.random.mtrand", numpy_random_mtrand_transform
|
||||
)
|
||||
astroid.register_module_extender(
|
||||
astroid.MANAGER, "numpy.core.numerictypes", numpy_core_numerictypes_transform
|
||||
)
|
||||
astroid.register_module_extender(astroid.MANAGER, "numpy", numpy_funcs)
|
@@ -0,0 +1,75 @@
|
||||
# Copyright (c) 2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
|
||||
import astroid
|
||||
from astroid import parse
|
||||
from astroid import inference_tip
|
||||
from astroid import register_module_extender
|
||||
from astroid import MANAGER
|
||||
|
||||
|
||||
def pkg_resources_transform():
|
||||
return parse(
|
||||
"""
|
||||
def require(*requirements):
|
||||
return pkg_resources.working_set.require(*requirements)
|
||||
|
||||
def run_script(requires, script_name):
|
||||
return pkg_resources.working_set.run_script(requires, script_name)
|
||||
|
||||
def iter_entry_points(group, name=None):
|
||||
return pkg_resources.working_set.iter_entry_points(group, name)
|
||||
|
||||
def resource_exists(package_or_requirement, resource_name):
|
||||
return get_provider(package_or_requirement).has_resource(resource_name)
|
||||
|
||||
def resource_isdir(package_or_requirement, resource_name):
|
||||
return get_provider(package_or_requirement).resource_isdir(
|
||||
resource_name)
|
||||
|
||||
def resource_filename(package_or_requirement, resource_name):
|
||||
return get_provider(package_or_requirement).get_resource_filename(
|
||||
self, resource_name)
|
||||
|
||||
def resource_stream(package_or_requirement, resource_name):
|
||||
return get_provider(package_or_requirement).get_resource_stream(
|
||||
self, resource_name)
|
||||
|
||||
def resource_string(package_or_requirement, resource_name):
|
||||
return get_provider(package_or_requirement).get_resource_string(
|
||||
self, resource_name)
|
||||
|
||||
def resource_listdir(package_or_requirement, resource_name):
|
||||
return get_provider(package_or_requirement).resource_listdir(
|
||||
resource_name)
|
||||
|
||||
def extraction_error():
|
||||
pass
|
||||
|
||||
def get_cache_path(archive_name, names=()):
|
||||
extract_path = self.extraction_path or get_default_cache()
|
||||
target_path = os.path.join(extract_path, archive_name+'-tmp', *names)
|
||||
return target_path
|
||||
|
||||
def postprocess(tempname, filename):
|
||||
pass
|
||||
|
||||
def set_extraction_path(path):
|
||||
pass
|
||||
|
||||
def cleanup_resources(force=False):
|
||||
pass
|
||||
|
||||
def get_distribution(dist):
|
||||
return Distribution(dist)
|
||||
|
||||
_namespace_packages = {}
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
register_module_extender(MANAGER, "pkg_resources", pkg_resources_transform)
|
@@ -0,0 +1,88 @@
|
||||
# Copyright (c) 2014-2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2014 Jeff Quast <contact@jeffquast.com>
|
||||
# Copyright (c) 2014 Google, Inc.
|
||||
# Copyright (c) 2016 Florian Bruhin <me@the-compiler.org>
|
||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid hooks for pytest."""
|
||||
from __future__ import absolute_import
|
||||
from astroid import MANAGER, register_module_extender
|
||||
from astroid.builder import AstroidBuilder
|
||||
|
||||
|
||||
def pytest_transform():
|
||||
return AstroidBuilder(MANAGER).string_build(
|
||||
"""
|
||||
|
||||
try:
|
||||
import _pytest.mark
|
||||
import _pytest.recwarn
|
||||
import _pytest.runner
|
||||
import _pytest.python
|
||||
import _pytest.skipping
|
||||
import _pytest.assertion
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
deprecated_call = _pytest.recwarn.deprecated_call
|
||||
warns = _pytest.recwarn.warns
|
||||
|
||||
exit = _pytest.runner.exit
|
||||
fail = _pytest.runner.fail
|
||||
skip = _pytest.runner.skip
|
||||
importorskip = _pytest.runner.importorskip
|
||||
|
||||
xfail = _pytest.skipping.xfail
|
||||
mark = _pytest.mark.MarkGenerator()
|
||||
raises = _pytest.python.raises
|
||||
|
||||
# New in pytest 3.0
|
||||
try:
|
||||
approx = _pytest.python.approx
|
||||
register_assert_rewrite = _pytest.assertion.register_assert_rewrite
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
|
||||
# Moved in pytest 3.0
|
||||
|
||||
try:
|
||||
import _pytest.freeze_support
|
||||
freeze_includes = _pytest.freeze_support.freeze_includes
|
||||
except ImportError:
|
||||
try:
|
||||
import _pytest.genscript
|
||||
freeze_includes = _pytest.genscript.freeze_includes
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import _pytest.debugging
|
||||
set_trace = _pytest.debugging.pytestPDB().set_trace
|
||||
except ImportError:
|
||||
try:
|
||||
import _pytest.pdb
|
||||
set_trace = _pytest.pdb.pytestPDB().set_trace
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
try:
|
||||
import _pytest.fixtures
|
||||
fixture = _pytest.fixtures.fixture
|
||||
yield_fixture = _pytest.fixtures.yield_fixture
|
||||
except ImportError:
|
||||
try:
|
||||
import _pytest.python
|
||||
fixture = _pytest.python.fixture
|
||||
yield_fixture = _pytest.python.yield_fixture
|
||||
except ImportError:
|
||||
pass
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
register_module_extender(MANAGER, "pytest", pytest_transform)
|
||||
register_module_extender(MANAGER, "py.test", pytest_transform)
|
82
venv/lib/python3.6/site-packages/astroid/brain/brain_qt.py
Normal file
82
venv/lib/python3.6/site-packages/astroid/brain/brain_qt.py
Normal file
@@ -0,0 +1,82 @@
|
||||
# Copyright (c) 2015-2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
||||
# Copyright (c) 2017 Roy Wright <roy@wright.org>
|
||||
# Copyright (c) 2018 Ashley Whetter <ashley@awhetter.co.uk>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid hooks for the PyQT library."""
|
||||
|
||||
from astroid import MANAGER, register_module_extender
|
||||
from astroid.builder import AstroidBuilder
|
||||
from astroid import nodes
|
||||
from astroid import parse
|
||||
|
||||
|
||||
def _looks_like_signal(node, signal_name="pyqtSignal"):
|
||||
if "__class__" in node.instance_attrs:
|
||||
try:
|
||||
cls = node.instance_attrs["__class__"][0]
|
||||
return cls.name == signal_name
|
||||
except AttributeError:
|
||||
# return False if the cls does not have a name attribute
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
def transform_pyqt_signal(node):
|
||||
module = parse(
|
||||
"""
|
||||
class pyqtSignal(object):
|
||||
def connect(self, slot, type=None, no_receiver_check=False):
|
||||
pass
|
||||
def disconnect(self, slot):
|
||||
pass
|
||||
def emit(self, *args):
|
||||
pass
|
||||
"""
|
||||
)
|
||||
signal_cls = module["pyqtSignal"]
|
||||
node.instance_attrs["emit"] = signal_cls["emit"]
|
||||
node.instance_attrs["disconnect"] = signal_cls["disconnect"]
|
||||
node.instance_attrs["connect"] = signal_cls["connect"]
|
||||
|
||||
|
||||
def transform_pyside_signal(node):
|
||||
module = parse(
|
||||
"""
|
||||
class NotPySideSignal(object):
|
||||
def connect(self, receiver, type=None):
|
||||
pass
|
||||
def disconnect(self, receiver):
|
||||
pass
|
||||
def emit(self, *args):
|
||||
pass
|
||||
"""
|
||||
)
|
||||
signal_cls = module["NotPySideSignal"]
|
||||
node.instance_attrs["connect"] = signal_cls["connect"]
|
||||
node.instance_attrs["disconnect"] = signal_cls["disconnect"]
|
||||
node.instance_attrs["emit"] = signal_cls["emit"]
|
||||
|
||||
|
||||
def pyqt4_qtcore_transform():
|
||||
return AstroidBuilder(MANAGER).string_build(
|
||||
"""
|
||||
|
||||
def SIGNAL(signal_name): pass
|
||||
|
||||
class QObject(object):
|
||||
def emit(self, signal): pass
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
register_module_extender(MANAGER, "PyQt4.QtCore", pyqt4_qtcore_transform)
|
||||
MANAGER.register_transform(nodes.FunctionDef, transform_pyqt_signal, _looks_like_signal)
|
||||
MANAGER.register_transform(
|
||||
nodes.ClassDef,
|
||||
transform_pyside_signal,
|
||||
lambda node: node.qname() == "PySide.QtCore.Signal",
|
||||
)
|
@@ -0,0 +1,75 @@
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
import random
|
||||
|
||||
import astroid
|
||||
from astroid import helpers
|
||||
from astroid import MANAGER
|
||||
|
||||
|
||||
ACCEPTED_ITERABLES_FOR_SAMPLE = (astroid.List, astroid.Set, astroid.Tuple)
|
||||
|
||||
|
||||
def _clone_node_with_lineno(node, parent, lineno):
|
||||
cls = node.__class__
|
||||
other_fields = node._other_fields
|
||||
_astroid_fields = node._astroid_fields
|
||||
init_params = {"lineno": lineno, "col_offset": node.col_offset, "parent": parent}
|
||||
postinit_params = {param: getattr(node, param) for param in _astroid_fields}
|
||||
if other_fields:
|
||||
init_params.update({param: getattr(node, param) for param in other_fields})
|
||||
new_node = cls(**init_params)
|
||||
if hasattr(node, "postinit") and _astroid_fields:
|
||||
new_node.postinit(**postinit_params)
|
||||
return new_node
|
||||
|
||||
|
||||
def infer_random_sample(node, context=None):
|
||||
if len(node.args) != 2:
|
||||
raise astroid.UseInferenceDefault
|
||||
|
||||
length = node.args[1]
|
||||
if not isinstance(length, astroid.Const):
|
||||
raise astroid.UseInferenceDefault
|
||||
if not isinstance(length.value, int):
|
||||
raise astroid.UseInferenceDefault
|
||||
|
||||
inferred_sequence = helpers.safe_infer(node.args[0], context=context)
|
||||
if not inferred_sequence:
|
||||
raise astroid.UseInferenceDefault
|
||||
|
||||
if not isinstance(inferred_sequence, ACCEPTED_ITERABLES_FOR_SAMPLE):
|
||||
raise astroid.UseInferenceDefault
|
||||
|
||||
if length.value > len(inferred_sequence.elts):
|
||||
# In this case, this will raise a ValueError
|
||||
raise astroid.UseInferenceDefault
|
||||
|
||||
try:
|
||||
elts = random.sample(inferred_sequence.elts, length.value)
|
||||
except ValueError:
|
||||
raise astroid.UseInferenceDefault
|
||||
|
||||
new_node = astroid.List(
|
||||
lineno=node.lineno, col_offset=node.col_offset, parent=node.scope()
|
||||
)
|
||||
new_elts = [
|
||||
_clone_node_with_lineno(elt, parent=new_node, lineno=new_node.lineno)
|
||||
for elt in elts
|
||||
]
|
||||
new_node.postinit(new_elts)
|
||||
return iter((new_node,))
|
||||
|
||||
|
||||
def _looks_like_random_sample(node):
|
||||
func = node.func
|
||||
if isinstance(func, astroid.Attribute):
|
||||
return func.attrname == "sample"
|
||||
if isinstance(func, astroid.Name):
|
||||
return func.name == "sample"
|
||||
return False
|
||||
|
||||
|
||||
MANAGER.register_transform(
|
||||
astroid.Call, astroid.inference_tip(infer_random_sample), _looks_like_random_sample
|
||||
)
|
36
venv/lib/python3.6/site-packages/astroid/brain/brain_re.py
Normal file
36
venv/lib/python3.6/site-packages/astroid/brain/brain_re.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
import sys
|
||||
import astroid
|
||||
|
||||
PY36 = sys.version_info >= (3, 6)
|
||||
|
||||
if PY36:
|
||||
# Since Python 3.6 there is the RegexFlag enum
|
||||
# where every entry will be exposed via updating globals()
|
||||
|
||||
def _re_transform():
|
||||
return astroid.parse(
|
||||
"""
|
||||
import sre_compile
|
||||
ASCII = sre_compile.SRE_FLAG_ASCII
|
||||
IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE
|
||||
LOCALE = sre_compile.SRE_FLAG_LOCALE
|
||||
UNICODE = sre_compile.SRE_FLAG_UNICODE
|
||||
MULTILINE = sre_compile.SRE_FLAG_MULTILINE
|
||||
DOTALL = sre_compile.SRE_FLAG_DOTALL
|
||||
VERBOSE = sre_compile.SRE_FLAG_VERBOSE
|
||||
A = ASCII
|
||||
I = IGNORECASE
|
||||
L = LOCALE
|
||||
U = UNICODE
|
||||
M = MULTILINE
|
||||
S = DOTALL
|
||||
X = VERBOSE
|
||||
TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE
|
||||
T = TEMPLATE
|
||||
DEBUG = sre_compile.SRE_FLAG_DEBUG
|
||||
"""
|
||||
)
|
||||
|
||||
astroid.register_module_extender(astroid.MANAGER, "re", _re_transform)
|
200
venv/lib/python3.6/site-packages/astroid/brain/brain_six.py
Normal file
200
venv/lib/python3.6/site-packages/astroid/brain/brain_six.py
Normal file
@@ -0,0 +1,200 @@
|
||||
# Copyright (c) 2014-2016, 2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2015-2016 Ceridwen <ceridwenv@gmail.com>
|
||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
|
||||
"""Astroid hooks for six module."""
|
||||
|
||||
from textwrap import dedent
|
||||
|
||||
from astroid import MANAGER, register_module_extender
|
||||
from astroid.builder import AstroidBuilder
|
||||
from astroid.exceptions import (
|
||||
AstroidBuildingError,
|
||||
InferenceError,
|
||||
AttributeInferenceError,
|
||||
)
|
||||
from astroid import nodes
|
||||
|
||||
|
||||
SIX_ADD_METACLASS = "six.add_metaclass"
|
||||
|
||||
|
||||
def _indent(text, prefix, predicate=None):
|
||||
"""Adds 'prefix' to the beginning of selected lines in 'text'.
|
||||
|
||||
If 'predicate' is provided, 'prefix' will only be added to the lines
|
||||
where 'predicate(line)' is True. If 'predicate' is not provided,
|
||||
it will default to adding 'prefix' to all non-empty lines that do not
|
||||
consist solely of whitespace characters.
|
||||
"""
|
||||
if predicate is None:
|
||||
predicate = lambda line: line.strip()
|
||||
|
||||
def prefixed_lines():
|
||||
for line in text.splitlines(True):
|
||||
yield prefix + line if predicate(line) else line
|
||||
|
||||
return "".join(prefixed_lines())
|
||||
|
||||
|
||||
_IMPORTS = """
|
||||
import _io
|
||||
cStringIO = _io.StringIO
|
||||
filter = filter
|
||||
from itertools import filterfalse
|
||||
input = input
|
||||
from sys import intern
|
||||
map = map
|
||||
range = range
|
||||
from imp import reload as reload_module
|
||||
from functools import reduce
|
||||
from shlex import quote as shlex_quote
|
||||
from io import StringIO
|
||||
from collections import UserDict, UserList, UserString
|
||||
xrange = range
|
||||
zip = zip
|
||||
from itertools import zip_longest
|
||||
import builtins
|
||||
import configparser
|
||||
import copyreg
|
||||
import _dummy_thread
|
||||
import http.cookiejar as http_cookiejar
|
||||
import http.cookies as http_cookies
|
||||
import html.entities as html_entities
|
||||
import html.parser as html_parser
|
||||
import http.client as http_client
|
||||
import http.server as http_server
|
||||
BaseHTTPServer = CGIHTTPServer = SimpleHTTPServer = http.server
|
||||
import pickle as cPickle
|
||||
import queue
|
||||
import reprlib
|
||||
import socketserver
|
||||
import _thread
|
||||
import winreg
|
||||
import xmlrpc.server as xmlrpc_server
|
||||
import xmlrpc.client as xmlrpc_client
|
||||
import urllib.robotparser as urllib_robotparser
|
||||
import email.mime.multipart as email_mime_multipart
|
||||
import email.mime.nonmultipart as email_mime_nonmultipart
|
||||
import email.mime.text as email_mime_text
|
||||
import email.mime.base as email_mime_base
|
||||
import urllib.parse as urllib_parse
|
||||
import urllib.error as urllib_error
|
||||
import tkinter
|
||||
import tkinter.dialog as tkinter_dialog
|
||||
import tkinter.filedialog as tkinter_filedialog
|
||||
import tkinter.scrolledtext as tkinter_scrolledtext
|
||||
import tkinter.simpledialog as tkinder_simpledialog
|
||||
import tkinter.tix as tkinter_tix
|
||||
import tkinter.ttk as tkinter_ttk
|
||||
import tkinter.constants as tkinter_constants
|
||||
import tkinter.dnd as tkinter_dnd
|
||||
import tkinter.colorchooser as tkinter_colorchooser
|
||||
import tkinter.commondialog as tkinter_commondialog
|
||||
import tkinter.filedialog as tkinter_tkfiledialog
|
||||
import tkinter.font as tkinter_font
|
||||
import tkinter.messagebox as tkinter_messagebox
|
||||
import urllib
|
||||
import urllib.request as urllib_request
|
||||
import urllib.robotparser as urllib_robotparser
|
||||
import urllib.parse as urllib_parse
|
||||
import urllib.error as urllib_error
|
||||
"""
|
||||
|
||||
|
||||
def six_moves_transform():
|
||||
code = dedent(
|
||||
"""
|
||||
class Moves(object):
|
||||
{}
|
||||
moves = Moves()
|
||||
"""
|
||||
).format(_indent(_IMPORTS, " "))
|
||||
module = AstroidBuilder(MANAGER).string_build(code)
|
||||
module.name = "six.moves"
|
||||
return module
|
||||
|
||||
|
||||
def _six_fail_hook(modname):
|
||||
"""Fix six.moves imports due to the dynamic nature of this
|
||||
class.
|
||||
|
||||
Construct a pseudo-module which contains all the necessary imports
|
||||
for six
|
||||
|
||||
:param modname: Name of failed module
|
||||
:type modname: str
|
||||
|
||||
:return: An astroid module
|
||||
:rtype: nodes.Module
|
||||
"""
|
||||
|
||||
attribute_of = modname != "six.moves" and modname.startswith("six.moves")
|
||||
if modname != "six.moves" and not attribute_of:
|
||||
raise AstroidBuildingError(modname=modname)
|
||||
module = AstroidBuilder(MANAGER).string_build(_IMPORTS)
|
||||
module.name = "six.moves"
|
||||
if attribute_of:
|
||||
# Facilitate import of submodules in Moves
|
||||
start_index = len(module.name)
|
||||
attribute = modname[start_index:].lstrip(".").replace(".", "_")
|
||||
try:
|
||||
import_attr = module.getattr(attribute)[0]
|
||||
except AttributeInferenceError:
|
||||
raise AstroidBuildingError(modname=modname)
|
||||
if isinstance(import_attr, nodes.Import):
|
||||
submodule = MANAGER.ast_from_module_name(import_attr.names[0][0])
|
||||
return submodule
|
||||
# Let dummy submodule imports pass through
|
||||
# This will cause an Uninferable result, which is okay
|
||||
return module
|
||||
|
||||
|
||||
def _looks_like_decorated_with_six_add_metaclass(node):
|
||||
if not node.decorators:
|
||||
return False
|
||||
|
||||
for decorator in node.decorators.nodes:
|
||||
if not isinstance(decorator, nodes.Call):
|
||||
continue
|
||||
if decorator.func.as_string() == SIX_ADD_METACLASS:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def transform_six_add_metaclass(node):
|
||||
"""Check if the given class node is decorated with *six.add_metaclass*
|
||||
|
||||
If so, inject its argument as the metaclass of the underlying class.
|
||||
"""
|
||||
if not node.decorators:
|
||||
return
|
||||
|
||||
for decorator in node.decorators.nodes:
|
||||
if not isinstance(decorator, nodes.Call):
|
||||
continue
|
||||
|
||||
try:
|
||||
func = next(decorator.func.infer())
|
||||
except InferenceError:
|
||||
continue
|
||||
if func.qname() == SIX_ADD_METACLASS and decorator.args:
|
||||
metaclass = decorator.args[0]
|
||||
node._metaclass = metaclass
|
||||
return node
|
||||
|
||||
|
||||
register_module_extender(MANAGER, "six", six_moves_transform)
|
||||
register_module_extender(
|
||||
MANAGER, "requests.packages.urllib3.packages.six", six_moves_transform
|
||||
)
|
||||
MANAGER.register_failed_import_hook(_six_fail_hook)
|
||||
MANAGER.register_transform(
|
||||
nodes.ClassDef,
|
||||
transform_six_add_metaclass,
|
||||
_looks_like_decorated_with_six_add_metaclass,
|
||||
)
|
74
venv/lib/python3.6/site-packages/astroid/brain/brain_ssl.py
Normal file
74
venv/lib/python3.6/site-packages/astroid/brain/brain_ssl.py
Normal file
@@ -0,0 +1,74 @@
|
||||
# Copyright (c) 2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2016 Ceridwen <ceridwenv@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid hooks for the ssl library."""
|
||||
|
||||
from astroid import MANAGER, register_module_extender
|
||||
from astroid.builder import AstroidBuilder
|
||||
from astroid import nodes
|
||||
from astroid import parse
|
||||
|
||||
|
||||
def ssl_transform():
|
||||
return parse(
|
||||
"""
|
||||
from _ssl import OPENSSL_VERSION_NUMBER, OPENSSL_VERSION_INFO, OPENSSL_VERSION
|
||||
from _ssl import _SSLContext, MemoryBIO
|
||||
from _ssl import (
|
||||
SSLError, SSLZeroReturnError, SSLWantReadError, SSLWantWriteError,
|
||||
SSLSyscallError, SSLEOFError,
|
||||
)
|
||||
from _ssl import CERT_NONE, CERT_OPTIONAL, CERT_REQUIRED
|
||||
from _ssl import txt2obj as _txt2obj, nid2obj as _nid2obj
|
||||
from _ssl import RAND_status, RAND_add, RAND_bytes, RAND_pseudo_bytes
|
||||
try:
|
||||
from _ssl import RAND_egd
|
||||
except ImportError:
|
||||
# LibreSSL does not provide RAND_egd
|
||||
pass
|
||||
from _ssl import (OP_ALL, OP_CIPHER_SERVER_PREFERENCE,
|
||||
OP_NO_COMPRESSION, OP_NO_SSLv2, OP_NO_SSLv3,
|
||||
OP_NO_TLSv1, OP_NO_TLSv1_1, OP_NO_TLSv1_2,
|
||||
OP_SINGLE_DH_USE, OP_SINGLE_ECDH_USE)
|
||||
|
||||
from _ssl import (ALERT_DESCRIPTION_ACCESS_DENIED, ALERT_DESCRIPTION_BAD_CERTIFICATE,
|
||||
ALERT_DESCRIPTION_BAD_CERTIFICATE_HASH_VALUE,
|
||||
ALERT_DESCRIPTION_BAD_CERTIFICATE_STATUS_RESPONSE,
|
||||
ALERT_DESCRIPTION_BAD_RECORD_MAC,
|
||||
ALERT_DESCRIPTION_CERTIFICATE_EXPIRED,
|
||||
ALERT_DESCRIPTION_CERTIFICATE_REVOKED,
|
||||
ALERT_DESCRIPTION_CERTIFICATE_UNKNOWN,
|
||||
ALERT_DESCRIPTION_CERTIFICATE_UNOBTAINABLE,
|
||||
ALERT_DESCRIPTION_CLOSE_NOTIFY, ALERT_DESCRIPTION_DECODE_ERROR,
|
||||
ALERT_DESCRIPTION_DECOMPRESSION_FAILURE,
|
||||
ALERT_DESCRIPTION_DECRYPT_ERROR,
|
||||
ALERT_DESCRIPTION_HANDSHAKE_FAILURE,
|
||||
ALERT_DESCRIPTION_ILLEGAL_PARAMETER,
|
||||
ALERT_DESCRIPTION_INSUFFICIENT_SECURITY,
|
||||
ALERT_DESCRIPTION_INTERNAL_ERROR,
|
||||
ALERT_DESCRIPTION_NO_RENEGOTIATION,
|
||||
ALERT_DESCRIPTION_PROTOCOL_VERSION,
|
||||
ALERT_DESCRIPTION_RECORD_OVERFLOW,
|
||||
ALERT_DESCRIPTION_UNEXPECTED_MESSAGE,
|
||||
ALERT_DESCRIPTION_UNKNOWN_CA,
|
||||
ALERT_DESCRIPTION_UNKNOWN_PSK_IDENTITY,
|
||||
ALERT_DESCRIPTION_UNRECOGNIZED_NAME,
|
||||
ALERT_DESCRIPTION_UNSUPPORTED_CERTIFICATE,
|
||||
ALERT_DESCRIPTION_UNSUPPORTED_EXTENSION,
|
||||
ALERT_DESCRIPTION_USER_CANCELLED)
|
||||
from _ssl import (SSL_ERROR_EOF, SSL_ERROR_INVALID_ERROR_CODE, SSL_ERROR_SSL,
|
||||
SSL_ERROR_SYSCALL, SSL_ERROR_WANT_CONNECT, SSL_ERROR_WANT_READ,
|
||||
SSL_ERROR_WANT_WRITE, SSL_ERROR_WANT_X509_LOOKUP, SSL_ERROR_ZERO_RETURN)
|
||||
from _ssl import VERIFY_CRL_CHECK_CHAIN, VERIFY_CRL_CHECK_LEAF, VERIFY_DEFAULT, VERIFY_X509_STRICT
|
||||
from _ssl import HAS_SNI, HAS_ECDH, HAS_NPN, HAS_ALPN
|
||||
from _ssl import _OPENSSL_API_VERSION
|
||||
from _ssl import PROTOCOL_SSLv23, PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, PROTOCOL_TLSv1_2
|
||||
from _ssl import PROTOCOL_TLS, PROTOCOL_TLS_CLIENT, PROTOCOL_TLS_SERVER
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
register_module_extender(MANAGER, "ssl", ssl_transform)
|
@@ -0,0 +1,119 @@
|
||||
# Copyright (c) 2016-2017 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2017 Hugo <hugovk@users.noreply.github.com>
|
||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
import six
|
||||
|
||||
import astroid
|
||||
|
||||
|
||||
PY37 = sys.version_info >= (3, 7)
|
||||
PY36 = sys.version_info >= (3, 6)
|
||||
PY34 = sys.version_info >= (3, 4)
|
||||
PY33 = sys.version_info >= (3, 3)
|
||||
|
||||
|
||||
def _subprocess_transform():
|
||||
if six.PY3:
|
||||
communicate = (bytes("string", "ascii"), bytes("string", "ascii"))
|
||||
communicate_signature = "def communicate(self, input=None, timeout=None)"
|
||||
if PY37:
|
||||
init = """
|
||||
def __init__(self, args, bufsize=0, executable=None,
|
||||
stdin=None, stdout=None, stderr=None,
|
||||
preexec_fn=None, close_fds=False, shell=False,
|
||||
cwd=None, env=None, universal_newlines=False,
|
||||
startupinfo=None, creationflags=0, restore_signals=True,
|
||||
start_new_session=False, pass_fds=(), *,
|
||||
encoding=None, errors=None, text=None):
|
||||
pass
|
||||
"""
|
||||
elif PY36:
|
||||
init = """
|
||||
def __init__(self, args, bufsize=0, executable=None,
|
||||
stdin=None, stdout=None, stderr=None,
|
||||
preexec_fn=None, close_fds=False, shell=False,
|
||||
cwd=None, env=None, universal_newlines=False,
|
||||
startupinfo=None, creationflags=0, restore_signals=True,
|
||||
start_new_session=False, pass_fds=(), *,
|
||||
encoding=None, errors=None):
|
||||
pass
|
||||
"""
|
||||
else:
|
||||
init = """
|
||||
def __init__(self, args, bufsize=0, executable=None,
|
||||
stdin=None, stdout=None, stderr=None,
|
||||
preexec_fn=None, close_fds=False, shell=False,
|
||||
cwd=None, env=None, universal_newlines=False,
|
||||
startupinfo=None, creationflags=0, restore_signals=True,
|
||||
start_new_session=False, pass_fds=()):
|
||||
pass
|
||||
"""
|
||||
else:
|
||||
communicate = ("string", "string")
|
||||
communicate_signature = "def communicate(self, input=None)"
|
||||
init = """
|
||||
def __init__(self, args, bufsize=0, executable=None,
|
||||
stdin=None, stdout=None, stderr=None,
|
||||
preexec_fn=None, close_fds=False, shell=False,
|
||||
cwd=None, env=None, universal_newlines=False,
|
||||
startupinfo=None, creationflags=0):
|
||||
pass
|
||||
"""
|
||||
if PY34:
|
||||
wait_signature = "def wait(self, timeout=None)"
|
||||
else:
|
||||
wait_signature = "def wait(self)"
|
||||
if six.PY3:
|
||||
ctx_manager = """
|
||||
def __enter__(self): return self
|
||||
def __exit__(self, *args): pass
|
||||
"""
|
||||
else:
|
||||
ctx_manager = ""
|
||||
py3_args = ""
|
||||
if PY33:
|
||||
py3_args = "args = []"
|
||||
code = textwrap.dedent(
|
||||
"""
|
||||
class Popen(object):
|
||||
returncode = pid = 0
|
||||
stdin = stdout = stderr = file()
|
||||
%(py3_args)s
|
||||
|
||||
%(communicate_signature)s:
|
||||
return %(communicate)r
|
||||
%(wait_signature)s:
|
||||
return self.returncode
|
||||
def poll(self):
|
||||
return self.returncode
|
||||
def send_signal(self, signal):
|
||||
pass
|
||||
def terminate(self):
|
||||
pass
|
||||
def kill(self):
|
||||
pass
|
||||
%(ctx_manager)s
|
||||
"""
|
||||
% {
|
||||
"communicate": communicate,
|
||||
"communicate_signature": communicate_signature,
|
||||
"wait_signature": wait_signature,
|
||||
"ctx_manager": ctx_manager,
|
||||
"py3_args": py3_args,
|
||||
}
|
||||
)
|
||||
|
||||
init_lines = textwrap.dedent(init).splitlines()
|
||||
indented_init = "\n".join(" " * 4 + line for line in init_lines)
|
||||
code += indented_init
|
||||
return astroid.parse(code)
|
||||
|
||||
|
||||
astroid.register_module_extender(astroid.MANAGER, "subprocess", _subprocess_transform)
|
@@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2016 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
import astroid
|
||||
|
||||
|
||||
def _thread_transform():
|
||||
return astroid.parse(
|
||||
"""
|
||||
class lock(object):
|
||||
def acquire(self, blocking=True, timeout=-1):
|
||||
pass
|
||||
def release(self):
|
||||
pass
|
||||
def __enter__(self):
|
||||
return True
|
||||
def __exit__(self, *args):
|
||||
pass
|
||||
|
||||
def Lock():
|
||||
return lock()
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
astroid.register_module_extender(astroid.MANAGER, "threading", _thread_transform)
|
@@ -0,0 +1,96 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017-2018 Claudiu Popa <pcmanticore@gmail.com>
|
||||
# Copyright (c) 2017 Łukasz Rogalski <rogalski.91@gmail.com>
|
||||
# Copyright (c) 2017 David Euresti <github@euresti.com>
|
||||
# Copyright (c) 2018 Bryce Guinta <bryce.paul.guinta@gmail.com>
|
||||
|
||||
"""Astroid hooks for typing.py support."""
|
||||
import typing
|
||||
|
||||
from astroid import (
|
||||
MANAGER,
|
||||
UseInferenceDefault,
|
||||
extract_node,
|
||||
inference_tip,
|
||||
nodes,
|
||||
InferenceError,
|
||||
)
|
||||
|
||||
|
||||
TYPING_NAMEDTUPLE_BASENAMES = {"NamedTuple", "typing.NamedTuple"}
|
||||
TYPING_TYPEVARS = {"TypeVar", "NewType"}
|
||||
TYPING_TYPEVARS_QUALIFIED = {"typing.TypeVar", "typing.NewType"}
|
||||
TYPING_TYPE_TEMPLATE = """
|
||||
class Meta(type):
|
||||
def __getitem__(self, item):
|
||||
return self
|
||||
|
||||
@property
|
||||
def __args__(self):
|
||||
return ()
|
||||
|
||||
class {0}(metaclass=Meta):
|
||||
pass
|
||||
"""
|
||||
TYPING_MEMBERS = set(typing.__all__)
|
||||
|
||||
|
||||
def looks_like_typing_typevar_or_newtype(node):
|
||||
func = node.func
|
||||
if isinstance(func, nodes.Attribute):
|
||||
return func.attrname in TYPING_TYPEVARS
|
||||
if isinstance(func, nodes.Name):
|
||||
return func.name in TYPING_TYPEVARS
|
||||
return False
|
||||
|
||||
|
||||
def infer_typing_typevar_or_newtype(node, context=None):
|
||||
"""Infer a typing.TypeVar(...) or typing.NewType(...) call"""
|
||||
try:
|
||||
func = next(node.func.infer(context=context))
|
||||
except InferenceError as exc:
|
||||
raise UseInferenceDefault from exc
|
||||
|
||||
if func.qname() not in TYPING_TYPEVARS_QUALIFIED:
|
||||
raise UseInferenceDefault
|
||||
if not node.args:
|
||||
raise UseInferenceDefault
|
||||
|
||||
typename = node.args[0].as_string().strip("'")
|
||||
node = extract_node(TYPING_TYPE_TEMPLATE.format(typename))
|
||||
return node.infer(context=context)
|
||||
|
||||
|
||||
def _looks_like_typing_subscript(node):
|
||||
"""Try to figure out if a Subscript node *might* be a typing-related subscript"""
|
||||
if isinstance(node, nodes.Name):
|
||||
return node.name in TYPING_MEMBERS
|
||||
elif isinstance(node, nodes.Attribute):
|
||||
return node.attrname in TYPING_MEMBERS
|
||||
elif isinstance(node, nodes.Subscript):
|
||||
return _looks_like_typing_subscript(node.value)
|
||||
return False
|
||||
|
||||
|
||||
def infer_typing_attr(node, context=None):
|
||||
"""Infer a typing.X[...] subscript"""
|
||||
try:
|
||||
value = next(node.value.infer())
|
||||
except InferenceError as exc:
|
||||
raise UseInferenceDefault from exc
|
||||
|
||||
if not value.qname().startswith("typing."):
|
||||
raise UseInferenceDefault
|
||||
|
||||
node = extract_node(TYPING_TYPE_TEMPLATE.format(value.qname().split(".")[-1]))
|
||||
return node.infer(context=context)
|
||||
|
||||
|
||||
MANAGER.register_transform(
|
||||
nodes.Call,
|
||||
inference_tip(infer_typing_typevar_or_newtype),
|
||||
looks_like_typing_typevar_or_newtype,
|
||||
)
|
||||
MANAGER.register_transform(
|
||||
nodes.Subscript, inference_tip(infer_typing_attr), _looks_like_typing_subscript
|
||||
)
|
20
venv/lib/python3.6/site-packages/astroid/brain/brain_uuid.py
Normal file
20
venv/lib/python3.6/site-packages/astroid/brain/brain_uuid.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2017 Claudiu Popa <pcmanticore@gmail.com>
|
||||
|
||||
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
|
||||
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
|
||||
|
||||
"""Astroid hooks for the UUID module."""
|
||||
|
||||
|
||||
from astroid import MANAGER
|
||||
from astroid import nodes
|
||||
|
||||
|
||||
def _patch_uuid_class(node):
|
||||
# The .int member is patched using __dict__
|
||||
node.locals["int"] = [nodes.Const(0, parent=node)]
|
||||
|
||||
|
||||
MANAGER.register_transform(
|
||||
nodes.ClassDef, _patch_uuid_class, lambda node: node.qname() == "uuid.UUID"
|
||||
)
|
Reference in New Issue
Block a user