1.1 --- a/simplify/__init__.py Sat Jun 23 01:57:13 2007 +0200
1.2 +++ b/simplify/__init__.py Sat Jun 23 21:10:01 2007 +0200
1.3 @@ -3,7 +3,7 @@
1.4 """
1.5 The simplify package for processing Python source code.
1.6
1.7 -Copyright (C) 2007 Paul Boddie <paul@boddie.org.uk>
1.8 +Copyright (C) 2006, 2007 Paul Boddie <paul@boddie.org.uk>
1.9
1.10 This software is free software; you can redistribute it and/or
1.11 modify it under the terms of the GNU General Public License as
1.12 @@ -19,6 +19,196 @@
1.13 License along with this library; see the file LICENCE.txt
1.14 If not, write to the Free Software Foundation, Inc.,
1.15 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
1.16 +
1.17 +--------
1.18 +
1.19 +To use this module, an importer should be constructed and the load method used.
1.20 +Here, the standard path for module searching is used:
1.21 +
1.22 +importer = Importer(sys.path)
1.23 +importer.load_from_file(builtins)
1.24 +importer.load_from_file(filename, builtins)
1.25 """
1.26
1.27 +from simplify.simplified import *
1.28 +import simplify.ast
1.29 +import simplify.fixnames
1.30 +import simplify.annotate
1.31 +import simplify.fixinstances
1.32 +
1.33 +class Importer:
1.34 +
1.35 + "An import machine, searching for and loading modules."
1.36 +
1.37 + def __init__(self, path=None, annotate=1, fixinstances=1):
1.38 +
1.39 + """
1.40 + Initialise the importer with the given search 'path' - a list of
1.41 + directories to search for Python modules. If the optional 'annotate'
1.42 + parameter is set to a false value (unlike the default), no annotation
1.43 + will be performed.
1.44 + false value (unlike the default), no instance fixing will be performed.
1.45 + """
1.46 +
1.47 + self.path = path or [os.getcwd()]
1.48 + self.path.append(libdir)
1.49 + self.annotate = annotate
1.50 + self.modules = {}
1.51 +
1.52 + def get_modules(self):
1.53 + return self.modules.values()
1.54 +
1.55 + def find_in_path(self, name):
1.56 +
1.57 + """
1.58 + Find the given module 'name' in the search path, returning None where no
1.59 + such module could be found, or a 2-tuple from the 'find' method
1.60 + otherwise.
1.61 + """
1.62 +
1.63 + for d in self.path:
1.64 + m = self.find(d, name)
1.65 + if m: return m
1.66 + return None
1.67 +
1.68 + def find(self, d, name):
1.69 +
1.70 + """
1.71 + In the directory 'd', find the given module 'name', where 'name' can
1.72 + either refer to a single file module or to a package. Return None if the
1.73 + 'name' cannot be associated with either a file or a package directory,
1.74 + or a 2-tuple from '_find_package' or '_find_module' otherwise.
1.75 + """
1.76 +
1.77 + m = self._find_package(d, name)
1.78 + if m: return m
1.79 + m = self._find_module(d, name)
1.80 + if m: return m
1.81 + return None
1.82 +
1.83 + def _find_module(self, d, name):
1.84 +
1.85 + """
1.86 + In the directory 'd', find the given module 'name', returning None where
1.87 + no suitable file exists in the directory, or a 2-tuple consisting of
1.88 + None (indicating that no package directory is involved) and a filename
1.89 + indicating the location of the module.
1.90 + """
1.91 +
1.92 + name_py = name + os.extsep + "py"
1.93 + filename = self._find_file(d, name_py)
1.94 + if filename:
1.95 + return None, filename
1.96 + return None
1.97 +
1.98 + def _find_package(self, d, name):
1.99 +
1.100 + """
1.101 + In the directory 'd', find the given package 'name', returning None
1.102 + where no suitable package directory exists, or a 2-tuple consisting of
1.103 + a directory (indicating the location of the package directory itself)
1.104 + and a filename indicating the location of the __init__.py module which
1.105 + declares the package's top-level contents.
1.106 + """
1.107 +
1.108 + filename = self._find_file(d, name)
1.109 + if filename:
1.110 + init_py = "__init__" + os.path.extsep + "py"
1.111 + init_py_filename = self._find_file(filename, init_py)
1.112 + if init_py_filename:
1.113 + return filename, init_py_filename
1.114 + return None
1.115 +
1.116 + def _find_file(self, d, filename):
1.117 +
1.118 + """
1.119 + Return the filename obtained when searching the directory 'd' for the
1.120 + given 'filename', or None if no actual file exists for the filename.
1.121 + """
1.122 +
1.123 + filename = os.path.join(d, filename)
1.124 + if os.path.exists(filename):
1.125 + return filename
1.126 + else:
1.127 + return None
1.128 +
1.129 + def load(self, name, builtins=None, alias=None):
1.130 +
1.131 + """
1.132 + Load the module or package with the given 'name' and using the specified
1.133 + 'builtins'. Return an Attribute object referencing the loaded module or
1.134 + package, or None if no such module or package exists.
1.135 + """
1.136 +
1.137 + if self.modules.has_key(name):
1.138 + return Attribute(None, self.modules[name])
1.139 +
1.140 + path = name.split(".")
1.141 + m = self.find_in_path(path[0])
1.142 + if not m:
1.143 + return None # NOTE: Import error.
1.144 + d, filename = m
1.145 +
1.146 + if self.modules.has_key(path[0]):
1.147 + top = module = self.modules[path[0]]
1.148 + else:
1.149 + top = module = self.load_from_file(filename, builtins, path[0])
1.150 +
1.151 + if len(path) > 1:
1.152 + path_so_far = path[:1]
1.153 + for p in path[1:]:
1.154 + path_so_far.append(p)
1.155 + m = self.find(d, p)
1.156 + if not m:
1.157 + return None # NOTE: Import error.
1.158 + d, filename = m
1.159 + module_name = ".".join(path_so_far)
1.160 +
1.161 + if self.modules.has_key(module_name):
1.162 + submodule = self.modules[module_name]
1.163 + else:
1.164 + submodule = self.load_from_file(filename, builtins, module_name)
1.165 +
1.166 + # Store the submodule within its parent module.
1.167 +
1.168 + module.namespace[p] = [Attribute(None, submodule)]
1.169 + module = submodule
1.170 +
1.171 + if alias:
1.172 + return Attribute(None, module)
1.173 + else:
1.174 + return Attribute(None, top)
1.175 +
1.176 + def load_from_file(self, name, builtins=None, module_name=None):
1.177 +
1.178 + """
1.179 + Load the module with the given 'name' (which may be a full module path),
1.180 + using the optional 'builtins' to resolve built-in names.
1.181 + """
1.182 +
1.183 + if module_name is None:
1.184 + if builtins is None:
1.185 + module_name = "__builtins__"
1.186 + else:
1.187 + module_name = "__main__"
1.188 +
1.189 + module = simplify.ast.simplify(name, builtins is None, module_name)
1.190 + simplify.fixnames.fix(module, builtins)
1.191 + if self.annotate:
1.192 + simplify.annotate.annotate(module, builtins, self)
1.193 +
1.194 + # Record the module.
1.195 +
1.196 + self.modules[module_name] = module
1.197 + return module
1.198 +
1.199 + def fix_instances(self):
1.200 +
1.201 + "Fix instances for all modules loaded by this importer."
1.202 +
1.203 + for module in self.get_modules():
1.204 + simplify.fixinstances.fix_structures(module)
1.205 + for module in self.get_modules():
1.206 + simplify.fixinstances.fix(module)
1.207 +
1.208 # vim: tabstop=4 expandtab shiftwidth=4
2.1 --- a/simplify/annotate.py Sat Jun 23 01:57:13 2007 +0200
2.2 +++ b/simplify/annotate.py Sat Jun 23 21:10:01 2007 +0200
2.3 @@ -24,25 +24,17 @@
2.4
2.5 --------
2.6
2.7 -To use this module, the easiest approach is to use the load function:
2.8 -
2.9 -load(filename, builtins)
2.10 -
2.11 -To control module importing, an importer should be constructed and employed.
2.12 -Here, the standard path for module searching is used:
2.13 +To use this module, the easiest approach is to use the annotate function which
2.14 +provides support for annotating modules already processed by simplify and
2.15 +fixnames:
2.16
2.17 -importer = Importer(sys.path)
2.18 -load(filename, builtins, importer)
2.19 +annotate(builtins, None, importer)
2.20 +annotate(module, builtins, importer)
2.21
2.22 -Underneath the load function, the annotate function provides support for
2.23 -annotating modules already processed by simplify and fixnames:
2.24 -
2.25 -annotate(module, builtins)
2.26 -
2.27 -And at the most basic level, the most intricate approach involves obtaining an
2.28 +At the most basic level, the most intricate approach involves obtaining an
2.29 Annotator object:
2.30
2.31 -annotator = Annotator()
2.32 +annotator = Annotator(importer)
2.33
2.34 Then, processing an existing module with it:
2.35
2.36 @@ -55,7 +47,6 @@
2.37 """
2.38
2.39 from simplify.simplified import *
2.40 -import simplify.ast, simplify.fixnames # for the load function
2.41 import compiler
2.42 import os
2.43
2.44 @@ -139,13 +130,13 @@
2.45 Try.
2.46 """
2.47
2.48 - def __init__(self, importer=None):
2.49 + def __init__(self, importer):
2.50
2.51 - "Initialise the visitor with an optional 'importer'."
2.52 + "Initialise the visitor with an 'importer'."
2.53
2.54 Visitor.__init__(self)
2.55 self.system = system
2.56 - self.importer = importer or Importer()
2.57 + self.importer = importer
2.58
2.59 # Satisfy visitor issues.
2.60
2.61 @@ -487,7 +478,7 @@
2.62 # exist for some combinations of classes in a hierarchy but not for
2.63 # others.
2.64
2.65 - if isinstance(attr.type, Class):
2.66 + if isinstance(attr.type, GeneralClass):
2.67 attributes = get_attributes(attr.type, "__init__")
2.68
2.69 # Deal with object invocations by using __call__ methods.
2.70 @@ -509,7 +500,7 @@
2.71 # If a class is involved, presume that it must create a new
2.72 # object.
2.73
2.74 - if isinstance(attr.type, Class):
2.75 + if isinstance(attr.type, GeneralClass):
2.76
2.77 # Instantiate the class.
2.78
2.79 @@ -534,7 +525,7 @@
2.80 if attribute.type not in invocations:
2.81 invocations.append(attribute.type)
2.82
2.83 - elif not isinstance(attr.type, Class):
2.84 + elif not isinstance(attr.type, GeneralClass):
2.85 print "Invocation type is None for", accessor
2.86
2.87 else:
2.88 @@ -547,7 +538,7 @@
2.89
2.90 # Special case: initialisation.
2.91
2.92 - if isinstance(attr.type, Class):
2.93 + if isinstance(attr.type, GeneralClass):
2.94
2.95 # Associate the instance with the result of this invocation.
2.96
2.97 @@ -811,7 +802,7 @@
2.98 raise_.dstar = None
2.99 types = set()
2.100 for attr in self.namespace.types:
2.101 - if isinstance(attr.type, Class):
2.102 + if isinstance(attr.type, GeneralClass):
2.103 self._visitInvoke(raise_, [attr], have_args=0)
2.104 types.update(self.namespace.types)
2.105 else:
2.106 @@ -1383,144 +1374,6 @@
2.107
2.108 # Namespace-related abstractions.
2.109
2.110 -class Importer:
2.111 -
2.112 - "An import machine, searching for and loading modules."
2.113 -
2.114 - def __init__(self, path=None):
2.115 -
2.116 - """
2.117 - Initialise the importer with the given search 'path' - a list of
2.118 - directories to search for Python modules.
2.119 - """
2.120 -
2.121 - self.path = path or [os.getcwd()]
2.122 - self.path.append(libdir)
2.123 - self.modules = {}
2.124 -
2.125 - def find_in_path(self, name):
2.126 -
2.127 - """
2.128 - Find the given module 'name' in the search path, returning None where no
2.129 - such module could be found, or a 2-tuple from the 'find' method
2.130 - otherwise.
2.131 - """
2.132 -
2.133 - for d in self.path:
2.134 - m = self.find(d, name)
2.135 - if m: return m
2.136 - return None
2.137 -
2.138 - def find(self, d, name):
2.139 -
2.140 - """
2.141 - In the directory 'd', find the given module 'name', where 'name' can
2.142 - either refer to a single file module or to a package. Return None if the
2.143 - 'name' cannot be associated with either a file or a package directory,
2.144 - or a 2-tuple from '_find_package' or '_find_module' otherwise.
2.145 - """
2.146 -
2.147 - m = self._find_package(d, name)
2.148 - if m: return m
2.149 - m = self._find_module(d, name)
2.150 - if m: return m
2.151 - return None
2.152 -
2.153 - def _find_module(self, d, name):
2.154 -
2.155 - """
2.156 - In the directory 'd', find the given module 'name', returning None where
2.157 - no suitable file exists in the directory, or a 2-tuple consisting of
2.158 - None (indicating that no package directory is involved) and a filename
2.159 - indicating the location of the module.
2.160 - """
2.161 -
2.162 - name_py = name + os.extsep + "py"
2.163 - filename = self._find_file(d, name_py)
2.164 - if filename:
2.165 - return None, filename
2.166 - return None
2.167 -
2.168 - def _find_package(self, d, name):
2.169 -
2.170 - """
2.171 - In the directory 'd', find the given package 'name', returning None
2.172 - where no suitable package directory exists, or a 2-tuple consisting of
2.173 - a directory (indicating the location of the package directory itself)
2.174 - and a filename indicating the location of the __init__.py module which
2.175 - declares the package's top-level contents.
2.176 - """
2.177 -
2.178 - filename = self._find_file(d, name)
2.179 - if filename:
2.180 - init_py = "__init__" + os.path.extsep + "py"
2.181 - init_py_filename = self._find_file(filename, init_py)
2.182 - if init_py_filename:
2.183 - return filename, init_py_filename
2.184 - return None
2.185 -
2.186 - def _find_file(self, d, filename):
2.187 -
2.188 - """
2.189 - Return the filename obtained when searching the directory 'd' for the
2.190 - given 'filename', or None if no actual file exists for the filename.
2.191 - """
2.192 -
2.193 - filename = os.path.join(d, filename)
2.194 - if os.path.exists(filename):
2.195 - return filename
2.196 - else:
2.197 - return None
2.198 -
2.199 - def load(self, name, builtins, alias=None):
2.200 -
2.201 - """
2.202 - Load the module or package with the given 'name' and using the specified
2.203 - 'builtins'. Return an Attribute object referencing the loaded module or
2.204 - package, or None if no such module or package exists.
2.205 - """
2.206 -
2.207 - if self.modules.has_key(name):
2.208 - return Attribute(None, self.modules[name])
2.209 -
2.210 - path = name.split(".")
2.211 - m = self.find_in_path(path[0])
2.212 - if not m:
2.213 - return None # NOTE: Import error.
2.214 - d, filename = m
2.215 -
2.216 - if self.modules.has_key(path[0]):
2.217 - top = module = self.modules[path[0]]
2.218 - else:
2.219 - top = module = self.modules[path[0]] = load(filename, builtins, path[0], self, no_annotate=1)
2.220 - annotate(module, builtins, self)
2.221 -
2.222 - if len(path) > 1:
2.223 - path_so_far = path[:1]
2.224 - for p in path[1:]:
2.225 - path_so_far.append(p)
2.226 - m = self.find(d, p)
2.227 - if not m:
2.228 - return None # NOTE: Import error.
2.229 - d, filename = m
2.230 - module_name = ".".join(path_so_far)
2.231 -
2.232 - if self.modules.has_key(module_name):
2.233 - submodule = self.modules[module_name]
2.234 - else:
2.235 - submodule = self.modules[module_name] = load(filename, builtins, module_name, self, no_annotate=1)
2.236 - annotate(submodule, builtins, self)
2.237 -
2.238 - # Store the submodule within its parent module.
2.239 -
2.240 - module.namespace[p] = [Attribute(None, submodule)]
2.241 - module = submodule
2.242 -
2.243 - if alias:
2.244 - return Attribute(None, module)
2.245 - else:
2.246 - return Attribute(None, top)
2.247 -
2.248 def combine(target, additions):
2.249
2.250 """
2.251 @@ -1566,7 +1419,7 @@
2.252
2.253 # Investigate any class's base classes.
2.254
2.255 - elif isinstance(structure, Class):
2.256 + elif isinstance(structure, GeneralClass):
2.257
2.258 # If no base classes exist, return an indicator that no attribute
2.259 # exists.
2.260 @@ -1609,7 +1462,7 @@
2.261
2.262 # Detect class attribute access via instances.
2.263
2.264 - if attribute is not None and isinstance(structure, Instance) and isinstance(accessor, Class):
2.265 + if attribute is not None and isinstance(structure, Instance) and isinstance(accessor, GeneralClass):
2.266 attribute = accessor.get_attribute_for_instance(attribute, structure)
2.267
2.268 # Produce an attribute with the appropriate context.
2.269 @@ -1640,26 +1493,11 @@
2.270
2.271 # Convenience functions.
2.272
2.273 -def load(name, builtins=None, module_name=None, importer=None, no_annotate=0):
2.274 +def annotate(module, builtins, importer):
2.275
2.276 """
2.277 - Load the module with the given 'name' (which may be a full module path),
2.278 - using the optional 'builtins' to resolve built-in names, and using the
2.279 - optional 'importer' to provide a means of finding and loading modules.
2.280 - """
2.281 -
2.282 - module = simplify.ast.simplify(name, builtins is None, module_name)
2.283 - simplify.fixnames.fix(module, builtins)
2.284 - if not no_annotate:
2.285 - annotate(module, builtins, importer)
2.286 - return module
2.287 -
2.288 -def annotate(module, builtins=None, importer=None):
2.289 -
2.290 - """
2.291 - Annotate the given 'module', also employing the optional 'builtins' module,
2.292 - if specified. If the optional 'importer' is given, use that to find and load
2.293 - modules.
2.294 + Annotate the given 'module', also employing the 'builtins' module which may
2.295 + be specified as None. Use the 'importer' to find and load modules.
2.296 """
2.297
2.298 annotator = Annotator(importer)
3.1 --- a/simplify/ast.py Sat Jun 23 01:57:13 2007 +0200
3.2 +++ b/simplify/ast.py Sat Jun 23 21:10:01 2007 +0200
3.3 @@ -547,7 +547,7 @@
3.4 else:
3.5 bases = class_.bases
3.6
3.7 - structure = Class(name=class_.name, module=self.module, bases=self.dispatches(bases))
3.8 + structure = get_class()(name=class_.name, module=self.module, bases=self.dispatches(bases))
3.9 self.structures.append(structure)
3.10 within_class = self.within_class
3.11 self.within_class = 1
4.1 --- a/simplify/fixinstances.py Sat Jun 23 01:57:13 2007 +0200
4.2 +++ b/simplify/fixinstances.py Sat Jun 23 21:10:01 2007 +0200
4.3 @@ -174,6 +174,12 @@
4.4 return node
4.5
4.6 def _replace(self, items, name=None):
4.7 +
4.8 + """
4.9 + Produce a new list or set for the given 'items', acquired from the
4.10 + annotation having the given 'name'.
4.11 + """
4.12 +
4.13 if name == "accesses":
4.14 new_items = []
4.15 else:
4.16 @@ -192,9 +198,29 @@
4.17 return new_items
4.18
4.19 def _get_replacement(self, value):
4.20 +
4.21 + "Get a replacement for the given 'value'."
4.22 +
4.23 + # Find the distinct instance for any given instance.
4.24 +
4.25 if isinstance(value, Instance):
4.26 distinct_instances = value.get_class().get_distinct_instances()
4.27 return distinct_instances[value]
4.28 +
4.29 + # For subprograms, find the distinct instance's copy for the owner
4.30 + # instance; otherwise, return the original subprogram.
4.31 +
4.32 + elif isinstance(value, Subprogram):
4.33 + if hasattr(value, "copy_of") and hasattr(value, "instance"):
4.34 + cls = value.instance.get_class()
4.35 + distinct = cls.get_distinct_instances()
4.36 + instance = distinct[value.instance]
4.37 + return value.copy_of.copies.get(instance, value)
4.38 + else:
4.39 + return value
4.40 +
4.41 + # Return all other values as they are.
4.42 +
4.43 else:
4.44 return value
4.45
5.1 --- a/simplify/simplified/__init__.py Sat Jun 23 01:57:13 2007 +0200
5.2 +++ b/simplify/simplified/__init__.py Sat Jun 23 21:10:01 2007 +0200
5.3 @@ -55,4 +55,7 @@
5.4 global Class
5.5 Class = ProlificMultipleInstanceClass
5.6
5.7 +def get_class():
5.8 + return Class
5.9 +
5.10 # vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/simplify/simplified/data.py Sat Jun 23 01:57:13 2007 +0200
6.2 +++ b/simplify/simplified/data.py Sat Jun 23 21:10:01 2007 +0200
6.3 @@ -30,7 +30,7 @@
6.4
6.5 # Special non-program nodes.
6.6
6.7 -class _Class(Structure, WithName):
6.8 +class GeneralClass(Structure, WithName):
6.9
6.10 """
6.11 The basis of a Python class. Classes with specific instantiation behaviour
6.12 @@ -117,12 +117,12 @@
6.13
6.14 return instances
6.15
6.16 -class SingleInstanceClass(_Class):
6.17 +class SingleInstanceClass(GeneralClass):
6.18
6.19 "A Python class producing only one instance."
6.20
6.21 def __init__(self, *args, **kw):
6.22 - _Class.__init__(self, *args, **kw)
6.23 + GeneralClass.__init__(self, *args, **kw)
6.24 self.instance = None
6.25
6.26 def has_instance(self, node):
6.27 @@ -148,12 +148,12 @@
6.28 def get_attribute_for_instance(self, attribute, instance):
6.29 return attribute
6.30
6.31 -class MultipleInstanceClass(_Class):
6.32 +class MultipleInstanceClass(GeneralClass):
6.33
6.34 "A Python class producing many instances."
6.35
6.36 def __init__(self, *args, **kw):
6.37 - _Class.__init__(self, *args, **kw)
6.38 + GeneralClass.__init__(self, *args, **kw)
6.39 self.instances = {}
6.40 self.attributes_for_instances = {}
6.41
7.1 --- a/simplify/viewer.py Sat Jun 23 01:57:13 2007 +0200
7.2 +++ b/simplify/viewer.py Sat Jun 23 21:10:01 2007 +0200
7.3 @@ -1302,11 +1302,11 @@
7.4 finally:
7.5 stream.close()
7.6
7.7 -def makedocs(module, modules, builtins, distinct=0):
7.8 - dirname = "%s-docs" % module.name
7.9 +def makedocs(filename, modules, distinct=0):
7.10 + dirname = "%s-docs" % os.path.split(os.path.splitext(filename)[0])[-1]
7.11 if not os.path.exists(dirname):
7.12 os.mkdir(dirname)
7.13 - for m in [module, builtins] + modules:
7.14 + for m in modules:
7.15 makedoc(m, os.path.join(dirname, "%s%sxhtml" % (m.name, os.path.extsep)))
7.16 makesummary(m, os.path.join(dirname, "%s%s%sxhtml" % (m.name, "-summary", os.path.extsep)), distinct=distinct)
7.17
8.1 --- a/test.py Sat Jun 23 01:57:13 2007 +0200
8.2 +++ b/test.py Sat Jun 23 21:10:01 2007 +0200
8.3 @@ -16,22 +16,14 @@
8.4 simplified.set_prolific_multiple_instance_mode()
8.5
8.6 import simplify.viewer
8.7 - import simplify.fixinstances
8.8 - from simplify.annotate import AnnotationError, Importer, load
8.9 + from simplify import Importer
8.10
8.11 - importer = Importer(sys.path)
8.12 - try:
8.13 - builtins = load(os.path.join("lib", "builtins.py"))
8.14 - module = load(sys.argv[1], builtins, None, importer, "-na" in sys.argv)
8.15 - except simplified.SimplifiedError, exc:
8.16 - raise
8.17 - else:
8.18 - if "-i" in sys.argv:
8.19 - simplify.fixinstances.fix_structures(module)
8.20 - simplify.fixinstances.fix_structures(builtins)
8.21 - simplify.fixinstances.fix(module)
8.22 - simplify.fixinstances.fix(builtins)
8.23 - if "-d" in sys.argv:
8.24 - simplify.viewer.makedocs(module, importer.modules.values(), builtins, distinct=("-i" in sys.argv))
8.25 + importer = Importer(sys.path, "-na" not in sys.argv)
8.26 + builtins = importer.load_from_file(os.path.join("lib", "builtins.py"))
8.27 + module = importer.load_from_file(sys.argv[1], builtins)
8.28 + if "-i" in sys.argv:
8.29 + importer.fix_instances()
8.30 + if "-d" in sys.argv:
8.31 + simplify.viewer.makedocs(sys.argv[1], importer.get_modules(), distinct=("-i" in sys.argv))
8.32
8.33 # vim: tabstop=4 expandtab shiftwidth=4