diff --git a/builtin.py b/builtin.py index 96d88221..8973844f 100644 --- a/builtin.py +++ b/builtin.py @@ -17,6 +17,10 @@ module_find_path = sys.path[1:] class CachedModule(object): + """ + The base type for all modules, which is not to be confused with + `parsing.Module`. Caching happens here. + """ cache = {} def __init__(self, path=None, name=None): @@ -103,6 +107,7 @@ class Parser(CachedModule): if path: self.sys_path.pop(0) + # module might already be defined if not self._module: path = self.path name = self.name @@ -124,6 +129,7 @@ class Parser(CachedModule): return self._module def _get_source(self): + """ Override this abstract method """ return self._generate_code(self.module, self._load_mixins()) def _load_mixins(self): @@ -208,7 +214,11 @@ class Parser(CachedModule): return True return False - def get_types(names): + def get_scope_objects(names): + """ + Looks for the names defined with dir() in an objects and divides + them into different object types. + """ classes = {} funcs = {} stmts = {} @@ -252,7 +262,7 @@ class Parser(CachedModule): names = set(dir(scope)) - set(['__file__', '__name__', '__doc__', '__path__', '__package__']) - classes, funcs, stmts, members = get_types(names) + classes, funcs, stmts, members = get_scope_objects(names) # classes for name, cl in classes.items(): @@ -383,6 +393,7 @@ def parse_function_doc(func): class _Builtin(object): + """ The builtin scope / module """ # Python 3 compatibility if is_py3k(): name = 'builtins' diff --git a/debug.py b/debug.py index 499e70da..729c79ad 100644 --- a/debug.py +++ b/debug.py @@ -1,5 +1,6 @@ import inspect try: + # Use colorama for nicer console output. from colorama import Fore, init init() except ImportError: @@ -12,8 +13,13 @@ NOTICE = object() WARNING = object() ERROR = object() +debug_function = None +#debug_function = print_to_stdout +ignored_modules = [] + def dbg(*args): + """ Looks at the stack, to see if a debug message should be printed. """ if debug_function: frm = inspect.stack()[1] mod = inspect.getmodule(frm[0]) @@ -35,8 +41,3 @@ def print_to_stdout(level, *args): """ The default debug function """ msg = (Fore.GREEN + 'dbg: ' if level == NOTICE else Fore.RED + 'warning: ') print(msg + ', '.join(str(a) for a in args) + Fore.RESET) - - -debug_function = None -#debug_function = print_to_stdout -ignored_modules = [] diff --git a/dynamic.py b/dynamic.py index 58b4586c..c465957e 100644 --- a/dynamic.py +++ b/dynamic.py @@ -126,6 +126,7 @@ def check_array_additions(array): counter = 0 def dec(func): + """ TODO delete this """ def wrapper(*args, **kwargs): global counter element = args[0] @@ -134,7 +135,7 @@ def dec(func): else: # must be instance stmt = element.var_args.parent_stmt() - print ' '*counter + 'recursion,', stmt + print ' ' * counter + 'recursion,', stmt counter += 1 res = func(*args, **kwargs) counter -= 1 @@ -142,6 +143,7 @@ def dec(func): return res return wrapper + #@dec @evaluate.memoize_default([]) def _check_array_additions(compare_array, module, is_list): @@ -167,6 +169,10 @@ def _check_array_additions(compare_array, module, is_list): return result def check_calls(calls, add_name): + """ + Calls are processed here. The part before the call is searched and + compared with the original Array. + """ result = [] for c in calls: call_path = list(c.generate_call_path()) @@ -245,6 +251,7 @@ def _check_array_additions(compare_array, module, is_list): def check_array_instances(instance): + """ Used for set() and list() instances. """ if not settings.dynamic_arrays_instances: return instance.var_args ai = ArrayInstance(instance) diff --git a/evaluate.py b/evaluate.py index 19f7dc97..925a05c7 100644 --- a/evaluate.py +++ b/evaluate.py @@ -706,6 +706,7 @@ class Execution(Executable): class Generator(parsing.Base): """ Cares for `yield` statements. """ __metaclass__ = CachedMetaClass + def __init__(self, func, var_args): super(Generator, self).__init__() self.func = func @@ -748,6 +749,7 @@ class Array(parsing.Base): methods which are important in this module. """ __metaclass__ = CachedMetaClass + def __init__(self, array): self._array = array @@ -1194,7 +1196,7 @@ def follow_statement(stmt, seek_name=None): the result for this name. :param stmt: A `parsing.Statement`. - :param seek_name: + :param seek_name: A string. """ statement_path.append(stmt) # important to know for the goto function diff --git a/helpers.py b/helpers.py index 0d9f79df..fd3b29d5 100644 --- a/helpers.py +++ b/helpers.py @@ -10,7 +10,10 @@ import settings class RecursionDecorator(object): - """ A decorator to detect recursions in statements """ + """ + A decorator to detect recursions in statements. In a recursion a statement + at the same place, in the same module may not be executed two times. + """ def __init__(self, func): self.func = func self.reset() @@ -58,6 +61,7 @@ class RecursionDecorator(object): class RecursionNode(object): + """ A node of the RecursionDecorator. """ def __init__(self, stmt, parent): self.script = stmt.get_parent_until() self.position = stmt.start_pos @@ -136,7 +140,7 @@ class ExecutionRecursionDecorator(object): def fast_parent_copy(obj): """ - Much, much faster than deepcopy, but just for the elements in `classes`. + Much, much faster than copy.deepcopy, but just for certain elements. """ new_elements = {} @@ -179,7 +183,7 @@ def fast_parent_copy(obj): def generate_param_array(args_tuple, parent_stmt=None): - """ This generates an array, that can be used as a param """ + """ This generates an array, that can be used as a param. """ values = [] for arg in args_tuple: if arg is None: diff --git a/imports.py b/imports.py index 16575d72..f13001a0 100644 --- a/imports.py +++ b/imports.py @@ -18,6 +18,9 @@ class ModuleNotFound(Exception): class ImportPath(object): + """ + An ImportPath is the path of a `parsing.Import` object. + """ class GlobalNamespace(object): pass @@ -80,6 +83,10 @@ class ImportPath(object): return names def get_module_names(self, search_path=None): + """ + Get the names of all modules in the search_path. This means file names + and not names defined in the files. + """ names = [] for module_loader, name, is_pkg in pkgutil.iter_modules(search_path): inf = float('inf') @@ -171,7 +178,7 @@ class ImportPath(object): def strip_imports(scopes): """ Here we strip the imports - they don't get resolved necessarily. - Really used anymore? + Really used anymore? Merge with remove_star_imports? """ result = [] for s in scopes: @@ -189,6 +196,10 @@ def strip_imports(scopes): def remove_star_imports(scope): """ + Check a module for star imports: + >>> from module import * + + and follow these modules. """ modules = strip_imports(i for i in scope.get_imports() if i.star) new = [] diff --git a/modules.py b/modules.py index bc4a59d8..45957e63 100644 --- a/modules.py +++ b/modules.py @@ -121,17 +121,17 @@ class ModuleWithCursor(Module): after = re.search("[\w\d]*", line[self.position[1]:]).group(0) return self.get_path_until_cursor() + after - def get_line(self, line): + def get_line(self, line_nr): if not self._line_cache: self._line_cache = self.source.split('\n') - if line == 0: + if line_nr == 0: # This is a fix for the zeroth line. We need a newline there, for # the backwards parser. return '' - if line < 0: + if line_nr < 0: raise StopIteration() try: - return self._line_cache[line - 1] + return self._line_cache[line_nr - 1] except IndexError: raise StopIteration()