'''
This module does most of the code processing to allow the execution of
a Python program.
The names defined here will be included in the globals namespace in which
the user's program is executed. We try to avoid names collisions by
almost always using a double underscore as a prefix.
'''
import sys
from browser import window, console
__REEBORG_EN = {}
exec("from reeborg_en import *", __REEBORG_EN)
__REEBORG_FR = {}
exec("from reeborg_fr import *", __REEBORG_FR)
def dir_py(obj, exclude=None):
'''Prints all "public" attributes of an object, one per line, identifying
which ones are callable by appending parentheses to their name.
By "public" attributes, we mean those whose name does not start with
a double underscore.'''
def html_escape(obj):
return str(obj).replace("&", "&").replace("<", "<").replace(">", ">")
out = []
for attr in dir(obj):
try:
if exclude:
if attr in exclude:
continue
if not attr.startswith("__"):
if callable(getattr(obj, attr)):
out.append(attr + "()")
else:
out.append(attr)
except AttributeError: # javascript extension, as in supplant()
pass # string prototype extension, can cause problems
window.RUR._print_html_(html_escape("\n".join(out)).replace("\n", "
"), True)
def _import_en(namespace):
'''Does the clean equivalent of
from reeborg_en import *
into a namespace.
'''
ReeborgOK_saved = window['ReeborgOK_en']
ReeborgOk_saved = window['ReeborgOk_en']
ReeborgError_saved = window['ReeborgError_en']
WallCollisionError_saved = window['WallCollisionError_en']
MissingObjectError_saved = window['MissingObjectError_en']
namespace.update(__REEBORG_EN)
window['ReeborgOK'] = ReeborgOK_saved
window['ReeborgOk'] = ReeborgOk_saved
window['ReeborgError'] = ReeborgError_saved
window['WallCollisionError'] = WallCollisionError_saved
window['MissingObjectError'] = MissingObjectError_saved
def _import_fr(namespace):
'''Does the clean equivalent of
from reeborg_fr import *
into a namespace.
'''
ReeborgOK_saved = window['ReeborgOK_fr']
ReeborgOk_saved = window['ReeborgOk_fr']
ReeborgError_saved = window['ReeborgError_fr']
WallCollisionError_saved = window['WallCollisionError_fr']
MissingObjectError_saved = window['MissingObjectError_fr']
namespace.update(__REEBORG_FR)
window['ReeborgOK'] = ReeborgOK_saved
window['ReeborgOk'] = ReeborgOk_saved
window['ReeborgError'] = ReeborgError_saved
window['WallCollisionError'] = WallCollisionError_saved
window['MissingObjectError'] = MissingObjectError_saved
def __add_watch(expr):
window.RUR.watched_expressions.append(expr)
window.RUR.add_watch = __add_watch
def __write(data):
window.RUR.output.write(str(data))
def __html_escape(obj):
return str(obj).replace("&", "&").replace("<", "<").replace(">", ">")
__old_vars = "%s: %s" # NOQA
__new_vars = "%s: %s" # NOQA
__changed_vars = "%s: %s" # NOQA
__html_div = "
{}".format(str(obj.__doc__)) out.append(doc) else: out.append("
No docstring found.
") except Exception as e: window.console.log("exception in __help", e.__name__) for attr in dir(obj): if attr == "__class__" or attr.startswith("__"): continue try: if hasattr(getattr(obj, attr), "__doc__"): if getattr(obj, attr).__doc__: out.append("{}".format(getattr(obj, attr).__doc__) out.append(doc) except AttributeError: pass if not out: raise AttributeError("This object has no docstring.") else: window.print_html("".join(out), True) window["__help"] = __help def __generic_translate_python(src, highlight=False, var_watch=False, pre_code='', post_code=''): ''' RUR.translate Python code into Javascript and execute src: source code in editor highlight: determines if the code will be highlighted as it is run var_watch: determines if some variable watch will take place pre_code: code included with world definition and prepended to user code post_code: code included with world definition and appended to user code ''' from preprocess import transform # keeping out of global namespace from highlight import insert_highlight_info sys.stdout.write = __write sys.stderr.write = __write # reeborg_en and reeborg_fr define some attributes to window; these # could have been redefined when importing a different language version - # or, perhas even when running a Javascript version; so it # is important to ensure that they have their proper definition by forcing # a fresh import each time such a request is made via something like # from reeborg_en import * # Similarly, library or biblio's content might have changed by the user # since the program was run last time for mod in ["reeborg_en", "reeborg_fr", "library", "biblio", "extra"]: if mod in sys.modules: del sys.modules[mod] globals_ = {} globals_['__help'] = __help globals_['__watch'] = __watch globals_['__previous_watch_values'] = {} globals_['window'] = window globals_['console'] = console globals_['print_dir'] = print_dir src = transform(src) # sometimes, when copying from documentation displayed in the browsers # some nonbreaking spaces are inserted instead of regular spaces. # We make the assumption that nonbreaking spaces should never appear # in source code - which is not necessarily valid... if '\xa0' in src: src = src.replace('\xa0', ' ') window.console.warn("Some nonbreaking spaces were replaced in the Python code.") # Notwithstanding what is writte above regarding fresh imports, # we simulate this here by doing a dict update, thus effectively using a # cached version of a previous import while ensuring that and # global ("window") definition is done properly. if window.RUR.from_import == "from reeborg_en import *": globals_.update(__REEBORG_EN) elif window.RUR.from_import == "from reeborg_fr import *": globals_.update(__REEBORG_FR) else: raise Exception("unknown import %s" % window.RUR.from_import) if highlight or var_watch: try: temp_src, problem = insert_highlight_info(src, highlight=highlight, var_watch=var_watch) if not problem: src = temp_src else: window.RUR.toggle_highlight() window.jQuery("#highlight-impossible").show() except Exception as e: window.RUR.__python_error = e window.console.log("problem with hightlight:", e) return if hasattr(window.RUR, "__debug"): window.console.log("processed source:") window.console.log(src) if var_watch: system_vars = "system_default_vars = set(locals().keys())\n" else: system_vars = "\n" src = "help=__help\n" + pre_code + "\n" + system_vars + src + "\n" + post_code try: exec(src, globals_) except Exception as e: window.RUR.__python_error = e