1 # Python Tools for Visual Studio
\r
2 # Copyright(c) Microsoft Corporation
\r
3 # All rights reserved.
\r
5 # Licensed under the Apache License, Version 2.0 (the License); you may not use
\r
6 # this file except in compliance with the License. You may obtain a copy of the
\r
7 # License at http://www.apache.org/licenses/LICENSE-2.0
\r
9 # THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
\r
10 # OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
\r
11 # IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
\r
12 # MERCHANTABLITY OR NON-INFRINGEMENT.
\r
14 # See the Apache Version 2.0 License for specific language governing
\r
15 # permissions and limitations under the License.
\r
17 from __future__ import print_function
\r
19 __author__ = "Microsoft Corporation <ptvshelp@microsoft.com>"
\r
20 __version__ = "15.8"
\r
31 if sys.version_info >= (3, 0):
\r
35 import __builtin__ as builtins
\r
37 import __builtin__ as builtins
\r
49 class InspectWarning(UserWarning): pass
\r
51 def _triple_quote(s):
\r
53 return "'''" + s + "'''"
\r
55 return '"""' + s + '"""'
\r
56 if not s.startswith("'"):
\r
57 return "'''" + s.replace("'''", "\\'\\'\\'") + " '''"
\r
58 if not s.startswith('"'):
\r
59 return '"""' + s.replace('"""', '\\"\\"\\"') + ' """'
\r
60 return "''' " + s.replace("'''", "\\'\\'\\'") + " '''"
\r
63 EXACT_TOKEN_TYPES = tokenize.EXACT_TOKEN_TYPES
\r
64 except AttributeError:
\r
65 # Bare minimum that we need here
\r
66 EXACT_TOKEN_TYPES = {
\r
71 '{': tokenize.LBRACE,
\r
72 '}': tokenize.RBRACE,
\r
73 ',': tokenize.COMMA,
\r
74 ':': tokenize.COLON,
\r
76 '**': tokenize.DOUBLESTAR,
\r
77 '=': tokenize.EQUAL,
\r
80 SKIP_TYPENAME_FOR_TYPES = bool, str, bytes, int, float
\r
81 STATICMETHOD_TYPES = ()
\r
82 CLASSMETHOD_TYPES = type(float.fromhex),
\r
83 PROPERTY_TYPES = type(int.real), type(property.fget)
\r
85 INVALID_ARGNAMES = set(keyword.kwlist) | set(('None', 'True', 'False'))
\r
87 # These full names are known to be lies. When we encounter
\r
88 # them while scraping a module, assume that we need to write
\r
89 # out the full type rather than including them by reference.
\r
90 LIES_ABOUT_MODULE = frozenset([
\r
91 builtins.__name__ + ".weakcallableproxy",
\r
92 builtins.__name__ + ".weakproxy",
\r
93 builtins.__name__ + ".weakref",
\r
94 "ctypes.ArgumentError",
\r
96 "os.statvfs_result",
\r
97 "xml.parsers.expat.ExpatError",
\r
100 "numpy.busdaycalendar",
\r
107 # These modules contain multiple members that lie about their
\r
108 # module. Always write out all members of these in full.
\r
116 "_testmultiphase.*",
\r
119 # These type names cause conflicts with their values, so
\r
120 # we need to forcibly rename them.
\r
121 SYS_INFO_TYPES = frozenset((
\r
130 float('inf'): "float('inf')",
\r
131 float('-inf'): "float('-inf')",
\r
134 IMPLICIT_CLASSMETHOD = (
\r
138 if sys.version_info[0] < 3:
\r
139 SKIP_TYPENAME_FOR_TYPES += unicode, long
\r
141 def safe_callable(v):
\r
143 return hasattr(v, '__call__')
\r
147 def safe_module_name(n):
\r
149 return '_mod_' + n.replace('.', '_')
\r
152 def do_not_inspect(v):
\r
153 # https://github.com/Microsoft/python-language-server/issues/740
\r
154 # https://github.com/cython/cython/issues/1470
\r
155 if type(v).__name__ != "fused_cython_function":
\r
158 # If a fused function has __defaults__, then attempting to access
\r
159 # __kwdefaults__ will fail if generated before cython 0.29.6.
\r
160 return bool(getattr(v, "__defaults__", False))
\r
162 class Signature(object):
\r
163 # These two dictionaries start with Python 3 values.
\r
164 # There is an update below for Python 2 differences.
\r
165 # They will be used as fallbacks for known protocols
\r
168 "__abs__": "__T__()",
\r
169 "__add__": "__T__()",
\r
170 "__and__": "__T__()",
\r
171 "__annotations__": "{}",
\r
172 "__base__": "type",
\r
173 "__bases__": "(type,)",
\r
174 "__bool__": "False",
\r
176 "__ceil__": "__T__()",
\r
177 "__code__": "object()",
\r
178 "__contains__": "False",
\r
180 "__delattr__": "None",
\r
181 "__delitem__": "None",
\r
182 "__dict__": "{'': Any}",
\r
184 "__divmod__": "(0, 0)",
\r
186 "__format__": "''",
\r
187 "__float__": "0.0",
\r
188 "__floor__": "__T__()",
\r
189 "__floordiv__": "0",
\r
191 "__get__": "__T__()",
\r
192 "__getattribute__": "Any",
\r
193 "__getitem__": "Any",
\r
194 "__getnewargs__": "()",
\r
195 "__getnewargs_ex__": "((), {})",
\r
196 "__getslice__": "__T__()",
\r
197 "__globals__": "{}",
\r
200 "__iadd__": "None",
\r
201 "__iand__": "None",
\r
202 "__imul__": "None",
\r
205 "__init_subclass__": "None",
\r
207 "__invert__": "__T__()",
\r
209 "__isub__": "None",
\r
210 "__iter__": "__T__()",
\r
211 "__ixor__": "None",
\r
214 "__length_hint__": "0",
\r
215 "__lshift__": "__T__()",
\r
217 "__mod__": "__T__()",
\r
218 "__mul__": "__T__()",
\r
220 "__neg__": "__T__()",
\r
222 "__pos__": "__T__()",
\r
223 "__pow__": "__T__()",
\r
224 "__or__": "__T__()",
\r
225 "__radd__": "__T__()",
\r
226 "__rand__": "__T__()",
\r
227 "__rdivmod__": "(0, 0)",
\r
228 "__rfloordiv__": "__T__()",
\r
229 "__rlshift__": "__T__()",
\r
230 "__rmod__": "__T__()",
\r
231 "__rmul__": "__T__()",
\r
232 "__ror__": "__T__()",
\r
233 "__round__": "__T__()",
\r
234 "__rpow__": "__T__()",
\r
235 "__rrshift__": "__T__()",
\r
236 "__rshift__": "__T__()",
\r
237 "__rsub__": "__T__()",
\r
238 "__rtruediv__": "__T__()",
\r
239 "__rxor__": "__T__()",
\r
240 "__reduce__": ["''", "()"],
\r
241 "__reduce_ex__": ["''", "()"],
\r
244 "__setattr__": "None",
\r
245 "__setitem__": "None",
\r
246 "__setstate__": "None",
\r
249 "__sub__": "__T__()",
\r
250 "__truediv__": "0.0",
\r
251 "__trunc__": "__T__()",
\r
252 "__xor__": "__T__()",
\r
253 "__subclasscheck__": "False",
\r
254 "__subclasshook__": "False",
\r
258 "__contains__": "(self, value)",
\r
259 "__del__": "(self)",
\r
260 "__dir__": "(self)",
\r
261 "__floor__": "(self)",
\r
262 "__format__": "(self, format_spec)",
\r
263 "__getitem__": "(self, index)",
\r
264 "__getnewargs__": "(self)",
\r
265 "__getnewargs_ex__": "(self)",
\r
266 "__init_subclass__": "(cls)",
\r
267 "__instancecheck__": "(self, instance)",
\r
268 "__length_hint__": "(self)",
\r
269 "__prepare__": "(cls, name, bases, **kwds)",
\r
270 "__round__": "(self, ndigits=0)",
\r
271 "__reduce__": "(self)",
\r
272 "__reduce_ex__": "(self, protocol)",
\r
273 "__reversed__": "(self)",
\r
274 "__setitem__": "(self, index, value)",
\r
275 "__setstate__": "(self, state)",
\r
276 "__sizeof__": "(self)",
\r
277 "__subclasses__": "(cls)",
\r
278 "__subclasscheck__": "(cls, subclass)",
\r
279 "__subclasshook__": "(cls, subclass)",
\r
280 "__trunc__": "(self)",
\r
293 self.callable = callable
\r
296 self.decorators = decorators or ()
\r
297 self._signature = None
\r
298 self._defaults = defaults or ()
\r
300 if scope and '@staticmethod' not in self.decorators:
\r
301 def_arg = 'cls' if ('@classmethod' in self.decorators or name in IMPLICIT_CLASSMETHOD) else 'self'
\r
302 if len(self._defaults) == 0 or self._defaults[0] != def_arg:
\r
303 self._defaults = (def_arg,) + self._defaults
\r
305 self.fullsig = None
\r
306 if self.name in ('__init__', '__new__') and module_doc:
\r
307 self.fullsig = self._init_argspec_fromdocstring(self._defaults, module_doc, override_name=self.name)
\r
308 elif not hasattr(self.callable, '__call__') and hasattr(self.callable, '__get__'):
\r
309 # We have a property
\r
310 self.decorators = '@property',
\r
311 self.fullsig = self.name + "(" + ", ".join(self._defaults) + ")"
\r
313 if scope_alias == "__Object__" and name == "__init__":
\r
314 self.fullsig = "__init__(self)"
\r
318 # Disable fromsignature() because it doesn't work as well as argspec
\r
319 #self._init_argspec_fromsignature(self._defaults) or
\r
320 self._init_argspec_fromargspec(self._defaults) or
\r
321 self._init_argspec_fromknown(self._defaults, scope_alias) or
\r
322 self._init_argspec_fromdocstring(self._defaults) or
\r
323 (self.name + "(" + ", ".join(self._defaults) + ")")
\r
326 self._init_restype_fromsignature() or
\r
327 self._init_restype_fromknown(scope_alias) or
\r
328 self._init_restype_fromdocstring() or
\r
333 self.restype = self.restype.replace('__T__', scope)
\r
335 if self.restype in ('return Any', 'return Unknown'):
\r
336 self.restype = 'pass'
\r
338 #Special case for 'with' statement and built-ins like open() or memoryview
\r
339 if name == '__enter__' and self.restype == 'pass':
\r
340 self.restype = 'return self'
\r
343 return self.fullsig
\r
345 def _init_argspec_fromsignature(self, defaults):
\r
346 if do_not_inspect(self.callable):
\r
350 sig = inspect.signature(self.callable)
\r
355 for arg in sig.parameters:
\r
356 p = sig.parameters[arg]
\r
357 if p.default != inspect.Signature.empty:
\r
359 ast.literal_eval(repr(p.default))
\r
361 p = p.replace(default=None)
\r
362 if p.kind == inspect.Parameter.POSITIONAL_ONLY:
\r
363 p = p.replace(kind=inspect.Parameter.POSITIONAL_OR_KEYWORD)
\r
365 sig = sig.replace(parameters=new_args)
\r
367 return self.name + str(sig)
\r
369 def _init_restype_fromsignature(self):
\r
370 if do_not_inspect(self.callable):
\r
374 sig = inspect.signature(self.callable)
\r
378 # If signature has a return annotation, it's in the
\r
379 # full signature and we don't need it from here.
\r
380 if not sig or sig.return_annotation == inspect._empty:
\r
382 ann = inspect.formatannotation(sig.return_annotation)
\r
383 if not ann or not self._can_eval(ann):
\r
385 return 'return ' + ann
\r
387 def _init_argspec_fromargspec(self, defaults):
\r
388 if do_not_inspect(self.callable):
\r
392 args = (getattr(inspect, 'getfullargspec', None) or inspect.getargspec)(self.callable)
\r
397 seen_names = set(INVALID_ARGNAMES)
\r
398 defaults = list(defaults)
\r
399 default_set = set(defaults)
\r
400 for a in args.args:
\r
401 if a in default_set:
\r
402 default_set.discard(a)
\r
403 argn.append(self._make_unique_name(a, seen_names))
\r
405 argn[:0] = [a for a in defaults if a in default_set]
\r
407 if getattr(args, 'varargs', None):
\r
408 argn.append('*' + args.varargs)
\r
409 if getattr(args, 'varkw', None):
\r
410 argn.append('**' + args.varkw)
\r
412 if argn and argn[-1] in ('*', '**'):
\r
413 argn[-1] += self._make_unique_name('_', seen_names)
\r
415 return self.name + '(' + ', '.join(argn) + ')'
\r
417 def _init_argspec_fromknown(self, defaults, scope_alias):
\r
419 if scope_alias and not spec:
\r
420 spec = self.KNOWN_ARGSPECS.get(scope_alias + '.' + self.name)
\r
421 if self.scope and not spec:
\r
422 spec = self.KNOWN_ARGSPECS.get(self.scope + '.' + self.name)
\r
424 spec = self.KNOWN_ARGSPECS.get(self.name)
\r
428 return self.name + spec
\r
430 def _init_restype_fromknown(self, scope_alias):
\r
432 if scope_alias and not restype:
\r
433 restype = self.KNOWN_RESTYPES.get(scope_alias + '.' + self.name)
\r
434 if self.scope and not restype:
\r
435 restype = self.KNOWN_RESTYPES.get(self.scope + '.' + self.name)
\r
437 restype = self.KNOWN_RESTYPES.get(self.name)
\r
441 if isinstance(restype, list):
\r
442 return "return " + "; return ".join(restype)
\r
443 return "return " + restype
\r
445 def _init_restype_fromdocstring(self):
\r
446 doc = getattr(self.callable, '__doc__', None)
\r
447 if not isinstance(doc, str):
\r
450 first_line = doc.partition('\n')[0].strip()
\r
451 if not '->' in first_line:
\r
454 index = first_line.index('->')
\r
455 typeName = first_line[index + 2:].strip()
\r
457 if typeName.startswith('str'):
\r
459 if typeName.startswith('float'):
\r
460 return "return 1.0"
\r
461 if typeName.startswith('int'):
\r
463 if typeName.startswith('long'):
\r
464 if sys.version_info[0] < 3:
\r
468 if typeName.startswith('list'):
\r
469 return "return list()"
\r
470 if typeName.startswith('dict'):
\r
471 return "return dict()"
\r
472 if typeName.startswith('('):
\r
473 return "return tuple()"
\r
474 if typeName.startswith('bool'):
\r
475 return "return True"
\r
476 if 'Return a string' in first_line:
\r
480 def _init_argspec_fromdocstring(self, defaults, doc=None, override_name=None):
\r
482 doc = getattr(self.callable, '__doc__', None)
\r
483 if not isinstance(doc, str):
\r
486 doc = self._get_first_function_call(doc)
\r
491 allow_name_mismatch = override_name not in doc
\r
493 allow_name_mismatch = False
\r
495 return self._parse_funcdef(doc, allow_name_mismatch, defaults, override_name)
\r
497 def _make_unique_name(self, name, seen_names):
\r
498 if name not in seen_names:
\r
499 seen_names.add(name)
\r
503 if n not in seen_names:
\r
510 n = name + '_' + str(i)
\r
511 if n not in seen_names:
\r
515 raise RuntimeError("Too many arguments in definition")
\r
517 def _tokenize(self, expr):
\r
518 if sys.version_info[0] == 3 and sys.version_info[1] <= 2:
\r
519 expr = '# coding: utf-8\n' + expr
\r
520 buf = io.BytesIO(expr.strip().encode('utf-8'))
\r
521 if sys.version_info[0] == 3:
\r
522 tokens = tokenize.tokenize(buf.readline)
\r
524 tokens = tokenize.generate_tokens(buf.readline)
\r
525 return [(EXACT_TOKEN_TYPES.get(s, tt) if tt == tokenize.OP else tt, s)
\r
526 for tt, s, _, _, _ in tokens]
\r
528 _PAREN_TOKEN_MAP = {
\r
529 tokenize.LPAR: tokenize.RPAR,
\r
530 tokenize.LBRACE: tokenize.RBRACE,
\r
531 tokenize.LSQB: tokenize.RSQB,
\r
534 def _parse_take_expr(self, tokens, *stop_at):
\r
539 if tt == tokenize.LSQB and len(tokens) > 2 and tokens[1][0] in stop_at:
\r
541 if tt in self._PAREN_TOKEN_MAP:
\r
542 expr.append((tt, s))
\r
543 nesting.append(self._PAREN_TOKEN_MAP[tt])
\r
544 elif nesting and tt == nesting[-1]:
\r
545 expr.append((tt, s))
\r
547 elif tt in (tokenize.RPAR, tokenize.RBRACE, tokenize.RSQB):
\r
549 elif not nesting and tt in stop_at:
\r
552 expr.append((tt, s))
\r
556 def _can_eval(self, s):
\r
560 ast.parse(s, mode='eval')
\r
561 except SyntaxError:
\r
566 def _parse_format_arg(self, name, args, defaults):
\r
567 defaults = list(defaults)
\r
568 default_set = set(defaults)
\r
569 seen_names = set(INVALID_ARGNAMES)
\r
570 parts = [name or '<function>', '(']
\r
572 any_default = False
\r
574 for a_names, a_ann, a_def, a_opt in args:
\r
577 a_name = ''.join(a_names)
\r
578 if a_name in default_set:
\r
579 default_set.discard(a_name)
\r
581 arg_parts.append(self._make_unique_name(a_name, seen_names))
\r
582 if self._can_eval(''.join(a_ann)):
\r
583 arg_parts.append(': ')
\r
584 arg_parts.extend(a_ann)
\r
585 if self._can_eval(''.join(a_def)):
\r
586 arg_parts.append('=')
\r
587 arg_parts.extend(a_def)
\r
589 elif a_opt[0] or (any_default and '*' not in a_name and '**' not in a_name):
\r
590 arg_parts.append('=None')
\r
592 if a_name.startswith('*'):
\r
594 arg_parts.append(', ')
\r
598 if a in default_set:
\r
601 parts.extend(arg_parts)
\r
602 if parts[-1] == ', ':
\r
604 if parts and parts[-1] in ('*', '**'):
\r
605 parts[-1] += self._make_unique_name('_', seen_names)
\r
609 return ''.join(parts)
\r
611 def _parse_funcdef(self, expr, allow_name_mismatch, defaults, override_name=None):
\r
612 '''Takes a call expression that was part of a docstring
\r
613 and parses the AST as if it were a definition. If the parsed
\r
614 AST matches the callable we are wrapping, returns the node.
\r
617 tokens = self._tokenize(expr)
\r
618 except (TypeError, tokenize.TokenError):
\r
619 warnings.warn('failed to tokenize ' + expr, InspectWarning)
\r
623 seen_open_paren = False
\r
624 args = [([], [], [], [False])]
\r
628 tt, s = tokens.pop(0)
\r
629 if tt == tokenize.NAME:
\r
632 elif seen_open_paren:
\r
633 args[-1][0].append(s)
\r
634 args[-1][3][0] = optional
\r
635 elif tt in (tokenize.STAR, tokenize.DOUBLESTAR):
\r
636 args[-1][0].append(s)
\r
637 elif tt == tokenize.COLON:
\r
638 e = self._parse_take_expr(tokens, tokenize.EQUAL, tokenize.COMMA)
\r
639 args[-1][1].append(''.join(i[1] for i in e))
\r
640 elif tt == tokenize.EQUAL:
\r
641 e = self._parse_take_expr(tokens, tokenize.COMMA)
\r
642 args[-1][2].append(''.join(i[1] for i in e))
\r
643 elif tt == tokenize.COMMA:
\r
644 args.append(([], [], [], [False]))
\r
645 elif tt == tokenize.LSQB:
\r
647 elif tt == tokenize.RSQB:
\r
649 elif tt == tokenize.LPAR:
\r
650 seen_open_paren = True
\r
651 elif tt == tokenize.RPAR:
\r
653 elif s in ('->', '...'):
\r
656 if name and (allow_name_mismatch or name == self.name):
\r
657 return self._parse_format_arg(override_name or name, args, defaults)
\r
659 def _get_first_function_call(self, expr):
\r
660 '''Scans the string for the first closing parenthesis,
\r
661 handling nesting, which is the best heuristic we have for
\r
662 an example call at the start of the docstring.'''
\r
663 if not expr or ')' not in expr:
\r
667 for line in expr.splitlines():
\r
669 line = line.strip('\r\n\t ')
\r
672 for i, c in enumerate(line):
\r
676 found.append(line[:i + 1])
\r
684 found.sort(key=len)
\r
688 class MemberInfo(object):
\r
689 NO_VALUE = object()
\r
691 def __init__(self, name, value, literal=None, scope=None, module=None, alias=None, module_doc=None, scope_alias=None):
\r
694 self.literal = literal
\r
697 self.need_imports = ()
\r
698 self.type_name = None
\r
699 self.scope_name = None
\r
701 self.signature = None
\r
702 self.documentation = getattr(value, '__doc__', None)
\r
704 self.instance = True
\r
706 if not isinstance(self.documentation, str):
\r
707 self.documentation = None
\r
709 # Special case for __init__ that refers to class docs
\r
710 if self.name == '__init__' and (
\r
711 not self.documentation
\r
712 or 'See help(type(self))' in self.documentation):
\r
713 self.documentation = module_doc
\r
716 self.name = self.name.replace('-', '_')
\r
718 value_type = type(value)
\r
719 if issubclass(value_type, type):
\r
720 self.instance = False
\r
721 self.need_imports, type_name = self._get_typename(value, module)
\r
722 if '.' in type_name:
\r
723 m, s, n = type_name.rpartition('.')
\r
724 self.literal = safe_module_name(m) + s + n
\r
726 self.scope_name = self.type_name = type_name
\r
727 self._collect_bases(value, module, self.type_name)
\r
729 elif safe_callable(value):
\r
732 if value_type in STATICMETHOD_TYPES:
\r
733 dec += '@staticmethod',
\r
734 elif value_type in CLASSMETHOD_TYPES:
\r
735 dec += '@classmethod',
\r
736 self.signature = Signature(name, value, scope, scope_alias=scope_alias, decorators=dec, module_doc=module_doc)
\r
737 elif value is not None:
\r
738 if value_type in PROPERTY_TYPES:
\r
739 self.signature = Signature(name, value, scope, scope_alias=scope_alias)
\r
740 if value_type not in SKIP_TYPENAME_FOR_TYPES:
\r
741 self.need_imports, self.type_name = self._get_typename(value_type, module)
\r
742 self._collect_bases(value_type, module, self.type_name)
\r
743 if isinstance(value, float) and repr(value) == 'nan':
\r
744 self.literal = "float('nan')"
\r
746 self.literal = VALUE_REPR_FIX[value]
\r
749 elif not self.literal:
\r
750 self.literal = 'None'
\r
752 def _collect_bases(self, value_type, module, type_name):
\r
754 bases = getattr(value_type, '__bases__', ())
\r
759 self.need_imports = list(self.need_imports)
\r
760 for ni, t in (self._get_typename(b, module) for b in bases):
\r
763 if t == type_name and module in ni:
\r
765 self.bases.append(t)
\r
766 self.need_imports.extend(ni)
\r
769 def _get_typename(cls, value_type, in_module):
\r
771 type_name = value_type.__name__.replace('-', '_')
\r
772 module = getattr(value_type, '__module__', None)
\r
774 # Special workaround for Python 2 exceptions lying about their module
\r
775 if sys.version_info[0] == 2 and module == 'exceptions' and in_module == builtins.__name__:
\r
776 module = builtins.__name__
\r
778 # Special workaround for IronPython types that include their module name
\r
779 if in_module and type_name.startswith(in_module + '.'):
\r
780 type_name = type_name[len(in_module) + 1:]
\r
783 if module and module != '<unknown>':
\r
784 if module == in_module:
\r
785 return (module,), type_name
\r
787 fullname = module + '.' + type_name
\r
789 if in_module and (fullname in LIES_ABOUT_MODULE or (in_module + '.*') in LIES_ABOUT_MODULE):
\r
790 # Treat the type as if it came from the current module
\r
791 return (in_module,), type_name
\r
793 return (module,), fullname
\r
795 return (), type_name
\r
797 warnings.warn('could not get type of ' + repr(value_type), InspectWarning)
\r
801 def _str_from_literal(self, lit):
\r
802 return self.name + ' = ' + lit
\r
804 def _str_from_typename(self, type_name):
\r
805 mod_name, sep, name = type_name.rpartition('.')
\r
806 s = self.name + ' = ' + safe_module_name(mod_name) + sep + name
\r
811 def _str_from_value(self, v):
\r
812 return self.name + ' = ' + repr(v)
\r
814 def _lines_with_members(self):
\r
816 split_bases = [n.rpartition('.') for n in self.bases]
\r
817 bases = ','.join((safe_module_name(n[0]) + n[1] + n[2]) for n in split_bases)
\r
818 yield 'class ' + self.name + '(' + bases + '):'
\r
820 yield 'class ' + self.name + ':'
\r
821 if self.documentation:
\r
822 yield ' ' + repr(self.documentation)
\r
824 for mi in self.members:
\r
825 if hasattr(mi, 'documentation') and mi.documentation != None and not isinstance(mi.documentation, str):
\r
827 if mi is not MemberInfo.NO_VALUE:
\r
828 yield mi.as_str(' ')
\r
833 def _lines_with_signature(self):
\r
834 seen_decorators = set()
\r
835 for d in self.signature.decorators:
\r
837 if d not in seen_decorators:
\r
838 seen_decorators.add(d)
\r
840 yield 'def ' + str(self.signature) + ':'
\r
841 if self.documentation:
\r
842 yield ' ' + repr(self.documentation)
\r
843 if self.signature.restype:
\r
844 yield ' ' + self.signature.restype
\r
849 def as_str(self, indent=''):
\r
851 return indent + self._str_from_literal(self.literal)
\r
854 return '\n'.join(indent + s for s in self._lines_with_members())
\r
857 return '\n'.join(indent + s for s in self._lines_with_signature())
\r
859 if self.type_name is not None:
\r
860 return indent + self._str_from_typename(self.type_name)
\r
862 if self.value is not None:
\r
863 return indent + self._str_from_value(self.value)
\r
865 return indent + self.name
\r
868 MODULE_MEMBER_SUBSTITUTE = {
\r
869 '__builtins__': MemberInfo('__builtins__', None, literal='{}'),
\r
871 '__loader__': None,
\r
874 CLASS_MEMBER_SUBSTITUTE = {
\r
875 '__bases__': MemberInfo('__bases__', None, literal='()'),
\r
876 '__mro__': MemberInfo('__mro__', None, literal='()'),
\r
877 '__dict__': MemberInfo('__dict__', None, literal='{}'),
\r
882 class ScrapeState(object):
\r
883 def __init__(self, module_name, module=None):
\r
884 self.root_module = None
\r
885 self.module = module
\r
886 self.module_name = module_name
\r
888 self.imports = set()
\r
891 def initial_import(self, search_path=None):
\r
896 sys.path.insert(0, search_path)
\r
900 mod = __import__(self.module_name)
\r
902 ex_msg = str(sys.exc_info()[1])
\r
903 warnings.warn("Working around " + ex_msg, InspectWarning)
\r
904 if ex_msg == "This must be an MFC application - try 'import win32ui' first":
\r
906 elif ex_msg == "Could not find TCL routines" or self.module_name == 'matplotlib.backends._tkagg':
\r
907 if sys.version_info[0] == 2:
\r
915 # Try the import again, either fixed or without chaining the
\r
916 # previous exception.
\r
917 mod = __import__(self.module_name)
\r
921 self.root_module = mod
\r
923 # __import__ gives us the topmost module. We should generally use
\r
924 # getattr() from here to find the child module. However, sometimes
\r
925 # this is unsuccessful. So we work backwards through the full name
\r
926 # to see what is in sys.modules, then getattr() to go forwards.
\r
927 mod_name = self.module_name
\r
929 while mod_name and mod_name not in sys.modules:
\r
930 mod_name, _, bit = self.module_name.rpartition('.')[0]
\r
931 bits.insert(0, bit)
\r
934 self.root_module = mod = sys.modules[mod_name]
\r
936 bits = self.module_name.split('.')[1:]
\r
939 mod = getattr(mod, bit)
\r
943 def collect_top_level_members(self):
\r
944 self._collect_members(self.module, self.members, MODULE_MEMBER_SUBSTITUTE, None)
\r
946 if self.module_name == 'sys':
\r
947 sysinfo = [m for m in self.members if m.type_name in SYS_INFO_TYPES]
\r
949 self.members.append(MemberInfo(m.name, None, literal="__" + m.name + "()"))
\r
950 m.name = m.scope_name = m.type_name = '__' + m.type_name
\r
952 m_names = set(m.name for m in self.members)
\r
954 for m in self.members:
\r
955 if m.value is not None and m.type_name and '.' not in m.type_name and m.type_name not in m_names:
\r
956 undeclared.append(MemberInfo(m.type_name, type(m.value), module=self.module_name))
\r
958 self.members[:0] = undeclared
\r
960 def _should_collect_members(self, member):
\r
961 if self.module_name in member.need_imports and member.name == member.type_name:
\r
963 # Support cffi libs
\r
964 if member.type_name == builtins.__name__ + '.CompiledLib':
\r
967 def collect_second_level_members(self):
\r
968 for mi in self.members:
\r
969 if self._should_collect_members(mi):
\r
970 substitutes = dict(CLASS_MEMBER_SUBSTITUTE)
\r
971 substitutes['__class__'] = MemberInfo('__class__', None, literal=mi.type_name)
\r
972 self._collect_members(mi.value, mi.members, substitutes, mi)
\r
974 if mi.scope_name != mi.type_name:
\r
975 # When the scope and type names are different, we have a static
\r
976 # class. To emulate this, we add '@staticmethod' decorators to
\r
978 for mi2 in mi.members:
\r
980 mi2.signature.decorators += '@staticmethod',
\r
982 def _collect_members(self, mod, members, substitutes, outer_member):
\r
983 '''Fills the members attribute with a dictionary containing
\r
984 all members from the module.'''
\r
986 raise RuntimeError("failed to import module")
\r
987 if mod is MemberInfo.NO_VALUE:
\r
990 existing_names = set(m.name for m in members)
\r
993 scope = outer_member.scope_name
\r
994 scope_alias = outer_member.alias
\r
996 scope, scope_alias = None, None
\r
998 mod_scope = (self.module_name + '.' + scope) if scope else self.module_name
\r
999 mod_doc = getattr(mod, '__doc__', None)
\r
1000 mro = (getattr(mod, '__mro__', None) or ())[1:]
\r
1001 for name in dir(mod):
\r
1002 if keyword.iskeyword(name):
\r
1005 m = substitutes[name]
\r
1009 except LookupError:
\r
1012 m = substitutes[mod_scope + '.' + name]
\r
1016 except LookupError:
\r
1019 if name in existing_names:
\r
1023 value = getattr(mod, name)
\r
1024 except AttributeError:
\r
1025 warnings.warn("attribute " + name + " on " + repr(mod) + " was in dir() but not getattr()", InspectWarning)
\r
1027 warnings.warn("error getting " + name + " for " + repr(mod), InspectWarning)
\r
1029 if not self._should_add_value(value):
\r
1031 if name != '__init__' and self._mro_contains(mro, name, value):
\r
1033 members.append(MemberInfo(name, value, scope=scope, module=self.module_name, module_doc=mod_doc, scope_alias=scope_alias))
\r
1035 def _should_add_value(self, value):
\r
1037 value_type = type(value)
\r
1038 mod = getattr(value_type, '__module__', None)
\r
1039 name = value_type.__name__
\r
1041 warnings.warn("error getting typename", InspectWarning)
\r
1044 if (mod, name) == (builtins.__name__, 'CompiledLib'):
\r
1045 # Always allow CFFI lib
\r
1048 if issubclass(value_type, (type(sys), type(inspect))):
\r
1049 # Disallow nested modules
\r
1052 # By default, include all values
\r
1055 def _mro_contains(self, mro, name, value):
\r
1058 mro_value = getattr(m, name)
\r
1062 if mro_value is value:
\r
1065 def translate_members(self):
\r
1068 def dump(self, out):
\r
1070 for value in self.members:
\r
1071 for mod in value.need_imports:
\r
1073 imports.discard(self.module_name)
\r
1076 for mod in sorted(imports):
\r
1077 print("import " + mod + " as " + safe_module_name(mod), file=out)
\r
1078 print("", file=out)
\r
1080 for value in self.members:
\r
1081 s = value.as_str('')
\r
1083 print(s, file=out)
\r
1085 print(repr(s), file=sys.stderr)
\r
1088 def add_builtin_objects(state):
\r
1089 Signature.KNOWN_RESTYPES.update({
\r
1090 "__Type__.__call__": "cls()",
\r
1091 "__Property__.__delete__": "None",
\r
1092 "__Float__.__getformat__": "''",
\r
1093 "__Bytes__.__getitem__": "__T__()",
\r
1094 "__Unicode__.__getitem__": "__T__()",
\r
1095 "__Type__.__instancecheck__": "False",
\r
1096 "__Tuple__.__iter__": "__TupleIterator__()",
\r
1097 "__List__.__iter__": "__ListIterator__()",
\r
1098 "__Dict__.__iter__": "__DictKeys__()",
\r
1099 "__Set__.__iter__": "__SetIterator__()",
\r
1100 "__FrozenSet__.__iter__": "__SetIterator__()",
\r
1101 "__Bytes__.__iter__": "__BytesIterator__()",
\r
1102 "__Unicode__.__iter__": "__UnicodeIterator__()",
\r
1103 "__BytesIterator__.__next__": "0",
\r
1104 "__UnicodeIterator__.__next__": "__Unicode__()",
\r
1105 "__Type__.__prepare__": "None",
\r
1106 "__List__.__reversed__": "__ListIterator__()",
\r
1107 "__Float__.__setformat__": "None",
\r
1108 "__Type__.__subclasses__": "(cls,)",
\r
1109 "__truediv__": "__Float__()",
\r
1110 "__Type__.__subclasscheck__": "False",
\r
1111 "__subclasshook__": "False",
\r
1115 "__Set__.add": "None",
\r
1116 "__List__.append": "None",
\r
1117 "__Float__.as_integer_ratio": "(0, 0)",
\r
1119 "__Int__.bit_length": "0",
\r
1120 "callable": "False",
\r
1121 "capitalize": "__T__()",
\r
1122 "casefold": "__T__()",
\r
1123 "center": "__T__()",
\r
1126 "__Generator__.close": "None",
\r
1127 "conjugate": "__Complex__()",
\r
1128 "copy": "__T__()",
\r
1130 "__Bytes__.decode": "''",
\r
1131 "__Property__.deleter": "func",
\r
1132 "__Set__.difference": "__T__()",
\r
1133 "__FrozenSet__.difference": "__T__()",
\r
1134 "__Set__.difference_update": "None",
\r
1135 "__Set__.discard": "None",
\r
1136 "divmod": "(0, 0)",
\r
1137 "__Bytes__.encode": "b''",
\r
1138 "__Unicode__.encode": "b''",
\r
1139 "endswith": "False",
\r
1140 "expandtabs": "__T__()",
\r
1141 "__List__.extend": "None",
\r
1143 "__Unicode__.format": "__T__()",
\r
1144 "__Unicode__.format_map": "__T__()",
\r
1145 "__Bool__.from_bytes": "False",
\r
1146 "__Int__.from_bytes": "0",
\r
1147 "__Long__.from_bytes": "__Long__()",
\r
1148 "__Float__.fromhex": "0.0",
\r
1149 "__Bytes__.fromhex": "b''",
\r
1150 "__Dict__.fromkeys": "{}",
\r
1151 "__Dict__.get": "self[0]",
\r
1152 "__Property__.getter": "func",
\r
1154 "globals": "__Dict__()",
\r
1155 "hasattr": "False",
\r
1161 "__List__.insert": "None",
\r
1162 "__Set__.intersection": "__T__()",
\r
1163 "__FrozenSet__.intersection": "__T__()",
\r
1164 "__Set__.intersection_update": "None",
\r
1165 "isalnum": "False",
\r
1166 "isalpha": "False",
\r
1167 "isdecimal": "False",
\r
1168 "isdigit": "False",
\r
1169 "islower": "False",
\r
1170 "isidentifier": "False",
\r
1171 "isnumeric": "False",
\r
1172 "isprintable": "False",
\r
1173 "isspace": "False",
\r
1174 "istitle": "False",
\r
1175 "isupper": "False",
\r
1176 "__Float__.is_integer": "False",
\r
1177 "__Set__.isdisjoint": "False",
\r
1178 "__FrozenSet__.isdisjoint": "False",
\r
1179 "__DictKeys__.isdisjoint": "False",
\r
1180 "__DictItems__.isdisjoint": "False",
\r
1181 "__Set__.issubset": "False",
\r
1182 "__FrozenSet__.issubset": "False",
\r
1183 "__Set__.issuperset": "False",
\r
1184 "__FrozenSet__.issuperset": "False",
\r
1185 "__Dict__.items": "__DictItems__()",
\r
1186 "__Bytes__.join": "b''",
\r
1187 "__Unicode__.join": "''",
\r
1188 "__Dict__.keys": "__DictKeys__()",
\r
1190 "locals": "__Dict__()",
\r
1191 "lower": "__T__()",
\r
1192 "ljust": "__T__()",
\r
1193 "lstrip": "__T__()",
\r
1194 "__Bytes__.maketrans": "b''",
\r
1195 "__Unicode__.maketrans": "{}",
\r
1196 "__Type__.mro": "[__Type__()]",
\r
1198 "partition": "(__T__(), __T__(), __T__())",
\r
1199 "__List__.pop": "self[0]",
\r
1200 "__Dict__.pop": "self.keys()[0]",
\r
1201 "__Set__.pop": "Any",
\r
1202 "__Dict__.popitem": "self.items()[0]",
\r
1204 "replace": "__T__()",
\r
1207 "__List__.reverse": "None",
\r
1209 "rjust": "__T__()",
\r
1211 "rpartition": "(__T__(), __T__(), __T__())",
\r
1212 "rsplit": "[__T__()]",
\r
1213 "rstrip": "__T__()",
\r
1214 "__Generator__.send": "self.__next__()",
\r
1215 "__Dict__.setdefault": "self[0]",
\r
1216 "__Property__.setter": "func",
\r
1217 "__List__.sort": "None",
\r
1218 "sorted": "__List__()",
\r
1219 "split": "[__T__()]",
\r
1220 "splitlines": "[self()]",
\r
1221 "startswith": "False",
\r
1222 "strip": "__T__()",
\r
1223 "swapcase": "__T__()",
\r
1224 "__Set__.symmetric_difference": "__T__()",
\r
1225 "__FrozenSet__.symmetric_difference": "__T__()",
\r
1226 "__Set__.symmetric_difference_update": "None",
\r
1227 "__Bytes__.translate": "__T__()",
\r
1228 "__Unicode__.translate": "__T__()",
\r
1229 "__Generator__.throw": "None",
\r
1230 "title": "__T__()",
\r
1231 "to_bytes": "b''",
\r
1232 "__Set__.union": "__T__()",
\r
1233 "__FrozenSet__.union": "__T__()",
\r
1234 "__Dict__.update": "None",
\r
1235 "__Set__.update": "None",
\r
1236 "upper": "__T__()",
\r
1237 "__Dict__.values": "__DictValues__()",
\r
1238 "zfill": "__T__()",
\r
1241 Signature.KNOWN_ARGSPECS.update({
\r
1242 "__Type__.__call__": "(cls, *args, **kwargs)",
\r
1243 "__Int__.__ceil__": "(self)",
\r
1244 "__Int__.__floor__": "(self)",
\r
1245 "__Float__.__getformat__": "(typestr)",
\r
1246 "__Dict__.__getitem__": "(self, key)",
\r
1247 "__Type__.__instancecheck__": "(self, instance)",
\r
1248 "__Bool__.__init__": "(self, x)",
\r
1249 "__Int__.__init__": "(self, x=0)",
\r
1250 "__List__.__init__": "(self, iterable)",
\r
1251 "__Tuple__.__init__": "(self, iterable)",
\r
1252 "__Type__.__prepare__": "(cls, name, bases, **kwds)",
\r
1253 "__Int__.__round__": "(self, ndigits=0)",
\r
1254 "__Float__.__round__": "(self, ndigits=0)",
\r
1255 "__List__.__reversed__": "(self)",
\r
1256 "__Float__.__setformat__": "(typestr, fmt)",
\r
1257 "__Dict__.__setitem__": "(self, key, value)",
\r
1258 "__Set__.add": "(self, value)",
\r
1259 "__List__.append": "(self, value)",
\r
1260 "__Float__.as_integer_ratio": "(self)",
\r
1261 "__Int__.bit_length": "(self)",
\r
1262 "capitalize": "(self)",
\r
1263 "casefold": "(self)",
\r
1264 "__Bytes__.center": "(self, width, fillbyte=b' ')",
\r
1265 "__Unicode__.center": "(self, width, fillchar=' ')",
\r
1266 "clear": "(self)",
\r
1267 "__Generator__.close": "(self)",
\r
1268 "conjugate": "(self)",
\r
1270 "count": "(self, x)",
\r
1271 "__Bytes__.count": "(self, sub, start=0, end=-1)",
\r
1272 "__Unicode__.count": "(self, sub, start=0, end=-1)",
\r
1273 "__Bytes__.decode": "(self, encoding='utf-8', errors='strict')",
\r
1274 "__Property__.deleter": "(self, func)",
\r
1275 "__Set__.difference": "(self, other)",
\r
1276 "__FrozenSet__.difference": "(self, other)",
\r
1277 "__Set__.difference_update": "(self, *others)",
\r
1278 "__Set__.discard": "(self, elem)",
\r
1279 "__Unicode__.encode": "(self, encoding='utf-8', errors='strict')",
\r
1280 "endswith": "(self, suffix, start=0, end=-1)",
\r
1281 "expandtabs": "(self, tabsize=8)",
\r
1282 "__List__.extend": "(self, iterable)",
\r
1283 "find": "(self, sub, start=0, end=-1)",
\r
1284 "__Unicode__.format": "(self, *args, **kwargs)",
\r
1285 "__Unicode__.format_map": "(self, mapping)",
\r
1286 "__Bool__.from_bytes": "(bytes, byteorder, *, signed=False)",
\r
1287 "__Int__.from_bytes": "(bytes, byteorder, *, signed=False)",
\r
1288 "__Float__.fromhex": "(string)",
\r
1289 "__Dict__.get": "(self, key, d=None)",
\r
1290 "__Property__.getter": "(self, func)",
\r
1292 "__List__.insert": "(self, index, value)",
\r
1293 "index": "(self, v)",
\r
1294 "__Bytes__.index": "(self, sub, start=0, end=-1)",
\r
1295 "__Unicode__.index": "(self, sub, start=0, end=-1)",
\r
1296 "__Set__.intersection": "(self, other)",
\r
1297 "__FrozenSet__.intersection": "(self, other)",
\r
1298 "__Set__.intersection_update": "(self, *others)",
\r
1299 "isalnum": "(self)",
\r
1300 "isalpha": "(self)",
\r
1301 "isdecimal": "(self)",
\r
1302 "isdigit": "(self)",
\r
1303 "isidentifier": "(self)",
\r
1304 "islower": "(self)",
\r
1305 "isnumeric": "(self)",
\r
1306 "isprintable": "(self)",
\r
1307 "isspace": "(self)",
\r
1308 "istitle": "(self)",
\r
1309 "isupper": "(self)",
\r
1310 "__Float__.is_integer": "(self)",
\r
1311 "__Set__.isdisjoint": "(self, other)",
\r
1312 "__FrozenSet__.isdisjoint": "(self, other)",
\r
1313 "__DictKeys__.isdisjoint": "(self, other)",
\r
1314 "__DictItems__.isdisjoint": "(self, other)",
\r
1315 "__Set__.issubset": "(self, other)",
\r
1316 "__FrozenSet__.issubset": "(self, other)",
\r
1317 "__Set__.issuperset": "(self, other)",
\r
1318 "__FrozenSet__.issuperset": "(self, other)",
\r
1319 "__Dict__.items": "(self)",
\r
1320 "__Bytes__.join": "(self, iterable)",
\r
1321 "__Unicode__.join": "(self, iterable)",
\r
1322 "__Dict__.keys": "(self)",
\r
1323 "lower": "(self)",
\r
1324 "__Bytes__.ljust": "(self, width, fillbyte=b' ')",
\r
1325 "__Unicode__.ljust": "(self, width, fillchar=' ')",
\r
1326 "lstrip": "(self, chars)",
\r
1327 "__Bytes__.maketrans": "(from_, to)",
\r
1328 "__Unicode__.maketrans": "(x, y, z)",
\r
1329 "__Type__.mro": "(cls)",
\r
1330 "__Bytes__.partition": "(self, sep)",
\r
1331 "__Unicode__.partition": "(self, sep)",
\r
1332 "__List__.pop": "(self, index=-1)",
\r
1333 "__Dict__.pop": "(self, k, d=None)",
\r
1334 "__Set__.pop": "(self)",
\r
1335 "__Dict__.popitem": "(self, k, d=None)",
\r
1336 "__List__.remove": "(self, value)",
\r
1337 "__Set__.remove": "(self, elem)",
\r
1338 "replace": "(self, old, new, count=-1)",
\r
1339 "__List__.reverse": "(self)",
\r
1340 "rfind": "(self, sub, start=0, end=-1)",
\r
1341 "rindex": "(self, sub, start=0, end=-1)",
\r
1342 "__Bytes__.rjust": "(self, width, fillbyte=b' ')",
\r
1343 "__Unicode__.rjust": "(self, width, fillchar=' ')",
\r
1344 "__Bytes__.rpartition": "(self, sep)",
\r
1345 "__Unicode__.rpartition": "(self, sep)",
\r
1346 "rsplit": "(self, sep=None, maxsplit=-1)",
\r
1347 "rstrip": "(self, chars=None)",
\r
1348 "__Generator__.send": "(self, value)",
\r
1349 "__Dict__.setdefault": "(self, k, d)",
\r
1350 "__Property__.setter": "(self, func)",
\r
1351 "__List__.sort": "(self)",
\r
1352 "split": "(self, sep=None, maxsplit=-1)",
\r
1353 "splitlines": "(self, keepends=False)",
\r
1354 "strip": "(self, chars=None)",
\r
1355 "startswith": "(self, prefix, start=0, end=-1)",
\r
1356 "swapcase": "(self)",
\r
1357 "__Set__.symmetric_difference": "(self, other)",
\r
1358 "__FrozenSet__.symmetric_difference": "(self, other)",
\r
1359 "__Set__.symmetric_difference_update": "(self, *others)",
\r
1360 "__Generator__.throw": "(self, type, value=None, traceback=None)",
\r
1361 "title": "(self)",
\r
1362 "__Int__.to_bytes": "(bytes, byteorder, *, signed=False)",
\r
1363 "__Bytes__.translate": "(self, table, delete=b'')",
\r
1364 "__Unicode__.translate": "(self, table)",
\r
1365 "__Set__.union": "(self, *others)",
\r
1366 "__FrozenSet__.union": "(self, *others)",
\r
1367 "__Dict__.update": "(self, d)",
\r
1368 "__Set__.update": "(self, *others)",
\r
1369 "upper": "(self)",
\r
1370 "__Dict__.values": "(self)",
\r
1371 "zfill": "(self, width)",
\r
1374 if sys.version[0] == '2':
\r
1375 Signature.KNOWN_RESTYPES.update({
\r
1376 "__BytesIterator__.__next__": None,
\r
1377 "__BytesIterator__.next": "b''",
\r
1378 "__UnicodeIterator__.__next__": None,
\r
1379 "__UnicodeIterator__.next": "u''",
\r
1380 "__Generator__.send": "self.next()",
\r
1381 "__Function__.func_closure": "()",
\r
1382 "__Function__.func_doc": "b''",
\r
1383 "__Function__.func_name": "b''",
\r
1385 "raw_input": "b''",
\r
1388 Signature.KNOWN_ARGSPECS.update({
\r
1389 "__BytesIterator__.next": "(self)",
\r
1390 "__UnicodeIterator__.next": "(self)",
\r
1393 already_added = set()
\r
1395 def add_simple(name, doc, *members):
\r
1396 mi = MemberInfo(name, MemberInfo.NO_VALUE)
\r
1397 mi.documentation = doc
\r
1398 mi.need_imports = (state.module_name,)
\r
1399 mi.members.extend(members)
\r
1400 state.members.append(mi)
\r
1402 def add_literal(name, literal):
\r
1403 state.members.append(MemberInfo(name, None, literal=literal))
\r
1405 def add_type(alias, type_obj):
\r
1406 if type_obj.__name__ in already_added:
\r
1407 add_literal(alias, type_obj.__name__)
\r
1409 already_added.add(type_obj.__name__)
\r
1410 mi = MemberInfo(type_obj.__name__, type_obj, module=builtins.__name__, alias=alias)
\r
1411 state.members.append(mi)
\r
1412 state.members.append(MemberInfo(alias, None, literal=mi.name))
\r
1414 # We don't need these anymore, as Unknown and None are specialized in the analysis.
\r
1415 #add_simple('__Unknown__', '<unknown>', MemberInfo("__name__", None, literal='"<unknown>"'))
\r
1416 #add_simple('__NoneType__', 'the type of the None object', MemberInfo.NO_VALUE)
\r
1418 # NoneType and None are explicitly defined to avoid parser errors
\r
1419 # because of None being a keyword.
\r
1420 #add_literal('NoneType', '__NoneType__')
\r
1421 #add_literal('None', '__NoneType__()')
\r
1423 add_type('__Object__', object)
\r
1424 add_type('__Type__', type)
\r
1426 add_type('__Int__', int)
\r
1427 if type(bool()) is int:
\r
1428 add_literal('__Bool__', '__Int__')
\r
1430 add_type('__Bool__', bool)
\r
1435 add_literal('__Long__', '__Int__')
\r
1437 add_type('__Long__', long)
\r
1439 add_type("__Float__", float)
\r
1440 add_type("__Complex__", complex)
\r
1442 add_type("__Tuple__", tuple)
\r
1443 add_type("__List__", list)
\r
1444 add_type("__Dict__", dict)
\r
1445 add_type("__Set__", set)
\r
1446 add_type("__FrozenSet__", frozenset)
\r
1448 if bytes is not str:
\r
1449 add_type("__Bytes__", bytes)
\r
1450 add_type("__BytesIterator__", type(iter(bytes())))
\r
1451 add_type("__Unicode__", str)
\r
1452 add_type("__UnicodeIterator__", type(iter(str())))
\r
1453 add_literal("__Str__", "__Unicode__")
\r
1454 add_literal("__StrIterator__", "__UnicodeIterator__")
\r
1457 add_type("__Bytes__", str)
\r
1458 add_type("__BytesIterator__", type(iter(str())))
\r
1459 add_type("__Unicode__", unicode)
\r
1460 add_type("__UnicodeIterator__", type(iter(unicode())))
\r
1461 add_literal("__Str__", "__Bytes__")
\r
1462 add_literal("__StrIterator__", "__BytesIterator__")
\r
1464 add_type("__Module__", type(inspect))
\r
1465 add_type("__Function__", type(add_simple))
\r
1467 add_type("__BuiltinMethodDescriptor__", type(object.__hash__))
\r
1468 add_type("__BuiltinFunction__", type(abs))
\r
1469 add_type("__Generator__", type((_ for _ in [])))
\r
1470 add_type("__Property__", property)
\r
1471 add_type("__ClassMethod__", classmethod)
\r
1472 add_type("__StaticMethod__", staticmethod)
\r
1473 add_type("__Ellipsis__", type(Ellipsis))
\r
1474 add_type("__TupleIterator__", type(iter(())))
\r
1475 add_type("__ListIterator__", type(iter([])))
\r
1476 add_type("__DictKeys__", type({}.keys()))
\r
1477 add_type("__DictValues__", type({}.values()))
\r
1478 add_type("__DictItems__", type({}.items()))
\r
1479 add_type("__SetIterator__", type(iter(set())))
\r
1480 add_type("__CallableIterator__", type(iter((lambda: None), None)))
\r
1482 # Also write out the builtin module names here so that we cache them
\r
1484 builtin_module_names = sys.builtin_module_names
\r
1485 except AttributeError:
\r
1488 add_literal('__builtin_module_names__', '"' + ','.join(builtin_module_names) + '"')
\r
1491 if __name__ == '__main__':
\r
1492 EXCLUDED_MEMBERS = ()
\r
1494 outfile = sys.stdout
\r
1495 if '-u8' in sys.argv:
\r
1496 sys.argv.remove('-u8')
\r
1498 b_outfile = outfile.buffer
\r
1499 except AttributeError:
\r
1500 warnings.warn("cannot enable UTF-8 output", InspectWarning)
\r
1501 pass # on Python 2, so hopefully everything is valid ASCII...
\r
1504 outfile = io.TextIOWrapper(b_outfile, encoding='utf-8', errors='replace')
\r
1506 if len(sys.argv) == 1:
\r
1507 state = ScrapeState(builtins.__name__, builtins)
\r
1508 add_builtin_objects(state)
\r
1510 EXCLUDED_MEMBERS += ('None', 'False', 'True', '__debug__')
\r
1511 if sys.version_info[0] == 2:
\r
1512 EXCLUDED_MEMBERS += ('print',)
\r
1514 elif len(sys.argv) >= 2:
\r
1515 state = ScrapeState(sys.argv[1])
\r
1517 if len(sys.argv) >= 3:
\r
1518 state.initial_import(sys.argv[2])
\r
1520 state.initial_import()
\r
1522 state.collect_top_level_members()
\r
1524 state.members[:] = [m for m in state.members if m.name not in EXCLUDED_MEMBERS]
\r
1526 state.collect_second_level_members()
\r
1528 state.dump(outfile)
\r
1530 #state.dump(io.BytesIO())
\r