1import inspect 2import types 3import traceback 4import sys 5import operator as op 6from collections import namedtuple 7import warnings 8import re 9import builtins 10import typing 11 12from jedi.inference.compiled.getattr_static import getattr_static 13 14ALLOWED_GETITEM_TYPES = (str, list, tuple, bytes, bytearray, dict) 15 16MethodDescriptorType = type(str.replace) 17# These are not considered classes and access is granted even though they have 18# a __class__ attribute. 19NOT_CLASS_TYPES = ( 20 types.BuiltinFunctionType, 21 types.CodeType, 22 types.FrameType, 23 types.FunctionType, 24 types.GeneratorType, 25 types.GetSetDescriptorType, 26 types.LambdaType, 27 types.MemberDescriptorType, 28 types.MethodType, 29 types.ModuleType, 30 types.TracebackType, 31 MethodDescriptorType, 32 types.MappingProxyType, 33 types.SimpleNamespace, 34 types.DynamicClassAttribute, 35) 36 37# Those types don't exist in typing. 38MethodDescriptorType = type(str.replace) 39WrapperDescriptorType = type(set.__iter__) 40# `object.__subclasshook__` is an already executed descriptor. 41object_class_dict = type.__dict__["__dict__"].__get__(object) 42ClassMethodDescriptorType = type(object_class_dict['__subclasshook__']) 43 44_sentinel = object() 45 46# Maps Python syntax to the operator module. 47COMPARISON_OPERATORS = { 48 '==': op.eq, 49 '!=': op.ne, 50 'is': op.is_, 51 'is not': op.is_not, 52 '<': op.lt, 53 '<=': op.le, 54 '>': op.gt, 55 '>=': op.ge, 56} 57 58_OPERATORS = { 59 '+': op.add, 60 '-': op.sub, 61} 62_OPERATORS.update(COMPARISON_OPERATORS) 63 64ALLOWED_DESCRIPTOR_ACCESS = ( 65 types.FunctionType, 66 types.GetSetDescriptorType, 67 types.MemberDescriptorType, 68 MethodDescriptorType, 69 WrapperDescriptorType, 70 ClassMethodDescriptorType, 71 staticmethod, 72 classmethod, 73) 74 75 76def safe_getattr(obj, name, default=_sentinel): 77 try: 78 attr, is_get_descriptor = getattr_static(obj, name) 79 except AttributeError: 80 if default is _sentinel: 81 raise 82 return default 83 else: 84 if isinstance(attr, ALLOWED_DESCRIPTOR_ACCESS): 85 # In case of descriptors that have get methods we cannot return 86 # it's value, because that would mean code execution. 87 # Since it's an isinstance call, code execution is still possible, 88 # but this is not really a security feature, but much more of a 89 # safety feature. Code execution is basically always possible when 90 # a module is imported. This is here so people don't shoot 91 # themselves in the foot. 92 return getattr(obj, name) 93 return attr 94 95 96SignatureParam = namedtuple( 97 'SignatureParam', 98 'name has_default default default_string has_annotation annotation annotation_string kind_name' 99) 100 101 102def shorten_repr(func): 103 def wrapper(self): 104 r = func(self) 105 if len(r) > 50: 106 r = r[:50] + '..' 107 return r 108 return wrapper 109 110 111def create_access(inference_state, obj): 112 return inference_state.compiled_subprocess.get_or_create_access_handle(obj) 113 114 115def load_module(inference_state, dotted_name, sys_path): 116 temp, sys.path = sys.path, sys_path 117 try: 118 __import__(dotted_name) 119 except ImportError: 120 # If a module is "corrupt" or not really a Python module or whatever. 121 warnings.warn( 122 "Module %s not importable in path %s." % (dotted_name, sys_path), 123 UserWarning, 124 stacklevel=2, 125 ) 126 return None 127 except Exception: 128 # Since __import__ pretty much makes code execution possible, just 129 # catch any error here and print it. 130 warnings.warn( 131 "Cannot import:\n%s" % traceback.format_exc(), UserWarning, stacklevel=2 132 ) 133 return None 134 finally: 135 sys.path = temp 136 137 # Just access the cache after import, because of #59 as well as the very 138 # complicated import structure of Python. 139 module = sys.modules[dotted_name] 140 return create_access_path(inference_state, module) 141 142 143class AccessPath: 144 def __init__(self, accesses): 145 self.accesses = accesses 146 147 148def create_access_path(inference_state, obj): 149 access = create_access(inference_state, obj) 150 return AccessPath(access.get_access_path_tuples()) 151 152 153def get_api_type(obj): 154 if inspect.isclass(obj): 155 return 'class' 156 elif inspect.ismodule(obj): 157 return 'module' 158 elif inspect.isbuiltin(obj) or inspect.ismethod(obj) \ 159 or inspect.ismethoddescriptor(obj) or inspect.isfunction(obj): 160 return 'function' 161 # Everything else... 162 return 'instance' 163 164 165class DirectObjectAccess: 166 def __init__(self, inference_state, obj): 167 self._inference_state = inference_state 168 self._obj = obj 169 170 def __repr__(self): 171 return '%s(%s)' % (self.__class__.__name__, self.get_repr()) 172 173 def _create_access(self, obj): 174 return create_access(self._inference_state, obj) 175 176 def _create_access_path(self, obj): 177 return create_access_path(self._inference_state, obj) 178 179 def py__bool__(self): 180 return bool(self._obj) 181 182 def py__file__(self): 183 try: 184 return self._obj.__file__ 185 except AttributeError: 186 return None 187 188 def py__doc__(self): 189 return inspect.getdoc(self._obj) or '' 190 191 def py__name__(self): 192 if not _is_class_instance(self._obj) or \ 193 inspect.ismethoddescriptor(self._obj): # slots 194 cls = self._obj 195 else: 196 try: 197 cls = self._obj.__class__ 198 except AttributeError: 199 # happens with numpy.core.umath._UFUNC_API (you get it 200 # automatically by doing `import numpy`. 201 return None 202 203 try: 204 return cls.__name__ 205 except AttributeError: 206 return None 207 208 def py__mro__accesses(self): 209 return tuple(self._create_access_path(cls) for cls in self._obj.__mro__[1:]) 210 211 def py__getitem__all_values(self): 212 if isinstance(self._obj, dict): 213 return [self._create_access_path(v) for v in self._obj.values()] 214 return self.py__iter__list() 215 216 def py__simple_getitem__(self, index): 217 if type(self._obj) not in ALLOWED_GETITEM_TYPES: 218 # Get rid of side effects, we won't call custom `__getitem__`s. 219 return None 220 221 return self._create_access_path(self._obj[index]) 222 223 def py__iter__list(self): 224 if not hasattr(self._obj, '__getitem__'): 225 return None 226 227 if type(self._obj) not in ALLOWED_GETITEM_TYPES: 228 # Get rid of side effects, we won't call custom `__getitem__`s. 229 return [] 230 231 lst = [] 232 for i, part in enumerate(self._obj): 233 if i > 20: 234 # Should not go crazy with large iterators 235 break 236 lst.append(self._create_access_path(part)) 237 return lst 238 239 def py__class__(self): 240 return self._create_access_path(self._obj.__class__) 241 242 def py__bases__(self): 243 return [self._create_access_path(base) for base in self._obj.__bases__] 244 245 def py__path__(self): 246 paths = getattr(self._obj, '__path__', None) 247 # Avoid some weird hacks that would just fail, because they cannot be 248 # used by pickle. 249 if not isinstance(paths, list) \ 250 or not all(isinstance(p, str) for p in paths): 251 return None 252 return paths 253 254 @shorten_repr 255 def get_repr(self): 256 if inspect.ismodule(self._obj): 257 return repr(self._obj) 258 # Try to avoid execution of the property. 259 if safe_getattr(self._obj, '__module__', default='') == 'builtins': 260 return repr(self._obj) 261 262 type_ = type(self._obj) 263 if type_ == type: 264 return type.__repr__(self._obj) 265 266 if safe_getattr(type_, '__module__', default='') == 'builtins': 267 # Allow direct execution of repr for builtins. 268 return repr(self._obj) 269 return object.__repr__(self._obj) 270 271 def is_class(self): 272 return inspect.isclass(self._obj) 273 274 def is_function(self): 275 return inspect.isfunction(self._obj) or inspect.ismethod(self._obj) 276 277 def is_module(self): 278 return inspect.ismodule(self._obj) 279 280 def is_instance(self): 281 return _is_class_instance(self._obj) 282 283 def ismethoddescriptor(self): 284 return inspect.ismethoddescriptor(self._obj) 285 286 def get_qualified_names(self): 287 def try_to_get_name(obj): 288 return getattr(obj, '__qualname__', getattr(obj, '__name__', None)) 289 290 if self.is_module(): 291 return () 292 name = try_to_get_name(self._obj) 293 if name is None: 294 name = try_to_get_name(type(self._obj)) 295 if name is None: 296 return () 297 return tuple(name.split('.')) 298 299 def dir(self): 300 return dir(self._obj) 301 302 def has_iter(self): 303 try: 304 iter(self._obj) 305 return True 306 except TypeError: 307 return False 308 309 def is_allowed_getattr(self, name, unsafe=False): 310 # TODO this API is ugly. 311 if unsafe: 312 # Unsafe is mostly used to check for __getattr__/__getattribute__. 313 # getattr_static works for properties, but the underscore methods 314 # are just ignored (because it's safer and avoids more code 315 # execution). See also GH #1378. 316 317 # Avoid warnings, see comment in the next function. 318 with warnings.catch_warnings(record=True): 319 warnings.simplefilter("always") 320 try: 321 return hasattr(self._obj, name), False 322 except Exception: 323 # Obviously has an attribute (propably a property) that 324 # gets executed, so just avoid all exceptions here. 325 return False, False 326 try: 327 attr, is_get_descriptor = getattr_static(self._obj, name) 328 except AttributeError: 329 return False, False 330 else: 331 if is_get_descriptor and type(attr) not in ALLOWED_DESCRIPTOR_ACCESS: 332 # In case of descriptors that have get methods we cannot return 333 # it's value, because that would mean code execution. 334 return True, True 335 return True, False 336 337 def getattr_paths(self, name, default=_sentinel): 338 try: 339 # Make sure no warnings are printed here, this is autocompletion, 340 # warnings should not be shown. See also GH #1383. 341 with warnings.catch_warnings(record=True): 342 warnings.simplefilter("always") 343 return_obj = getattr(self._obj, name) 344 except Exception as e: 345 if default is _sentinel: 346 if isinstance(e, AttributeError): 347 # Happens e.g. in properties of 348 # PyQt4.QtGui.QStyleOptionComboBox.currentText 349 # -> just set it to None 350 raise 351 # Just in case anything happens, return an AttributeError. It 352 # should not crash. 353 raise AttributeError 354 return_obj = default 355 access = self._create_access(return_obj) 356 if inspect.ismodule(return_obj): 357 return [access] 358 359 try: 360 module = return_obj.__module__ 361 except AttributeError: 362 pass 363 else: 364 if module is not None: 365 try: 366 __import__(module) 367 # For some modules like _sqlite3, the __module__ for classes is 368 # different, in this case it's sqlite3. So we have to try to 369 # load that "original" module, because it's not loaded yet. If 370 # we don't do that, we don't really have a "parent" module and 371 # we would fall back to builtins. 372 except ImportError: 373 pass 374 375 module = inspect.getmodule(return_obj) 376 if module is None: 377 module = inspect.getmodule(type(return_obj)) 378 if module is None: 379 module = builtins 380 return [self._create_access(module), access] 381 382 def get_safe_value(self): 383 if type(self._obj) in (bool, bytes, float, int, str, slice) or self._obj is None: 384 return self._obj 385 raise ValueError("Object is type %s and not simple" % type(self._obj)) 386 387 def get_api_type(self): 388 return get_api_type(self._obj) 389 390 def get_array_type(self): 391 if isinstance(self._obj, dict): 392 return 'dict' 393 return None 394 395 def get_key_paths(self): 396 def iter_partial_keys(): 397 # We could use list(keys()), but that might take a lot more memory. 398 for (i, k) in enumerate(self._obj.keys()): 399 # Limit key listing at some point. This is artificial, but this 400 # way we don't get stalled because of slow completions 401 if i > 50: 402 break 403 yield k 404 405 return [self._create_access_path(k) for k in iter_partial_keys()] 406 407 def get_access_path_tuples(self): 408 accesses = [create_access(self._inference_state, o) for o in self._get_objects_path()] 409 return [(access.py__name__(), access) for access in accesses] 410 411 def _get_objects_path(self): 412 def get(): 413 obj = self._obj 414 yield obj 415 try: 416 obj = obj.__objclass__ 417 except AttributeError: 418 pass 419 else: 420 yield obj 421 422 try: 423 # Returns a dotted string path. 424 imp_plz = obj.__module__ 425 except AttributeError: 426 # Unfortunately in some cases like `int` there's no __module__ 427 if not inspect.ismodule(obj): 428 yield builtins 429 else: 430 if imp_plz is None: 431 # Happens for example in `(_ for _ in []).send.__module__`. 432 yield builtins 433 else: 434 try: 435 yield sys.modules[imp_plz] 436 except KeyError: 437 # __module__ can be something arbitrary that doesn't exist. 438 yield builtins 439 440 return list(reversed(list(get()))) 441 442 def execute_operation(self, other_access_handle, operator): 443 other_access = other_access_handle.access 444 op = _OPERATORS[operator] 445 return self._create_access_path(op(self._obj, other_access._obj)) 446 447 def get_annotation_name_and_args(self): 448 """ 449 Returns Tuple[Optional[str], Tuple[AccessPath, ...]] 450 """ 451 name = None 452 args = () 453 if safe_getattr(self._obj, '__module__', default='') == 'typing': 454 m = re.match(r'typing.(\w+)\[', repr(self._obj)) 455 if m is not None: 456 name = m.group(1) 457 458 import typing 459 if sys.version_info >= (3, 8): 460 args = typing.get_args(self._obj) 461 else: 462 args = safe_getattr(self._obj, '__args__', default=None) 463 return name, tuple(self._create_access_path(arg) for arg in args) 464 465 def needs_type_completions(self): 466 return inspect.isclass(self._obj) and self._obj != type 467 468 def _annotation_to_str(self, annotation): 469 return inspect.formatannotation(annotation) 470 471 def get_signature_params(self): 472 return [ 473 SignatureParam( 474 name=p.name, 475 has_default=p.default is not p.empty, 476 default=self._create_access_path(p.default), 477 default_string=repr(p.default), 478 has_annotation=p.annotation is not p.empty, 479 annotation=self._create_access_path(p.annotation), 480 annotation_string=self._annotation_to_str(p.annotation), 481 kind_name=str(p.kind) 482 ) for p in self._get_signature().parameters.values() 483 ] 484 485 def _get_signature(self): 486 obj = self._obj 487 try: 488 return inspect.signature(obj) 489 except (RuntimeError, TypeError): 490 # Reading the code of the function in Python 3.6 implies there are 491 # at least these errors that might occur if something is wrong with 492 # the signature. In that case we just want a simple escape for now. 493 raise ValueError 494 495 def get_return_annotation(self): 496 try: 497 o = self._obj.__annotations__.get('return') 498 except AttributeError: 499 return None 500 501 if o is None: 502 return None 503 504 try: 505 o = typing.get_type_hints(self._obj).get('return') 506 except Exception: 507 pass 508 509 return self._create_access_path(o) 510 511 def negate(self): 512 return self._create_access_path(-self._obj) 513 514 def get_dir_infos(self): 515 """ 516 Used to return a couple of infos that are needed when accessing the sub 517 objects of an objects 518 """ 519 tuples = dict( 520 (name, self.is_allowed_getattr(name)) 521 for name in self.dir() 522 ) 523 return self.needs_type_completions(), tuples 524 525 526def _is_class_instance(obj): 527 """Like inspect.* methods.""" 528 try: 529 cls = obj.__class__ 530 except AttributeError: 531 return False 532 else: 533 # The isinstance check for cls is just there so issubclass doesn't 534 # raise an exception. 535 return cls != type and isinstance(cls, type) and not issubclass(cls, NOT_CLASS_TYPES) 536