Mercurial > pydertron
changeset 20:d382ca63d43f
Added docs with doctests.
author | Atul Varma <varmaa@toolness.com> |
---|---|
date | Thu, 10 Sep 2009 15:44:18 -0700 |
parents | 2dc43c316df9 |
children | cb73bb169b67 |
files | pydertron.py test_docs.py |
diffstat | 2 files changed, 79 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/pydertron.py Thu Sep 10 15:13:33 2009 -0700 +++ b/pydertron.py Thu Sep 10 15:44:18 2009 -0700 @@ -37,6 +37,75 @@ """ Pydertron is a high-level wrapper for Pydermonkey that provides convenient, secure object wrapping between JS and Python space. + + The JsSandbox class encapsulates a JavaScript runtime, context, global + object, and a simple SecurableModule implementation that complies + with the CommonJS standard. It also provides a high-level bridge between + Python and JavaScript so that you don't need to deal with any of the + low-level details of the Pydermonkey API. + + For instance, here we'll create a JsSandbox whose module root + points to the 'monkeys' SecurableModule compliance test over HTTP: + + >>> url = ("http://interoperablejs.googlecode.com/svn/trunk/" + ... "compliance/monkeys/") + >>> sandbox = JsSandbox(HttpFileSystem(url)) + + This compliance test requires a global 'sys' object that contains one + method, print(), that takes two arguments. First, we'll create the + print() function and prepare it for exposure to JS code: + + >>> @jsexposed + ... def jsprint(message, label): + ... print message, label + + Note the use of the @jsexposed decorator: all this does is set the + function's __jsexposed__ attribute to True. This is done for security + purposes: only Python callables satisfying this criteria will be + exposed to JavaScript code, to ensure that untrusted JS can't + accidentally gain access to privileged Python functionality. + + Creating a JS object can be done like this: + + >>> system = sandbox.new_object() + + We can now access and set properties on this object via either + item or attribute lookup, just like in JavaScript. Because 'print' + is a reserved word in Python, though, we'll use item lookup to set + the property here: + + >>> system['print'] = jsprint + + Now we tell the sandbox that we want the 'sys' object to be a + global: + + >>> sandbox.set_globals(sys = system) + + And finally, we execute the compliance test by running a one-line + script that imports the 'program' module, like so: + + >>> sandbox.run_script("require('program');") + PASS monkeys permitted pass + DONE info + 0 + + Note the '0' in the last line: this is the return value of + sandbox.run_script(), which returns 0 on success, and -1 if an + exception was raised. For instance, the output of bad + code looks like this: + + >>> sandbox.run_script("(function foo() { bar(); })();", + ... stderr=sys.stdout) + Traceback (most recent call last): + File "<string>", line 1, in <module> + File "<string>", line 1, in foo + ReferenceError: bar is not defined + -1 + + Note that the traceback displayed is actually referring to + JavaScript code: one of Pydertron's helpful conveniences is that + it makes debugging JS code as much like debugging Python code as + possible. """ import sys @@ -562,11 +631,14 @@ return self.__modules[filename] def run_script(self, contents, filename='<string>', lineno=1, - callback=None, stderr=sys.stderr): + callback=None, stderr=None): """ Runs the given JS script, returning 0 on success, -1 on failure. """ + if stderr is None: + stderr = sys.stderr + retval = -1 cx = self.cx try: