customising py py
DESCRIPTION
Making a Python capable binary by customising PyPyTRANSCRIPT
Customising PyPyMake your own rules
Custom ExecutableSubcommand paradigm
Run from anywhere
Executable name and location used to resolve library path
Executable Module in PyPy
pypy/module/mymod __init__.py app_part1.py interp_part2.py test/test_part1.py test/test_part2.py
Interface in __init__.pyExposes symbols to the "user"from pypy.interpreter.mixedmodule import MixedModule
class Module(MixedModule):
interpleveldefs = {}
appleveldefs = { 'commands' : 'app_commands.COMMANDS', 'find_commands' : 'app_commands.find_commands', 'CommandError' : 'app_commands.CommandError', }
App Level PythonStart with#NOT RPYTHONConsider your imports carefully
And then write python like you normally will
Testing - App Level
Hacking a module is pain. Roundtrip to build executable is >30 mins
TDD winsWrite unit tests to cover as much as you can. Time to write pypy/module/test/test_one.py
Testing - App Level PythonBeware of imports and test setup mocks
from pypy.conftest import gettestobjspace
class AppTestCall(object): def setup_class(cls): # import mymod, sys space = cls.space = gettestobjspace(usemodules=('mymod','sys',)) # sys.app_name = "pypy-c" space.setattr(space.sys, space.wrap("app_name"), space.wrap("pypy-c"))
def test_mymod(): import mymod
Interface in __init__.pyExposes symbols to the "user"from pypy.interpreter.mixedmodule import MixedModule
class Module(MixedModule):
interpleveldefs = { 'find_module': 'interp_imp.find_module',}
appleveldefs = {}
Interp Level Python
RPython for Speed
You can implement the internals of a module in RPython which will be compiled to binary.
It is your responsibility to handle wrapping and unwrapping
def find_module(space, w_name, w_path=None): name = space.str_w(w_name) if space.is_w(w_path, space.w_None): w_path = None return space.newtuple([w_fileobj, w_filename, w_import_info])
Testing - Interp Level Python
Beware of imports and test setup mocks
from pypy.conftest import gettestobjspace
class AppTestImpModule: def setup_class(cls): cls.w_imp = cls.space.getbuiltinmodule('imp') def test_find_module(self): import os file, pathname, description = self.imp.find_module('StringIO')
Customising the Command Linepypy/translator/goal/ targetpypystandalone.py
# manually imports app_main.py filename = os.path.join(this_dir, 'app_main.py') app = gateway.applevel(open(filename).read(), 'app_main.py', 'app_main')
Keep changes to a minimum as you have to build a
binary to test them!
Customising the Command Line
pypy/translator/goal/ app_main.py
def run_command_line(.. settings .., cmd=None, **ignored): mainmodule = type(sys)('__main__') import site if run_command: ... elif run_module: ... elif run_stdin: # piped or interactive shell ... else: import installation if not sys.argv[0].endswith(".py") and sys.argv[0].find("/") == -1: argv = sys.argv[:] argv.insert(0,"") installation.commands.execute(argv) success = True else: ...
Main Sequence
(I’m not too sure about this)nanos moduleapp_main.py...full os module...run_command_line(..)site.pysitecustomize.pymain module/script/interpreter loading
Command Line Parsers
app_main.py:def parse_command_line(argv)optparse.OptionParser
argsparse.ArgsParser
My ObjectiveObjectiveSelf updating
Filesystem monitoring
Network Peer
Daemon/Service capable
Configurable command line
Building PyPy
Add to pypy/config/pypyoptions.py (or)Use --with-mymod
cd pypy/translator/goal translate.py --with-mymodtargetpypystandalone.py
Henrik Vendelbo
[email protected]://github.com/thepian/pypy