From 3d4e23cc9cdefa4b83c20f9483a7c95f2afa563e Mon Sep 17 00:00:00 2001 From: rocky Date: Sun, 13 Dec 2015 00:25:34 -0500 Subject: [PATCH] Add tests and start a more turnkey testing system. --- .gitignore | 2 + Makefile | 23 +- README.rst | 97 +- test/Makefile | 21 + test/base-tests/python2/compile_tests | 77 + .../python2}/test_applyEquiv.py | 0 test/base-tests/python2/test_applyEquiv.pyc | Bin 0 -> 1108 bytes .../python2}/test_augmentedAssign.py | 0 .../python2/test_augmentedAssign.pyc | Bin 0 -> 1180 bytes test/{ => base-tests/python2}/test_class.py | 0 test/base-tests/python2/test_class.pyc | Bin 0 -> 2412 bytes test/{ => base-tests/python2}/test_del.py | 0 test/base-tests/python2/test_del.pyc | Bin 0 -> 554 bytes .../python2}/test_divide_future.py | 0 .../base-tests/python2/test_divide_future.pyc | Bin 0 -> 405 bytes .../python2}/test_divide_no_future.py | 0 .../python2/test_divide_no_future.pyc | Bin 0 -> 337 bytes .../python2}/test_docstring.py | 0 test/base-tests/python2/test_docstring.pyc | Bin 0 -> 2244 bytes test/{ => base-tests/python2}/test_empty.py | 0 test/base-tests/python2/test_empty.pyc | Bin 0 -> 166 bytes .../python2}/test_exceptions.py | 0 test/base-tests/python2/test_exceptions.pyc | Bin 0 -> 3541 bytes test/{ => base-tests/python2}/test_exec.py | 0 test/base-tests/python2/test_exec.pyc | Bin 0 -> 259 bytes .../python2}/test_expressions.py | 0 test/base-tests/python2/test_expressions.pyc | Bin 0 -> 725 bytes .../python2}/test_extendedImport.py | 0 .../python2/test_extendedImport.pyc | Bin 0 -> 604 bytes .../python2}/test_extendedPrint.py | 0 .../base-tests/python2/test_extendedPrint.pyc | Bin 0 -> 319 bytes .../python2/test_extendedarg.py-notyet} | 0 .../python2}/test_functions.py | 0 test/base-tests/python2/test_functions.pyc | Bin 0 -> 3958 bytes test/{ => base-tests/python2}/test_global.py | 0 test/base-tests/python2/test_global.pyc | Bin 0 -> 838 bytes test/{ => base-tests/python2}/test_globals.py | 0 test/base-tests/python2/test_globals.pyc | Bin 0 -> 444 bytes test/{ => base-tests/python2}/test_import.py | 0 test/base-tests/python2/test_import.pyc | Bin 0 -> 553 bytes .../python2}/test_import_as.py | 0 test/base-tests/python2/test_import_as.pyc | Bin 0 -> 676 bytes .../{ => base-tests/python2}/test_integers.py | 0 test/base-tests/python2/test_integers.pyc | Bin 0 -> 482 bytes .../python2}/test_iterators.py | 0 test/base-tests/python2/test_iterators.pyc | Bin 0 -> 278 bytes test/{ => base-tests/python2}/test_lambda.py | 0 test/base-tests/python2/test_lambda.pyc | Bin 0 -> 1529 bytes .../python2}/test_listComprehensions.py | 0 .../python2/test_listComprehensions.pyc | Bin 0 -> 1146 bytes test/{ => base-tests/python2}/test_loops.py | 0 test/base-tests/python2/test_loops.pyc | Bin 0 -> 944 bytes test/{ => base-tests/python2}/test_loops2.py | 0 test/base-tests/python2/test_loops2.pyc | Bin 0 -> 233 bytes test/{ => base-tests/python2}/test_mine.py | 0 test/base-tests/python2/test_mine.pyc | Bin 0 -> 669 bytes test/{ => base-tests/python2}/test_misc.py | 0 test/base-tests/python2/test_misc.pyc | Bin 0 -> 1325 bytes .../python2}/test_nested_elif.py | 0 test/base-tests/python2/test_nested_elif.pyc | Bin 0 -> 902 bytes .../python2}/test_nested_scopes.py | 0 .../base-tests/python2/test_nested_scopes.pyc | Bin 0 -> 5729 bytes .../python2}/test_prettyprint.py | 0 test/base-tests/python2/test_prettyprint.pyc | Bin 0 -> 2414 bytes test/{ => base-tests/python2}/test_print.py | 0 test/base-tests/python2/test_print.pyc | Bin 0 -> 314 bytes .../{ => base-tests/python2}/test_print_to.py | 0 test/base-tests/python2/test_print_to.pyc | Bin 0 -> 413 bytes .../python2}/test_single_stmt.py | 0 test/base-tests/python2/test_single_stmt.pyc | Bin 0 -> 182 bytes test/{ => base-tests/python2}/test_slices.py | 0 test/base-tests/python2/test_slices.pyc | Bin 0 -> 798 bytes .../python2/test_tuple_params.py-notyet} | 0 .../python2/test_tuples.py-notyet} | 0 test/{ => base-tests/python2}/test_yield.py | 0 test/base-tests/python2/test_yield.pyc | Bin 0 -> 908 bytes test/compile_tests | 21 +- test/ok_2.7/aifc.py | 986 ++++++++++++ test/ok_2.7/aifc.pyc_dis | 932 +++++++++++ test/ok_2.7/antigravity.py | 4 + test/ok_2.7/antigravity.pyc_dis | 3 + test/ok_2.7/anydbm.py | 85 + test/ok_2.7/anydbm.pyc_dis | 83 + test/ok_2.7/asynchat.py | 314 ++++ test/ok_2.7/asynchat.pyc_dis | 231 +++ test/ok_2.7/asyncore.py | 659 ++++++++ test/ok_2.7/asyncore.pyc_dis | 560 +++++++ test/ok_2.7/atexit.py | 65 + test/ok_2.7/atexit.pyc_dis | 69 + test/ok_2.7/audiodev.py | 260 +++ test/ok_2.7/audiodev.pyc_dis | 245 +++ test/ok_2.7/base64.py | 360 +++++ test/ok_2.7/binhex.py | 508 ++++++ test/ok_2.7/bisect.py | 92 ++ test/ok_2.7/bsddb/__init__.py | 455 ++++++ test/ok_2.7/bsddb/db.py | 60 + test/ok_2.7/bsddb/dbobj.py | 266 +++ test/ok_2.7/bsddb/dbrecio.py | 190 +++ test/ok_2.7/bsddb/dbshelve.py | 381 +++++ test/ok_2.7/bsddb/dbutils.py | 83 + test/ok_2.7/calendar.py | 713 +++++++++ test/ok_2.7/cgitb.py | 323 ++++ test/ok_2.7/chunk.py | 167 ++ test/ok_2.7/codeop.py | 168 ++ test/ok_2.7/colorsys.py | 156 ++ test/ok_2.7/commands.py | 90 ++ test/ok_2.7/compileall.py | 227 +++ test/ok_2.7/compiler/__init__.py | 31 + test/ok_2.7/compiler/ast.py | 1419 +++++++++++++++++ test/ok_2.7/compiler/consts.py | 23 + test/ok_2.7/compiler/future.py | 74 + test/ok_2.7/compiler/misc.py | 73 + test/ok_2.7/compiler/syntax.py | 46 + test/ok_2.7/ctypes/_endian.py | 64 + test/ok_2.7/ctypes/util.py | 287 ++++ test/ok_2.7/ctypes/wintypes.py | 185 +++ test/ok_2.7/curses/__init__.py | 59 + test/ok_2.7/curses/ascii.py | 99 ++ test/ok_2.7/curses/has_key.py | 192 +++ test/ok_2.7/curses/panel.py | 8 + test/ok_2.7/curses/wrapper.py | 50 + test/ok_2.7/dircache.py | 41 + test/ok_2.7/dis.py | 224 +++ test_one => test/test_one | 0 test/test_pythonlib.py | 167 ++ uncompyle-code.py => test/uncompyle-code.py | 0 test_pythonlib.py | 124 -- uncompyle6/#spark.py# | 704 ++++++++ uncompyle6/__init__.py | 4 +- uncompyle6/verify.py | 8 +- 130 files changed, 12657 insertions(+), 201 deletions(-) create mode 100644 test/Makefile create mode 100755 test/base-tests/python2/compile_tests rename test/{ => base-tests/python2}/test_applyEquiv.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_applyEquiv.pyc rename test/{ => base-tests/python2}/test_augmentedAssign.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_augmentedAssign.pyc rename test/{ => base-tests/python2}/test_class.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_class.pyc rename test/{ => base-tests/python2}/test_del.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_del.pyc rename test/{ => base-tests/python2}/test_divide_future.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_divide_future.pyc rename test/{ => base-tests/python2}/test_divide_no_future.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_divide_no_future.pyc rename test/{ => base-tests/python2}/test_docstring.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_docstring.pyc rename test/{ => base-tests/python2}/test_empty.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_empty.pyc rename test/{ => base-tests/python2}/test_exceptions.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_exceptions.pyc rename test/{ => base-tests/python2}/test_exec.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_exec.pyc rename test/{ => base-tests/python2}/test_expressions.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_expressions.pyc rename test/{ => base-tests/python2}/test_extendedImport.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_extendedImport.pyc rename test/{ => base-tests/python2}/test_extendedPrint.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_extendedPrint.pyc rename test/{test_extendedarg.py => base-tests/python2/test_extendedarg.py-notyet} (100%) mode change 100755 => 100644 rename test/{ => base-tests/python2}/test_functions.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_functions.pyc rename test/{ => base-tests/python2}/test_global.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_global.pyc rename test/{ => base-tests/python2}/test_globals.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_globals.pyc rename test/{ => base-tests/python2}/test_import.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_import.pyc rename test/{ => base-tests/python2}/test_import_as.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_import_as.pyc rename test/{ => base-tests/python2}/test_integers.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_integers.pyc rename test/{ => base-tests/python2}/test_iterators.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_iterators.pyc rename test/{ => base-tests/python2}/test_lambda.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_lambda.pyc rename test/{ => base-tests/python2}/test_listComprehensions.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_listComprehensions.pyc rename test/{ => base-tests/python2}/test_loops.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_loops.pyc rename test/{ => base-tests/python2}/test_loops2.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_loops2.pyc rename test/{ => base-tests/python2}/test_mine.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_mine.pyc rename test/{ => base-tests/python2}/test_misc.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_misc.pyc rename test/{ => base-tests/python2}/test_nested_elif.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_nested_elif.pyc rename test/{ => base-tests/python2}/test_nested_scopes.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_nested_scopes.pyc rename test/{ => base-tests/python2}/test_prettyprint.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_prettyprint.pyc rename test/{ => base-tests/python2}/test_print.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_print.pyc rename test/{ => base-tests/python2}/test_print_to.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_print_to.pyc rename test/{ => base-tests/python2}/test_single_stmt.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_single_stmt.pyc rename test/{ => base-tests/python2}/test_slices.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_slices.pyc rename test/{test_tuple_params.py => base-tests/python2/test_tuple_params.py-notyet} (100%) mode change 100755 => 100644 rename test/{test_tuples.py => base-tests/python2/test_tuples.py-notyet} (100%) mode change 100755 => 100644 rename test/{ => base-tests/python2}/test_yield.py (100%) mode change 100755 => 100644 create mode 100644 test/base-tests/python2/test_yield.pyc mode change 100755 => 100644 test/compile_tests create mode 100644 test/ok_2.7/aifc.py create mode 100644 test/ok_2.7/aifc.pyc_dis create mode 100644 test/ok_2.7/antigravity.py create mode 100644 test/ok_2.7/antigravity.pyc_dis create mode 100644 test/ok_2.7/anydbm.py create mode 100644 test/ok_2.7/anydbm.pyc_dis create mode 100644 test/ok_2.7/asynchat.py create mode 100644 test/ok_2.7/asynchat.pyc_dis create mode 100644 test/ok_2.7/asyncore.py create mode 100644 test/ok_2.7/asyncore.pyc_dis create mode 100644 test/ok_2.7/atexit.py create mode 100644 test/ok_2.7/atexit.pyc_dis create mode 100644 test/ok_2.7/audiodev.py create mode 100644 test/ok_2.7/audiodev.pyc_dis create mode 100755 test/ok_2.7/base64.py create mode 100644 test/ok_2.7/binhex.py create mode 100644 test/ok_2.7/bisect.py create mode 100644 test/ok_2.7/bsddb/__init__.py create mode 100644 test/ok_2.7/bsddb/db.py create mode 100644 test/ok_2.7/bsddb/dbobj.py create mode 100644 test/ok_2.7/bsddb/dbrecio.py create mode 100644 test/ok_2.7/bsddb/dbshelve.py create mode 100644 test/ok_2.7/bsddb/dbutils.py create mode 100644 test/ok_2.7/calendar.py create mode 100644 test/ok_2.7/cgitb.py create mode 100644 test/ok_2.7/chunk.py create mode 100644 test/ok_2.7/codeop.py create mode 100644 test/ok_2.7/colorsys.py create mode 100644 test/ok_2.7/commands.py create mode 100644 test/ok_2.7/compileall.py create mode 100644 test/ok_2.7/compiler/__init__.py create mode 100644 test/ok_2.7/compiler/ast.py create mode 100644 test/ok_2.7/compiler/consts.py create mode 100644 test/ok_2.7/compiler/future.py create mode 100644 test/ok_2.7/compiler/misc.py create mode 100644 test/ok_2.7/compiler/syntax.py create mode 100644 test/ok_2.7/ctypes/_endian.py create mode 100644 test/ok_2.7/ctypes/util.py create mode 100644 test/ok_2.7/ctypes/wintypes.py create mode 100644 test/ok_2.7/curses/__init__.py create mode 100644 test/ok_2.7/curses/ascii.py create mode 100644 test/ok_2.7/curses/has_key.py create mode 100644 test/ok_2.7/curses/panel.py create mode 100644 test/ok_2.7/curses/wrapper.py create mode 100644 test/ok_2.7/dircache.py create mode 100644 test/ok_2.7/dis.py rename test_one => test/test_one (100%) create mode 100755 test/test_pythonlib.py rename uncompyle-code.py => test/uncompyle-code.py (100%) delete mode 100755 test_pythonlib.py create mode 100755 uncompyle6/#spark.py# diff --git a/.gitignore b/.gitignore index 0e5e5852..e4ea5e61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ +*_dis *.pyc *~ /.python-version +/dist /uncompyle6.egg-info build diff --git a/Makefile b/Makefile index e62cd02a..4b214c2d 100644 --- a/Makefile +++ b/Makefile @@ -23,27 +23,14 @@ html: #: Same as "check" test: check -#: Same as "check" -nosetests: check - -#: Run all tests -check-short: test-unit-short - -#: Run all tests: unit, functional and integration verbosely -check: test-unit lint - -#: Run unit (white-box) tests -test-unit: - $(PYTHON) ./setup.py nosetests - -#: Run unit (white-box) tests -test-unit-short: - $(PYTHON) ./setup.py nosetests --quiet 2>&1 | \ - $(PYTHON) ./test/make-check-filter.py +#: Run tests +check check-short: + $(MAKE) -C test $@ #: Clean up temporary files and .pyc files clean: clean_pyc $(PYTHON) ./setup.py $@ + (cd test && $(MAKE) clean) #: Create source (tarball) and binary (egg) distribution dist: @@ -51,7 +38,7 @@ dist: #: Remove .pyc files clean_pyc: - $(RM) -f */*.pyc */*/*.pyc */*/*/*.pyc */*/*/*/*.pyc + ( cd uncompyle6 && $(RM) -f *.pyc */*.pyc ) #: Create source tarball sdist: diff --git a/README.rst b/README.rst index 2585b6ec..465ff7aa 100755 --- a/README.rst +++ b/README.rst @@ -1,32 +1,31 @@ -uncompyle2 +uncompyle6 ========== -A Python 2.5, 2.6, 2.7 byte-code decompiler, written in Python 2.7 +A Python 2.x and possibly 3.x byte-code decompiler. + +This is written in Python 2.7 but is Python3 compatible. + Introduction ------------ -'uncompyle2' converts Python byte-code back into equivalent Python -source code. It accepts byte-code from Python version 2.5 to 2.7. -Additionally, it will only run on Python 2.7. +'uncompyle6' converts Python byte-code back into equivalent Python +source code. It accepts byte-codes from Python version 2.5 to 2.7. +It runs on Python 2.7 and with a little more work Python 3. -The generated source is very readable: docstrings, lists, tuples and -hashes get pretty-printed. +The generated source is fairly readable: docstrings, lists, tuples and +hashes are somewhat pretty-printed. -'uncompyle2' is based on John Aycock's generic small languages compiler -'spark' (http://www.csr.uvic.ca/~aycock/python/) and his prior work on -a tool called 'decompyle'. This tool has been vastly improved by -Hartmut Goebel `http://www.crazy-compilers.com/`_ +'uncompyle6' is based on John Aycock's generic small languages +compiler 'spark' (http://www.csr.uvic.ca/~aycock/python/) and his +prior work on a tool called 'decompyle'. This was improved by Hartmut Goebel +`http://www.crazy-compilers.com/`_ -# Additional note (3 July 2004, Ben Burton): +# Additional note (3 July 2004): -This software is no longer available from the original website. It has -now become a commercial decompilation service, with no software -available for download. - -Any developers seeking to make alterations or enhancements to this code -should therefore consider these debian packages an appropriate starting -point. +This software is no longer available from the original website. +However http://www.crazy-compilers.com/decompyle/ provides a +decompilation service. # Additional note (5 June 2012): @@ -34,6 +33,14 @@ The decompilation of python bytecode 2.5 & 2.6 is based on the work of Eloi Vanderbeken. bytecode is translated to a pseudo 2.7 python bytecode and then decompiled. +# Additional note (12 Dec 2016): + +I will be using this to deparse fragments of code inside my trepan_ +debuggers_. For that, I need to record text fragements for all +byte-code offsets (of interest). This purpose although largely +compatible with the original intention is yet a little bit different. + + Features -------- @@ -44,51 +51,53 @@ Features - output may be written to file, a directory or to stdout - option for including byte-code disassembly into generated source -For a list of changes please refer to the 'CHANGES' file. - - Requirements ------------ -uncompyle2 requires Python 2.7 +The code runs on Python 2.7. It is compatable with Python3, +and I've run some tests there, but more work is needed to make that +more solid. + +Work to support decompyling Python 3 bytecodes and magics is +still needed. Installation ------------ -You may either create a RPM and install this, or install directly from -the source distribution. +This uses setup.py, so it follows the standard Python routine: -Creating RPMS: + python setup.py install # may need sudo + # or if you have pyenv: + python setup.py develop - python setup.py bdist_rpm +A GNU makefile is also provided so `make install` (possibly as root or +sudo) will do the steps above. -### Installation from the source distribution: +Testing +------- - python setup.py install - -To install to a user's home-dir: - - python setup.py install --home= - -To install to another prefix (eg. /usr/local) - - python setup.py install --prefix=/usr/local - -For more information on 'Installing Python Modules' please refer to -http://www.python.org/doc/current/inst/inst.html +Testing right now is largely via utility `test/test_pythonlib.py`. A +GNU makefile has been added to smooth over setting running the right +command. If you have remake_ installed, you can see the list of all +tasks including tests via `remake --tasks` Usage ----- -./scripts/uncompyle2 -h prints usage +Run + + ./scripts/uncompyle6 -h + +for usage help -./test_pythonlib.py test files and python library Known Bugs/Restrictions ----------------------- -No support for python 3.2 +Support Python 3 bytecode and syntax is lacking. -It currently reconstructs most of Python code but probably needs to be tested more thoroughly. All feedback welcome +.. _trepan: https://pypi.python.org/pypi/trepan +.. _debuggers: https://pypi.python.org/pypi/trepan3k +.. _remake: https://bashdb.sf.net/remake diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 00000000..099f865f --- /dev/null +++ b/test/Makefile @@ -0,0 +1,21 @@ +PHONY=check clean dist distclean test test-unit test-functional rmChangeLog clean_pyc nosetests + +GIT2CL ?= git2cl +PYTHON ?= python + +# Set COMILE='--compile' to force compilation before check +COMPILE ?= + +#: Run all tests +check: check-short check-2.7-ok + +#: Run quick tests +check-short: + $(PYTHON) test_pythonlib.py --base2 --verify $(COMPILE) + +#: Run longer Python 2.7's lib files known to be okay +check-2.7-ok: + $(PYTHON) test_pythonlib.py --ok-2.7 --verify $(COMPILE) + +clean: + find . -name '*_dis' -exec rm -v '{}' ';' diff --git a/test/base-tests/python2/compile_tests b/test/base-tests/python2/compile_tests new file mode 100755 index 00000000..730fa43b --- /dev/null +++ b/test/base-tests/python2/compile_tests @@ -0,0 +1,77 @@ +#!/usr/bin/env python +from __future__ import print_function + +""" +compile_tests -- compile test patterns for the decompyle test suite +""" + +import py_compile, os, sys, getopt + +work_dir = os.path.dirname(sys.argv[0]) +src_dir = work_dir + +opts, args = getopt.getopt(sys.argv[1:], 's:w:') + +for opt, val in opts: + if opt == '-s': + src_dir = val + if opt == '-w': + work_dir = val + else: + raise "Unknown Option '%s'" % opt +if args: + raise 'This tool does not want any arguments' + +print("Using files in dir %s" % src_dir) +print("Compiling into dir %s" % work_dir) + +tests = {} + +tests['1.5'] = ["class", "del", "docstring", 'empty', "exec", + "exceptions", "expressions", "functions", "global", + "globals", "import", "integers", "lambda", "loops", + "misc", "nested_elif", "prettyprint", "print", + 'single_stmt', "slices", "tuple_params", 'tuples'] + +tests['1.6'] = ["applyEquiv", ] + tests['1.5'] + +tests['2.0'] = ["augmentedAssign", "extendedImport", "extendedPrint", + "import_as", "listComprehensions", 'print_to'] + \ + tests['1.6'] # [ "--extendedarg", ] + +tests['2.1'] = ['loops2', 'nested_scopes'] + tests['2.0'] + +tests['2.2'] = ['divide_future', 'divide_no_future', 'iterators', + 'yield'] + tests['2.1'] + +tests['2.3'] = tests['2.2'] +tests['2.5'] = tests['2.3'] +tests['2.6'] = tests['2.5'] +tests['2.7'] = ['mine'] + tests['2.6'] +tests['3.4'] = ['mine'] +total_tests = len(tests['2.7']) +#tests['2.2'].sort(); print tests['2.2'] + +extension = '.py' + (__debug__ and 'c' or 'o') + +def compile(file, target_dir): + sfile = os.path.join(src_dir, 'test_%s.py' % file) + cfile = os.path.join(target_dir, 'test_%s%s' % (file, extension) ) + py_compile.compile(sfile, cfile=cfile) + +def compile_for_version(version): + target_dir = os.path.join(work_dir, 'bytecode_' + version) + if not os.path.exists(target_dir): + os.mkdir(target_dir) + for file in tests[version]: + compile(file, target_dir) + +try: + version = '%i.%i' % sys.version_info[:2] +except AttributeError: + version = sys.version[:3] + +print('Compiling test files for Python', version) +print('(%i/%i files)' % (len(tests[version]), total_tests)) +compile_for_version(version) +print('Done.') diff --git a/test/test_applyEquiv.py b/test/base-tests/python2/test_applyEquiv.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_applyEquiv.py rename to test/base-tests/python2/test_applyEquiv.py diff --git a/test/base-tests/python2/test_applyEquiv.pyc b/test/base-tests/python2/test_applyEquiv.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a2d9a117b1132c350fd969e2482a3c978721fae9 GIT binary patch literal 1108 zcmcgrv2GJV5PfrJC$SwXkw6rbR41fx5=c}Cr2qv9DM${Yph4%`OS0tbGv0NGrBIm? z_#l3ZAK=ZL6)-)qHP3Hnc6Q&)j?-Vm{@o|_yAtcqfWL>d@PgogufTf}F(Pn@kpxu& zm%?@6x^P=?+s1d`dT@QX0al$<+%8VCArG?Sg+%Q&E$k7lfseonIC{mKPBIN18^$iF zkJTi!%PlT1J{R+|kdeV4yd}%Syv(bsSk0$JeQ;TZ{LIJm#W%_XsRuL%eQn zC3nbfOYqM6E|sjE`&)9#^)~H|`hOBk^0nNwKJrxsD}j(P_zn1y;D)Q0aSiB}1Wf(T zevok(I0Lp8iDW!n@I!+f4a?EBrg7bFUT?Ae+_K@7*2|gtCyK_s^ZTE&s9Ru+j}X$ Gd%pp`J>b*; literal 0 HcmV?d00001 diff --git a/test/test_augmentedAssign.py b/test/base-tests/python2/test_augmentedAssign.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_augmentedAssign.py rename to test/base-tests/python2/test_augmentedAssign.py diff --git a/test/base-tests/python2/test_augmentedAssign.pyc b/test/base-tests/python2/test_augmentedAssign.pyc new file mode 100644 index 0000000000000000000000000000000000000000..98b19bc010c2ba3fc9969aef46dd3ab45cdbcda6 GIT binary patch literal 1180 zcmcIiU279T6g@M$*>uzN!&b#0X!;<=mb#!|EksciS`hlsip8LW&F;8Ovf0G_DCw*1 z-|$!Z2Rt*`rm62H+_U$dGjqQf>(5HEUIDs<}TARXJ{j`(2-E|1p% z*pI>rB6cWSOuz=2RqCwGlDD?!ys7s1nt!&yhYkV@TcuRlnM+lKONb? z*hHrWD;*~(4vPM$i6c4 zvNZ72G*@Zj$Ghi2=0*Mdtmt{^I2c}dMG}lhlZ#lr@^Y2sUeC|euJ$r-a*>~nlNW~X z`b9KSNv^{8S=Nt|=M;6xA5RFG9s;r^j{5iLn0*-4H`p^6=M`$_eq5+rk5A7qsh>pZ zm;`b?Q#>%I2eV*kf+5!p_>+lB!ed?aW<=xt=Q)>Hu{|1xMXcWH>e)AfBOT$08Y=&q sTodbX#fEqwR;g~5cAwvMRHQ4`L|ts~_9pMo?2h1Ht_ruZLGGdW3o8@LcK`qY literal 0 HcmV?d00001 diff --git a/test/test_class.py b/test/base-tests/python2/test_class.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_class.py rename to test/base-tests/python2/test_class.py diff --git a/test/base-tests/python2/test_class.pyc b/test/base-tests/python2/test_class.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a32e099e8421c054df8dd17db86e0cb33cc06621 GIT binary patch literal 2412 zcmc&$OOMk)40e(>eee)agarJ7UfO6u+7m*wJ-}&^vJw)#L~Sx;Gh=^ad+Y|kAGM#q&A+6wc>?@?z_8aK8NLn4Jh>D3CGvHQxi48$ zvS26jB&&%LF`mruuD*NWi}AT@9Eb_zx<=k3SKo1=a#<*s-4@I_4`h&n=o5erF>DV6 z7RE3I0JTFvu;|kwjAV*wT$A{+TgMLPgAC4g>Zn}Ry*gCKy-=b@gc9uKwv>yvV+7t3 zA69+*1PJAt3;O`F!C5~^=8L&Yk}jswxtQd=AE}ML z&E3^%8ZC?T`#M@J(&FZJotyK>8SA3y#F`#C8{MwmRk3)Z@+8eC*7hN4Lg&^xk8Fuu zyyMV^SPJyBqSynEso=z*8CDo2_6^=H-L*N)Vsc}W#I+$wlA9u1<(S6Y6LZxbn{ub{ zYRm{~07*ix6&&YJLLU4h87lCp`iI$guLNMm3@VSmhVk(pYZ*~uiIp%dH3ZcL9ae?O zZ)rdDJB?PLO~z@Vxga84S>{Kbt)YY7@>D@V3VPUF(g)Q_a`FNDihOzaYZn-f4wU^)_bia4`IFY Nq|-+=G zl!{H}?VC4mUN>w1w7u>{@)Se;HSoN_(%%RI;ERD^aC;}Qv!M5kt&Qyqp3X*|2$#4; zvx#V|`A{@#u>~WsRdWwS3&t3=_B$Z9LF~Ya7TdLWhgmFA*M`7&3yV2xUg@2hpRix4%wcT+ literal 0 HcmV?d00001 diff --git a/test/test_divide_future.py b/test/base-tests/python2/test_divide_future.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_divide_future.py rename to test/base-tests/python2/test_divide_future.py diff --git a/test/base-tests/python2/test_divide_future.pyc b/test/base-tests/python2/test_divide_future.pyc new file mode 100644 index 0000000000000000000000000000000000000000..dcc34748ce7ebb152741d68626d1d885026eef3d GIT binary patch literal 405 zcmY+A!A`?442GQ|q^)egBjni27PbT8z}Rl%w8M}<;!X?^+|&X(yR6BJ$oxt>?>B0!o9U3BBAzYBYY(tNpN7s?O zfk-)%%yKTJTv&m^#>4GuHkr07jKvNm-q*v)(DF>nU;50Th|Hsn$R9wXnEr`>MaRBW zY(9c1i%mYRmFJxe`)bRjQ|}E|g>r{ulbc%(#s}VRyctL5`PhWLE9PyVXQqpd>~ literal 0 HcmV?d00001 diff --git a/test/test_docstring.py b/test/base-tests/python2/test_docstring.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_docstring.py rename to test/base-tests/python2/test_docstring.py diff --git a/test/base-tests/python2/test_docstring.pyc b/test/base-tests/python2/test_docstring.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c598d92ba7246f18c1b3a1d27f4b5a237fa9e19b GIT binary patch literal 2244 zcmd5-O>fgc5FOh|h$G4YDh^11k3LYWI28wk5CSAP<=|8($z|o(Zex+!QFeofL{IRK z`2)-wJ6I`Sr=&#jc=mJVy?MKKz903D2a690)jx;dulUiYY*L~rTZ_K2V^L~T+M(1z z^DEJ0%I%hnIg}B-d!M#xJ$*Ft^2qV~l(o zEv%G<^H_VP^k$j2TxB{d%+Ti{x@Po<`vSd6g6y-&RzJveu(o@RmJL90*N~sNKzGmL4G%)=>FgVQWVZD9~X(-EJ_veWu}w? z=}KLe>3YG<2*4uDig5o#E}Mo<@%AP52oxcnM&yp=cHNfS`c)-IJX+msJ3`r+DEH0Z zCh{Iqq~>C}nIb{4lfmFIzqTbpY9g2DHauywiBuxo)J?1(i9eX8I+m#U=VliN&e9AXc${L1jrsex4Cn fJU%tIprld{D8vCY(+YSj2buH0$Q!a;7Y4J7T8 zzWLy@f2V(delvIcEQm>M@nDC!xxL+)Z@<|cqCYdKlOM+08iiK`zt7S1cL)n#MRlSN zP$KjdiXtm2N`$PKC{eQJM2V3#FUlNQaZ%>UN{A9CD=A8XtduB8vKB;1k(Cx@f$TI{ z89IuP_l<0#&qQ{Hz9>?z__3e82A`Z?xGLf=`x-^tLDTmkIv7mR8PPj8LrN+5j2le^S$hPmX_hd{FS3wWChq*sV1itxny3RPb%>7YwbVx+Sq!Lm!&1 z-hiDWY8Q+ABVLkmoF z#4^QvqN5afYg5vIhh{YP?9MCCYkCgHKAZ@=@;;lpeIzSpfJUjf!p?E#254lE7d;?QQrq;l~wX4ic9 zcJnT&hH|gRrhg3CJThO zH{itD=oL_pmwC2KEblRv*CB?O*iGLk?7Zr74m^Q!Dup9gluKb{=-#1I6oNny#&t0& za#5(FZbV6of-x);d8~@VyOkaf37$}vd-ab(DH3a0dBWn7i^R?1JDw!i$pn$~gM YekP2(4MRGTOyH9WWeQpvEtyuo0fLRwwg3PC literal 0 HcmV?d00001 diff --git a/test/test_exec.py b/test/base-tests/python2/test_exec.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_exec.py rename to test/base-tests/python2/test_exec.py diff --git a/test/base-tests/python2/test_exec.pyc b/test/base-tests/python2/test_exec.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9c31ded4f50130df949cf851ed0ed72e71996508 GIT binary patch literal 259 zcmYk0!485j42C-}NHpGj0FGR65fe{pd;%^84_*w628@FdHVmA7WM9C}m}ry!{rY!n z>b@4USYsVuD*)=#IBd#B9^Yk3u+wFfgc5FOk7N=QhXR-Af7!k5-kkSY!cA%s+V2$d29Xa$NKdvM(DdV^r*QuQZ~(snZVnaSe}4wwLNG^Q zhJZ)Vzr-P2e)#zdzKEk~yd&<)2U#EEKq&7EjFBiUFxD?juN^wc7gKk^A zi-p1#=&OVY)meh~jCGaTv%8FvqU6PDp42|OZIV@$dADpVUL@)!nWuzj$|zYjyztei p)o0qF$}zukOJDQ3Qnet^zY#ha7l z<-K{#W6FCo>0=yWgd;!J7{8yABDqo%O>_5YNPs}B5 zQJ+h6^C|U67eenbgfv>E9DHNcDim~)S{W;&j#$TteQLQD27f>+k(RQv_|BN)CXC-4 z*ij<9&+LQ-7@q(W8ILP2`DKJ;}a3B;N*{ O>2{=zK`}H}a=rkcVMX}> literal 0 HcmV?d00001 diff --git a/test/test_extendedarg.py b/test/base-tests/python2/test_extendedarg.py-notyet old mode 100755 new mode 100644 similarity index 100% rename from test/test_extendedarg.py rename to test/base-tests/python2/test_extendedarg.py-notyet diff --git a/test/test_functions.py b/test/base-tests/python2/test_functions.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_functions.py rename to test/base-tests/python2/test_functions.py diff --git a/test/base-tests/python2/test_functions.pyc b/test/base-tests/python2/test_functions.pyc new file mode 100644 index 0000000000000000000000000000000000000000..83fa020fe2d5d8d5e94eafdfd7b1fca68ebdc3cc GIT binary patch literal 3958 zcmd^COK;jh5FTSg0)dbhY5F+iP*oh75C}~#RaGg6RH{U!Md~4{6dA9RAP7XZX-EaP z{H6Y~{(;Unyc~pY#f?;u$Ft+L_xomMXLrrtxy;US`2*=Er1PTWNbi!~qz8k}*GX@QF;9A%^o|%eNEfJHe8$M9d<<@!f{!)gQ!m0&E3%+D z;n&$#@;#^I_5;`J*zJQKj$gWJ2G_kt$?H0;`%6&+wMszaQ&dvuzmLcnqRuT z53akNir6nMxnt1mcKky&C-}SlBaG`qCBuO}xgyb_Ljc&ecU7KYT`tTr2AseIT3kR9 z2@@Su7;7aitd$iWdV-bJsY}mbUli~#Og{#gCIjgo+Zo^)ho03b&M&Y>;!N?=)*S~w zKBSEt5QUIVqW?7tsYE}?PZfd@n@gRI8PF!8+5`{>{)RtciA(}?2+;Gg+m(C6_D1)% ztw1F%7FBzjN1M1ij6E_jfL$S-)EYzh67S)PRYID#+V%QGeHhSEgB|CI1a1@MDYoQSvF!@ zR+}(v!2sTlNF4+30*|(ccV(X+jENT}#4#5@Tqb{rxCy>v;z=5&Xka43$pysm2_dfF zaVZEh?h0rW=De*Bupk76#R^?By2Y(vbY0)?255`2{GDH^Vj zt!SFeQVj&c&Pgv@G)W zp$Afe_gV(p{Gg7jh#63mkBBPexi8xqr{~EECT9u1`O}^8T^dWc*>i3Ep6@bW$#`X0 zMoqBEUTx%gDKFfI6!0s&rex(oLM!-6VN0skA@UH|GASJK6ymI~tScLmmgL$%Lh j#&Nmf1kMjPUEOQDAF(d_7(8vx{&^Gsv^Du>t+e?EjU`!p literal 0 HcmV?d00001 diff --git a/test/test_global.py b/test/base-tests/python2/test_global.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_global.py rename to test/base-tests/python2/test_global.py diff --git a/test/base-tests/python2/test_global.pyc b/test/base-tests/python2/test_global.pyc new file mode 100644 index 0000000000000000000000000000000000000000..0abed12ccb7f3db93d30cdf5f94f1fc7763e8404 GIT binary patch literal 838 zcmcgpO-lnY5S`i9-LBAE!IKy9P=y*$@FXI5sHY-Z@Zd%EBeZMNZfR1n(4O=k`v-iJ zl~%mhz`RT*^JZQqjj#4$=gK_g^s^ZI9n78q3ZfLqlrj|oeG)wfqyzdOVn@_>O#O$V zLBnnn*`;vH2;i&9N$ehGj{&HI3LBy|{i#5x5FlgViQ=WM>^kC-RZ?FHNCgos!{32 z%SSpniOD9^F) z6ukP8B%;$NoBvRh$rx=5KpZzij)Gc+1QNOP`jP|jB(~=PrSf_kN+*uvhzI_g6FGY| diCpc3>`_e%jc%q@u{8QtzRu4mq>$rw#NPl3tuz1t literal 0 HcmV?d00001 diff --git a/test/test_globals.py b/test/base-tests/python2/test_globals.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_globals.py rename to test/base-tests/python2/test_globals.py diff --git a/test/base-tests/python2/test_globals.pyc b/test/base-tests/python2/test_globals.pyc new file mode 100644 index 0000000000000000000000000000000000000000..7bb8bc1149a575e89cc2c3e8ecbcbcfbeef7c423 GIT binary patch literal 444 zcmcIe!Ait16nyErRTsPo>a7>Cmo=c^Nks6Vrv-Nx4||a|jcqY)N?s~k(2M%V{($dg z7yJSPZ!#HX@@DjNFgd(5PYSk2(0xmTrvwGSH^7RBfKLHM1S*|*9z-C*>U^cua)Gt^UND7(Q|w!H}Yb7^dz89XPEx4bZ5OaNjmCIU~0 zEvp)n&e_ssO`@{)%qO`{T;GPCv(S0Y!8zytdIt7SW%p>)bz_U(=$p`)h5d0H#bQ_d E0`DDR+5i9m literal 0 HcmV?d00001 diff --git a/test/test_import.py b/test/base-tests/python2/test_import.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_import.py rename to test/base-tests/python2/test_import.py diff --git a/test/base-tests/python2/test_import.pyc b/test/base-tests/python2/test_import.pyc new file mode 100644 index 0000000000000000000000000000000000000000..eff156dd3982787a6440555cf752d65ccc6a5408 GIT binary patch literal 553 zcmZusOG^VW5T5MTzHHS)@zkT>BIrT|@gO21*h{6+Z`N zj9A#Mx4|OQFFrS(U}`E1JtPVz=-EvM{J@kM5{z|%W}9g|)tYb|>BTGwvwT%)%MZLQ zn{Ep!C*!cyWUTKpBSruTzX9552(*ypR(A;R~|SE<>4|Wf0CN%BJwjG zKj;2p7Hc)nC7$?JpC7UKL(9mY=Vq#Box(p()m&%hh<#OVdZu);ka%uqlij%?_MC>Z KBif?ww8b|9(spzJ literal 0 HcmV?d00001 diff --git a/test/test_import_as.py b/test/base-tests/python2/test_import_as.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_import_as.py rename to test/base-tests/python2/test_import_as.py diff --git a/test/base-tests/python2/test_import_as.pyc b/test/base-tests/python2/test_import_as.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2cfecd0c4712b8bb1eb7135a83f3b273fac1f424 GIT binary patch literal 676 zcmZ8dO>fgc5FOi1+w?01TsY7p2On@P1qtKMdgyo%i^Y(fCX1rgAd;Y8XO92m$$N3!}{K=u@*MS-!bvo=q>UEg;tq%7f z-R|%XT<=2KZ%Y^IJ<$7*9)Kh5Jg5)b`Uvy@(gEmWNFVVXcj|#Z8sEJH^%(8}uAfMJ z|NS|9-f!^-CzJmWyZV1sQ=z9!^yZLm$BlC~YQ(+@En@x?`s zYCN5OPL$m!OS?>UB}q$CNM{nVxYFvUgt@jtiEoJg_akRff;s^+zs<@`mD@7RP!68%jZH?+mrs+A2m!@qzD zml4_`Qg>{8nb+Z_z-V64Vm*tjDQ=o*y)2AgHMM#j$xP9VHxdfMXw}fdEQc+hReEJC iWjUTPEqi*SO}VbsTk(Oi%LC_yJ8+MkQ?KuyI)4D2UdEM@^JSyp`*^e65C zsc}_mWbLIYCU)?aIy1}td^I&ynZDL$Rix!&SzEa_UYs}6iIahnGt1h~%i=Ql&-kCr oq;eN<^;S2FGFw@>)$_SC$YGpt^X&66ceu^Hh~f0Oi>)!?UxqPdyZ`_I literal 0 HcmV?d00001 diff --git a/test/test_iterators.py b/test/base-tests/python2/test_iterators.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_iterators.py rename to test/base-tests/python2/test_iterators.py diff --git a/test/base-tests/python2/test_iterators.pyc b/test/base-tests/python2/test_iterators.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b355484e14a867e333453270744fc4280265d282 GIT binary patch literal 278 zcmZ9G&uYRz5XNVdN+sZ_9=r%WrU$#wLr+qAQ1s+MONBxyad$AmxT`xGNzOin&*=*| zD}vC0`OTjXzM1&kNe-v^w}M+lTt7J}pzZ+zXn>=D(Qg7j0#LwY-+|?{?q4WM!1y?wS(crAP8|l@Sg?M{?Kr+?u!R{;yzz%v(pVyl%7aaBFo{;z#&{ N!h27m9f^n;UjTR1JZ%5~ literal 0 HcmV?d00001 diff --git a/test/test_lambda.py b/test/base-tests/python2/test_lambda.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_lambda.py rename to test/base-tests/python2/test_lambda.py diff --git a/test/base-tests/python2/test_lambda.pyc b/test/base-tests/python2/test_lambda.pyc new file mode 100644 index 0000000000000000000000000000000000000000..767dd6a557234c29b0cf93a0aba7706d48181580 GIT binary patch literal 1529 zcmd5+O-sW-5S`uhQ|zS*`V(?#R}?&n2;PfC@F0S0lI@4)i|ke`*pvQa|9~?SW38TB znr2_#%!b*wZ_@QXdwYjx$z25BR|B6{IP4RG0f+%UkO+tcyyGq5UUFV?UjE8>Yniw~ zA-)_pYtpJon~0Gx=4x>VZv8GU7YPI!9*%1qwukUm-(wHoqv?^408Aalx{4`jZxEC% zBV}HlDKni6ULva|GdG=ws?4M3g_>tko)(M5oGWLnQ=ztIK+LLQ;ih?Z%K67cr(vvz znCoECiz>XN1uYJkkyMu4!01Qv00Wf#;K5SBQo_;$hZ%N{2s$RxQVR*tjEEy+^;f8k`kP=$k5_qewP@cO&>Trv-a*V2G1T?V?bz~Fw;J^I`IQ7SV z^nOh$sSKzD>kXR3S_s=vPK)iXujInYSL*lf^t`>p+UR^>-$p)tSNu0lb>XPnrOqbC jk@`X>#yPY4%$RNP#7gsco|x*y+D8G$qA&WgE9mzHxI|3~ literal 0 HcmV?d00001 diff --git a/test/test_listComprehensions.py b/test/base-tests/python2/test_listComprehensions.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_listComprehensions.py rename to test/base-tests/python2/test_listComprehensions.py diff --git a/test/base-tests/python2/test_listComprehensions.pyc b/test/base-tests/python2/test_listComprehensions.pyc new file mode 100644 index 0000000000000000000000000000000000000000..f7b0ed83a2b0238148e6b9f285ded80a8cdf8568 GIT binary patch literal 1146 zcmcgr-D(q25dO~D{MJ;XX{(|rXedE!mR1liM1&OVO$%0#uvkm7=XA5}cGKOnkp|K$ zz4tY|?j!gzeE?s;nUh@#sn-T(cFvw}zWHWm;4R}sBE8}S(rs&8-9WDw zXo)p7&sY^)!X~wH`Kw~FO7A+4tLzF^kjreto6EEuYxi^B(DLTeLy_zfsj9#$LEVN| zwoBo$K806-E>lEvtU}YFYUfBDUy9_H5UPqFfLDXAfye_|OtG85u1D1nQ1LoTQcF;` zcwscApv;4$vJHId+@UWcEU^>p=o3Ncu&c5oL&nF!(Dxa@F{68ArcI9cW+0UhaUn39 ze@+(?Guk*Qy^EwuML2V>Lk=A#u#840S%nT}GUSjU=W_@}Fki^ICiPu?p6N6mL>u3H z;|5_inhf1^?4L~CN$ihL&!&-n?Pl6!?r>oA21mv{n`WbNyk*}XMxn`igiQ5F$0i)d zrc3wyw>XLhS*GL7M_iFxhX~8$Llzb?BCM0!>-=j#{LZ$sFu4w=WK5F|;y~MG`~AM{ zFtq+S<6P=`vk12K?Ob>W(|t=!5&ri$-ky%tB+~C#hUt=P$Ol3Qwl>)lvS(y1@?G(U Ro(<6y>#`y$@`bEBe*uZo&_HjDV4{d20YQTU27)4)t|DpDlTJS(oy}}q z`2+a`KS5Xif%64!{0DL8!h0+2BoP;es#EuQ>f}}zemLbzcY{|R@}JG;W8TSk0TUB zHF@7ihHT@$jNuUK0&_eQj_e84MRw}B0J)SOVj+Y%`GT_DHL9=6ySmY5>O~9U)r&sx z4*22<4r@F7(tcT>ARv#Q78zPWqJ2K$^H%`h5|DTzR-<8#W+Rnk)8PK|nkhOfU%G}> z8f#*0cE6Nb6JNVT%Kkeh#HnbG2a};TI(&nf!Fi2SSV8iFT{nq6S7)h?Cxc+`otL;n zKON1E+&J{cb9XlJ!sF>Y(D&R_C#ichNc5gqi94OAqi}M^#NP&CI8APIXp1=?9*1fc y=%)Okq|dNJ6)N#A(w1ctSxcX7t3*{Q|CL?Eq+*w|7238OIrDml9J<1tHvI<1)SPDk literal 0 HcmV?d00001 diff --git a/test/test_loops2.py b/test/base-tests/python2/test_loops2.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_loops2.py rename to test/base-tests/python2/test_loops2.py diff --git a/test/base-tests/python2/test_loops2.pyc b/test/base-tests/python2/test_loops2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..8dbf4697ff9bad3d6dbed73dc85f3e41d0e028f6 GIT binary patch literal 233 zcmYL@JqyAx5QZ;SsfyiP9NoHTpn{W#gF`0~1S^6_O+zcDP0gihf46_Ys|X&v&wcW8 z&fDt`XKF9t7j4Qb68ePK7$m^@G=d|8x(DIYg)q9iz!)PQNKpc?^BEm){1(wR2C+%; zTUcrG#t8nvEwvnt;POT5B36@!K%QQ0R$aK!;#Tvj5IQewCFk5qwEPmIoHP~kvbLEn hg75sSv@S82(yU9Si(Ds_lFQ};91uL_(4!9PkUoN)Ga>*0 literal 0 HcmV?d00001 diff --git a/test/test_mine.py b/test/base-tests/python2/test_mine.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_mine.py rename to test/base-tests/python2/test_mine.py diff --git a/test/base-tests/python2/test_mine.pyc b/test/base-tests/python2/test_mine.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6e7554c8a7d78ca7683ac2cfc1cfc24519a4cfbc GIT binary patch literal 669 zcmcgpJx{|h5Is8uK_$cj11zjrS|bJ)D#XB?p_Mv;Q0ko0hwLC zfOCLPeSjfApTTq+qyxf*a|Um|G@$Q-WN=&p2_UT(H`vJ&=uJO^SjU*Ijd7tPD$tQD zi>NCNU7|$kwwC!s74CO1@nzJb&fduf=!p&JuYz0!aSIy7PY}1Ev!^iC8h*tc=z904 zqXvq@QKFl9kqwJz+>9f&ZJGnwEGEh@+-+UbK-OzI^biHMgWVz-NI)MOW>#?_?0ODv z$0RORn+~m^IAd@Iz%7YgkMadp8W&YH8QY_#MBy_18d89VYc6zvny-u4ms2AP6{S0; zvG#|F8BGR$k;UI;{zS#uIG?5Rxo@O4{vgtFhcxZyGc(H6uJ!YAqT{FNsbEUZ6O|aw zZCQd0ET+n|$h<^vumON$Mzgp;PXQLaHpLt-9Sh0*KadwPFE}q_H9be}Q5TE0R5X^H zn;LpJA7^5cq8Sp^;R=c?d{(;wdPA%NR8JGCGOIcXfiZLy+O2~F{`Ozh~C3ZS40n5noNHT!IS{B1BhFj3V7UjnavU;MGHMm)4_e$CnQI?Im;8Sp-)7)*;nnHe<)uyb9Tpf+NS3;oITu&%U}&|NlanUX4#9)&9Pxq z`w&V!5LsNBi7j1*a3nJko4^|P+kySb2yK}PEA|7}k$h2Cuw^QXn7G#>OZ!Q97b$id z>%rujWilF0*(8nRXgp2C0n^k~1@Q{v7v+t}v!eJV6-wflRVa&Zt6+;?QK2G!RfVefjtY+WH5F>& zuc@#m{}k%hR2A zU`78g{Owqfq75{oAdCXP9d^&ogRswGHJ$>EKf)2dhX$6zUTAe8@>f^KS zXXUDMVfFZ(sv*LX%OlP%v7|c^YvadHzUj$D>N!@tYN|H*wV@ssxfWUsD{DT z`46yVbifzKkuZG7Vs%33U_9RK3?}2wy+?-5^r{YI_NtUSuj9Qf8hwq|6^v%O>w zX%?YMMP55V^E>`6>7hPZ@|&iU6X5<9ZYauIMc+qBVHGRO@nuSJKDO0OvN(IzjPN!Z z#sVi^qQ5yFFmW!&Pc>!~qKHA#W7H^ExpI;y#7*x*bcyFU)Mr>|tqPg4rcEymW1Jeb zU534Jr@EMcxa(+gR~YIrOhPUu)^@?NZ2W3V{JV<@@NW+#`HFKFJRHB)vHN@&^HHus@Mfm6p=bZ&P4eO%Ne`DzKegwvo4 zAzw_X@vG0cipfj1btQFE1H(_U!DR~5be=_Yu0E$H;^wDllVC1ZtiJM;s)sCR)8-Nk zneq*WoTu96uIRLRKha67O`F`DF_UKSIO6p$(98(MtzVMp=Qs(L&9cWLC;13XHMDGj z+`92Z;!5~goZ}}wySOdVXE214bfrAz(_70(iSboBT}ifwHIuZI21~Z1P?e~#o6%Co zR^x3FFm84l=)x-3wKh>?{*{@kF!MqdJ<8EsnMqxz%}yPih6@VfJT(az^-^kn3?Zc^ znCa!=()s_iZ_H96r(c08cf6E+kFfBU?P|U1!wtshl|GFauw<&mhO9X<7C{RO1+CK zbEkwWPs(UE{DzAd$1p1yy_f~MRFvCs_WCly1O{*Xq?_K0GRp_#3tKKKi>|B6Ydfh) z>W1sv-<$l!5*F`zcnyRw^HA!mh$wk_C0AVNhbK4|f|^h$nIAMvw-+(ayz%oeB7UbY zDZ2c!qk49~Qzb*u=uicU2pJvoZRF(&uP0Q&q~9snqLmc;-(A!DGgE_$8XHf?aUR`m-I!S;xQ#$fD% literal 0 HcmV?d00001 diff --git a/test/test_prettyprint.py b/test/base-tests/python2/test_prettyprint.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_prettyprint.py rename to test/base-tests/python2/test_prettyprint.py diff --git a/test/base-tests/python2/test_prettyprint.pyc b/test/base-tests/python2/test_prettyprint.pyc new file mode 100644 index 0000000000000000000000000000000000000000..bf3726b0e3636faae1367d4392a2b0002001b73d GIT binary patch literal 2414 zcmcgtO>+`K5ba&Q0)%`)zV%L(#x=y^WTm2BJf%{b(gPO@b_TLafMN$r4xHk@@!$AY z`~mvjEJ)TeC0NFVdDGL|J=6Vq8dBd%h000yZ6MPpgZT_2>Np|_Uq`wk4G69@90}8+ zQlipQR~b=RscT16&Q6f(4OhaPsFm9mA?)*_3b9KO6I@m?m45ZU({e4gT*m=8e?xfa zrl>9Hq@{s4%AzV(xh-mkO0_F$&%Vtj?Ax$Md`WvKV|%_u==<^+8Rtcdycf}~+&JRA zp03jKRYBB&s6)9C2mJiW8Wx$kFIHK*0vVUp2OvEBj_2IC5SvYNWT)ohk3qSl8GcQR zSg~bMnN+-y@s`~XK`@qJIhr7bg%(qSmZto$bg5owe`8P1vIaCpar<&jz*j zd<(hE2Av>ALGM%$@43(Leco5w0X}cNpChag@`M5b?IC`Nutr!XY!EgHTZA%!yZYMz zOAvRb=Ospjv;PS}WG6LeN5#}2`P_hP7a>}M$yIWrl84V@RPN&;7@=OXKHQQ{tleul)0_HOV}gq6AlQ61pdPR zm+Z*3&F%z3bPD)=a`W_N3C79JlAdZ^OIO%ax@STbx>^KS<-js(lecwcsh`G#+)2Yj zI`c|h*qU6hCVDt0=Duscf}@{b_tmJYPx*%#;SXL`-7Mn+zw=a^nzO zf`>STWLk=|foX^%`vcB+70^nd-&VI(T0}1i;$dvwWumR+vlm?@>$2$!y%Sc068 oq6tLP+q|wegMV*YQ`t3IGyHR3)~YM?f%d}!5pbUec&GyY1>s^nlmGw# literal 0 HcmV?d00001 diff --git a/test/test_print_to.py b/test/base-tests/python2/test_print_to.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_print_to.py rename to test/base-tests/python2/test_print_to.py diff --git a/test/base-tests/python2/test_print_to.pyc b/test/base-tests/python2/test_print_to.pyc new file mode 100644 index 0000000000000000000000000000000000000000..b58e328857db9fede5c0d90b06cee5db588d3d2e GIT binary patch literal 413 zcmb7<&q@O^5XL9j?H@!v`3i--w1Eme74d2h9uz$EQraZ6(R8!y%!>PHK9>)mGpiuI zly=DcX7cednPgvA7dN-@#ll}?T<$m>X66I V_sKQU-^nI;&A8MfJyHWs;SW=9O(OsR literal 0 HcmV?d00001 diff --git a/test/test_single_stmt.py b/test/base-tests/python2/test_single_stmt.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_single_stmt.py rename to test/base-tests/python2/test_single_stmt.py diff --git a/test/base-tests/python2/test_single_stmt.pyc b/test/base-tests/python2/test_single_stmt.pyc new file mode 100644 index 0000000000000000000000000000000000000000..e383d4fdaa57363d4768cc5bd016dc9957d8e0a2 GIT binary patch literal 182 zcmZSn%*$0aGbk*X0SXv_v;z{ZD5hUr zl&qgxQIcAemzbklmRzi#o>`JnnxtQppPXH(Uz(SkpIcCwlWL}4l3HA%pOjdfstaNj u>laj(WaQ@=fyLvCGxO4OQsawDa!d4p5*$F2ZF2KdN^?@}KyE7rVg>*~Ni4(w literal 0 HcmV?d00001 diff --git a/test/test_slices.py b/test/base-tests/python2/test_slices.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_slices.py rename to test/base-tests/python2/test_slices.py diff --git a/test/base-tests/python2/test_slices.pyc b/test/base-tests/python2/test_slices.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c815c5a7d32c546b5419e3af0dac4dda79823aa8 GIT binary patch literal 798 zcma)3O>Yx15FI<8Yza_WBzi&S04zoAqVjQS5%~iZQX{TtvmUZmH{Qs0fLxLKi}?f0 z%tjDSWmkSPe)Bvt_Vj*Dvcosc=L)vpi0nsNu~YyS;HLs4N5PRI=-l(pT(Hq#lc06T=69vx+3D8%R=g18+;cVw%uV@bNhN!gvf)Tay@ZZz0CQX$(WwB+o; z*8#VER}$SOlOxa1RMC!8^-b;cLF$1OZn_P*4S-K#(RJN6!O8~YMI04a0`7j*Nh z{1HF(5y7l>(X2wd2<6gLrGJsk98FkzM{@vo%(_f;Xr?}X$KW&vpbv2AI1&d0Q`5BR z)IH`9O%D>!^D2eXFEEbDpOx2W%BFESNBPLC4v6k0d2vE8^=+y#7@_kXF(MU#wDI2@ z_m_qY7}F9HbqbfQN3INiA%3E55kpnrkA%UO&B?ba77Lf^^}Gmeb-gLpzG|1NO@r?X zPFBpzh$rmDVzo(i>(7M$5*t@xJSC3rdcJJ!y1@_pg7G!MP>)rnMqAuh-G87S=;ta| Q&-6fzRA29@iONLt8|n6mf&c&j literal 0 HcmV?d00001 diff --git a/test/test_tuple_params.py b/test/base-tests/python2/test_tuple_params.py-notyet old mode 100755 new mode 100644 similarity index 100% rename from test/test_tuple_params.py rename to test/base-tests/python2/test_tuple_params.py-notyet diff --git a/test/test_tuples.py b/test/base-tests/python2/test_tuples.py-notyet old mode 100755 new mode 100644 similarity index 100% rename from test/test_tuples.py rename to test/base-tests/python2/test_tuples.py-notyet diff --git a/test/test_yield.py b/test/base-tests/python2/test_yield.py old mode 100755 new mode 100644 similarity index 100% rename from test/test_yield.py rename to test/base-tests/python2/test_yield.py diff --git a/test/base-tests/python2/test_yield.pyc b/test/base-tests/python2/test_yield.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a10da2716c2139c3fb057648c45af30ae08028d7 GIT binary patch literal 908 zcmcIi!EVz)5PfSqX_7Vqsa3@R#D#+|WhD-rDB@75J*AQ(HBuyGIrcVjaMtPWy4X@V zm7m}{`2d*N26{l^*0uNfd3UrkZ{CJK$D`XH$yJWs2`x4IcwRos#AKwJ-1g^x*F=iCB4v4p}|AdAA zgq>ohz4EC~K8Yhb-T8`iZ3<-^FI4KxJi*mkdk8Mo<@L(^ANo#Vc zTBnT8s*~H?%4O+R%|ey(k^TVbtno50SyX+Cc^I$j_Mu%jT5C>x9pWl@yz=Qw* literal 0 HcmV?d00001 diff --git a/test/compile_tests b/test/compile_tests old mode 100755 new mode 100644 index 730fa43b..608a5b44 --- a/test/compile_tests +++ b/test/compile_tests @@ -1,8 +1,12 @@ -#!/usr/bin/env python -from __future__ import print_function - +#!/usr/bin/env python2.3 """ compile_tests -- compile test patterns for the decompyle test suite + +This source is part of the decompyle test suite. + +decompyle is a Python byte-code decompiler +See http://www.crazy-compilers.com/decompyle/ for +for further information """ import py_compile, os, sys, getopt @@ -22,8 +26,8 @@ for opt, val in opts: if args: raise 'This tool does not want any arguments' -print("Using files in dir %s" % src_dir) -print("Compiling into dir %s" % work_dir) +print "Using files in dir %s" % src_dir +print "Compiling into dir %s" % work_dir tests = {} @@ -48,7 +52,6 @@ tests['2.3'] = tests['2.2'] tests['2.5'] = tests['2.3'] tests['2.6'] = tests['2.5'] tests['2.7'] = ['mine'] + tests['2.6'] -tests['3.4'] = ['mine'] total_tests = len(tests['2.7']) #tests['2.2'].sort(); print tests['2.2'] @@ -71,7 +74,7 @@ try: except AttributeError: version = sys.version[:3] -print('Compiling test files for Python', version) -print('(%i/%i files)' % (len(tests[version]), total_tests)) +print 'Compiling test files for Python', version, +print '(%i/%i files)' % (len(tests[version]), total_tests) compile_for_version(version) -print('Done.') +print 'Done.' diff --git a/test/ok_2.7/aifc.py b/test/ok_2.7/aifc.py new file mode 100644 index 00000000..9ac710fb --- /dev/null +++ b/test/ok_2.7/aifc.py @@ -0,0 +1,986 @@ +"""Stuff to parse AIFF-C and AIFF files. + +Unless explicitly stated otherwise, the description below is true +both for AIFF-C files and AIFF files. + +An AIFF-C file has the following structure. + + +-----------------+ + | FORM | + +-----------------+ + | | + +----+------------+ + | | AIFC | + | +------------+ + | | | + | | . | + | | . | + | | . | + +----+------------+ + +An AIFF file has the string "AIFF" instead of "AIFC". + +A chunk consists of an identifier (4 bytes) followed by a size (4 bytes, +big endian order), followed by the data. The size field does not include +the size of the 8 byte header. + +The following chunk types are recognized. + + FVER + (AIFF-C only). + MARK + <# of markers> (2 bytes) + list of markers: + (2 bytes, must be > 0) + (4 bytes) + ("pstring") + COMM + <# of channels> (2 bytes) + <# of sound frames> (4 bytes) + (2 bytes) + (10 bytes, IEEE 80-bit extended + floating point) + in AIFF-C files only: + (4 bytes) + ("pstring") + SSND + (4 bytes, not used by this program) + (4 bytes, not used by this program) + + +A pstring consists of 1 byte length, a string of characters, and 0 or 1 +byte pad to make the total length even. + +Usage. + +Reading AIFF files: + f = aifc.open(file, 'r') +where file is either the name of a file or an open file pointer. +The open file pointer must have methods read(), seek(), and close(). +In some types of audio files, if the setpos() method is not used, +the seek() method is not necessary. + +This returns an instance of a class with the following public methods: + getnchannels() -- returns number of audio channels (1 for + mono, 2 for stereo) + getsampwidth() -- returns sample width in bytes + getframerate() -- returns sampling frequency + getnframes() -- returns number of audio frames + getcomptype() -- returns compression type ('NONE' for AIFF files) + getcompname() -- returns human-readable version of + compression type ('not compressed' for AIFF files) + getparams() -- returns a tuple consisting of all of the + above in the above order + getmarkers() -- get the list of marks in the audio file or None + if there are no marks + getmark(id) -- get mark with the specified id (raises an error + if the mark does not exist) + readframes(n) -- returns at most n frames of audio + rewind() -- rewind to the beginning of the audio stream + setpos(pos) -- seek to the specified position + tell() -- return the current position + close() -- close the instance (make it unusable) +The position returned by tell(), the position given to setpos() and +the position of marks are all compatible and have nothing to do with +the actual position in the file. +The close() method is called automatically when the class instance +is destroyed. + +Writing AIFF files: + f = aifc.open(file, 'w') +where file is either the name of a file or an open file pointer. +The open file pointer must have methods write(), tell(), seek(), and +close(). + +This returns an instance of a class with the following public methods: + aiff() -- create an AIFF file (AIFF-C default) + aifc() -- create an AIFF-C file + setnchannels(n) -- set the number of channels + setsampwidth(n) -- set the sample width + setframerate(n) -- set the frame rate + setnframes(n) -- set the number of frames + setcomptype(type, name) + -- set the compression type and the + human-readable compression type + setparams(tuple) + -- set all parameters at once + setmark(id, pos, name) + -- add specified mark to the list of marks + tell() -- return current position in output file (useful + in combination with setmark()) + writeframesraw(data) + -- write audio frames without pathing up the + file header + writeframes(data) + -- write audio frames and patch up the file header + close() -- patch up the file header and close the + output file +You should set the parameters before the first writeframesraw or +writeframes. The total number of frames does not need to be set, +but when it is set to the correct value, the header does not have to +be patched up. +It is best to first set all parameters, perhaps possibly the +compression type, and then write audio frames using writeframesraw. +When all frames have been written, either call writeframes('') or +close() to patch up the sizes in the header. +Marks can be added anytime. If there are any marks, you must call +close() after all frames have been written. +The close() method is called automatically when the class instance +is destroyed. + +When a file is opened with the extension '.aiff', an AIFF file is +written, otherwise an AIFF-C file is written. This default can be +changed by calling aiff() or aifc() before the first writeframes or +writeframesraw. +""" + +import struct +import __builtin__ + +__all__ = ["Error","open","openfp"] + +class Error(Exception): + pass + +_AIFC_version = 0xA2805140L # Version 1 of AIFF-C + +def _read_long(file): + try: + return struct.unpack('>l', file.read(4))[0] + except struct.error: + raise EOFError + +def _read_ulong(file): + try: + return struct.unpack('>L', file.read(4))[0] + except struct.error: + raise EOFError + +def _read_short(file): + try: + return struct.unpack('>h', file.read(2))[0] + except struct.error: + raise EOFError + +def _read_ushort(file): + try: + return struct.unpack('>H', file.read(2))[0] + except struct.error: + raise EOFError + +def _read_string(file): + length = ord(file.read(1)) + if length == 0: + data = '' + else: + data = file.read(length) + if length & 1 == 0: + dummy = file.read(1) + return data + +_HUGE_VAL = 1.79769313486231e+308 # See + +def _read_float(f): # 10 bytes + expon = _read_short(f) # 2 bytes + sign = 1 + if expon < 0: + sign = -1 + expon = expon + 0x8000 + himant = _read_ulong(f) # 4 bytes + lomant = _read_ulong(f) # 4 bytes + if expon == himant == lomant == 0: + f = 0.0 + elif expon == 0x7FFF: + f = _HUGE_VAL + else: + expon = expon - 16383 + f = (himant * 0x100000000L + lomant) * pow(2.0, expon - 63) + return sign * f + +def _write_short(f, x): + f.write(struct.pack('>h', x)) + +def _write_ushort(f, x): + f.write(struct.pack('>H', x)) + +def _write_long(f, x): + f.write(struct.pack('>l', x)) + +def _write_ulong(f, x): + f.write(struct.pack('>L', x)) + +def _write_string(f, s): + if len(s) > 255: + raise ValueError("string exceeds maximum pstring length") + f.write(struct.pack('B', len(s))) + f.write(s) + if len(s) & 1 == 0: + f.write(chr(0)) + +def _write_float(f, x): + import math + if x < 0: + sign = 0x8000 + x = x * -1 + else: + sign = 0 + if x == 0: + expon = 0 + himant = 0 + lomant = 0 + else: + fmant, expon = math.frexp(x) + if expon > 16384 or fmant >= 1 or fmant != fmant: # Infinity or NaN + expon = sign|0x7FFF + himant = 0 + lomant = 0 + else: # Finite + expon = expon + 16382 + if expon < 0: # denormalized + fmant = math.ldexp(fmant, expon) + expon = 0 + expon = expon | sign + fmant = math.ldexp(fmant, 32) + fsmant = math.floor(fmant) + himant = long(fsmant) + fmant = math.ldexp(fmant - fsmant, 32) + fsmant = math.floor(fmant) + lomant = long(fsmant) + _write_ushort(f, expon) + _write_ulong(f, himant) + _write_ulong(f, lomant) + +from chunk import Chunk + +class Aifc_read: + # Variables used in this class: + # + # These variables are available to the user though appropriate + # methods of this class: + # _file -- the open file with methods read(), close(), and seek() + # set through the __init__() method + # _nchannels -- the number of audio channels + # available through the getnchannels() method + # _nframes -- the number of audio frames + # available through the getnframes() method + # _sampwidth -- the number of bytes per audio sample + # available through the getsampwidth() method + # _framerate -- the sampling frequency + # available through the getframerate() method + # _comptype -- the AIFF-C compression type ('NONE' if AIFF) + # available through the getcomptype() method + # _compname -- the human-readable AIFF-C compression type + # available through the getcomptype() method + # _markers -- the marks in the audio file + # available through the getmarkers() and getmark() + # methods + # _soundpos -- the position in the audio stream + # available through the tell() method, set through the + # setpos() method + # + # These variables are used internally only: + # _version -- the AIFF-C version number + # _decomp -- the decompressor from builtin module cl + # _comm_chunk_read -- 1 iff the COMM chunk has been read + # _aifc -- 1 iff reading an AIFF-C file + # _ssnd_seek_needed -- 1 iff positioned correctly in audio + # file for readframes() + # _ssnd_chunk -- instantiation of a chunk class for the SSND chunk + # _framesize -- size of one frame in the file + + def initfp(self, file): + self._version = 0 + self._decomp = None + self._convert = None + self._markers = [] + self._soundpos = 0 + self._file = file + chunk = Chunk(file) + if chunk.getname() != 'FORM': + raise Error, 'file does not start with FORM id' + formdata = chunk.read(4) + if formdata == 'AIFF': + self._aifc = 0 + elif formdata == 'AIFC': + self._aifc = 1 + else: + raise Error, 'not an AIFF or AIFF-C file' + self._comm_chunk_read = 0 + while 1: + self._ssnd_seek_needed = 1 + try: + chunk = Chunk(self._file) + except EOFError: + break + chunkname = chunk.getname() + if chunkname == 'COMM': + self._read_comm_chunk(chunk) + self._comm_chunk_read = 1 + elif chunkname == 'SSND': + self._ssnd_chunk = chunk + dummy = chunk.read(8) + self._ssnd_seek_needed = 0 + elif chunkname == 'FVER': + self._version = _read_ulong(chunk) + elif chunkname == 'MARK': + self._readmark(chunk) + chunk.skip() + if not self._comm_chunk_read or not self._ssnd_chunk: + raise Error, 'COMM chunk and/or SSND chunk missing' + if self._aifc and self._decomp: + import cl + params = [cl.ORIGINAL_FORMAT, 0, + cl.BITS_PER_COMPONENT, self._sampwidth * 8, + cl.FRAME_RATE, self._framerate] + if self._nchannels == 1: + params[1] = cl.MONO + elif self._nchannels == 2: + params[1] = cl.STEREO_INTERLEAVED + else: + raise Error, 'cannot compress more than 2 channels' + self._decomp.SetParams(params) + + def __init__(self, f): + if type(f) == type(''): + f = __builtin__.open(f, 'rb') + # else, assume it is an open file object already + self.initfp(f) + + # + # User visible methods. + # + def getfp(self): + return self._file + + def rewind(self): + self._ssnd_seek_needed = 1 + self._soundpos = 0 + + def close(self): + if self._decomp: + self._decomp.CloseDecompressor() + self._decomp = None + self._file.close() + + def tell(self): + return self._soundpos + + def getnchannels(self): + return self._nchannels + + def getnframes(self): + return self._nframes + + def getsampwidth(self): + return self._sampwidth + + def getframerate(self): + return self._framerate + + def getcomptype(self): + return self._comptype + + def getcompname(self): + return self._compname + +## def getversion(self): +## return self._version + + def getparams(self): + return self.getnchannels(), self.getsampwidth(), \ + self.getframerate(), self.getnframes(), \ + self.getcomptype(), self.getcompname() + + def getmarkers(self): + if len(self._markers) == 0: + return None + return self._markers + + def getmark(self, id): + for marker in self._markers: + if id == marker[0]: + return marker + raise Error, 'marker %r does not exist' % (id,) + + def setpos(self, pos): + if pos < 0 or pos > self._nframes: + raise Error, 'position not in range' + self._soundpos = pos + self._ssnd_seek_needed = 1 + + def readframes(self, nframes): + if self._ssnd_seek_needed: + self._ssnd_chunk.seek(0) + dummy = self._ssnd_chunk.read(8) + pos = self._soundpos * self._framesize + if pos: + self._ssnd_chunk.seek(pos + 8) + self._ssnd_seek_needed = 0 + if nframes == 0: + return '' + data = self._ssnd_chunk.read(nframes * self._framesize) + if self._convert and data: + data = self._convert(data) + self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth) + return data + + # + # Internal methods. + # + + def _decomp_data(self, data): + import cl + dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE, + len(data) * 2) + return self._decomp.Decompress(len(data) // self._nchannels, + data) + + def _ulaw2lin(self, data): + import audioop + return audioop.ulaw2lin(data, 2) + + def _adpcm2lin(self, data): + import audioop + if not hasattr(self, '_adpcmstate'): + # first time + self._adpcmstate = None + data, self._adpcmstate = audioop.adpcm2lin(data, 2, + self._adpcmstate) + return data + + def _read_comm_chunk(self, chunk): + self._nchannels = _read_short(chunk) + self._nframes = _read_long(chunk) + self._sampwidth = (_read_short(chunk) + 7) // 8 + self._framerate = int(_read_float(chunk)) + self._framesize = self._nchannels * self._sampwidth + if self._aifc: + #DEBUG: SGI's soundeditor produces a bad size :-( + kludge = 0 + if chunk.chunksize == 18: + kludge = 1 + print 'Warning: bad COMM chunk size' + chunk.chunksize = 23 + #DEBUG end + self._comptype = chunk.read(4) + #DEBUG start + if kludge: + length = ord(chunk.file.read(1)) + if length & 1 == 0: + length = length + 1 + chunk.chunksize = chunk.chunksize + length + chunk.file.seek(-1, 1) + #DEBUG end + self._compname = _read_string(chunk) + if self._comptype != 'NONE': + if self._comptype == 'G722': + try: + import audioop + except ImportError: + pass + else: + self._convert = self._adpcm2lin + self._sampwidth = 2 + return + # for ULAW and ALAW try Compression Library + try: + import cl + except ImportError: + if self._comptype in ('ULAW', 'ulaw'): + try: + import audioop + self._convert = self._ulaw2lin + self._sampwidth = 2 + return + except ImportError: + pass + raise Error, 'cannot read compressed AIFF-C files' + if self._comptype in ('ULAW', 'ulaw'): + scheme = cl.G711_ULAW + elif self._comptype in ('ALAW', 'alaw'): + scheme = cl.G711_ALAW + else: + raise Error, 'unsupported compression type' + self._decomp = cl.OpenDecompressor(scheme) + self._convert = self._decomp_data + self._sampwidth = 2 + else: + self._comptype = 'NONE' + self._compname = 'not compressed' + + def _readmark(self, chunk): + nmarkers = _read_short(chunk) + # Some files appear to contain invalid counts. + # Cope with this by testing for EOF. + try: + for i in range(nmarkers): + id = _read_short(chunk) + pos = _read_long(chunk) + name = _read_string(chunk) + if pos or name: + # some files appear to have + # dummy markers consisting of + # a position 0 and name '' + self._markers.append((id, pos, name)) + except EOFError: + print 'Warning: MARK chunk contains only', + print len(self._markers), + if len(self._markers) == 1: print 'marker', + else: print 'markers', + print 'instead of', nmarkers + +class Aifc_write: + # Variables used in this class: + # + # These variables are user settable through appropriate methods + # of this class: + # _file -- the open file with methods write(), close(), tell(), seek() + # set through the __init__() method + # _comptype -- the AIFF-C compression type ('NONE' in AIFF) + # set through the setcomptype() or setparams() method + # _compname -- the human-readable AIFF-C compression type + # set through the setcomptype() or setparams() method + # _nchannels -- the number of audio channels + # set through the setnchannels() or setparams() method + # _sampwidth -- the number of bytes per audio sample + # set through the setsampwidth() or setparams() method + # _framerate -- the sampling frequency + # set through the setframerate() or setparams() method + # _nframes -- the number of audio frames written to the header + # set through the setnframes() or setparams() method + # _aifc -- whether we're writing an AIFF-C file or an AIFF file + # set through the aifc() method, reset through the + # aiff() method + # + # These variables are used internally only: + # _version -- the AIFF-C version number + # _comp -- the compressor from builtin module cl + # _nframeswritten -- the number of audio frames actually written + # _datalength -- the size of the audio samples written to the header + # _datawritten -- the size of the audio samples actually written + + def __init__(self, f): + if type(f) == type(''): + filename = f + f = __builtin__.open(f, 'wb') + else: + # else, assume it is an open file object already + filename = '???' + self.initfp(f) + if filename[-5:] == '.aiff': + self._aifc = 0 + else: + self._aifc = 1 + + def initfp(self, file): + self._file = file + self._version = _AIFC_version + self._comptype = 'NONE' + self._compname = 'not compressed' + self._comp = None + self._convert = None + self._nchannels = 0 + self._sampwidth = 0 + self._framerate = 0 + self._nframes = 0 + self._nframeswritten = 0 + self._datawritten = 0 + self._datalength = 0 + self._markers = [] + self._marklength = 0 + self._aifc = 1 # AIFF-C is default + + def __del__(self): + if self._file: + self.close() + + # + # User visible methods. + # + def aiff(self): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._aifc = 0 + + def aifc(self): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._aifc = 1 + + def setnchannels(self, nchannels): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if nchannels < 1: + raise Error, 'bad # of channels' + self._nchannels = nchannels + + def getnchannels(self): + if not self._nchannels: + raise Error, 'number of channels not set' + return self._nchannels + + def setsampwidth(self, sampwidth): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if sampwidth < 1 or sampwidth > 4: + raise Error, 'bad sample width' + self._sampwidth = sampwidth + + def getsampwidth(self): + if not self._sampwidth: + raise Error, 'sample width not set' + return self._sampwidth + + def setframerate(self, framerate): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if framerate <= 0: + raise Error, 'bad frame rate' + self._framerate = framerate + + def getframerate(self): + if not self._framerate: + raise Error, 'frame rate not set' + return self._framerate + + def setnframes(self, nframes): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._nframes = nframes + + def getnframes(self): + return self._nframeswritten + + def setcomptype(self, comptype, compname): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if comptype not in ('NONE', 'ULAW', 'ulaw', 'ALAW', 'alaw', 'G722'): + raise Error, 'unsupported compression type' + self._comptype = comptype + self._compname = compname + + def getcomptype(self): + return self._comptype + + def getcompname(self): + return self._compname + +## def setversion(self, version): +## if self._nframeswritten: +## raise Error, 'cannot change parameters after starting to write' +## self._version = version + + def setparams(self, info): + nchannels, sampwidth, framerate, nframes, comptype, compname = info + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if comptype not in ('NONE', 'ULAW', 'ulaw', 'ALAW', 'alaw', 'G722'): + raise Error, 'unsupported compression type' + self.setnchannels(nchannels) + self.setsampwidth(sampwidth) + self.setframerate(framerate) + self.setnframes(nframes) + self.setcomptype(comptype, compname) + + def getparams(self): + if not self._nchannels or not self._sampwidth or not self._framerate: + raise Error, 'not all parameters set' + return self._nchannels, self._sampwidth, self._framerate, \ + self._nframes, self._comptype, self._compname + + def setmark(self, id, pos, name): + if id <= 0: + raise Error, 'marker ID must be > 0' + if pos < 0: + raise Error, 'marker position must be >= 0' + if type(name) != type(''): + raise Error, 'marker name must be a string' + for i in range(len(self._markers)): + if id == self._markers[i][0]: + self._markers[i] = id, pos, name + return + self._markers.append((id, pos, name)) + + def getmark(self, id): + for marker in self._markers: + if id == marker[0]: + return marker + raise Error, 'marker %r does not exist' % (id,) + + def getmarkers(self): + if len(self._markers) == 0: + return None + return self._markers + + def tell(self): + return self._nframeswritten + + def writeframesraw(self, data): + self._ensure_header_written(len(data)) + nframes = len(data) // (self._sampwidth * self._nchannels) + if self._convert: + data = self._convert(data) + self._file.write(data) + self._nframeswritten = self._nframeswritten + nframes + self._datawritten = self._datawritten + len(data) + + def writeframes(self, data): + self.writeframesraw(data) + if self._nframeswritten != self._nframes or \ + self._datalength != self._datawritten: + self._patchheader() + + def close(self): + if self._file is None: + return + try: + self._ensure_header_written(0) + if self._datawritten & 1: + # quick pad to even size + self._file.write(chr(0)) + self._datawritten = self._datawritten + 1 + self._writemarkers() + if self._nframeswritten != self._nframes or \ + self._datalength != self._datawritten or \ + self._marklength: + self._patchheader() + if self._comp: + self._comp.CloseCompressor() + self._comp = None + finally: + # Prevent ref cycles + self._convert = None + f = self._file + self._file = None + f.close() + + # + # Internal methods. + # + + def _comp_data(self, data): + import cl + dummy = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data)) + dummy = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data)) + return self._comp.Compress(self._nframes, data) + + def _lin2ulaw(self, data): + import audioop + return audioop.lin2ulaw(data, 2) + + def _lin2adpcm(self, data): + import audioop + if not hasattr(self, '_adpcmstate'): + self._adpcmstate = None + data, self._adpcmstate = audioop.lin2adpcm(data, 2, + self._adpcmstate) + return data + + def _ensure_header_written(self, datasize): + if not self._nframeswritten: + if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw'): + if not self._sampwidth: + self._sampwidth = 2 + if self._sampwidth != 2: + raise Error, 'sample width must be 2 when compressing with ULAW or ALAW' + if self._comptype == 'G722': + if not self._sampwidth: + self._sampwidth = 2 + if self._sampwidth != 2: + raise Error, 'sample width must be 2 when compressing with G7.22 (ADPCM)' + if not self._nchannels: + raise Error, '# channels not specified' + if not self._sampwidth: + raise Error, 'sample width not specified' + if not self._framerate: + raise Error, 'sampling rate not specified' + self._write_header(datasize) + + def _init_compression(self): + if self._comptype == 'G722': + self._convert = self._lin2adpcm + return + try: + import cl + except ImportError: + if self._comptype in ('ULAW', 'ulaw'): + try: + import audioop + self._convert = self._lin2ulaw + return + except ImportError: + pass + raise Error, 'cannot write compressed AIFF-C files' + if self._comptype in ('ULAW', 'ulaw'): + scheme = cl.G711_ULAW + elif self._comptype in ('ALAW', 'alaw'): + scheme = cl.G711_ALAW + else: + raise Error, 'unsupported compression type' + self._comp = cl.OpenCompressor(scheme) + params = [cl.ORIGINAL_FORMAT, 0, + cl.BITS_PER_COMPONENT, self._sampwidth * 8, + cl.FRAME_RATE, self._framerate, + cl.FRAME_BUFFER_SIZE, 100, + cl.COMPRESSED_BUFFER_SIZE, 100] + if self._nchannels == 1: + params[1] = cl.MONO + elif self._nchannels == 2: + params[1] = cl.STEREO_INTERLEAVED + else: + raise Error, 'cannot compress more than 2 channels' + self._comp.SetParams(params) + # the compressor produces a header which we ignore + dummy = self._comp.Compress(0, '') + self._convert = self._comp_data + + def _write_header(self, initlength): + if self._aifc and self._comptype != 'NONE': + self._init_compression() + self._file.write('FORM') + if not self._nframes: + self._nframes = initlength // (self._nchannels * self._sampwidth) + self._datalength = self._nframes * self._nchannels * self._sampwidth + if self._datalength & 1: + self._datalength = self._datalength + 1 + if self._aifc: + if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw'): + self._datalength = self._datalength // 2 + if self._datalength & 1: + self._datalength = self._datalength + 1 + elif self._comptype == 'G722': + self._datalength = (self._datalength + 3) // 4 + if self._datalength & 1: + self._datalength = self._datalength + 1 + try: + self._form_length_pos = self._file.tell() + except (AttributeError, IOError): + self._form_length_pos = None + commlength = self._write_form_length(self._datalength) + if self._aifc: + self._file.write('AIFC') + self._file.write('FVER') + _write_ulong(self._file, 4) + _write_ulong(self._file, self._version) + else: + self._file.write('AIFF') + self._file.write('COMM') + _write_ulong(self._file, commlength) + _write_short(self._file, self._nchannels) + if self._form_length_pos is not None: + self._nframes_pos = self._file.tell() + _write_ulong(self._file, self._nframes) + if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw', 'G722'): + _write_short(self._file, 8) + else: + _write_short(self._file, self._sampwidth * 8) + _write_float(self._file, self._framerate) + if self._aifc: + self._file.write(self._comptype) + _write_string(self._file, self._compname) + self._file.write('SSND') + if self._form_length_pos is not None: + self._ssnd_length_pos = self._file.tell() + _write_ulong(self._file, self._datalength + 8) + _write_ulong(self._file, 0) + _write_ulong(self._file, 0) + + def _write_form_length(self, datalength): + if self._aifc: + commlength = 18 + 5 + len(self._compname) + if commlength & 1: + commlength = commlength + 1 + verslength = 12 + else: + commlength = 18 + verslength = 0 + _write_ulong(self._file, 4 + verslength + self._marklength + \ + 8 + commlength + 16 + datalength) + return commlength + + def _patchheader(self): + curpos = self._file.tell() + if self._datawritten & 1: + datalength = self._datawritten + 1 + self._file.write(chr(0)) + else: + datalength = self._datawritten + if datalength == self._datalength and \ + self._nframes == self._nframeswritten and \ + self._marklength == 0: + self._file.seek(curpos, 0) + return + self._file.seek(self._form_length_pos, 0) + dummy = self._write_form_length(datalength) + self._file.seek(self._nframes_pos, 0) + _write_ulong(self._file, self._nframeswritten) + self._file.seek(self._ssnd_length_pos, 0) + _write_ulong(self._file, datalength + 8) + self._file.seek(curpos, 0) + self._nframes = self._nframeswritten + self._datalength = datalength + + def _writemarkers(self): + if len(self._markers) == 0: + return + self._file.write('MARK') + length = 2 + for marker in self._markers: + id, pos, name = marker + length = length + len(name) + 1 + 6 + if len(name) & 1 == 0: + length = length + 1 + _write_ulong(self._file, length) + self._marklength = length + 8 + _write_short(self._file, len(self._markers)) + for marker in self._markers: + id, pos, name = marker + _write_short(self._file, id) + _write_ulong(self._file, pos) + _write_string(self._file, name) + +def open(f, mode=None): + if mode is None: + if hasattr(f, 'mode'): + mode = f.mode + else: + mode = 'rb' + if mode in ('r', 'rb'): + return Aifc_read(f) + elif mode in ('w', 'wb'): + return Aifc_write(f) + else: + raise Error, "mode must be 'r', 'rb', 'w', or 'wb'" + +openfp = open # B/W compatibility + +if __name__ == '__main__': + import sys + if not sys.argv[1:]: + sys.argv.append('/usr/demos/data/audio/bach.aiff') + fn = sys.argv[1] + f = open(fn, 'r') + try: + print "Reading", fn + print "nchannels =", f.getnchannels() + print "nframes =", f.getnframes() + print "sampwidth =", f.getsampwidth() + print "framerate =", f.getframerate() + print "comptype =", f.getcomptype() + print "compname =", f.getcompname() + if sys.argv[2:]: + gn = sys.argv[2] + print "Writing", gn + g = open(gn, 'w') + try: + g.setparams(f.getparams()) + while 1: + data = f.readframes(1024) + if not data: + break + g.writeframes(data) + finally: + g.close() + print "Done." + finally: + f.close() diff --git a/test/ok_2.7/aifc.pyc_dis b/test/ok_2.7/aifc.pyc_dis new file mode 100644 index 00000000..76ef3d97 --- /dev/null +++ b/test/ok_2.7/aifc.pyc_dis @@ -0,0 +1,932 @@ +# Embedded file name: /src/external-vcs/github/rocky/uncompyle6/test/ok_2.7/aifc.py +"""Stuff to parse AIFF-C and AIFF files. + +Unless explicitly stated otherwise, the description below is true +both for AIFF-C files and AIFF files. + +An AIFF-C file has the following structure. + + +-----------------+ + | FORM | + +-----------------+ + | | + +----+------------+ + | | AIFC | + | +------------+ + | | | + | | . | + | | . | + | | . | + +----+------------+ + +An AIFF file has the string "AIFF" instead of "AIFC". + +A chunk consists of an identifier (4 bytes) followed by a size (4 bytes, +big endian order), followed by the data. The size field does not include +the size of the 8 byte header. + +The following chunk types are recognized. + + FVER + (AIFF-C only). + MARK + <# of markers> (2 bytes) + list of markers: + (2 bytes, must be > 0) + (4 bytes) + ("pstring") + COMM + <# of channels> (2 bytes) + <# of sound frames> (4 bytes) + (2 bytes) + (10 bytes, IEEE 80-bit extended + floating point) + in AIFF-C files only: + (4 bytes) + ("pstring") + SSND + (4 bytes, not used by this program) + (4 bytes, not used by this program) + + +A pstring consists of 1 byte length, a string of characters, and 0 or 1 +byte pad to make the total length even. + +Usage. + +Reading AIFF files: + f = aifc.open(file, 'r') +where file is either the name of a file or an open file pointer. +The open file pointer must have methods read(), seek(), and close(). +In some types of audio files, if the setpos() method is not used, +the seek() method is not necessary. + +This returns an instance of a class with the following public methods: + getnchannels() -- returns number of audio channels (1 for + mono, 2 for stereo) + getsampwidth() -- returns sample width in bytes + getframerate() -- returns sampling frequency + getnframes() -- returns number of audio frames + getcomptype() -- returns compression type ('NONE' for AIFF files) + getcompname() -- returns human-readable version of + compression type ('not compressed' for AIFF files) + getparams() -- returns a tuple consisting of all of the + above in the above order + getmarkers() -- get the list of marks in the audio file or None + if there are no marks + getmark(id) -- get mark with the specified id (raises an error + if the mark does not exist) + readframes(n) -- returns at most n frames of audio + rewind() -- rewind to the beginning of the audio stream + setpos(pos) -- seek to the specified position + tell() -- return the current position + close() -- close the instance (make it unusable) +The position returned by tell(), the position given to setpos() and +the position of marks are all compatible and have nothing to do with +the actual position in the file. +The close() method is called automatically when the class instance +is destroyed. + +Writing AIFF files: + f = aifc.open(file, 'w') +where file is either the name of a file or an open file pointer. +The open file pointer must have methods write(), tell(), seek(), and +close(). + +This returns an instance of a class with the following public methods: + aiff() -- create an AIFF file (AIFF-C default) + aifc() -- create an AIFF-C file + setnchannels(n) -- set the number of channels + setsampwidth(n) -- set the sample width + setframerate(n) -- set the frame rate + setnframes(n) -- set the number of frames + setcomptype(type, name) + -- set the compression type and the + human-readable compression type + setparams(tuple) + -- set all parameters at once + setmark(id, pos, name) + -- add specified mark to the list of marks + tell() -- return current position in output file (useful + in combination with setmark()) + writeframesraw(data) + -- write audio frames without pathing up the + file header + writeframes(data) + -- write audio frames and patch up the file header + close() -- patch up the file header and close the + output file +You should set the parameters before the first writeframesraw or +writeframes. The total number of frames does not need to be set, +but when it is set to the correct value, the header does not have to +be patched up. +It is best to first set all parameters, perhaps possibly the +compression type, and then write audio frames using writeframesraw. +When all frames have been written, either call writeframes('') or +close() to patch up the sizes in the header. +Marks can be added anytime. If there are any marks, you must call +close() after all frames have been written. +The close() method is called automatically when the class instance +is destroyed. + +When a file is opened with the extension '.aiff', an AIFF file is +written, otherwise an AIFF-C file is written. This default can be +changed by calling aiff() or aifc() before the first writeframes or +writeframesraw. +""" +import struct +import __builtin__ +__all__ = ['Error', 'open', 'openfp'] + +class Error(Exception): + pass + + +_AIFC_version = 2726318400L + +def _read_long(file): + try: + return struct.unpack('>l', file.read(4))[0] + except struct.error: + raise EOFError + + +def _read_ulong(file): + try: + return struct.unpack('>L', file.read(4))[0] + except struct.error: + raise EOFError + + +def _read_short(file): + try: + return struct.unpack('>h', file.read(2))[0] + except struct.error: + raise EOFError + + +def _read_ushort(file): + try: + return struct.unpack('>H', file.read(2))[0] + except struct.error: + raise EOFError + + +def _read_string(file): + length = ord(file.read(1)) + if length == 0: + data = '' + else: + data = file.read(length) + if length & 1 == 0: + dummy = file.read(1) + return data + + +_HUGE_VAL = 1.79769313486231e+308 + +def _read_float(f): + expon = _read_short(f) + sign = 1 + if expon < 0: + sign = -1 + expon = expon + 32768 + himant = _read_ulong(f) + lomant = _read_ulong(f) + if expon == himant == lomant == 0: + f = 0.0 + elif expon == 32767: + f = _HUGE_VAL + else: + expon = expon - 16383 + f = (himant * 4294967296L + lomant) * pow(2.0, expon - 63) + return sign * f + + +def _write_short(f, x): + f.write(struct.pack('>h', x)) + + +def _write_ushort(f, x): + f.write(struct.pack('>H', x)) + + +def _write_long(f, x): + f.write(struct.pack('>l', x)) + + +def _write_ulong(f, x): + f.write(struct.pack('>L', x)) + + +def _write_string(f, s): + if len(s) > 255: + raise ValueError('string exceeds maximum pstring length') + f.write(struct.pack('B', len(s))) + f.write(s) + if len(s) & 1 == 0: + f.write(chr(0)) + + +def _write_float(f, x): + import math + if x < 0: + sign = 32768 + x = x * -1 + else: + sign = 0 + if x == 0: + expon = 0 + himant = 0 + lomant = 0 + else: + fmant, expon = math.frexp(x) + if expon > 16384 or fmant >= 1 or fmant != fmant: + expon = sign | 32767 + himant = 0 + lomant = 0 + else: + expon = expon + 16382 + if expon < 0: + fmant = math.ldexp(fmant, expon) + expon = 0 + expon = expon | sign + fmant = math.ldexp(fmant, 32) + fsmant = math.floor(fmant) + himant = long(fsmant) + fmant = math.ldexp(fmant - fsmant, 32) + fsmant = math.floor(fmant) + lomant = long(fsmant) + _write_ushort(f, expon) + _write_ulong(f, himant) + _write_ulong(f, lomant) + + +from chunk import Chunk + +class Aifc_read(): + + def initfp(self, file): + self._version = 0 + self._decomp = None + self._convert = None + self._markers = [] + self._soundpos = 0 + self._file = file + chunk = Chunk(file) + if chunk.getname() != 'FORM': + raise Error, 'file does not start with FORM id' + formdata = chunk.read(4) + if formdata == 'AIFF': + self._aifc = 0 + elif formdata == 'AIFC': + self._aifc = 1 + else: + raise Error, 'not an AIFF or AIFF-C file' + self._comm_chunk_read = 0 + while 1: + self._ssnd_seek_needed = 1 + try: + chunk = Chunk(self._file) + except EOFError: + break + + chunkname = chunk.getname() + if chunkname == 'COMM': + self._read_comm_chunk(chunk) + self._comm_chunk_read = 1 + elif chunkname == 'SSND': + self._ssnd_chunk = chunk + dummy = chunk.read(8) + self._ssnd_seek_needed = 0 + elif chunkname == 'FVER': + self._version = _read_ulong(chunk) + elif chunkname == 'MARK': + self._readmark(chunk) + chunk.skip() + + if not self._comm_chunk_read or not self._ssnd_chunk: + raise Error, 'COMM chunk and/or SSND chunk missing' + if self._aifc and self._decomp: + import cl + params = [cl.ORIGINAL_FORMAT, + 0, + cl.BITS_PER_COMPONENT, + self._sampwidth * 8, + cl.FRAME_RATE, + self._framerate] + if self._nchannels == 1: + params[1] = cl.MONO + elif self._nchannels == 2: + params[1] = cl.STEREO_INTERLEAVED + else: + raise Error, 'cannot compress more than 2 channels' + self._decomp.SetParams(params) + return + + def __init__(self, f): + if type(f) == type(''): + f = __builtin__.open(f, 'rb') + self.initfp(f) + + def getfp(self): + return self._file + + def rewind(self): + self._ssnd_seek_needed = 1 + self._soundpos = 0 + + def close(self): + if self._decomp: + self._decomp.CloseDecompressor() + self._decomp = None + self._file.close() + return + + def tell(self): + return self._soundpos + + def getnchannels(self): + return self._nchannels + + def getnframes(self): + return self._nframes + + def getsampwidth(self): + return self._sampwidth + + def getframerate(self): + return self._framerate + + def getcomptype(self): + return self._comptype + + def getcompname(self): + return self._compname + + def getparams(self): + return (self.getnchannels(), + self.getsampwidth(), + self.getframerate(), + self.getnframes(), + self.getcomptype(), + self.getcompname()) + + def getmarkers(self): + if len(self._markers) == 0: + return None + else: + return self._markers + + def getmark(self, id): + for marker in self._markers: + if id == marker[0]: + return marker + + raise Error, 'marker %r does not exist' % (id,) + + def setpos(self, pos): + if pos < 0 or pos > self._nframes: + raise Error, 'position not in range' + self._soundpos = pos + self._ssnd_seek_needed = 1 + + def readframes(self, nframes): + if self._ssnd_seek_needed: + self._ssnd_chunk.seek(0) + dummy = self._ssnd_chunk.read(8) + pos = self._soundpos * self._framesize + if pos: + self._ssnd_chunk.seek(pos + 8) + self._ssnd_seek_needed = 0 + if nframes == 0: + return '' + data = self._ssnd_chunk.read(nframes * self._framesize) + if self._convert and data: + data = self._convert(data) + self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth) + return data + + def _decomp_data(self, data): + import cl + dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE, len(data) * 2) + return self._decomp.Decompress(len(data) // self._nchannels, data) + + def _ulaw2lin(self, data): + import audioop + return audioop.ulaw2lin(data, 2) + + def _adpcm2lin(self, data): + import audioop + if not hasattr(self, '_adpcmstate'): + self._adpcmstate = None + data, self._adpcmstate = audioop.adpcm2lin(data, 2, self._adpcmstate) + return data + + def _read_comm_chunk(self, chunk): + self._nchannels = _read_short(chunk) + self._nframes = _read_long(chunk) + self._sampwidth = (_read_short(chunk) + 7) // 8 + self._framerate = int(_read_float(chunk)) + self._framesize = self._nchannels * self._sampwidth + if self._aifc: + kludge = 0 + if chunk.chunksize == 18: + kludge = 1 + print 'Warning: bad COMM chunk size' + chunk.chunksize = 23 + self._comptype = chunk.read(4) + if kludge: + length = ord(chunk.file.read(1)) + if length & 1 == 0: + length = length + 1 + chunk.chunksize = chunk.chunksize + length + chunk.file.seek(-1, 1) + self._compname = _read_string(chunk) + if self._comptype != 'NONE': + if self._comptype == 'G722': + try: + import audioop + except ImportError: + pass + else: + self._convert = self._adpcm2lin + self._sampwidth = 2 + return + + try: + import cl + except ImportError: + if self._comptype in ('ULAW', 'ulaw'): + try: + import audioop + self._convert = self._ulaw2lin + self._sampwidth = 2 + return + except ImportError: + pass + + raise Error, 'cannot read compressed AIFF-C files' + + if self._comptype in ('ULAW', 'ulaw'): + scheme = cl.G711_ULAW + elif self._comptype in ('ALAW', 'alaw'): + scheme = cl.G711_ALAW + else: + raise Error, 'unsupported compression type' + self._decomp = cl.OpenDecompressor(scheme) + self._convert = self._decomp_data + self._sampwidth = 2 + else: + self._comptype = 'NONE' + self._compname = 'not compressed' + + def _readmark(self, chunk): + nmarkers = _read_short(chunk) + try: + for i in range(nmarkers): + id = _read_short(chunk) + pos = _read_long(chunk) + name = _read_string(chunk) + if pos or name: + self._markers.append((id, pos, name)) + + except EOFError: + print 'Warning: MARK chunk contains only', + print len(self._markers), + if len(self._markers) == 1: + print 'marker', + else: + print 'markers', + print 'instead of', nmarkers + + +class Aifc_write(): + + def __init__(self, f): + if type(f) == type(''): + filename = f + f = __builtin__.open(f, 'wb') + else: + filename = '???' + self.initfp(f) + if filename[-5:] == '.aiff': + self._aifc = 0 + else: + self._aifc = 1 + + def initfp(self, file): + self._file = file + self._version = _AIFC_version + self._comptype = 'NONE' + self._compname = 'not compressed' + self._comp = None + self._convert = None + self._nchannels = 0 + self._sampwidth = 0 + self._framerate = 0 + self._nframes = 0 + self._nframeswritten = 0 + self._datawritten = 0 + self._datalength = 0 + self._markers = [] + self._marklength = 0 + self._aifc = 1 + return + + def __del__(self): + if self._file: + self.close() + + def aiff(self): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._aifc = 0 + + def aifc(self): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._aifc = 1 + + def setnchannels(self, nchannels): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if nchannels < 1: + raise Error, 'bad # of channels' + self._nchannels = nchannels + + def getnchannels(self): + if not self._nchannels: + raise Error, 'number of channels not set' + return self._nchannels + + def setsampwidth(self, sampwidth): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if sampwidth < 1 or sampwidth > 4: + raise Error, 'bad sample width' + self._sampwidth = sampwidth + + def getsampwidth(self): + if not self._sampwidth: + raise Error, 'sample width not set' + return self._sampwidth + + def setframerate(self, framerate): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if framerate <= 0: + raise Error, 'bad frame rate' + self._framerate = framerate + + def getframerate(self): + if not self._framerate: + raise Error, 'frame rate not set' + return self._framerate + + def setnframes(self, nframes): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + self._nframes = nframes + + def getnframes(self): + return self._nframeswritten + + def setcomptype(self, comptype, compname): + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if comptype not in ('NONE', 'ULAW', 'ulaw', 'ALAW', 'alaw', 'G722'): + raise Error, 'unsupported compression type' + self._comptype = comptype + self._compname = compname + + def getcomptype(self): + return self._comptype + + def getcompname(self): + return self._compname + + def setparams(self, info): + nchannels, sampwidth, framerate, nframes, comptype, compname = info + if self._nframeswritten: + raise Error, 'cannot change parameters after starting to write' + if comptype not in ('NONE', 'ULAW', 'ulaw', 'ALAW', 'alaw', 'G722'): + raise Error, 'unsupported compression type' + self.setnchannels(nchannels) + self.setsampwidth(sampwidth) + self.setframerate(framerate) + self.setnframes(nframes) + self.setcomptype(comptype, compname) + + def getparams(self): + if not self._nchannels or not self._sampwidth or not self._framerate: + raise Error, 'not all parameters set' + return (self._nchannels, + self._sampwidth, + self._framerate, + self._nframes, + self._comptype, + self._compname) + + def setmark(self, id, pos, name): + if id <= 0: + raise Error, 'marker ID must be > 0' + if pos < 0: + raise Error, 'marker position must be >= 0' + if type(name) != type(''): + raise Error, 'marker name must be a string' + for i in range(len(self._markers)): + if id == self._markers[i][0]: + self._markers[i] = (id, pos, name) + return + + self._markers.append((id, pos, name)) + + def getmark(self, id): + for marker in self._markers: + if id == marker[0]: + return marker + + raise Error, 'marker %r does not exist' % (id,) + + def getmarkers(self): + if len(self._markers) == 0: + return None + else: + return self._markers + + def tell(self): + return self._nframeswritten + + def writeframesraw(self, data): + self._ensure_header_written(len(data)) + nframes = len(data) // (self._sampwidth * self._nchannels) + if self._convert: + data = self._convert(data) + self._file.write(data) + self._nframeswritten = self._nframeswritten + nframes + self._datawritten = self._datawritten + len(data) + + def writeframes(self, data): + self.writeframesraw(data) + if self._nframeswritten != self._nframes or self._datalength != self._datawritten: + self._patchheader() + + def close(self): + if self._file is None: + return + else: + try: + self._ensure_header_written(0) + if self._datawritten & 1: + self._file.write(chr(0)) + self._datawritten = self._datawritten + 1 + self._writemarkers() + if self._nframeswritten != self._nframes or self._datalength != self._datawritten or self._marklength: + self._patchheader() + if self._comp: + self._comp.CloseCompressor() + self._comp = None + finally: + self._convert = None + f = self._file + self._file = None + f.close() + + return + + def _comp_data(self, data): + import cl + dummy = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data)) + dummy = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data)) + return self._comp.Compress(self._nframes, data) + + def _lin2ulaw(self, data): + import audioop + return audioop.lin2ulaw(data, 2) + + def _lin2adpcm(self, data): + import audioop + if not hasattr(self, '_adpcmstate'): + self._adpcmstate = None + data, self._adpcmstate = audioop.lin2adpcm(data, 2, self._adpcmstate) + return data + + def _ensure_header_written(self, datasize): + if not self._nframeswritten: + if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw'): + if not self._sampwidth: + self._sampwidth = 2 + if self._sampwidth != 2: + raise Error, 'sample width must be 2 when compressing with ULAW or ALAW' + if self._comptype == 'G722': + if not self._sampwidth: + self._sampwidth = 2 + if self._sampwidth != 2: + raise Error, 'sample width must be 2 when compressing with G7.22 (ADPCM)' + if not self._nchannels: + raise Error, '# channels not specified' + if not self._sampwidth: + raise Error, 'sample width not specified' + if not self._framerate: + raise Error, 'sampling rate not specified' + self._write_header(datasize) + + def _init_compression(self): + if self._comptype == 'G722': + self._convert = self._lin2adpcm + return + try: + import cl + except ImportError: + if self._comptype in ('ULAW', 'ulaw'): + try: + import audioop + self._convert = self._lin2ulaw + return + except ImportError: + pass + + raise Error, 'cannot write compressed AIFF-C files' + + if self._comptype in ('ULAW', 'ulaw'): + scheme = cl.G711_ULAW + elif self._comptype in ('ALAW', 'alaw'): + scheme = cl.G711_ALAW + else: + raise Error, 'unsupported compression type' + self._comp = cl.OpenCompressor(scheme) + params = [cl.ORIGINAL_FORMAT, + 0, + cl.BITS_PER_COMPONENT, + self._sampwidth * 8, + cl.FRAME_RATE, + self._framerate, + cl.FRAME_BUFFER_SIZE, + 100, + cl.COMPRESSED_BUFFER_SIZE, + 100] + if self._nchannels == 1: + params[1] = cl.MONO + elif self._nchannels == 2: + params[1] = cl.STEREO_INTERLEAVED + else: + raise Error, 'cannot compress more than 2 channels' + self._comp.SetParams(params) + dummy = self._comp.Compress(0, '') + self._convert = self._comp_data + + def _write_header(self, initlength): + if self._aifc and self._comptype != 'NONE': + self._init_compression() + self._file.write('FORM') + if not self._nframes: + self._nframes = initlength // (self._nchannels * self._sampwidth) + self._datalength = self._nframes * self._nchannels * self._sampwidth + if self._datalength & 1: + self._datalength = self._datalength + 1 + if self._aifc: + if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw'): + self._datalength = self._datalength // 2 + if self._datalength & 1: + self._datalength = self._datalength + 1 + elif self._comptype == 'G722': + self._datalength = (self._datalength + 3) // 4 + if self._datalength & 1: + self._datalength = self._datalength + 1 + try: + self._form_length_pos = self._file.tell() + except (AttributeError, IOError): + self._form_length_pos = None + + commlength = self._write_form_length(self._datalength) + if self._aifc: + self._file.write('AIFC') + self._file.write('FVER') + _write_ulong(self._file, 4) + _write_ulong(self._file, self._version) + else: + self._file.write('AIFF') + self._file.write('COMM') + _write_ulong(self._file, commlength) + _write_short(self._file, self._nchannels) + if self._form_length_pos is not None: + self._nframes_pos = self._file.tell() + _write_ulong(self._file, self._nframes) + if self._comptype in ('ULAW', 'ulaw', 'ALAW', 'alaw', 'G722'): + _write_short(self._file, 8) + else: + _write_short(self._file, self._sampwidth * 8) + _write_float(self._file, self._framerate) + if self._aifc: + self._file.write(self._comptype) + _write_string(self._file, self._compname) + self._file.write('SSND') + if self._form_length_pos is not None: + self._ssnd_length_pos = self._file.tell() + _write_ulong(self._file, self._datalength + 8) + _write_ulong(self._file, 0) + _write_ulong(self._file, 0) + return + + def _write_form_length(self, datalength): + if self._aifc: + commlength = 23 + len(self._compname) + if commlength & 1: + commlength = commlength + 1 + verslength = 12 + else: + commlength = 18 + verslength = 0 + _write_ulong(self._file, 4 + verslength + self._marklength + 8 + commlength + 16 + datalength) + return commlength + + def _patchheader(self): + curpos = self._file.tell() + if self._datawritten & 1: + datalength = self._datawritten + 1 + self._file.write(chr(0)) + else: + datalength = self._datawritten + if datalength == self._datalength and self._nframes == self._nframeswritten and self._marklength == 0: + self._file.seek(curpos, 0) + return + self._file.seek(self._form_length_pos, 0) + dummy = self._write_form_length(datalength) + self._file.seek(self._nframes_pos, 0) + _write_ulong(self._file, self._nframeswritten) + self._file.seek(self._ssnd_length_pos, 0) + _write_ulong(self._file, datalength + 8) + self._file.seek(curpos, 0) + self._nframes = self._nframeswritten + self._datalength = datalength + + def _writemarkers(self): + if len(self._markers) == 0: + return + self._file.write('MARK') + length = 2 + for marker in self._markers: + id, pos, name = marker + length = length + len(name) + 1 + 6 + if len(name) & 1 == 0: + length = length + 1 + + _write_ulong(self._file, length) + self._marklength = length + 8 + _write_short(self._file, len(self._markers)) + for marker in self._markers: + id, pos, name = marker + _write_short(self._file, id) + _write_ulong(self._file, pos) + _write_string(self._file, name) + + +def open(f, mode = None): + if mode is None: + if hasattr(f, 'mode'): + mode = f.mode + else: + mode = 'rb' + if mode in ('r', 'rb'): + return Aifc_read(f) + elif mode in ('w', 'wb'): + return Aifc_write(f) + else: + raise Error, "mode must be 'r', 'rb', 'w', or 'wb'" + return + + +openfp = open +if __name__ == '__main__': + import sys + if not sys.argv[1:]: + sys.argv.append('/usr/demos/data/audio/bach.aiff') + fn = sys.argv[1] + f = open(fn, 'r') + try: + print 'Reading', fn + print 'nchannels =', f.getnchannels() + print 'nframes =', f.getnframes() + print 'sampwidth =', f.getsampwidth() + print 'framerate =', f.getframerate() + print 'comptype =', f.getcomptype() + print 'compname =', f.getcompname() + if sys.argv[2:]: + gn = sys.argv[2] + print 'Writing', gn + g = open(gn, 'w') + try: + g.setparams(f.getparams()) + while 1: + data = f.readframes(1024) + if not data: + break + g.writeframes(data) + + finally: + g.close() + + print 'Done.' + finally: + f.close() \ No newline at end of file diff --git a/test/ok_2.7/antigravity.py b/test/ok_2.7/antigravity.py new file mode 100644 index 00000000..7fb7d828 --- /dev/null +++ b/test/ok_2.7/antigravity.py @@ -0,0 +1,4 @@ + +import webbrowser + +webbrowser.open("http://xkcd.com/353/") diff --git a/test/ok_2.7/antigravity.pyc_dis b/test/ok_2.7/antigravity.pyc_dis new file mode 100644 index 00000000..fe0ddabb --- /dev/null +++ b/test/ok_2.7/antigravity.pyc_dis @@ -0,0 +1,3 @@ +# Embedded file name: /src/external-vcs/github/rocky/uncompyle6/test/ok_2.7/antigravity.py +import webbrowser +webbrowser.open('http://xkcd.com/353/') \ No newline at end of file diff --git a/test/ok_2.7/anydbm.py b/test/ok_2.7/anydbm.py new file mode 100644 index 00000000..ba7e9051 --- /dev/null +++ b/test/ok_2.7/anydbm.py @@ -0,0 +1,85 @@ +"""Generic interface to all dbm clones. + +Instead of + + import dbm + d = dbm.open(file, 'w', 0666) + +use + + import anydbm + d = anydbm.open(file, 'w') + +The returned object is a dbhash, gdbm, dbm or dumbdbm object, +dependent on the type of database being opened (determined by whichdb +module) in the case of an existing dbm. If the dbm does not exist and +the create or new flag ('c' or 'n') was specified, the dbm type will +be determined by the availability of the modules (tested in the above +order). + +It has the following interface (key and data are strings): + + d[key] = data # store data at key (may override data at + # existing key) + data = d[key] # retrieve data at key (raise KeyError if no + # such key) + del d[key] # delete data stored at key (raises KeyError + # if no such key) + flag = key in d # true if the key exists + list = d.keys() # return a list of all existing keys (slow!) + +Future versions may change the order in which implementations are +tested for existence, and add interfaces to other dbm-like +implementations. +""" + +class error(Exception): + pass + +_names = ['dbhash', 'gdbm', 'dbm', 'dumbdbm'] +_errors = [error] +_defaultmod = None + +for _name in _names: + try: + _mod = __import__(_name) + except ImportError: + continue + if not _defaultmod: + _defaultmod = _mod + _errors.append(_mod.error) + +if not _defaultmod: + raise ImportError, "no dbm clone found; tried %s" % _names + +error = tuple(_errors) + +def open(file, flag='r', mode=0666): + """Open or create database at path given by *file*. + + Optional argument *flag* can be 'r' (default) for read-only access, 'w' + for read-write access of an existing database, 'c' for read-write access + to a new or existing database, and 'n' for read-write access to a new + database. + + Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it + only if it doesn't exist; and 'n' always creates a new database. + """ + + # guess the type of an existing database + from whichdb import whichdb + result=whichdb(file) + if result is None: + # db doesn't exist + if 'c' in flag or 'n' in flag: + # file doesn't exist and the new + # flag was used so use default type + mod = _defaultmod + else: + raise error, "need 'c' or 'n' flag to open new db" + elif result == "": + # db type cannot be determined + raise error, "db type could not be determined" + else: + mod = __import__(result) + return mod.open(file, flag, mode) diff --git a/test/ok_2.7/anydbm.pyc_dis b/test/ok_2.7/anydbm.pyc_dis new file mode 100644 index 00000000..4b5617a2 --- /dev/null +++ b/test/ok_2.7/anydbm.pyc_dis @@ -0,0 +1,83 @@ +# Embedded file name: /src/external-vcs/github/rocky/uncompyle6/test/ok_2.7/anydbm.py +"""Generic interface to all dbm clones. + +Instead of + + import dbm + d = dbm.open(file, 'w', 0666) + +use + + import anydbm + d = anydbm.open(file, 'w') + +The returned object is a dbhash, gdbm, dbm or dumbdbm object, +dependent on the type of database being opened (determined by whichdb +module) in the case of an existing dbm. If the dbm does not exist and +the create or new flag ('c' or 'n') was specified, the dbm type will +be determined by the availability of the modules (tested in the above +order). + +It has the following interface (key and data are strings): + + d[key] = data # store data at key (may override data at + # existing key) + data = d[key] # retrieve data at key (raise KeyError if no + # such key) + del d[key] # delete data stored at key (raises KeyError + # if no such key) + flag = key in d # true if the key exists + list = d.keys() # return a list of all existing keys (slow!) + +Future versions may change the order in which implementations are +tested for existence, and add interfaces to other dbm-like +implementations. +""" + +class error(Exception): + pass + + +_names = ['dbhash', + 'gdbm', + 'dbm', + 'dumbdbm'] +_errors = [error] +_defaultmod = None +for _name in _names: + try: + _mod = __import__(_name) + except ImportError: + continue + + if not _defaultmod: + _defaultmod = _mod + _errors.append(_mod.error) + +if not _defaultmod: + raise ImportError, 'no dbm clone found; tried %s' % _names +error = tuple(_errors) + +def open(file, flag = 'r', mode = 438): + """Open or create database at path given by *file*. + + Optional argument *flag* can be 'r' (default) for read-only access, 'w' + for read-write access of an existing database, 'c' for read-write access + to a new or existing database, and 'n' for read-write access to a new + database. + + Note: 'r' and 'w' fail if the database doesn't exist; 'c' creates it + only if it doesn't exist; and 'n' always creates a new database. + """ + from whichdb import whichdb + result = whichdb(file) + if result is None: + if 'c' in flag or 'n' in flag: + mod = _defaultmod + else: + raise error, "need 'c' or 'n' flag to open new db" + elif result == '': + raise error, 'db type could not be determined' + else: + mod = __import__(result) + return mod.open(file, flag, mode) \ No newline at end of file diff --git a/test/ok_2.7/asynchat.py b/test/ok_2.7/asynchat.py new file mode 100644 index 00000000..911833d5 --- /dev/null +++ b/test/ok_2.7/asynchat.py @@ -0,0 +1,314 @@ +# -*- Mode: Python; tab-width: 4 -*- +# Id: asynchat.py,v 2.26 2000/09/07 22:29:26 rushing Exp +# Author: Sam Rushing + +# ====================================================================== +# Copyright 1996 by Sam Rushing +# +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appear in all +# copies and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of Sam +# Rushing not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# ====================================================================== + +r"""A class supporting chat-style (command/response) protocols. + +This class adds support for 'chat' style protocols - where one side +sends a 'command', and the other sends a response (examples would be +the common internet protocols - smtp, nntp, ftp, etc..). + +The handle_read() method looks at the input stream for the current +'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n' +for multi-line output), calling self.found_terminator() on its +receipt. + +for example: +Say you build an async nntp client using this class. At the start +of the connection, you'll have self.terminator set to '\r\n', in +order to process the single-line greeting. Just before issuing a +'LIST' command you'll set it to '\r\n.\r\n'. The output of the LIST +command will be accumulated (using your own 'collect_incoming_data' +method) up to the terminator, and then control will be returned to +you - by calling your self.found_terminator() method. +""" + +import socket +import asyncore +from collections import deque +from sys import py3kwarning +from warnings import filterwarnings, catch_warnings + +class async_chat (asyncore.dispatcher): + """This is an abstract class. You must derive from this class, and add + the two methods collect_incoming_data() and found_terminator()""" + + # these are overridable defaults + + ac_in_buffer_size = 4096 + ac_out_buffer_size = 4096 + + def __init__ (self, sock=None, map=None): + # for string terminator matching + self.ac_in_buffer = '' + + # we use a list here rather than cStringIO for a few reasons... + # del lst[:] is faster than sio.truncate(0) + # lst = [] is faster than sio.truncate(0) + # cStringIO will be gaining unicode support in py3k, which + # will negatively affect the performance of bytes compared to + # a ''.join() equivalent + self.incoming = [] + + # we toss the use of the "simple producer" and replace it with + # a pure deque, which the original fifo was a wrapping of + self.producer_fifo = deque() + asyncore.dispatcher.__init__ (self, sock, map) + + def collect_incoming_data(self, data): + raise NotImplementedError("must be implemented in subclass") + + def _collect_incoming_data(self, data): + self.incoming.append(data) + + def _get_data(self): + d = ''.join(self.incoming) + del self.incoming[:] + return d + + def found_terminator(self): + raise NotImplementedError("must be implemented in subclass") + + def set_terminator (self, term): + "Set the input delimiter. Can be a fixed string of any length, an integer, or None" + self.terminator = term + + def get_terminator (self): + return self.terminator + + # grab some more data from the socket, + # throw it to the collector method, + # check for the terminator, + # if found, transition to the next state. + + def handle_read (self): + + try: + data = self.recv (self.ac_in_buffer_size) + except socket.error, why: + self.handle_error() + return + + self.ac_in_buffer = self.ac_in_buffer + data + + # Continue to search for self.terminator in self.ac_in_buffer, + # while calling self.collect_incoming_data. The while loop + # is necessary because we might read several data+terminator + # combos with a single recv(4096). + + while self.ac_in_buffer: + lb = len(self.ac_in_buffer) + terminator = self.get_terminator() + if not terminator: + # no terminator, collect it all + self.collect_incoming_data (self.ac_in_buffer) + self.ac_in_buffer = '' + elif isinstance(terminator, int) or isinstance(terminator, long): + # numeric terminator + n = terminator + if lb < n: + self.collect_incoming_data (self.ac_in_buffer) + self.ac_in_buffer = '' + self.terminator = self.terminator - lb + else: + self.collect_incoming_data (self.ac_in_buffer[:n]) + self.ac_in_buffer = self.ac_in_buffer[n:] + self.terminator = 0 + self.found_terminator() + else: + # 3 cases: + # 1) end of buffer matches terminator exactly: + # collect data, transition + # 2) end of buffer matches some prefix: + # collect data to the prefix + # 3) end of buffer does not match any prefix: + # collect data + terminator_len = len(terminator) + index = self.ac_in_buffer.find(terminator) + if index != -1: + # we found the terminator + if index > 0: + # don't bother reporting the empty string (source of subtle bugs) + self.collect_incoming_data (self.ac_in_buffer[:index]) + self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:] + # This does the Right Thing if the terminator is changed here. + self.found_terminator() + else: + # check for a prefix of the terminator + index = find_prefix_at_end (self.ac_in_buffer, terminator) + if index: + if index != lb: + # we found a prefix, collect up to the prefix + self.collect_incoming_data (self.ac_in_buffer[:-index]) + self.ac_in_buffer = self.ac_in_buffer[-index:] + break + else: + # no prefix, collect it all + self.collect_incoming_data (self.ac_in_buffer) + self.ac_in_buffer = '' + + def handle_write (self): + self.initiate_send() + + def handle_close (self): + self.close() + + def push (self, data): + sabs = self.ac_out_buffer_size + if len(data) > sabs: + for i in xrange(0, len(data), sabs): + self.producer_fifo.append(data[i:i+sabs]) + else: + self.producer_fifo.append(data) + self.initiate_send() + + def push_with_producer (self, producer): + self.producer_fifo.append(producer) + self.initiate_send() + + def readable (self): + "predicate for inclusion in the readable for select()" + # cannot use the old predicate, it violates the claim of the + # set_terminator method. + + # return (len(self.ac_in_buffer) <= self.ac_in_buffer_size) + return 1 + + def writable (self): + "predicate for inclusion in the writable for select()" + return self.producer_fifo or (not self.connected) + + def close_when_done (self): + "automatically close this channel once the outgoing queue is empty" + self.producer_fifo.append(None) + + def initiate_send(self): + while self.producer_fifo and self.connected: + first = self.producer_fifo[0] + # handle empty string/buffer or None entry + if not first: + del self.producer_fifo[0] + if first is None: + self.handle_close() + return + + # handle classic producer behavior + obs = self.ac_out_buffer_size + try: + with catch_warnings(): + if py3kwarning: + filterwarnings("ignore", ".*buffer", DeprecationWarning) + data = buffer(first, 0, obs) + except TypeError: + data = first.more() + if data: + self.producer_fifo.appendleft(data) + else: + del self.producer_fifo[0] + continue + + # send the data + try: + num_sent = self.send(data) + except socket.error: + self.handle_error() + return + + if num_sent: + if num_sent < len(data) or obs < len(first): + self.producer_fifo[0] = first[num_sent:] + else: + del self.producer_fifo[0] + # we tried to send some actual data + return + + def discard_buffers (self): + # Emergencies only! + self.ac_in_buffer = '' + del self.incoming[:] + self.producer_fifo.clear() + +class simple_producer: + + def __init__ (self, data, buffer_size=512): + self.data = data + self.buffer_size = buffer_size + + def more (self): + if len (self.data) > self.buffer_size: + result = self.data[:self.buffer_size] + self.data = self.data[self.buffer_size:] + return result + else: + result = self.data + self.data = '' + return result + +class fifo: + def __init__ (self, list=None): + if not list: + self.list = deque() + else: + self.list = deque(list) + + def __len__ (self): + return len(self.list) + + def is_empty (self): + return not self.list + + def first (self): + return self.list[0] + + def push (self, data): + self.list.append(data) + + def pop (self): + if self.list: + return (1, self.list.popleft()) + else: + return (0, None) + +# Given 'haystack', see if any prefix of 'needle' is at its end. This +# assumes an exact match has already been checked. Return the number of +# characters matched. +# for example: +# f_p_a_e ("qwerty\r", "\r\n") => 1 +# f_p_a_e ("qwertydkjf", "\r\n") => 0 +# f_p_a_e ("qwerty\r\n", "\r\n") => + +# this could maybe be made faster with a computed regex? +# [answer: no; circa Python-2.0, Jan 2001] +# new python: 28961/s +# old python: 18307/s +# re: 12820/s +# regex: 14035/s + +def find_prefix_at_end (haystack, needle): + l = len(needle) - 1 + while l and not haystack.endswith(needle[:l]): + l -= 1 + return l diff --git a/test/ok_2.7/asynchat.pyc_dis b/test/ok_2.7/asynchat.pyc_dis new file mode 100644 index 00000000..71577895 --- /dev/null +++ b/test/ok_2.7/asynchat.pyc_dis @@ -0,0 +1,231 @@ +# Embedded file name: /src/external-vcs/github/rocky/uncompyle6/test/ok_2.7/asynchat.py +r"""A class supporting chat-style (command/response) protocols. + +This class adds support for 'chat' style protocols - where one side +sends a 'command', and the other sends a response (examples would be +the common internet protocols - smtp, nntp, ftp, etc..). + +The handle_read() method looks at the input stream for the current +'terminator' (usually '\r\n' for single-line responses, '\r\n.\r\n' +for multi-line output), calling self.found_terminator() on its +receipt. + +for example: +Say you build an async nntp client using this class. At the start +of the connection, you'll have self.terminator set to '\r\n', in +order to process the single-line greeting. Just before issuing a +'LIST' command you'll set it to '\r\n.\r\n'. The output of the LIST +command will be accumulated (using your own 'collect_incoming_data' +method) up to the terminator, and then control will be returned to +you - by calling your self.found_terminator() method. +""" +import socket +import asyncore +from collections import deque +from sys import py3kwarning +from warnings import filterwarnings, catch_warnings + +class async_chat(asyncore.dispatcher): + """This is an abstract class. You must derive from this class, and add + the two methods collect_incoming_data() and found_terminator()""" + ac_in_buffer_size = 4096 + ac_out_buffer_size = 4096 + + def __init__(self, sock = None, map = None): + self.ac_in_buffer = '' + self.incoming = [] + self.producer_fifo = deque() + asyncore.dispatcher.__init__(self, sock, map) + + def collect_incoming_data(self, data): + raise NotImplementedError('must be implemented in subclass') + + def _collect_incoming_data(self, data): + self.incoming.append(data) + + def _get_data(self): + d = ''.join(self.incoming) + del self.incoming[:] + return d + + def found_terminator(self): + raise NotImplementedError('must be implemented in subclass') + + def set_terminator(self, term): + """Set the input delimiter. Can be a fixed string of any length, an integer, or None""" + self.terminator = term + + def get_terminator(self): + return self.terminator + + def handle_read(self): + try: + data = self.recv(self.ac_in_buffer_size) + except socket.error as why: + self.handle_error() + return + + self.ac_in_buffer = self.ac_in_buffer + data + while self.ac_in_buffer: + lb = len(self.ac_in_buffer) + terminator = self.get_terminator() + if not terminator: + self.collect_incoming_data(self.ac_in_buffer) + self.ac_in_buffer = '' + elif isinstance(terminator, int) or isinstance(terminator, long): + n = terminator + if lb < n: + self.collect_incoming_data(self.ac_in_buffer) + self.ac_in_buffer = '' + self.terminator = self.terminator - lb + else: + self.collect_incoming_data(self.ac_in_buffer[:n]) + self.ac_in_buffer = self.ac_in_buffer[n:] + self.terminator = 0 + self.found_terminator() + else: + terminator_len = len(terminator) + index = self.ac_in_buffer.find(terminator) + if index != -1: + if index > 0: + self.collect_incoming_data(self.ac_in_buffer[:index]) + self.ac_in_buffer = self.ac_in_buffer[index + terminator_len:] + self.found_terminator() + else: + index = find_prefix_at_end(self.ac_in_buffer, terminator) + if index: + if index != lb: + self.collect_incoming_data(self.ac_in_buffer[:-index]) + self.ac_in_buffer = self.ac_in_buffer[-index:] + break + else: + self.collect_incoming_data(self.ac_in_buffer) + self.ac_in_buffer = '' + + def handle_write(self): + self.initiate_send() + + def handle_close(self): + self.close() + + def push(self, data): + sabs = self.ac_out_buffer_size + if len(data) > sabs: + for i in xrange(0, len(data), sabs): + self.producer_fifo.append(data[i:i + sabs]) + + else: + self.producer_fifo.append(data) + self.initiate_send() + + def push_with_producer(self, producer): + self.producer_fifo.append(producer) + self.initiate_send() + + def readable(self): + """predicate for inclusion in the readable for select()""" + return 1 + + def writable(self): + """predicate for inclusion in the writable for select()""" + return self.producer_fifo or not self.connected + + def close_when_done(self): + """automatically close this channel once the outgoing queue is empty""" + self.producer_fifo.append(None) + return + + def initiate_send(self): + while self.producer_fifo and self.connected: + first = self.producer_fifo[0] + if not first: + del self.producer_fifo[0] + if first is None: + self.handle_close() + return + obs = self.ac_out_buffer_size + try: + with catch_warnings(): + if py3kwarning: + filterwarnings('ignore', '.*buffer', DeprecationWarning) + data = buffer(first, 0, obs) + except TypeError: + data = first.more() + if data: + self.producer_fifo.appendleft(data) + else: + del self.producer_fifo[0] + continue + + try: + num_sent = self.send(data) + except socket.error: + self.handle_error() + return + + if num_sent: + if num_sent < len(data) or obs < len(first): + self.producer_fifo[0] = first[num_sent:] + else: + del self.producer_fifo[0] + return + + return + + def discard_buffers(self): + self.ac_in_buffer = '' + del self.incoming[:] + self.producer_fifo.clear() + + +class simple_producer: + + def __init__(self, data, buffer_size = 512): + self.data = data + self.buffer_size = buffer_size + + def more(self): + if len(self.data) > self.buffer_size: + result = self.data[:self.buffer_size] + self.data = self.data[self.buffer_size:] + return result + else: + result = self.data + self.data = '' + return result + + +class fifo: + + def __init__(self, list = None): + if not list: + self.list = deque() + else: + self.list = deque(list) + + def __len__(self): + return len(self.list) + + def is_empty(self): + return not self.list + + def first(self): + return self.list[0] + + def push(self, data): + self.list.append(data) + + def pop(self): + if self.list: + return (1, self.list.popleft()) + else: + return (0, None) + return None + + +def find_prefix_at_end(haystack, needle): + l = len(needle) - 1 + while l and not haystack.endswith(needle[:l]): + l -= 1 + + return l \ No newline at end of file diff --git a/test/ok_2.7/asyncore.py b/test/ok_2.7/asyncore.py new file mode 100644 index 00000000..29099bdf --- /dev/null +++ b/test/ok_2.7/asyncore.py @@ -0,0 +1,659 @@ +# -*- Mode: Python -*- +# Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp +# Author: Sam Rushing + +# ====================================================================== +# Copyright 1996 by Sam Rushing +# +# All Rights Reserved +# +# Permission to use, copy, modify, and distribute this software and +# its documentation for any purpose and without fee is hereby +# granted, provided that the above copyright notice appear in all +# copies and that both that copyright notice and this permission +# notice appear in supporting documentation, and that the name of Sam +# Rushing not be used in advertising or publicity pertaining to +# distribution of the software without specific, written prior +# permission. +# +# SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, +# INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN +# NO EVENT SHALL SAM RUSHING BE LIABLE FOR ANY SPECIAL, INDIRECT OR +# CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS +# OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, +# NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# ====================================================================== + +"""Basic infrastructure for asynchronous socket service clients and servers. + +There are only two ways to have a program on a single processor do "more +than one thing at a time". Multi-threaded programming is the simplest and +most popular way to do it, but there is another very different technique, +that lets you have nearly all the advantages of multi-threading, without +actually using multiple threads. it's really only practical if your program +is largely I/O bound. If your program is CPU bound, then pre-emptive +scheduled threads are probably what you really need. Network servers are +rarely CPU-bound, however. + +If your operating system supports the select() system call in its I/O +library (and nearly all do), then you can use it to juggle multiple +communication channels at once; doing other work while your I/O is taking +place in the "background." Although this strategy can seem strange and +complex, especially at first, it is in many ways easier to understand and +control than multi-threaded programming. The module documented here solves +many of the difficult problems for you, making the task of building +sophisticated high-performance network servers and clients a snap. +""" + +import select +import socket +import sys +import time +import warnings + +import os +from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, \ + ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, \ + errorcode + +_DISCONNECTED = frozenset((ECONNRESET, ENOTCONN, ESHUTDOWN, ECONNABORTED, EPIPE, + EBADF)) + +try: + socket_map +except NameError: + socket_map = {} + +def _strerror(err): + try: + return os.strerror(err) + except (ValueError, OverflowError, NameError): + if err in errorcode: + return errorcode[err] + return "Unknown error %s" %err + +class ExitNow(Exception): + pass + +_reraised_exceptions = (ExitNow, KeyboardInterrupt, SystemExit) + +def read(obj): + try: + obj.handle_read_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + +def write(obj): + try: + obj.handle_write_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + +def _exception(obj): + try: + obj.handle_expt_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + +def readwrite(obj, flags): + try: + if flags & select.POLLIN: + obj.handle_read_event() + if flags & select.POLLOUT: + obj.handle_write_event() + if flags & select.POLLPRI: + obj.handle_expt_event() + if flags & (select.POLLHUP | select.POLLERR | select.POLLNVAL): + obj.handle_close() + except socket.error, e: + if e.args[0] not in _DISCONNECTED: + obj.handle_error() + else: + obj.handle_close() + except _reraised_exceptions: + raise + except: + obj.handle_error() + +def poll(timeout=0.0, map=None): + if map is None: + map = socket_map + if map: + r = []; w = []; e = [] + for fd, obj in map.items(): + is_r = obj.readable() + is_w = obj.writable() + if is_r: + r.append(fd) + # accepting sockets should not be writable + if is_w and not obj.accepting: + w.append(fd) + if is_r or is_w: + e.append(fd) + if [] == r == w == e: + time.sleep(timeout) + return + + try: + r, w, e = select.select(r, w, e, timeout) + except select.error, err: + if err.args[0] != EINTR: + raise + else: + return + + for fd in r: + obj = map.get(fd) + if obj is None: + continue + read(obj) + + for fd in w: + obj = map.get(fd) + if obj is None: + continue + write(obj) + + for fd in e: + obj = map.get(fd) + if obj is None: + continue + _exception(obj) + +def poll2(timeout=0.0, map=None): + # Use the poll() support added to the select module in Python 2.0 + if map is None: + map = socket_map + if timeout is not None: + # timeout is in milliseconds + timeout = int(timeout*1000) + pollster = select.poll() + if map: + for fd, obj in map.items(): + flags = 0 + if obj.readable(): + flags |= select.POLLIN | select.POLLPRI + # accepting sockets should not be writable + if obj.writable() and not obj.accepting: + flags |= select.POLLOUT + if flags: + # Only check for exceptions if object was either readable + # or writable. + flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL + pollster.register(fd, flags) + try: + r = pollster.poll(timeout) + except select.error, err: + if err.args[0] != EINTR: + raise + r = [] + for fd, flags in r: + obj = map.get(fd) + if obj is None: + continue + readwrite(obj, flags) + +poll3 = poll2 # Alias for backward compatibility + +def loop(timeout=30.0, use_poll=False, map=None, count=None): + if map is None: + map = socket_map + + if use_poll and hasattr(select, 'poll'): + poll_fun = poll2 + else: + poll_fun = poll + + if count is None: + while map: + poll_fun(timeout, map) + + else: + while map and count > 0: + poll_fun(timeout, map) + count = count - 1 + +class dispatcher: + + debug = False + connected = False + accepting = False + connecting = False + closing = False + addr = None + ignore_log_types = frozenset(['warning']) + + def __init__(self, sock=None, map=None): + if map is None: + self._map = socket_map + else: + self._map = map + + self._fileno = None + + if sock: + # Set to nonblocking just to make sure for cases where we + # get a socket from a blocking source. + sock.setblocking(0) + self.set_socket(sock, map) + self.connected = True + # The constructor no longer requires that the socket + # passed be connected. + try: + self.addr = sock.getpeername() + except socket.error, err: + if err.args[0] in (ENOTCONN, EINVAL): + # To handle the case where we got an unconnected + # socket. + self.connected = False + else: + # The socket is broken in some unknown way, alert + # the user and remove it from the map (to prevent + # polling of broken sockets). + self.del_channel(map) + raise + else: + self.socket = None + + def __repr__(self): + status = [self.__class__.__module__+"."+self.__class__.__name__] + if self.accepting and self.addr: + status.append('listening') + elif self.connected: + status.append('connected') + if self.addr is not None: + try: + status.append('%s:%d' % self.addr) + except TypeError: + status.append(repr(self.addr)) + return '<%s at %#x>' % (' '.join(status), id(self)) + + __str__ = __repr__ + + def add_channel(self, map=None): + #self.log_info('adding channel %s' % self) + if map is None: + map = self._map + map[self._fileno] = self + + def del_channel(self, map=None): + fd = self._fileno + if map is None: + map = self._map + if fd in map: + #self.log_info('closing channel %d:%s' % (fd, self)) + del map[fd] + self._fileno = None + + def create_socket(self, family, type): + self.family_and_type = family, type + sock = socket.socket(family, type) + sock.setblocking(0) + self.set_socket(sock) + + def set_socket(self, sock, map=None): + self.socket = sock +## self.__dict__['socket'] = sock + self._fileno = sock.fileno() + self.add_channel(map) + + def set_reuse_addr(self): + # try to re-use a server port if possible + try: + self.socket.setsockopt( + socket.SOL_SOCKET, socket.SO_REUSEADDR, + self.socket.getsockopt(socket.SOL_SOCKET, + socket.SO_REUSEADDR) | 1 + ) + except socket.error: + pass + + # ================================================== + # predicates for select() + # these are used as filters for the lists of sockets + # to pass to select(). + # ================================================== + + def readable(self): + return True + + def writable(self): + return True + + # ================================================== + # socket object methods. + # ================================================== + + def listen(self, num): + self.accepting = True + if os.name == 'nt' and num > 5: + num = 5 + return self.socket.listen(num) + + def bind(self, addr): + self.addr = addr + return self.socket.bind(addr) + + def connect(self, address): + self.connected = False + self.connecting = True + err = self.socket.connect_ex(address) + if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) \ + or err == EINVAL and os.name in ('nt', 'ce'): + self.addr = address + return + if err in (0, EISCONN): + self.addr = address + self.handle_connect_event() + else: + raise socket.error(err, errorcode[err]) + + def accept(self): + # XXX can return either an address pair or None + try: + conn, addr = self.socket.accept() + except TypeError: + return None + except socket.error as why: + if why.args[0] in (EWOULDBLOCK, ECONNABORTED, EAGAIN): + return None + else: + raise + else: + return conn, addr + + def send(self, data): + try: + result = self.socket.send(data) + return result + except socket.error, why: + if why.args[0] == EWOULDBLOCK: + return 0 + elif why.args[0] in _DISCONNECTED: + self.handle_close() + return 0 + else: + raise + + def recv(self, buffer_size): + try: + data = self.socket.recv(buffer_size) + if not data: + # a closed connection is indicated by signaling + # a read condition, and having recv() return 0. + self.handle_close() + return '' + else: + return data + except socket.error, why: + # winsock sometimes raises ENOTCONN + if why.args[0] in _DISCONNECTED: + self.handle_close() + return '' + else: + raise + + def close(self): + self.connected = False + self.accepting = False + self.connecting = False + self.del_channel() + try: + self.socket.close() + except socket.error, why: + if why.args[0] not in (ENOTCONN, EBADF): + raise + + # cheap inheritance, used to pass all other attribute + # references to the underlying socket object. + def __getattr__(self, attr): + try: + retattr = getattr(self.socket, attr) + except AttributeError: + raise AttributeError("%s instance has no attribute '%s'" + %(self.__class__.__name__, attr)) + else: + msg = "%(me)s.%(attr)s is deprecated. Use %(me)s.socket.%(attr)s " \ + "instead." % {'me': self.__class__.__name__, 'attr':attr} + warnings.warn(msg, DeprecationWarning, stacklevel=2) + return retattr + + # log and log_info may be overridden to provide more sophisticated + # logging and warning methods. In general, log is for 'hit' logging + # and 'log_info' is for informational, warning and error logging. + + def log(self, message): + sys.stderr.write('log: %s\n' % str(message)) + + def log_info(self, message, type='info'): + if type not in self.ignore_log_types: + print '%s: %s' % (type, message) + + def handle_read_event(self): + if self.accepting: + # accepting sockets are never connected, they "spawn" new + # sockets that are connected + self.handle_accept() + elif not self.connected: + if self.connecting: + self.handle_connect_event() + self.handle_read() + else: + self.handle_read() + + def handle_connect_event(self): + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + raise socket.error(err, _strerror(err)) + self.handle_connect() + self.connected = True + self.connecting = False + + def handle_write_event(self): + if self.accepting: + # Accepting sockets shouldn't get a write event. + # We will pretend it didn't happen. + return + + if not self.connected: + if self.connecting: + self.handle_connect_event() + self.handle_write() + + def handle_expt_event(self): + # handle_expt_event() is called if there might be an error on the + # socket, or if there is OOB data + # check for the error condition first + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + # we can get here when select.select() says that there is an + # exceptional condition on the socket + # since there is an error, we'll go ahead and close the socket + # like we would in a subclassed handle_read() that received no + # data + self.handle_close() + else: + self.handle_expt() + + def handle_error(self): + nil, t, v, tbinfo = compact_traceback() + + # sometimes a user repr method will crash. + try: + self_repr = repr(self) + except: + self_repr = '<__repr__(self) failed for object at %0x>' % id(self) + + self.log_info( + 'uncaptured python exception, closing channel %s (%s:%s %s)' % ( + self_repr, + t, + v, + tbinfo + ), + 'error' + ) + self.handle_close() + + def handle_expt(self): + self.log_info('unhandled incoming priority event', 'warning') + + def handle_read(self): + self.log_info('unhandled read event', 'warning') + + def handle_write(self): + self.log_info('unhandled write event', 'warning') + + def handle_connect(self): + self.log_info('unhandled connect event', 'warning') + + def handle_accept(self): + self.log_info('unhandled accept event', 'warning') + + def handle_close(self): + self.log_info('unhandled close event', 'warning') + self.close() + +# --------------------------------------------------------------------------- +# adds simple buffered output capability, useful for simple clients. +# [for more sophisticated usage use asynchat.async_chat] +# --------------------------------------------------------------------------- + +class dispatcher_with_send(dispatcher): + + def __init__(self, sock=None, map=None): + dispatcher.__init__(self, sock, map) + self.out_buffer = '' + + def initiate_send(self): + num_sent = 0 + num_sent = dispatcher.send(self, self.out_buffer[:512]) + self.out_buffer = self.out_buffer[num_sent:] + + def handle_write(self): + self.initiate_send() + + def writable(self): + return (not self.connected) or len(self.out_buffer) + + def send(self, data): + if self.debug: + self.log_info('sending %s' % repr(data)) + self.out_buffer = self.out_buffer + data + self.initiate_send() + +# --------------------------------------------------------------------------- +# used for debugging. +# --------------------------------------------------------------------------- + +def compact_traceback(): + t, v, tb = sys.exc_info() + tbinfo = [] + if not tb: # Must have a traceback + raise AssertionError("traceback does not exist") + while tb: + tbinfo.append(( + tb.tb_frame.f_code.co_filename, + tb.tb_frame.f_code.co_name, + str(tb.tb_lineno) + )) + tb = tb.tb_next + + # just to be safe + del tb + + file, function, line = tbinfo[-1] + info = ' '.join(['[%s|%s|%s]' % x for x in tbinfo]) + return (file, function, line), t, v, info + +def close_all(map=None, ignore_all=False): + if map is None: + map = socket_map + for x in map.values(): + try: + x.close() + except OSError, x: + if x.args[0] == EBADF: + pass + elif not ignore_all: + raise + except _reraised_exceptions: + raise + except: + if not ignore_all: + raise + map.clear() + +# Asynchronous File I/O: +# +# After a little research (reading man pages on various unixen, and +# digging through the linux kernel), I've determined that select() +# isn't meant for doing asynchronous file i/o. +# Heartening, though - reading linux/mm/filemap.c shows that linux +# supports asynchronous read-ahead. So _MOST_ of the time, the data +# will be sitting in memory for us already when we go to read it. +# +# What other OS's (besides NT) support async file i/o? [VMS?] +# +# Regardless, this is useful for pipes, and stdin/stdout... + +if os.name == 'posix': + import fcntl + + class file_wrapper: + # Here we override just enough to make a file + # look like a socket for the purposes of asyncore. + # The passed fd is automatically os.dup()'d + + def __init__(self, fd): + self.fd = os.dup(fd) + + def recv(self, *args): + return os.read(self.fd, *args) + + def send(self, *args): + return os.write(self.fd, *args) + + def getsockopt(self, level, optname, buflen=None): + if (level == socket.SOL_SOCKET and + optname == socket.SO_ERROR and + not buflen): + return 0 + raise NotImplementedError("Only asyncore specific behaviour " + "implemented.") + + read = recv + write = send + + def close(self): + os.close(self.fd) + + def fileno(self): + return self.fd + + class file_dispatcher(dispatcher): + + def __init__(self, fd, map=None): + dispatcher.__init__(self, None, map) + self.connected = True + try: + fd = fd.fileno() + except AttributeError: + pass + self.set_file(fd) + # set it to non-blocking mode + flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) + + def set_file(self, fd): + self.socket = file_wrapper(fd) + self._fileno = self.socket.fileno() + self.add_channel() diff --git a/test/ok_2.7/asyncore.pyc_dis b/test/ok_2.7/asyncore.pyc_dis new file mode 100644 index 00000000..f6d9354e --- /dev/null +++ b/test/ok_2.7/asyncore.pyc_dis @@ -0,0 +1,560 @@ +# Embedded file name: /src/external-vcs/github/rocky/uncompyle6/test/ok_2.7/asyncore.py +"""Basic infrastructure for asynchronous socket service clients and servers. + +There are only two ways to have a program on a single processor do "more +than one thing at a time". Multi-threaded programming is the simplest and +most popular way to do it, but there is another very different technique, +that lets you have nearly all the advantages of multi-threading, without +actually using multiple threads. it's really only practical if your program +is largely I/O bound. If your program is CPU bound, then pre-emptive +scheduled threads are probably what you really need. Network servers are +rarely CPU-bound, however. + +If your operating system supports the select() system call in its I/O +library (and nearly all do), then you can use it to juggle multiple +communication channels at once; doing other work while your I/O is taking +place in the "background." Although this strategy can seem strange and +complex, especially at first, it is in many ways easier to understand and +control than multi-threaded programming. The module documented here solves +many of the difficult problems for you, making the task of building +sophisticated high-performance network servers and clients a snap. +""" +import select +import socket +import sys +import time +import warnings +import os +from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, EINVAL, ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, ECONNABORTED, EPIPE, EAGAIN, errorcode +_DISCONNECTED = frozenset((ECONNRESET, + ENOTCONN, + ESHUTDOWN, + ECONNABORTED, + EPIPE, + EBADF)) +try: + socket_map +except NameError: + socket_map = {} + +def _strerror(err): + try: + return os.strerror(err) + except (ValueError, OverflowError, NameError): + if err in errorcode: + return errorcode[err] + return 'Unknown error %s' % err + + +class ExitNow(Exception): + pass + + +_reraised_exceptions = (ExitNow, KeyboardInterrupt, SystemExit) + +def read(obj): + try: + obj.handle_read_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + + +def write(obj): + try: + obj.handle_write_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + + +def _exception(obj): + try: + obj.handle_expt_event() + except _reraised_exceptions: + raise + except: + obj.handle_error() + + +def readwrite(obj, flags): + try: + if flags & select.POLLIN: + obj.handle_read_event() + if flags & select.POLLOUT: + obj.handle_write_event() + if flags & select.POLLPRI: + obj.handle_expt_event() + if flags & (select.POLLHUP | select.POLLERR | select.POLLNVAL): + obj.handle_close() + except socket.error as e: + if e.args[0] not in _DISCONNECTED: + obj.handle_error() + else: + obj.handle_close() + except _reraised_exceptions: + raise + except: + obj.handle_error() + + +def poll(timeout = 0.0, map = None): + if map is None: + map = socket_map + if map: + r = [] + w = [] + e = [] + for fd, obj in map.items(): + is_r = obj.readable() + is_w = obj.writable() + if is_r: + r.append(fd) + if is_w and not obj.accepting: + w.append(fd) + if is_r or is_w: + e.append(fd) + + if [] == r == w == e: + time.sleep(timeout) + return + try: + r, w, e = select.select(r, w, e, timeout) + except select.error as err: + if err.args[0] != EINTR: + raise + else: + return + + for fd in r: + obj = map.get(fd) + if obj is None: + continue + read(obj) + + for fd in w: + obj = map.get(fd) + if obj is None: + continue + write(obj) + + for fd in e: + obj = map.get(fd) + if obj is None: + continue + _exception(obj) + + return + + +def poll2(timeout = 0.0, map = None): + if map is None: + map = socket_map + if timeout is not None: + timeout = int(timeout * 1000) + pollster = select.poll() + if map: + for fd, obj in map.items(): + flags = 0 + if obj.readable(): + flags |= select.POLLIN | select.POLLPRI + if obj.writable() and not obj.accepting: + flags |= select.POLLOUT + if flags: + flags |= select.POLLERR | select.POLLHUP | select.POLLNVAL + pollster.register(fd, flags) + + try: + r = pollster.poll(timeout) + except select.error as err: + if err.args[0] != EINTR: + raise + r = [] + + for fd, flags in r: + obj = map.get(fd) + if obj is None: + continue + readwrite(obj, flags) + + return + + +poll3 = poll2 + +def loop(timeout = 30.0, use_poll = False, map = None, count = None): + if map is None: + map = socket_map + if use_poll and hasattr(select, 'poll'): + poll_fun = poll2 + else: + poll_fun = poll + if count is None: + while map: + poll_fun(timeout, map) + + else: + while map and count > 0: + poll_fun(timeout, map) + count = count - 1 + + return + + +class dispatcher(): + debug = False + connected = False + accepting = False + connecting = False + closing = False + addr = None + ignore_log_types = frozenset(['warning']) + + def __init__(self, sock = None, map = None): + if map is None: + self._map = socket_map + else: + self._map = map + self._fileno = None + if sock: + sock.setblocking(0) + self.set_socket(sock, map) + self.connected = True + try: + self.addr = sock.getpeername() + except socket.error as err: + if err.args[0] in (ENOTCONN, EINVAL): + self.connected = False + else: + self.del_channel(map) + raise + + else: + self.socket = None + return + + def __repr__(self): + status = [self.__class__.__module__ + '.' + self.__class__.__name__] + if self.accepting and self.addr: + status.append('listening') + elif self.connected: + status.append('connected') + if self.addr is not None: + try: + status.append('%s:%d' % self.addr) + except TypeError: + status.append(repr(self.addr)) + + return '<%s at %#x>' % (' '.join(status), id(self)) + + __str__ = __repr__ + + def add_channel(self, map = None): + if map is None: + map = self._map + map[self._fileno] = self + return + + def del_channel(self, map = None): + fd = self._fileno + if map is None: + map = self._map + if fd in map: + del map[fd] + self._fileno = None + return + + def create_socket(self, family, type): + self.family_and_type = (family, type) + sock = socket.socket(family, type) + sock.setblocking(0) + self.set_socket(sock) + + def set_socket(self, sock, map = None): + self.socket = sock + self._fileno = sock.fileno() + self.add_channel(map) + + def set_reuse_addr(self): + try: + self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR) | 1) + except socket.error: + pass + + def readable(self): + return True + + def writable(self): + return True + + def listen(self, num): + self.accepting = True + if os.name == 'nt' and num > 5: + num = 5 + return self.socket.listen(num) + + def bind(self, addr): + self.addr = addr + return self.socket.bind(addr) + + def connect(self, address): + self.connected = False + self.connecting = True + err = self.socket.connect_ex(address) + if err in (EINPROGRESS, EALREADY, EWOULDBLOCK) or err == EINVAL and os.name in ('nt', 'ce'): + self.addr = address + return + if err in (0, EISCONN): + self.addr = address + self.handle_connect_event() + else: + raise socket.error(err, errorcode[err]) + + def accept(self): + try: + conn, addr = self.socket.accept() + except TypeError: + return None + except socket.error as why: + if why.args[0] in (EWOULDBLOCK, ECONNABORTED, EAGAIN): + return None + raise + else: + return (conn, addr) + + return None + + def send(self, data): + try: + result = self.socket.send(data) + return result + except socket.error as why: + if why.args[0] == EWOULDBLOCK: + return 0 + if why.args[0] in _DISCONNECTED: + self.handle_close() + return 0 + raise + + def recv(self, buffer_size): + try: + data = self.socket.recv(buffer_size) + if not data: + self.handle_close() + return '' + return data + except socket.error as why: + if why.args[0] in _DISCONNECTED: + self.handle_close() + return '' + raise + + def close(self): + self.connected = False + self.accepting = False + self.connecting = False + self.del_channel() + try: + self.socket.close() + except socket.error as why: + if why.args[0] not in (ENOTCONN, EBADF): + raise + + def __getattr__(self, attr): + try: + retattr = getattr(self.socket, attr) + except AttributeError: + raise AttributeError("%s instance has no attribute '%s'" % (self.__class__.__name__, attr)) + else: + msg = '%(me)s.%(attr)s is deprecated. Use %(me)s.socket.%(attr)s instead.' % {'me': self.__class__.__name__, + 'attr': attr} + warnings.warn(msg, DeprecationWarning, stacklevel=2) + return retattr + + def log(self, message): + sys.stderr.write('log: %s\n' % str(message)) + + def log_info(self, message, type = 'info'): + if type not in self.ignore_log_types: + print '%s: %s' % (type, message) + + def handle_read_event(self): + if self.accepting: + self.handle_accept() + elif not self.connected: + if self.connecting: + self.handle_connect_event() + self.handle_read() + else: + self.handle_read() + + def handle_connect_event(self): + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + raise socket.error(err, _strerror(err)) + self.handle_connect() + self.connected = True + self.connecting = False + + def handle_write_event(self): + if self.accepting: + return + if not self.connected: + if self.connecting: + self.handle_connect_event() + self.handle_write() + + def handle_expt_event(self): + err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR) + if err != 0: + self.handle_close() + else: + self.handle_expt() + + def handle_error(self): + nil, t, v, tbinfo = compact_traceback() + try: + self_repr = repr(self) + except: + self_repr = '<__repr__(self) failed for object at %0x>' % id(self) + + self.log_info('uncaptured python exception, closing channel %s (%s:%s %s)' % (self_repr, + t, + v, + tbinfo), 'error') + self.handle_close() + + def handle_expt(self): + self.log_info('unhandled incoming priority event', 'warning') + + def handle_read(self): + self.log_info('unhandled read event', 'warning') + + def handle_write(self): + self.log_info('unhandled write event', 'warning') + + def handle_connect(self): + self.log_info('unhandled connect event', 'warning') + + def handle_accept(self): + self.log_info('unhandled accept event', 'warning') + + def handle_close(self): + self.log_info('unhandled close event', 'warning') + self.close() + + +class dispatcher_with_send(dispatcher): + + def __init__(self, sock = None, map = None): + dispatcher.__init__(self, sock, map) + self.out_buffer = '' + + def initiate_send(self): + num_sent = 0 + num_sent = dispatcher.send(self, self.out_buffer[:512]) + self.out_buffer = self.out_buffer[num_sent:] + + def handle_write(self): + self.initiate_send() + + def writable(self): + return not self.connected or len(self.out_buffer) + + def send(self, data): + if self.debug: + self.log_info('sending %s' % repr(data)) + self.out_buffer = self.out_buffer + data + self.initiate_send() + + +def compact_traceback(): + t, v, tb = sys.exc_info() + tbinfo = [] + if not tb: + raise AssertionError('traceback does not exist') + while tb: + tbinfo.append((tb.tb_frame.f_code.co_filename, tb.tb_frame.f_code.co_name, str(tb.tb_lineno))) + tb = tb.tb_next + + del tb + file, function, line = tbinfo[-1] + info = ' '.join([ '[%s|%s|%s]' % x for x in tbinfo ]) + return ((file, function, line), + t, + v, + info) + + +def close_all(map = None, ignore_all = False): + if map is None: + map = socket_map + for x in map.values(): + try: + x.close() + except OSError as x: + if x.args[0] == EBADF: + pass + elif not ignore_all: + raise + except _reraised_exceptions: + raise + except: + if not ignore_all: + raise + + map.clear() + return + + +if os.name == 'posix': + import fcntl + + class file_wrapper(): + + def __init__(self, fd): + self.fd = os.dup(fd) + + def recv(self, *args): + return os.read(self.fd, *args) + + def send(self, *args): + return os.write(self.fd, *args) + + def getsockopt(self, level, optname, buflen = None): + if level == socket.SOL_SOCKET and optname == socket.SO_ERROR and not buflen: + return 0 + raise NotImplementedError('Only asyncore specific behaviour implemented.') + + read = recv + write = send + + def close(self): + os.close(self.fd) + + def fileno(self): + return self.fd + + + class file_dispatcher(dispatcher): + + def __init__(self, fd, map = None): + dispatcher.__init__(self, None, map) + self.connected = True + try: + fd = fd.fileno() + except AttributeError: + pass + + self.set_file(fd) + flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0) + flags = flags | os.O_NONBLOCK + fcntl.fcntl(fd, fcntl.F_SETFL, flags) + return + + def set_file(self, fd): + self.socket = file_wrapper(fd) + self._fileno = self.socket.fileno() + self.add_channel() \ No newline at end of file diff --git a/test/ok_2.7/atexit.py b/test/ok_2.7/atexit.py new file mode 100644 index 00000000..93fddf7f --- /dev/null +++ b/test/ok_2.7/atexit.py @@ -0,0 +1,65 @@ +""" +atexit.py - allow programmer to define multiple exit functions to be executed +upon normal program termination. + +One public function, register, is defined. +""" + +__all__ = ["register"] + +import sys + +_exithandlers = [] +def _run_exitfuncs(): + """run any registered exit functions + + _exithandlers is traversed in reverse order so functions are executed + last in, first out. + """ + + exc_info = None + while _exithandlers: + func, targs, kargs = _exithandlers.pop() + try: + func(*targs, **kargs) + except SystemExit: + exc_info = sys.exc_info() + except: + import traceback + print >> sys.stderr, "Error in atexit._run_exitfuncs:" + traceback.print_exc() + exc_info = sys.exc_info() + + if exc_info is not None: + raise exc_info[0], exc_info[1], exc_info[2] + + +def register(func, *targs, **kargs): + """register a function to be executed upon normal program termination + + func - function to be called at exit + targs - optional arguments to pass to func + kargs - optional keyword arguments to pass to func + + func is returned to facilitate usage as a decorator. + """ + _exithandlers.append((func, targs, kargs)) + return func + +if hasattr(sys, "exitfunc"): + # Assume it's another registered exit function - append it to our list + register(sys.exitfunc) +sys.exitfunc = _run_exitfuncs + +if __name__ == "__main__": + def x1(): + print "running x1" + def x2(n): + print "running x2(%r)" % (n,) + def x3(n, kwd=None): + print "running x3(%r, kwd=%r)" % (n, kwd) + + register(x1) + register(x2, 12) + register(x3, 5, "bar") + register(x3, "no kwd args") diff --git a/test/ok_2.7/atexit.pyc_dis b/test/ok_2.7/atexit.pyc_dis new file mode 100644 index 00000000..d86ecc27 --- /dev/null +++ b/test/ok_2.7/atexit.pyc_dis @@ -0,0 +1,69 @@ +# Embedded file name: /src/external-vcs/github/rocky/uncompyle6/test/ok_2.7/atexit.py +""" +atexit.py - allow programmer to define multiple exit functions to be executed +upon normal program termination. + +One public function, register, is defined. +""" +__all__ = ['register'] +import sys +_exithandlers = [] + +def _run_exitfuncs(): + """run any registered exit functions + + _exithandlers is traversed in reverse order so functions are executed + last in, first out. + """ + exc_info = None + while _exithandlers: + func, targs, kargs = _exithandlers.pop() + try: + func(*targs, **kargs) + except SystemExit: + exc_info = sys.exc_info() + except: + import traceback + print >> sys.stderr, 'Error in atexit._run_exitfuncs:' + traceback.print_exc() + exc_info = sys.exc_info() + + if exc_info is not None: + raise exc_info[0], exc_info[1], exc_info[2] + return + + +def register(func, *targs, **kargs): + """register a function to be executed upon normal program termination + + func - function to be called at exit + targs - optional arguments to pass to func + kargs - optional keyword arguments to pass to func + + func is returned to facilitate usage as a decorator. + """ + _exithandlers.append((func, targs, kargs)) + return func + + +if hasattr(sys, 'exitfunc'): + register(sys.exitfunc) +sys.exitfunc = _run_exitfuncs +if __name__ == '__main__': + + def x1(): + print 'running x1' + + + def x2(n): + print 'running x2(%r)' % (n,) + + + def x3(n, kwd = None): + print 'running x3(%r, kwd=%r)' % (n, kwd) + + + register(x1) + register(x2, 12) + register(x3, 5, 'bar') + register(x3, 'no kwd args') \ No newline at end of file diff --git a/test/ok_2.7/audiodev.py b/test/ok_2.7/audiodev.py new file mode 100644 index 00000000..b6831a69 --- /dev/null +++ b/test/ok_2.7/audiodev.py @@ -0,0 +1,260 @@ +"""Classes for manipulating audio devices (currently only for Sun and SGI)""" +from warnings import warnpy3k +warnpy3k("the audiodev module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +__all__ = ["error","AudioDev"] + +class error(Exception): + pass + +class Play_Audio_sgi: + # Private instance variables +## if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \ +## params, config, inited_outrate, inited_width, \ +## inited_nchannels, port, converter, classinited: private + + classinited = 0 + frameratelist = nchannelslist = sampwidthlist = None + + def initclass(self): + import AL + self.frameratelist = [ + (48000, AL.RATE_48000), + (44100, AL.RATE_44100), + (32000, AL.RATE_32000), + (22050, AL.RATE_22050), + (16000, AL.RATE_16000), + (11025, AL.RATE_11025), + ( 8000, AL.RATE_8000), + ] + self.nchannelslist = [ + (1, AL.MONO), + (2, AL.STEREO), + (4, AL.QUADRO), + ] + self.sampwidthlist = [ + (1, AL.SAMPLE_8), + (2, AL.SAMPLE_16), + (3, AL.SAMPLE_24), + ] + self.classinited = 1 + + def __init__(self): + import al, AL + if not self.classinited: + self.initclass() + self.oldparams = [] + self.params = [AL.OUTPUT_RATE, 0] + self.config = al.newconfig() + self.inited_outrate = 0 + self.inited_width = 0 + self.inited_nchannels = 0 + self.converter = None + self.port = None + return + + def __del__(self): + if self.port: + self.stop() + if self.oldparams: + import al, AL + al.setparams(AL.DEFAULT_DEVICE, self.oldparams) + self.oldparams = [] + + def wait(self): + if not self.port: + return + import time + while self.port.getfilled() > 0: + time.sleep(0.1) + self.stop() + + def stop(self): + if self.port: + self.port.closeport() + self.port = None + if self.oldparams: + import al, AL + al.setparams(AL.DEFAULT_DEVICE, self.oldparams) + self.oldparams = [] + + def setoutrate(self, rate): + for (raw, cooked) in self.frameratelist: + if rate == raw: + self.params[1] = cooked + self.inited_outrate = 1 + break + else: + raise error, 'bad output rate' + + def setsampwidth(self, width): + for (raw, cooked) in self.sampwidthlist: + if width == raw: + self.config.setwidth(cooked) + self.inited_width = 1 + break + else: + if width == 0: + import AL + self.inited_width = 0 + self.config.setwidth(AL.SAMPLE_16) + self.converter = self.ulaw2lin + else: + raise error, 'bad sample width' + + def setnchannels(self, nchannels): + for (raw, cooked) in self.nchannelslist: + if nchannels == raw: + self.config.setchannels(cooked) + self.inited_nchannels = 1 + break + else: + raise error, 'bad # of channels' + + def writeframes(self, data): + if not (self.inited_outrate and self.inited_nchannels): + raise error, 'params not specified' + if not self.port: + import al, AL + self.port = al.openport('Python', 'w', self.config) + self.oldparams = self.params[:] + al.getparams(AL.DEFAULT_DEVICE, self.oldparams) + al.setparams(AL.DEFAULT_DEVICE, self.params) + if self.converter: + data = self.converter(data) + self.port.writesamps(data) + + def getfilled(self): + if self.port: + return self.port.getfilled() + else: + return 0 + + def getfillable(self): + if self.port: + return self.port.getfillable() + else: + return self.config.getqueuesize() + + # private methods +## if 0: access *: private + + def ulaw2lin(self, data): + import audioop + return audioop.ulaw2lin(data, 2) + +class Play_Audio_sun: +## if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \ +## inited_nchannels, converter: private + + def __init__(self): + self.outrate = 0 + self.sampwidth = 0 + self.nchannels = 0 + self.inited_outrate = 0 + self.inited_width = 0 + self.inited_nchannels = 0 + self.converter = None + self.port = None + return + + def __del__(self): + self.stop() + + def setoutrate(self, rate): + self.outrate = rate + self.inited_outrate = 1 + + def setsampwidth(self, width): + self.sampwidth = width + self.inited_width = 1 + + def setnchannels(self, nchannels): + self.nchannels = nchannels + self.inited_nchannels = 1 + + def writeframes(self, data): + if not (self.inited_outrate and self.inited_width and self.inited_nchannels): + raise error, 'params not specified' + if not self.port: + import sunaudiodev, SUNAUDIODEV + self.port = sunaudiodev.open('w') + info = self.port.getinfo() + info.o_sample_rate = self.outrate + info.o_channels = self.nchannels + if self.sampwidth == 0: + info.o_precision = 8 + self.o_encoding = SUNAUDIODEV.ENCODING_ULAW + # XXX Hack, hack -- leave defaults + else: + info.o_precision = 8 * self.sampwidth + info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR + self.port.setinfo(info) + if self.converter: + data = self.converter(data) + self.port.write(data) + + def wait(self): + if not self.port: + return + self.port.drain() + self.stop() + + def stop(self): + if self.port: + self.port.flush() + self.port.close() + self.port = None + + def getfilled(self): + if self.port: + return self.port.obufcount() + else: + return 0 + +## # Nobody remembers what this method does, and it's broken. :-( +## def getfillable(self): +## return BUFFERSIZE - self.getfilled() + +def AudioDev(): + # Dynamically try to import and use a platform specific module. + try: + import al + except ImportError: + try: + import sunaudiodev + return Play_Audio_sun() + except ImportError: + try: + import Audio_mac + except ImportError: + raise error, 'no audio device' + else: + return Audio_mac.Play_Audio_mac() + else: + return Play_Audio_sgi() + +def test(fn = None): + import sys + if sys.argv[1:]: + fn = sys.argv[1] + else: + fn = 'f:just samples:just.aif' + import aifc + af = aifc.open(fn, 'r') + print fn, af.getparams() + p = AudioDev() + p.setoutrate(af.getframerate()) + p.setsampwidth(af.getsampwidth()) + p.setnchannels(af.getnchannels()) + BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels() + while 1: + data = af.readframes(BUFSIZ) + if not data: break + print len(data) + p.writeframes(data) + p.wait() + +if __name__ == '__main__': + test() diff --git a/test/ok_2.7/audiodev.pyc_dis b/test/ok_2.7/audiodev.pyc_dis new file mode 100644 index 00000000..701f8216 --- /dev/null +++ b/test/ok_2.7/audiodev.pyc_dis @@ -0,0 +1,245 @@ +# Embedded file name: /src/external-vcs/github/rocky/uncompyle6/test/ok_2.7/audiodev.py +"""Classes for manipulating audio devices (currently only for Sun and SGI)""" +from warnings import warnpy3k +warnpy3k('the audiodev module has been removed in Python 3.0', stacklevel=2) +del warnpy3k +__all__ = ['error', 'AudioDev'] + +class error(Exception): + pass + + +class Play_Audio_sgi: + classinited = 0 + frameratelist = nchannelslist = sampwidthlist = None + + def initclass(self): + import AL + self.frameratelist = [(48000, AL.RATE_48000), + (44100, AL.RATE_44100), + (32000, AL.RATE_32000), + (22050, AL.RATE_22050), + (16000, AL.RATE_16000), + (11025, AL.RATE_11025), + (8000, AL.RATE_8000)] + self.nchannelslist = [(1, AL.MONO), (2, AL.STEREO), (4, AL.QUADRO)] + self.sampwidthlist = [(1, AL.SAMPLE_8), (2, AL.SAMPLE_16), (3, AL.SAMPLE_24)] + self.classinited = 1 + + def __init__(self): + import al, AL + if not self.classinited: + self.initclass() + self.oldparams = [] + self.params = [AL.OUTPUT_RATE, 0] + self.config = al.newconfig() + self.inited_outrate = 0 + self.inited_width = 0 + self.inited_nchannels = 0 + self.converter = None + self.port = None + return + + def __del__(self): + if self.port: + self.stop() + if self.oldparams: + import al, AL + al.setparams(AL.DEFAULT_DEVICE, self.oldparams) + self.oldparams = [] + + def wait(self): + if not self.port: + return + import time + while self.port.getfilled() > 0: + time.sleep(0.1) + + self.stop() + + def stop(self): + if self.port: + self.port.closeport() + self.port = None + if self.oldparams: + import al, AL + al.setparams(AL.DEFAULT_DEVICE, self.oldparams) + self.oldparams = [] + return + + def setoutrate(self, rate): + for raw, cooked in self.frameratelist: + if rate == raw: + self.params[1] = cooked + self.inited_outrate = 1 + break + else: + raise error, 'bad output rate' + + def setsampwidth(self, width): + for raw, cooked in self.sampwidthlist: + if width == raw: + self.config.setwidth(cooked) + self.inited_width = 1 + break + else: + if width == 0: + import AL + self.inited_width = 0 + self.config.setwidth(AL.SAMPLE_16) + self.converter = self.ulaw2lin + else: + raise error, 'bad sample width' + + def setnchannels(self, nchannels): + for raw, cooked in self.nchannelslist: + if nchannels == raw: + self.config.setchannels(cooked) + self.inited_nchannels = 1 + break + else: + raise error, 'bad # of channels' + + def writeframes(self, data): + if not (self.inited_outrate and self.inited_nchannels): + raise error, 'params not specified' + if not self.port: + import al, AL + self.port = al.openport('Python', 'w', self.config) + self.oldparams = self.params[:] + al.getparams(AL.DEFAULT_DEVICE, self.oldparams) + al.setparams(AL.DEFAULT_DEVICE, self.params) + if self.converter: + data = self.converter(data) + self.port.writesamps(data) + + def getfilled(self): + if self.port: + return self.port.getfilled() + else: + return 0 + + def getfillable(self): + if self.port: + return self.port.getfillable() + else: + return self.config.getqueuesize() + + def ulaw2lin(self, data): + import audioop + return audioop.ulaw2lin(data, 2) + + +class Play_Audio_sun: + + def __init__(self): + self.outrate = 0 + self.sampwidth = 0 + self.nchannels = 0 + self.inited_outrate = 0 + self.inited_width = 0 + self.inited_nchannels = 0 + self.converter = None + self.port = None + return + + def __del__(self): + self.stop() + + def setoutrate(self, rate): + self.outrate = rate + self.inited_outrate = 1 + + def setsampwidth(self, width): + self.sampwidth = width + self.inited_width = 1 + + def setnchannels(self, nchannels): + self.nchannels = nchannels + self.inited_nchannels = 1 + + def writeframes(self, data): + if not (self.inited_outrate and self.inited_width and self.inited_nchannels): + raise error, 'params not specified' + if not self.port: + import sunaudiodev, SUNAUDIODEV + self.port = sunaudiodev.open('w') + info = self.port.getinfo() + info.o_sample_rate = self.outrate + info.o_channels = self.nchannels + if self.sampwidth == 0: + info.o_precision = 8 + self.o_encoding = SUNAUDIODEV.ENCODING_ULAW + else: + info.o_precision = 8 * self.sampwidth + info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR + self.port.setinfo(info) + if self.converter: + data = self.converter(data) + self.port.write(data) + + def wait(self): + if not self.port: + return + self.port.drain() + self.stop() + + def stop(self): + if self.port: + self.port.flush() + self.port.close() + self.port = None + return + + def getfilled(self): + if self.port: + return self.port.obufcount() + else: + return 0 + + +def AudioDev(): + try: + import al + except ImportError: + try: + import sunaudiodev + return Play_Audio_sun() + except ImportError: + try: + import Audio_mac + except ImportError: + raise error, 'no audio device' + else: + return Audio_mac.Play_Audio_mac() + + else: + return Play_Audio_sgi() + + +def test(fn = None): + import sys + if sys.argv[1:]: + fn = sys.argv[1] + else: + fn = 'f:just samples:just.aif' + import aifc + af = aifc.open(fn, 'r') + print fn, af.getparams() + p = AudioDev() + p.setoutrate(af.getframerate()) + p.setsampwidth(af.getsampwidth()) + p.setnchannels(af.getnchannels()) + BUFSIZ = af.getframerate() / af.getsampwidth() / af.getnchannels() + while 1: + data = af.readframes(BUFSIZ) + if not data: + break + print len(data) + p.writeframes(data) + + p.wait() + + +if __name__ == '__main__': + test() \ No newline at end of file diff --git a/test/ok_2.7/base64.py b/test/ok_2.7/base64.py new file mode 100755 index 00000000..041d9d13 --- /dev/null +++ b/test/ok_2.7/base64.py @@ -0,0 +1,360 @@ +#! /usr/bin/python2.7 + +"""RFC 3548: Base16, Base32, Base64 Data Encodings""" + +# Modified 04-Oct-1995 by Jack Jansen to use binascii module +# Modified 30-Dec-2003 by Barry Warsaw to add full RFC 3548 support + +import re +import struct +import binascii + + +__all__ = [ + # Legacy interface exports traditional RFC 1521 Base64 encodings + 'encode', 'decode', 'encodestring', 'decodestring', + # Generalized interface for other encodings + 'b64encode', 'b64decode', 'b32encode', 'b32decode', + 'b16encode', 'b16decode', + # Standard Base64 encoding + 'standard_b64encode', 'standard_b64decode', + # Some common Base64 alternatives. As referenced by RFC 3458, see thread + # starting at: + # + # http://zgp.org/pipermail/p2p-hackers/2001-September/000316.html + 'urlsafe_b64encode', 'urlsafe_b64decode', + ] + +_translation = [chr(_x) for _x in range(256)] +EMPTYSTRING = '' + + +def _translate(s, altchars): + translation = _translation[:] + for k, v in altchars.items(): + translation[ord(k)] = v + return s.translate(''.join(translation)) + + + +# Base64 encoding/decoding uses binascii + +def b64encode(s, altchars=None): + """Encode a string using Base64. + + s is the string to encode. Optional altchars must be a string of at least + length 2 (additional characters are ignored) which specifies an + alternative alphabet for the '+' and '/' characters. This allows an + application to e.g. generate url or filesystem safe Base64 strings. + + The encoded string is returned. + """ + # Strip off the trailing newline + encoded = binascii.b2a_base64(s)[:-1] + if altchars is not None: + return _translate(encoded, {'+': altchars[0], '/': altchars[1]}) + return encoded + + +def b64decode(s, altchars=None): + """Decode a Base64 encoded string. + + s is the string to decode. Optional altchars must be a string of at least + length 2 (additional characters are ignored) which specifies the + alternative alphabet used instead of the '+' and '/' characters. + + The decoded string is returned. A TypeError is raised if s were + incorrectly padded or if there are non-alphabet characters present in the + string. + """ + if altchars is not None: + s = _translate(s, {altchars[0]: '+', altchars[1]: '/'}) + try: + return binascii.a2b_base64(s) + except binascii.Error, msg: + # Transform this exception for consistency + raise TypeError(msg) + + +def standard_b64encode(s): + """Encode a string using the standard Base64 alphabet. + + s is the string to encode. The encoded string is returned. + """ + return b64encode(s) + +def standard_b64decode(s): + """Decode a string encoded with the standard Base64 alphabet. + + s is the string to decode. The decoded string is returned. A TypeError + is raised if the string is incorrectly padded or if there are non-alphabet + characters present in the string. + """ + return b64decode(s) + +def urlsafe_b64encode(s): + """Encode a string using a url-safe Base64 alphabet. + + s is the string to encode. The encoded string is returned. The alphabet + uses '-' instead of '+' and '_' instead of '/'. + """ + return b64encode(s, '-_') + +def urlsafe_b64decode(s): + """Decode a string encoded with the standard Base64 alphabet. + + s is the string to decode. The decoded string is returned. A TypeError + is raised if the string is incorrectly padded or if there are non-alphabet + characters present in the string. + + The alphabet uses '-' instead of '+' and '_' instead of '/'. + """ + return b64decode(s, '-_') + + + +# Base32 encoding/decoding must be done in Python +_b32alphabet = { + 0: 'A', 9: 'J', 18: 'S', 27: '3', + 1: 'B', 10: 'K', 19: 'T', 28: '4', + 2: 'C', 11: 'L', 20: 'U', 29: '5', + 3: 'D', 12: 'M', 21: 'V', 30: '6', + 4: 'E', 13: 'N', 22: 'W', 31: '7', + 5: 'F', 14: 'O', 23: 'X', + 6: 'G', 15: 'P', 24: 'Y', + 7: 'H', 16: 'Q', 25: 'Z', + 8: 'I', 17: 'R', 26: '2', + } + +_b32tab = _b32alphabet.items() +_b32tab.sort() +_b32tab = [v for k, v in _b32tab] +_b32rev = dict([(v, long(k)) for k, v in _b32alphabet.items()]) + + +def b32encode(s): + """Encode a string using Base32. + + s is the string to encode. The encoded string is returned. + """ + parts = [] + quanta, leftover = divmod(len(s), 5) + # Pad the last quantum with zero bits if necessary + if leftover: + s += ('\0' * (5 - leftover)) + quanta += 1 + for i in range(quanta): + # c1 and c2 are 16 bits wide, c3 is 8 bits wide. The intent of this + # code is to process the 40 bits in units of 5 bits. So we take the 1 + # leftover bit of c1 and tack it onto c2. Then we take the 2 leftover + # bits of c2 and tack them onto c3. The shifts and masks are intended + # to give us values of exactly 5 bits in width. + c1, c2, c3 = struct.unpack('!HHB', s[i*5:(i+1)*5]) + c2 += (c1 & 1) << 16 # 17 bits wide + c3 += (c2 & 3) << 8 # 10 bits wide + parts.extend([_b32tab[c1 >> 11], # bits 1 - 5 + _b32tab[(c1 >> 6) & 0x1f], # bits 6 - 10 + _b32tab[(c1 >> 1) & 0x1f], # bits 11 - 15 + _b32tab[c2 >> 12], # bits 16 - 20 (1 - 5) + _b32tab[(c2 >> 7) & 0x1f], # bits 21 - 25 (6 - 10) + _b32tab[(c2 >> 2) & 0x1f], # bits 26 - 30 (11 - 15) + _b32tab[c3 >> 5], # bits 31 - 35 (1 - 5) + _b32tab[c3 & 0x1f], # bits 36 - 40 (1 - 5) + ]) + encoded = EMPTYSTRING.join(parts) + # Adjust for any leftover partial quanta + if leftover == 1: + return encoded[:-6] + '======' + elif leftover == 2: + return encoded[:-4] + '====' + elif leftover == 3: + return encoded[:-3] + '===' + elif leftover == 4: + return encoded[:-1] + '=' + return encoded + + +def b32decode(s, casefold=False, map01=None): + """Decode a Base32 encoded string. + + s is the string to decode. Optional casefold is a flag specifying whether + a lowercase alphabet is acceptable as input. For security purposes, the + default is False. + + RFC 3548 allows for optional mapping of the digit 0 (zero) to the letter O + (oh), and for optional mapping of the digit 1 (one) to either the letter I + (eye) or letter L (el). The optional argument map01 when not None, + specifies which letter the digit 1 should be mapped to (when map01 is not + None, the digit 0 is always mapped to the letter O). For security + purposes the default is None, so that 0 and 1 are not allowed in the + input. + + The decoded string is returned. A TypeError is raised if s were + incorrectly padded or if there are non-alphabet characters present in the + string. + """ + quanta, leftover = divmod(len(s), 8) + if leftover: + raise TypeError('Incorrect padding') + # Handle section 2.4 zero and one mapping. The flag map01 will be either + # False, or the character to map the digit 1 (one) to. It should be + # either L (el) or I (eye). + if map01: + s = _translate(s, {'0': 'O', '1': map01}) + if casefold: + s = s.upper() + # Strip off pad characters from the right. We need to count the pad + # characters because this will tell us how many null bytes to remove from + # the end of the decoded string. + padchars = 0 + mo = re.search('(?P[=]*)$', s) + if mo: + padchars = len(mo.group('pad')) + if padchars > 0: + s = s[:-padchars] + # Now decode the full quanta + parts = [] + acc = 0 + shift = 35 + for c in s: + val = _b32rev.get(c) + if val is None: + raise TypeError('Non-base32 digit found') + acc += _b32rev[c] << shift + shift -= 5 + if shift < 0: + parts.append(binascii.unhexlify('%010x' % acc)) + acc = 0 + shift = 35 + # Process the last, partial quanta + last = binascii.unhexlify('%010x' % acc) + if padchars == 0: + last = '' # No characters + elif padchars == 1: + last = last[:-1] + elif padchars == 3: + last = last[:-2] + elif padchars == 4: + last = last[:-3] + elif padchars == 6: + last = last[:-4] + else: + raise TypeError('Incorrect padding') + parts.append(last) + return EMPTYSTRING.join(parts) + + + +# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns +# lowercase. The RFC also recommends against accepting input case +# insensitively. +def b16encode(s): + """Encode a string using Base16. + + s is the string to encode. The encoded string is returned. + """ + return binascii.hexlify(s).upper() + + +def b16decode(s, casefold=False): + """Decode a Base16 encoded string. + + s is the string to decode. Optional casefold is a flag specifying whether + a lowercase alphabet is acceptable as input. For security purposes, the + default is False. + + The decoded string is returned. A TypeError is raised if s were + incorrectly padded or if there are non-alphabet characters present in the + string. + """ + if casefold: + s = s.upper() + if re.search('[^0-9A-F]', s): + raise TypeError('Non-base16 digit found') + return binascii.unhexlify(s) + + + +# Legacy interface. This code could be cleaned up since I don't believe +# binascii has any line length limitations. It just doesn't seem worth it +# though. + +MAXLINESIZE = 76 # Excluding the CRLF +MAXBINSIZE = (MAXLINESIZE//4)*3 + +def encode(input, output): + """Encode a file.""" + while True: + s = input.read(MAXBINSIZE) + if not s: + break + while len(s) < MAXBINSIZE: + ns = input.read(MAXBINSIZE-len(s)) + if not ns: + break + s += ns + line = binascii.b2a_base64(s) + output.write(line) + + +def decode(input, output): + """Decode a file.""" + while True: + line = input.readline() + if not line: + break + s = binascii.a2b_base64(line) + output.write(s) + + +def encodestring(s): + """Encode a string into multiple lines of base-64 data.""" + pieces = [] + for i in range(0, len(s), MAXBINSIZE): + chunk = s[i : i + MAXBINSIZE] + pieces.append(binascii.b2a_base64(chunk)) + return "".join(pieces) + + +def decodestring(s): + """Decode a string.""" + return binascii.a2b_base64(s) + + + +# Useable as a script... +def test(): + """Small test program""" + import sys, getopt + try: + opts, args = getopt.getopt(sys.argv[1:], 'deut') + except getopt.error, msg: + sys.stdout = sys.stderr + print msg + print """usage: %s [-d|-e|-u|-t] [file|-] + -d, -u: decode + -e: encode (default) + -t: encode and decode string 'Aladdin:open sesame'"""%sys.argv[0] + sys.exit(2) + func = encode + for o, a in opts: + if o == '-e': func = encode + if o == '-d': func = decode + if o == '-u': func = decode + if o == '-t': test1(); return + if args and args[0] != '-': + with open(args[0], 'rb') as f: + func(f, sys.stdout) + else: + func(sys.stdin, sys.stdout) + + +def test1(): + s0 = "Aladdin:open sesame" + s1 = encodestring(s0) + s2 = decodestring(s1) + print s0, repr(s1), s2 + + +if __name__ == '__main__': + test() diff --git a/test/ok_2.7/binhex.py b/test/ok_2.7/binhex.py new file mode 100644 index 00000000..8abc9f3e --- /dev/null +++ b/test/ok_2.7/binhex.py @@ -0,0 +1,508 @@ +"""Macintosh binhex compression/decompression. + +easy interface: +binhex(inputfilename, outputfilename) +hexbin(inputfilename, outputfilename) +""" + +# +# Jack Jansen, CWI, August 1995. +# +# The module is supposed to be as compatible as possible. Especially the +# easy interface should work "as expected" on any platform. +# XXXX Note: currently, textfiles appear in mac-form on all platforms. +# We seem to lack a simple character-translate in python. +# (we should probably use ISO-Latin-1 on all but the mac platform). +# XXXX The simple routines are too simple: they expect to hold the complete +# files in-core. Should be fixed. +# XXXX It would be nice to handle AppleDouble format on unix +# (for servers serving macs). +# XXXX I don't understand what happens when you get 0x90 times the same byte on +# input. The resulting code (xx 90 90) would appear to be interpreted as an +# escaped *value* of 0x90. All coders I've seen appear to ignore this nicety... +# +import sys +import os +import struct +import binascii + +__all__ = ["binhex","hexbin","Error"] + +class Error(Exception): + pass + +# States (what have we written) +[_DID_HEADER, _DID_DATA, _DID_RSRC] = range(3) + +# Various constants +REASONABLY_LARGE=32768 # Minimal amount we pass the rle-coder +LINELEN=64 +RUNCHAR=chr(0x90) # run-length introducer + +# +# This code is no longer byte-order dependent + +# +# Workarounds for non-mac machines. +try: + from Carbon.File import FSSpec, FInfo + from MacOS import openrf + + def getfileinfo(name): + finfo = FSSpec(name).FSpGetFInfo() + dir, file = os.path.split(name) + # XXX Get resource/data sizes + fp = open(name, 'rb') + fp.seek(0, 2) + dlen = fp.tell() + fp = openrf(name, '*rb') + fp.seek(0, 2) + rlen = fp.tell() + return file, finfo, dlen, rlen + + def openrsrc(name, *mode): + if not mode: + mode = '*rb' + else: + mode = '*' + mode[0] + return openrf(name, mode) + +except ImportError: + # + # Glue code for non-macintosh usage + # + + class FInfo: + def __init__(self): + self.Type = '????' + self.Creator = '????' + self.Flags = 0 + + def getfileinfo(name): + finfo = FInfo() + # Quick check for textfile + fp = open(name) + data = open(name).read(256) + for c in data: + if not c.isspace() and (c<' ' or ord(c) > 0x7f): + break + else: + finfo.Type = 'TEXT' + fp.seek(0, 2) + dsize = fp.tell() + fp.close() + dir, file = os.path.split(name) + file = file.replace(':', '-', 1) + return file, finfo, dsize, 0 + + class openrsrc: + def __init__(self, *args): + pass + + def read(self, *args): + return '' + + def write(self, *args): + pass + + def close(self): + pass + +class _Hqxcoderengine: + """Write data to the coder in 3-byte chunks""" + + def __init__(self, ofp): + self.ofp = ofp + self.data = '' + self.hqxdata = '' + self.linelen = LINELEN-1 + + def write(self, data): + self.data = self.data + data + datalen = len(self.data) + todo = (datalen//3)*3 + data = self.data[:todo] + self.data = self.data[todo:] + if not data: + return + self.hqxdata = self.hqxdata + binascii.b2a_hqx(data) + self._flush(0) + + def _flush(self, force): + first = 0 + while first <= len(self.hqxdata)-self.linelen: + last = first + self.linelen + self.ofp.write(self.hqxdata[first:last]+'\n') + self.linelen = LINELEN + first = last + self.hqxdata = self.hqxdata[first:] + if force: + self.ofp.write(self.hqxdata + ':\n') + + def close(self): + if self.data: + self.hqxdata = \ + self.hqxdata + binascii.b2a_hqx(self.data) + self._flush(1) + self.ofp.close() + del self.ofp + +class _Rlecoderengine: + """Write data to the RLE-coder in suitably large chunks""" + + def __init__(self, ofp): + self.ofp = ofp + self.data = '' + + def write(self, data): + self.data = self.data + data + if len(self.data) < REASONABLY_LARGE: + return + rledata = binascii.rlecode_hqx(self.data) + self.ofp.write(rledata) + self.data = '' + + def close(self): + if self.data: + rledata = binascii.rlecode_hqx(self.data) + self.ofp.write(rledata) + self.ofp.close() + del self.ofp + +class BinHex: + def __init__(self, name_finfo_dlen_rlen, ofp): + name, finfo, dlen, rlen = name_finfo_dlen_rlen + if type(ofp) == type(''): + ofname = ofp + ofp = open(ofname, 'w') + ofp.write('(This file must be converted with BinHex 4.0)\n\n:') + hqxer = _Hqxcoderengine(ofp) + self.ofp = _Rlecoderengine(hqxer) + self.crc = 0 + if finfo is None: + finfo = FInfo() + self.dlen = dlen + self.rlen = rlen + self._writeinfo(name, finfo) + self.state = _DID_HEADER + + def _writeinfo(self, name, finfo): + nl = len(name) + if nl > 63: + raise Error, 'Filename too long' + d = chr(nl) + name + '\0' + d2 = finfo.Type + finfo.Creator + + # Force all structs to be packed with big-endian + d3 = struct.pack('>h', finfo.Flags) + d4 = struct.pack('>ii', self.dlen, self.rlen) + info = d + d2 + d3 + d4 + self._write(info) + self._writecrc() + + def _write(self, data): + self.crc = binascii.crc_hqx(data, self.crc) + self.ofp.write(data) + + def _writecrc(self): + # XXXX Should this be here?? + # self.crc = binascii.crc_hqx('\0\0', self.crc) + if self.crc < 0: + fmt = '>h' + else: + fmt = '>H' + self.ofp.write(struct.pack(fmt, self.crc)) + self.crc = 0 + + def write(self, data): + if self.state != _DID_HEADER: + raise Error, 'Writing data at the wrong time' + self.dlen = self.dlen - len(data) + self._write(data) + + def close_data(self): + if self.dlen != 0: + raise Error, 'Incorrect data size, diff=%r' % (self.rlen,) + self._writecrc() + self.state = _DID_DATA + + def write_rsrc(self, data): + if self.state < _DID_DATA: + self.close_data() + if self.state != _DID_DATA: + raise Error, 'Writing resource data at the wrong time' + self.rlen = self.rlen - len(data) + self._write(data) + + def close(self): + if self.state < _DID_DATA: + self.close_data() + if self.state != _DID_DATA: + raise Error, 'Close at the wrong time' + if self.rlen != 0: + raise Error, \ + "Incorrect resource-datasize, diff=%r" % (self.rlen,) + self._writecrc() + self.ofp.close() + self.state = None + del self.ofp + +def binhex(inp, out): + """(infilename, outfilename) - Create binhex-encoded copy of a file""" + finfo = getfileinfo(inp) + ofp = BinHex(finfo, out) + + ifp = open(inp, 'rb') + # XXXX Do textfile translation on non-mac systems + while 1: + d = ifp.read(128000) + if not d: break + ofp.write(d) + ofp.close_data() + ifp.close() + + ifp = openrsrc(inp, 'rb') + while 1: + d = ifp.read(128000) + if not d: break + ofp.write_rsrc(d) + ofp.close() + ifp.close() + +class _Hqxdecoderengine: + """Read data via the decoder in 4-byte chunks""" + + def __init__(self, ifp): + self.ifp = ifp + self.eof = 0 + + def read(self, totalwtd): + """Read at least wtd bytes (or until EOF)""" + decdata = '' + wtd = totalwtd + # + # The loop here is convoluted, since we don't really now how + # much to decode: there may be newlines in the incoming data. + while wtd > 0: + if self.eof: return decdata + wtd = ((wtd+2)//3)*4 + data = self.ifp.read(wtd) + # + # Next problem: there may not be a complete number of + # bytes in what we pass to a2b. Solve by yet another + # loop. + # + while 1: + try: + decdatacur, self.eof = \ + binascii.a2b_hqx(data) + break + except binascii.Incomplete: + pass + newdata = self.ifp.read(1) + if not newdata: + raise Error, \ + 'Premature EOF on binhex file' + data = data + newdata + decdata = decdata + decdatacur + wtd = totalwtd - len(decdata) + if not decdata and not self.eof: + raise Error, 'Premature EOF on binhex file' + return decdata + + def close(self): + self.ifp.close() + +class _Rledecoderengine: + """Read data via the RLE-coder""" + + def __init__(self, ifp): + self.ifp = ifp + self.pre_buffer = '' + self.post_buffer = '' + self.eof = 0 + + def read(self, wtd): + if wtd > len(self.post_buffer): + self._fill(wtd-len(self.post_buffer)) + rv = self.post_buffer[:wtd] + self.post_buffer = self.post_buffer[wtd:] + return rv + + def _fill(self, wtd): + self.pre_buffer = self.pre_buffer + self.ifp.read(wtd+4) + if self.ifp.eof: + self.post_buffer = self.post_buffer + \ + binascii.rledecode_hqx(self.pre_buffer) + self.pre_buffer = '' + return + + # + # Obfuscated code ahead. We have to take care that we don't + # end up with an orphaned RUNCHAR later on. So, we keep a couple + # of bytes in the buffer, depending on what the end of + # the buffer looks like: + # '\220\0\220' - Keep 3 bytes: repeated \220 (escaped as \220\0) + # '?\220' - Keep 2 bytes: repeated something-else + # '\220\0' - Escaped \220: Keep 2 bytes. + # '?\220?' - Complete repeat sequence: decode all + # otherwise: keep 1 byte. + # + mark = len(self.pre_buffer) + if self.pre_buffer[-3:] == RUNCHAR + '\0' + RUNCHAR: + mark = mark - 3 + elif self.pre_buffer[-1] == RUNCHAR: + mark = mark - 2 + elif self.pre_buffer[-2:] == RUNCHAR + '\0': + mark = mark - 2 + elif self.pre_buffer[-2] == RUNCHAR: + pass # Decode all + else: + mark = mark - 1 + + self.post_buffer = self.post_buffer + \ + binascii.rledecode_hqx(self.pre_buffer[:mark]) + self.pre_buffer = self.pre_buffer[mark:] + + def close(self): + self.ifp.close() + +class HexBin: + def __init__(self, ifp): + if type(ifp) == type(''): + ifp = open(ifp) + # + # Find initial colon. + # + while 1: + ch = ifp.read(1) + if not ch: + raise Error, "No binhex data found" + # Cater for \r\n terminated lines (which show up as \n\r, hence + # all lines start with \r) + if ch == '\r': + continue + if ch == ':': + break + if ch != '\n': + dummy = ifp.readline() + + hqxifp = _Hqxdecoderengine(ifp) + self.ifp = _Rledecoderengine(hqxifp) + self.crc = 0 + self._readheader() + + def _read(self, len): + data = self.ifp.read(len) + self.crc = binascii.crc_hqx(data, self.crc) + return data + + def _checkcrc(self): + filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff + #self.crc = binascii.crc_hqx('\0\0', self.crc) + # XXXX Is this needed?? + self.crc = self.crc & 0xffff + if filecrc != self.crc: + raise Error, 'CRC error, computed %x, read %x' \ + %(self.crc, filecrc) + self.crc = 0 + + def _readheader(self): + len = self._read(1) + fname = self._read(ord(len)) + rest = self._read(1+4+4+2+4+4) + self._checkcrc() + + type = rest[1:5] + creator = rest[5:9] + flags = struct.unpack('>h', rest[9:11])[0] + self.dlen = struct.unpack('>l', rest[11:15])[0] + self.rlen = struct.unpack('>l', rest[15:19])[0] + + self.FName = fname + self.FInfo = FInfo() + self.FInfo.Creator = creator + self.FInfo.Type = type + self.FInfo.Flags = flags + + self.state = _DID_HEADER + + def read(self, *n): + if self.state != _DID_HEADER: + raise Error, 'Read data at wrong time' + if n: + n = n[0] + n = min(n, self.dlen) + else: + n = self.dlen + rv = '' + while len(rv) < n: + rv = rv + self._read(n-len(rv)) + self.dlen = self.dlen - n + return rv + + def close_data(self): + if self.state != _DID_HEADER: + raise Error, 'close_data at wrong time' + if self.dlen: + dummy = self._read(self.dlen) + self._checkcrc() + self.state = _DID_DATA + + def read_rsrc(self, *n): + if self.state == _DID_HEADER: + self.close_data() + if self.state != _DID_DATA: + raise Error, 'Read resource data at wrong time' + if n: + n = n[0] + n = min(n, self.rlen) + else: + n = self.rlen + self.rlen = self.rlen - n + return self._read(n) + + def close(self): + if self.rlen: + dummy = self.read_rsrc(self.rlen) + self._checkcrc() + self.state = _DID_RSRC + self.ifp.close() + +def hexbin(inp, out): + """(infilename, outfilename) - Decode binhexed file""" + ifp = HexBin(inp) + finfo = ifp.FInfo + if not out: + out = ifp.FName + + ofp = open(out, 'wb') + # XXXX Do translation on non-mac systems + while 1: + d = ifp.read(128000) + if not d: break + ofp.write(d) + ofp.close() + ifp.close_data() + + d = ifp.read_rsrc(128000) + if d: + ofp = openrsrc(out, 'wb') + ofp.write(d) + while 1: + d = ifp.read_rsrc(128000) + if not d: break + ofp.write(d) + ofp.close() + + ifp.close() + +def _test(): + fname = sys.argv[1] + binhex(fname, fname+'.hqx') + hexbin(fname+'.hqx', fname+'.viahqx') + #hexbin(fname, fname+'.unpacked') + sys.exit(1) + +if __name__ == '__main__': + _test() diff --git a/test/ok_2.7/bisect.py b/test/ok_2.7/bisect.py new file mode 100644 index 00000000..4a4d0525 --- /dev/null +++ b/test/ok_2.7/bisect.py @@ -0,0 +1,92 @@ +"""Bisection algorithms.""" + +def insort_right(a, x, lo=0, hi=None): + """Insert item x in list a, and keep it sorted assuming a is sorted. + + If x is already in a, insert it to the right of the rightmost x. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if x < a[mid]: hi = mid + else: lo = mid+1 + a.insert(lo, x) + +insort = insort_right # backward compatibility + +def bisect_right(a, x, lo=0, hi=None): + """Return the index where to insert item x in list a, assuming a is sorted. + + The return value i is such that all e in a[:i] have e <= x, and all e in + a[i:] have e > x. So if x already appears in the list, a.insert(x) will + insert just after the rightmost x already there. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if x < a[mid]: hi = mid + else: lo = mid+1 + return lo + +bisect = bisect_right # backward compatibility + +def insort_left(a, x, lo=0, hi=None): + """Insert item x in list a, and keep it sorted assuming a is sorted. + + If x is already in a, insert it to the left of the leftmost x. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if a[mid] < x: lo = mid+1 + else: hi = mid + a.insert(lo, x) + + +def bisect_left(a, x, lo=0, hi=None): + """Return the index where to insert item x in list a, assuming a is sorted. + + The return value i is such that all e in a[:i] have e < x, and all e in + a[i:] have e >= x. So if x already appears in the list, a.insert(x) will + insert just before the leftmost x already there. + + Optional args lo (default 0) and hi (default len(a)) bound the + slice of a to be searched. + """ + + if lo < 0: + raise ValueError('lo must be non-negative') + if hi is None: + hi = len(a) + while lo < hi: + mid = (lo+hi)//2 + if a[mid] < x: lo = mid+1 + else: hi = mid + return lo + +# Overwrite above definitions with a fast C implementation +try: + from _bisect import * +except ImportError: + pass diff --git a/test/ok_2.7/bsddb/__init__.py b/test/ok_2.7/bsddb/__init__.py new file mode 100644 index 00000000..13c9c27a --- /dev/null +++ b/test/ok_2.7/bsddb/__init__.py @@ -0,0 +1,455 @@ +#---------------------------------------------------------------------- +# Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA +# and Andrew Kuchling. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# o Redistributions of source code must retain the above copyright +# notice, this list of conditions, and the disclaimer that follows. +# +# o Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions, and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# o Neither the name of Digital Creations nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS +# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL +# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +#---------------------------------------------------------------------- + + +"""Support for Berkeley DB 4.3 through 5.3 with a simple interface. + +For the full featured object oriented interface use the bsddb.db module +instead. It mirrors the Oracle Berkeley DB C API. +""" + +import sys +absolute_import = (sys.version_info[0] >= 3) + +if (sys.version_info >= (2, 6)) and (sys.version_info < (3, 0)) : + import warnings + if sys.py3kwarning and (__name__ != 'bsddb3') : + warnings.warnpy3k("in 3.x, the bsddb module has been removed; " + "please use the pybsddb project instead", + DeprecationWarning, 2) + warnings.filterwarnings("ignore", ".*CObject.*", DeprecationWarning, + "bsddb.__init__") + +try: + if __name__ == 'bsddb3': + # import _pybsddb binary as it should be the more recent version from + # a standalone pybsddb addon package than the version included with + # python as bsddb._bsddb. + if absolute_import : + # Because this syntaxis is not valid before Python 2.5 + exec("from . import _pybsddb") + else : + import _pybsddb + _bsddb = _pybsddb + from bsddb3.dbutils import DeadlockWrap as _DeadlockWrap + else: + import _bsddb + from bsddb.dbutils import DeadlockWrap as _DeadlockWrap +except ImportError: + # Remove ourselves from sys.modules + import sys + del sys.modules[__name__] + raise + +# bsddb3 calls it db, but provide _db for backwards compatibility +db = _db = _bsddb +__version__ = db.__version__ + +error = db.DBError # So bsddb.error will mean something... + +#---------------------------------------------------------------------- + +import sys, os + +from weakref import ref + +if sys.version_info < (2, 6) : + import UserDict + MutableMapping = UserDict.DictMixin +else : + import collections + MutableMapping = collections.MutableMapping + +class _iter_mixin(MutableMapping): + def _make_iter_cursor(self): + cur = _DeadlockWrap(self.db.cursor) + key = id(cur) + self._cursor_refs[key] = ref(cur, self._gen_cref_cleaner(key)) + return cur + + def _gen_cref_cleaner(self, key): + # use generate the function for the weakref callback here + # to ensure that we do not hold a strict reference to cur + # in the callback. + return lambda ref: self._cursor_refs.pop(key, None) + + def __iter__(self): + self._kill_iteration = False + self._in_iter += 1 + try: + try: + cur = self._make_iter_cursor() + + # FIXME-20031102-greg: race condition. cursor could + # be closed by another thread before this call. + + # since we're only returning keys, we call the cursor + # methods with flags=0, dlen=0, dofs=0 + key = _DeadlockWrap(cur.first, 0,0,0)[0] + yield key + + next = getattr(cur, "next") + while 1: + try: + key = _DeadlockWrap(next, 0,0,0)[0] + yield key + except _bsddb.DBCursorClosedError: + if self._kill_iteration: + raise RuntimeError('Database changed size ' + 'during iteration.') + cur = self._make_iter_cursor() + # FIXME-20031101-greg: race condition. cursor could + # be closed by another thread before this call. + _DeadlockWrap(cur.set, key,0,0,0) + next = getattr(cur, "next") + except _bsddb.DBNotFoundError: + pass + except _bsddb.DBCursorClosedError: + # the database was modified during iteration. abort. + pass +# When Python 2.4 not supported in bsddb3, we can change this to "finally" + except : + self._in_iter -= 1 + raise + + self._in_iter -= 1 + + def iteritems(self): + if not self.db: + return + self._kill_iteration = False + self._in_iter += 1 + try: + try: + cur = self._make_iter_cursor() + + # FIXME-20031102-greg: race condition. cursor could + # be closed by another thread before this call. + + kv = _DeadlockWrap(cur.first) + key = kv[0] + yield kv + + next = getattr(cur, "next") + while 1: + try: + kv = _DeadlockWrap(next) + key = kv[0] + yield kv + except _bsddb.DBCursorClosedError: + if self._kill_iteration: + raise RuntimeError('Database changed size ' + 'during iteration.') + cur = self._make_iter_cursor() + # FIXME-20031101-greg: race condition. cursor could + # be closed by another thread before this call. + _DeadlockWrap(cur.set, key,0,0,0) + next = getattr(cur, "next") + except _bsddb.DBNotFoundError: + pass + except _bsddb.DBCursorClosedError: + # the database was modified during iteration. abort. + pass +# When Python 2.4 not supported in bsddb3, we can change this to "finally" + except : + self._in_iter -= 1 + raise + + self._in_iter -= 1 + + +class _DBWithCursor(_iter_mixin): + """ + A simple wrapper around DB that makes it look like the bsddbobject in + the old module. It uses a cursor as needed to provide DB traversal. + """ + def __init__(self, db): + self.db = db + self.db.set_get_returns_none(0) + + # FIXME-20031101-greg: I believe there is still the potential + # for deadlocks in a multithreaded environment if someone + # attempts to use the any of the cursor interfaces in one + # thread while doing a put or delete in another thread. The + # reason is that _checkCursor and _closeCursors are not atomic + # operations. Doing our own locking around self.dbc, + # self.saved_dbc_key and self._cursor_refs could prevent this. + # TODO: A test case demonstrating the problem needs to be written. + + # self.dbc is a DBCursor object used to implement the + # first/next/previous/last/set_location methods. + self.dbc = None + self.saved_dbc_key = None + + # a collection of all DBCursor objects currently allocated + # by the _iter_mixin interface. + self._cursor_refs = {} + self._in_iter = 0 + self._kill_iteration = False + + def __del__(self): + self.close() + + def _checkCursor(self): + if self.dbc is None: + self.dbc = _DeadlockWrap(self.db.cursor) + if self.saved_dbc_key is not None: + _DeadlockWrap(self.dbc.set, self.saved_dbc_key) + self.saved_dbc_key = None + + # This method is needed for all non-cursor DB calls to avoid + # Berkeley DB deadlocks (due to being opened with DB_INIT_LOCK + # and DB_THREAD to be thread safe) when intermixing database + # operations that use the cursor internally with those that don't. + def _closeCursors(self, save=1): + if self.dbc: + c = self.dbc + self.dbc = None + if save: + try: + self.saved_dbc_key = _DeadlockWrap(c.current, 0,0,0)[0] + except db.DBError: + pass + _DeadlockWrap(c.close) + del c + for cref in self._cursor_refs.values(): + c = cref() + if c is not None: + _DeadlockWrap(c.close) + + def _checkOpen(self): + if self.db is None: + raise error, "BSDDB object has already been closed" + + def isOpen(self): + return self.db is not None + + def __len__(self): + self._checkOpen() + return _DeadlockWrap(lambda: len(self.db)) # len(self.db) + + if sys.version_info >= (2, 6) : + def __repr__(self) : + if self.isOpen() : + return repr(dict(_DeadlockWrap(self.db.items))) + return repr(dict()) + + def __getitem__(self, key): + self._checkOpen() + return _DeadlockWrap(lambda: self.db[key]) # self.db[key] + + def __setitem__(self, key, value): + self._checkOpen() + self._closeCursors() + if self._in_iter and key not in self: + self._kill_iteration = True + def wrapF(): + self.db[key] = value + _DeadlockWrap(wrapF) # self.db[key] = value + + def __delitem__(self, key): + self._checkOpen() + self._closeCursors() + if self._in_iter and key in self: + self._kill_iteration = True + def wrapF(): + del self.db[key] + _DeadlockWrap(wrapF) # del self.db[key] + + def close(self): + self._closeCursors(save=0) + if self.dbc is not None: + _DeadlockWrap(self.dbc.close) + v = 0 + if self.db is not None: + v = _DeadlockWrap(self.db.close) + self.dbc = None + self.db = None + return v + + def keys(self): + self._checkOpen() + return _DeadlockWrap(self.db.keys) + + def has_key(self, key): + self._checkOpen() + return _DeadlockWrap(self.db.has_key, key) + + def set_location(self, key): + self._checkOpen() + self._checkCursor() + return _DeadlockWrap(self.dbc.set_range, key) + + def next(self): # Renamed by "2to3" + self._checkOpen() + self._checkCursor() + rv = _DeadlockWrap(getattr(self.dbc, "next")) + return rv + + if sys.version_info[0] >= 3 : # For "2to3" conversion + next = __next__ + + def previous(self): + self._checkOpen() + self._checkCursor() + rv = _DeadlockWrap(self.dbc.prev) + return rv + + def first(self): + self._checkOpen() + # fix 1725856: don't needlessly try to restore our cursor position + self.saved_dbc_key = None + self._checkCursor() + rv = _DeadlockWrap(self.dbc.first) + return rv + + def last(self): + self._checkOpen() + # fix 1725856: don't needlessly try to restore our cursor position + self.saved_dbc_key = None + self._checkCursor() + rv = _DeadlockWrap(self.dbc.last) + return rv + + def sync(self): + self._checkOpen() + return _DeadlockWrap(self.db.sync) + + +#---------------------------------------------------------------------- +# Compatibility object factory functions + +def hashopen(file, flag='c', mode=0666, pgsize=None, ffactor=None, nelem=None, + cachesize=None, lorder=None, hflags=0): + + flags = _checkflag(flag, file) + e = _openDBEnv(cachesize) + d = db.DB(e) + d.set_flags(hflags) + if pgsize is not None: d.set_pagesize(pgsize) + if lorder is not None: d.set_lorder(lorder) + if ffactor is not None: d.set_h_ffactor(ffactor) + if nelem is not None: d.set_h_nelem(nelem) + d.open(file, db.DB_HASH, flags, mode) + return _DBWithCursor(d) + +#---------------------------------------------------------------------- + +def btopen(file, flag='c', mode=0666, + btflags=0, cachesize=None, maxkeypage=None, minkeypage=None, + pgsize=None, lorder=None): + + flags = _checkflag(flag, file) + e = _openDBEnv(cachesize) + d = db.DB(e) + if pgsize is not None: d.set_pagesize(pgsize) + if lorder is not None: d.set_lorder(lorder) + d.set_flags(btflags) + if minkeypage is not None: d.set_bt_minkey(minkeypage) + if maxkeypage is not None: d.set_bt_maxkey(maxkeypage) + d.open(file, db.DB_BTREE, flags, mode) + return _DBWithCursor(d) + +#---------------------------------------------------------------------- + + +def rnopen(file, flag='c', mode=0666, + rnflags=0, cachesize=None, pgsize=None, lorder=None, + rlen=None, delim=None, source=None, pad=None): + + flags = _checkflag(flag, file) + e = _openDBEnv(cachesize) + d = db.DB(e) + if pgsize is not None: d.set_pagesize(pgsize) + if lorder is not None: d.set_lorder(lorder) + d.set_flags(rnflags) + if delim is not None: d.set_re_delim(delim) + if rlen is not None: d.set_re_len(rlen) + if source is not None: d.set_re_source(source) + if pad is not None: d.set_re_pad(pad) + d.open(file, db.DB_RECNO, flags, mode) + return _DBWithCursor(d) + +#---------------------------------------------------------------------- + +def _openDBEnv(cachesize): + e = db.DBEnv() + if cachesize is not None: + if cachesize >= 20480: + e.set_cachesize(0, cachesize) + else: + raise error, "cachesize must be >= 20480" + e.set_lk_detect(db.DB_LOCK_DEFAULT) + e.open('.', db.DB_PRIVATE | db.DB_CREATE | db.DB_THREAD | db.DB_INIT_LOCK | db.DB_INIT_MPOOL) + return e + +def _checkflag(flag, file): + if flag == 'r': + flags = db.DB_RDONLY + elif flag == 'rw': + flags = 0 + elif flag == 'w': + flags = db.DB_CREATE + elif flag == 'c': + flags = db.DB_CREATE + elif flag == 'n': + flags = db.DB_CREATE + #flags = db.DB_CREATE | db.DB_TRUNCATE + # we used db.DB_TRUNCATE flag for this before but Berkeley DB + # 4.2.52 changed to disallowed truncate with txn environments. + if file is not None and os.path.isfile(file): + os.unlink(file) + else: + raise error, "flags should be one of 'r', 'w', 'c' or 'n'" + return flags | db.DB_THREAD + +#---------------------------------------------------------------------- + + +# This is a silly little hack that allows apps to continue to use the +# DB_THREAD flag even on systems without threads without freaking out +# Berkeley DB. +# +# This assumes that if Python was built with thread support then +# Berkeley DB was too. + +try: + # 2to3 automatically changes "import thread" to "import _thread" + import thread as T + del T + +except ImportError: + db.DB_THREAD = 0 + +#---------------------------------------------------------------------- diff --git a/test/ok_2.7/bsddb/db.py b/test/ok_2.7/bsddb/db.py new file mode 100644 index 00000000..c3aee307 --- /dev/null +++ b/test/ok_2.7/bsddb/db.py @@ -0,0 +1,60 @@ +#---------------------------------------------------------------------- +# Copyright (c) 1999-2001, Digital Creations, Fredericksburg, VA, USA +# and Andrew Kuchling. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# o Redistributions of source code must retain the above copyright +# notice, this list of conditions, and the disclaimer that follows. +# +# o Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions, and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# o Neither the name of Digital Creations nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY DIGITAL CREATIONS AND CONTRIBUTORS *AS +# IS* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +# PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL DIGITAL +# CREATIONS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR +# TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH +# DAMAGE. +#---------------------------------------------------------------------- + + +# This module is just a placeholder for possible future expansion, in +# case we ever want to augment the stuff in _db in any way. For now +# it just simply imports everything from _db. + +import sys +absolute_import = (sys.version_info[0] >= 3) + +if not absolute_import : + if __name__.startswith('bsddb3.') : + # import _pybsddb binary as it should be the more recent version from + # a standalone pybsddb addon package than the version included with + # python as bsddb._bsddb. + from _pybsddb import * + from _pybsddb import __version__ + else: + from _bsddb import * + from _bsddb import __version__ +else : + # Because this syntaxis is not valid before Python 2.5 + if __name__.startswith('bsddb3.') : + exec("from ._pybsddb import *") + exec("from ._pybsddb import __version__") + else : + exec("from ._bsddb import *") + exec("from ._bsddb import __version__") diff --git a/test/ok_2.7/bsddb/dbobj.py b/test/ok_2.7/bsddb/dbobj.py new file mode 100644 index 00000000..1400fe15 --- /dev/null +++ b/test/ok_2.7/bsddb/dbobj.py @@ -0,0 +1,266 @@ +#------------------------------------------------------------------------- +# This file contains real Python object wrappers for DB and DBEnv +# C "objects" that can be usefully subclassed. The previous SWIG +# based interface allowed this thanks to SWIG's shadow classes. +# -- Gregory P. Smith +#------------------------------------------------------------------------- +# +# (C) Copyright 2001 Autonomous Zone Industries +# +# License: This is free software. You may use this software for any +# purpose including modification/redistribution, so long as +# this header remains intact and that you do not claim any +# rights of ownership or authorship of this software. This +# software has been tested, but no warranty is expressed or +# implied. +# + +# +# TODO it would be *really nice* to have an automatic shadow class populator +# so that new methods don't need to be added here manually after being +# added to _bsddb.c. +# + +import sys +absolute_import = (sys.version_info[0] >= 3) +if absolute_import : + # Because this syntaxis is not valid before Python 2.5 + exec("from . import db") +else : + import db + +if sys.version_info < (2, 6) : + from UserDict import DictMixin as MutableMapping +else : + import collections + MutableMapping = collections.MutableMapping + +class DBEnv: + def __init__(self, *args, **kwargs): + self._cobj = db.DBEnv(*args, **kwargs) + + def close(self, *args, **kwargs): + return self._cobj.close(*args, **kwargs) + def open(self, *args, **kwargs): + return self._cobj.open(*args, **kwargs) + def remove(self, *args, **kwargs): + return self._cobj.remove(*args, **kwargs) + def set_shm_key(self, *args, **kwargs): + return self._cobj.set_shm_key(*args, **kwargs) + def set_cachesize(self, *args, **kwargs): + return self._cobj.set_cachesize(*args, **kwargs) + def set_data_dir(self, *args, **kwargs): + return self._cobj.set_data_dir(*args, **kwargs) + def set_flags(self, *args, **kwargs): + return self._cobj.set_flags(*args, **kwargs) + def set_lg_bsize(self, *args, **kwargs): + return self._cobj.set_lg_bsize(*args, **kwargs) + def set_lg_dir(self, *args, **kwargs): + return self._cobj.set_lg_dir(*args, **kwargs) + def set_lg_max(self, *args, **kwargs): + return self._cobj.set_lg_max(*args, **kwargs) + def set_lk_detect(self, *args, **kwargs): + return self._cobj.set_lk_detect(*args, **kwargs) + if db.version() < (4,5): + def set_lk_max(self, *args, **kwargs): + return self._cobj.set_lk_max(*args, **kwargs) + def set_lk_max_locks(self, *args, **kwargs): + return self._cobj.set_lk_max_locks(*args, **kwargs) + def set_lk_max_lockers(self, *args, **kwargs): + return self._cobj.set_lk_max_lockers(*args, **kwargs) + def set_lk_max_objects(self, *args, **kwargs): + return self._cobj.set_lk_max_objects(*args, **kwargs) + def set_mp_mmapsize(self, *args, **kwargs): + return self._cobj.set_mp_mmapsize(*args, **kwargs) + def set_timeout(self, *args, **kwargs): + return self._cobj.set_timeout(*args, **kwargs) + def set_tmp_dir(self, *args, **kwargs): + return self._cobj.set_tmp_dir(*args, **kwargs) + def txn_begin(self, *args, **kwargs): + return self._cobj.txn_begin(*args, **kwargs) + def txn_checkpoint(self, *args, **kwargs): + return self._cobj.txn_checkpoint(*args, **kwargs) + def txn_stat(self, *args, **kwargs): + return self._cobj.txn_stat(*args, **kwargs) + def set_tx_max(self, *args, **kwargs): + return self._cobj.set_tx_max(*args, **kwargs) + def set_tx_timestamp(self, *args, **kwargs): + return self._cobj.set_tx_timestamp(*args, **kwargs) + def lock_detect(self, *args, **kwargs): + return self._cobj.lock_detect(*args, **kwargs) + def lock_get(self, *args, **kwargs): + return self._cobj.lock_get(*args, **kwargs) + def lock_id(self, *args, **kwargs): + return self._cobj.lock_id(*args, **kwargs) + def lock_put(self, *args, **kwargs): + return self._cobj.lock_put(*args, **kwargs) + def lock_stat(self, *args, **kwargs): + return self._cobj.lock_stat(*args, **kwargs) + def log_archive(self, *args, **kwargs): + return self._cobj.log_archive(*args, **kwargs) + + def set_get_returns_none(self, *args, **kwargs): + return self._cobj.set_get_returns_none(*args, **kwargs) + + def log_stat(self, *args, **kwargs): + return self._cobj.log_stat(*args, **kwargs) + + def dbremove(self, *args, **kwargs): + return self._cobj.dbremove(*args, **kwargs) + def dbrename(self, *args, **kwargs): + return self._cobj.dbrename(*args, **kwargs) + def set_encrypt(self, *args, **kwargs): + return self._cobj.set_encrypt(*args, **kwargs) + + if db.version() >= (4,4): + def fileid_reset(self, *args, **kwargs): + return self._cobj.fileid_reset(*args, **kwargs) + + def lsn_reset(self, *args, **kwargs): + return self._cobj.lsn_reset(*args, **kwargs) + + +class DB(MutableMapping): + def __init__(self, dbenv, *args, **kwargs): + # give it the proper DBEnv C object that its expecting + self._cobj = db.DB(*((dbenv._cobj,) + args), **kwargs) + + # TODO are there other dict methods that need to be overridden? + def __len__(self): + return len(self._cobj) + def __getitem__(self, arg): + return self._cobj[arg] + def __setitem__(self, key, value): + self._cobj[key] = value + def __delitem__(self, arg): + del self._cobj[arg] + + if sys.version_info >= (2, 6) : + def __iter__(self) : + return self._cobj.__iter__() + + def append(self, *args, **kwargs): + return self._cobj.append(*args, **kwargs) + def associate(self, *args, **kwargs): + return self._cobj.associate(*args, **kwargs) + def close(self, *args, **kwargs): + return self._cobj.close(*args, **kwargs) + def consume(self, *args, **kwargs): + return self._cobj.consume(*args, **kwargs) + def consume_wait(self, *args, **kwargs): + return self._cobj.consume_wait(*args, **kwargs) + def cursor(self, *args, **kwargs): + return self._cobj.cursor(*args, **kwargs) + def delete(self, *args, **kwargs): + return self._cobj.delete(*args, **kwargs) + def fd(self, *args, **kwargs): + return self._cobj.fd(*args, **kwargs) + def get(self, *args, **kwargs): + return self._cobj.get(*args, **kwargs) + def pget(self, *args, **kwargs): + return self._cobj.pget(*args, **kwargs) + def get_both(self, *args, **kwargs): + return self._cobj.get_both(*args, **kwargs) + def get_byteswapped(self, *args, **kwargs): + return self._cobj.get_byteswapped(*args, **kwargs) + def get_size(self, *args, **kwargs): + return self._cobj.get_size(*args, **kwargs) + def get_type(self, *args, **kwargs): + return self._cobj.get_type(*args, **kwargs) + def join(self, *args, **kwargs): + return self._cobj.join(*args, **kwargs) + def key_range(self, *args, **kwargs): + return self._cobj.key_range(*args, **kwargs) + def has_key(self, *args, **kwargs): + return self._cobj.has_key(*args, **kwargs) + def items(self, *args, **kwargs): + return self._cobj.items(*args, **kwargs) + def keys(self, *args, **kwargs): + return self._cobj.keys(*args, **kwargs) + def open(self, *args, **kwargs): + return self._cobj.open(*args, **kwargs) + def put(self, *args, **kwargs): + return self._cobj.put(*args, **kwargs) + def remove(self, *args, **kwargs): + return self._cobj.remove(*args, **kwargs) + def rename(self, *args, **kwargs): + return self._cobj.rename(*args, **kwargs) + def set_bt_minkey(self, *args, **kwargs): + return self._cobj.set_bt_minkey(*args, **kwargs) + def set_bt_compare(self, *args, **kwargs): + return self._cobj.set_bt_compare(*args, **kwargs) + def set_cachesize(self, *args, **kwargs): + return self._cobj.set_cachesize(*args, **kwargs) + def set_dup_compare(self, *args, **kwargs) : + return self._cobj.set_dup_compare(*args, **kwargs) + def set_flags(self, *args, **kwargs): + return self._cobj.set_flags(*args, **kwargs) + def set_h_ffactor(self, *args, **kwargs): + return self._cobj.set_h_ffactor(*args, **kwargs) + def set_h_nelem(self, *args, **kwargs): + return self._cobj.set_h_nelem(*args, **kwargs) + def set_lorder(self, *args, **kwargs): + return self._cobj.set_lorder(*args, **kwargs) + def set_pagesize(self, *args, **kwargs): + return self._cobj.set_pagesize(*args, **kwargs) + def set_re_delim(self, *args, **kwargs): + return self._cobj.set_re_delim(*args, **kwargs) + def set_re_len(self, *args, **kwargs): + return self._cobj.set_re_len(*args, **kwargs) + def set_re_pad(self, *args, **kwargs): + return self._cobj.set_re_pad(*args, **kwargs) + def set_re_source(self, *args, **kwargs): + return self._cobj.set_re_source(*args, **kwargs) + def set_q_extentsize(self, *args, **kwargs): + return self._cobj.set_q_extentsize(*args, **kwargs) + def stat(self, *args, **kwargs): + return self._cobj.stat(*args, **kwargs) + def sync(self, *args, **kwargs): + return self._cobj.sync(*args, **kwargs) + def type(self, *args, **kwargs): + return self._cobj.type(*args, **kwargs) + def upgrade(self, *args, **kwargs): + return self._cobj.upgrade(*args, **kwargs) + def values(self, *args, **kwargs): + return self._cobj.values(*args, **kwargs) + def verify(self, *args, **kwargs): + return self._cobj.verify(*args, **kwargs) + def set_get_returns_none(self, *args, **kwargs): + return self._cobj.set_get_returns_none(*args, **kwargs) + + def set_encrypt(self, *args, **kwargs): + return self._cobj.set_encrypt(*args, **kwargs) + + +class DBSequence: + def __init__(self, *args, **kwargs): + self._cobj = db.DBSequence(*args, **kwargs) + + def close(self, *args, **kwargs): + return self._cobj.close(*args, **kwargs) + def get(self, *args, **kwargs): + return self._cobj.get(*args, **kwargs) + def get_dbp(self, *args, **kwargs): + return self._cobj.get_dbp(*args, **kwargs) + def get_key(self, *args, **kwargs): + return self._cobj.get_key(*args, **kwargs) + def init_value(self, *args, **kwargs): + return self._cobj.init_value(*args, **kwargs) + def open(self, *args, **kwargs): + return self._cobj.open(*args, **kwargs) + def remove(self, *args, **kwargs): + return self._cobj.remove(*args, **kwargs) + def stat(self, *args, **kwargs): + return self._cobj.stat(*args, **kwargs) + def set_cachesize(self, *args, **kwargs): + return self._cobj.set_cachesize(*args, **kwargs) + def set_flags(self, *args, **kwargs): + return self._cobj.set_flags(*args, **kwargs) + def set_range(self, *args, **kwargs): + return self._cobj.set_range(*args, **kwargs) + def get_cachesize(self, *args, **kwargs): + return self._cobj.get_cachesize(*args, **kwargs) + def get_flags(self, *args, **kwargs): + return self._cobj.get_flags(*args, **kwargs) + def get_range(self, *args, **kwargs): + return self._cobj.get_range(*args, **kwargs) diff --git a/test/ok_2.7/bsddb/dbrecio.py b/test/ok_2.7/bsddb/dbrecio.py new file mode 100644 index 00000000..d439f325 --- /dev/null +++ b/test/ok_2.7/bsddb/dbrecio.py @@ -0,0 +1,190 @@ + +""" +File-like objects that read from or write to a bsddb record. + +This implements (nearly) all stdio methods. + +f = DBRecIO(db, key, txn=None) +f.close() # explicitly release resources held +flag = f.isatty() # always false +pos = f.tell() # get current position +f.seek(pos) # set current position +f.seek(pos, mode) # mode 0: absolute; 1: relative; 2: relative to EOF +buf = f.read() # read until EOF +buf = f.read(n) # read up to n bytes +f.truncate([size]) # truncate file at to at most size (default: current pos) +f.write(buf) # write at current position +f.writelines(list) # for line in list: f.write(line) + +Notes: +- fileno() is left unimplemented so that code which uses it triggers + an exception early. +- There's a simple test set (see end of this file) - not yet updated + for DBRecIO. +- readline() is not implemented yet. + + +From: + Itamar Shtull-Trauring +""" + +import errno +import string + +class DBRecIO: + def __init__(self, db, key, txn=None): + self.db = db + self.key = key + self.txn = txn + self.len = None + self.pos = 0 + self.closed = 0 + self.softspace = 0 + + def close(self): + if not self.closed: + self.closed = 1 + del self.db, self.txn + + def isatty(self): + if self.closed: + raise ValueError, "I/O operation on closed file" + return 0 + + def seek(self, pos, mode = 0): + if self.closed: + raise ValueError, "I/O operation on closed file" + if mode == 1: + pos = pos + self.pos + elif mode == 2: + pos = pos + self.len + self.pos = max(0, pos) + + def tell(self): + if self.closed: + raise ValueError, "I/O operation on closed file" + return self.pos + + def read(self, n = -1): + if self.closed: + raise ValueError, "I/O operation on closed file" + if n < 0: + newpos = self.len + else: + newpos = min(self.pos+n, self.len) + + dlen = newpos - self.pos + + r = self.db.get(self.key, txn=self.txn, dlen=dlen, doff=self.pos) + self.pos = newpos + return r + + __fixme = """ + def readline(self, length=None): + if self.closed: + raise ValueError, "I/O operation on closed file" + if self.buflist: + self.buf = self.buf + string.joinfields(self.buflist, '') + self.buflist = [] + i = string.find(self.buf, '\n', self.pos) + if i < 0: + newpos = self.len + else: + newpos = i+1 + if length is not None: + if self.pos + length < newpos: + newpos = self.pos + length + r = self.buf[self.pos:newpos] + self.pos = newpos + return r + + def readlines(self, sizehint = 0): + total = 0 + lines = [] + line = self.readline() + while line: + lines.append(line) + total += len(line) + if 0 < sizehint <= total: + break + line = self.readline() + return lines + """ + + def truncate(self, size=None): + if self.closed: + raise ValueError, "I/O operation on closed file" + if size is None: + size = self.pos + elif size < 0: + raise IOError(errno.EINVAL, + "Negative size not allowed") + elif size < self.pos: + self.pos = size + self.db.put(self.key, "", txn=self.txn, dlen=self.len-size, doff=size) + + def write(self, s): + if self.closed: + raise ValueError, "I/O operation on closed file" + if not s: return + if self.pos > self.len: + self.buflist.append('\0'*(self.pos - self.len)) + self.len = self.pos + newpos = self.pos + len(s) + self.db.put(self.key, s, txn=self.txn, dlen=len(s), doff=self.pos) + self.pos = newpos + + def writelines(self, list): + self.write(string.joinfields(list, '')) + + def flush(self): + if self.closed: + raise ValueError, "I/O operation on closed file" + + +""" +# A little test suite + +def _test(): + import sys + if sys.argv[1:]: + file = sys.argv[1] + else: + file = '/etc/passwd' + lines = open(file, 'r').readlines() + text = open(file, 'r').read() + f = StringIO() + for line in lines[:-2]: + f.write(line) + f.writelines(lines[-2:]) + if f.getvalue() != text: + raise RuntimeError, 'write failed' + length = f.tell() + print 'File length =', length + f.seek(len(lines[0])) + f.write(lines[1]) + f.seek(0) + print 'First line =', repr(f.readline()) + here = f.tell() + line = f.readline() + print 'Second line =', repr(line) + f.seek(-len(line), 1) + line2 = f.read(len(line)) + if line != line2: + raise RuntimeError, 'bad result after seek back' + f.seek(len(line2), 1) + list = f.readlines() + line = list[-1] + f.seek(f.tell() - len(line)) + line2 = f.read() + if line != line2: + raise RuntimeError, 'bad result after seek back from EOF' + print 'Read', len(list), 'more lines' + print 'File length =', f.tell() + if f.tell() != length: + raise RuntimeError, 'bad length' + f.close() + +if __name__ == '__main__': + _test() +""" diff --git a/test/ok_2.7/bsddb/dbshelve.py b/test/ok_2.7/bsddb/dbshelve.py new file mode 100644 index 00000000..7d0daa2f --- /dev/null +++ b/test/ok_2.7/bsddb/dbshelve.py @@ -0,0 +1,381 @@ +#------------------------------------------------------------------------ +# Copyright (c) 1997-2001 by Total Control Software +# All Rights Reserved +#------------------------------------------------------------------------ +# +# Module Name: dbShelve.py +# +# Description: A reimplementation of the standard shelve.py that +# forces the use of cPickle, and DB. +# +# Creation Date: 11/3/97 3:39:04PM +# +# License: This is free software. You may use this software for any +# purpose including modification/redistribution, so long as +# this header remains intact and that you do not claim any +# rights of ownership or authorship of this software. This +# software has been tested, but no warranty is expressed or +# implied. +# +# 13-Dec-2000: Updated to be used with the new bsddb3 package. +# Added DBShelfCursor class. +# +#------------------------------------------------------------------------ + +"""Manage shelves of pickled objects using bsddb database files for the +storage. +""" + +#------------------------------------------------------------------------ + +import sys +absolute_import = (sys.version_info[0] >= 3) +if absolute_import : + # Because this syntaxis is not valid before Python 2.5 + exec("from . import db") +else : + import db + +if sys.version_info[0] >= 3 : + import cPickle # Will be converted to "pickle" by "2to3" +else : + if sys.version_info < (2, 6) : + import cPickle + else : + # When we drop support for python 2.4 + # we could use: (in 2.5 we need a __future__ statement) + # + # with warnings.catch_warnings(): + # warnings.filterwarnings(...) + # ... + # + # We can not use "with" as is, because it would be invalid syntax + # in python 2.4 and (with no __future__) 2.5. + # Here we simulate "with" following PEP 343 : + import warnings + w = warnings.catch_warnings() + w.__enter__() + try : + warnings.filterwarnings('ignore', + message='the cPickle module has been removed in Python 3.0', + category=DeprecationWarning) + import cPickle + finally : + w.__exit__() + del w + +HIGHEST_PROTOCOL = cPickle.HIGHEST_PROTOCOL +def _dumps(object, protocol): + return cPickle.dumps(object, protocol=protocol) + +if sys.version_info < (2, 6) : + from UserDict import DictMixin as MutableMapping +else : + import collections + MutableMapping = collections.MutableMapping + +#------------------------------------------------------------------------ + + +def open(filename, flags=db.DB_CREATE, mode=0660, filetype=db.DB_HASH, + dbenv=None, dbname=None): + """ + A simple factory function for compatibility with the standard + shleve.py module. It can be used like this, where key is a string + and data is a pickleable object: + + from bsddb import dbshelve + db = dbshelve.open(filename) + + db[key] = data + + db.close() + """ + if type(flags) == type(''): + sflag = flags + if sflag == 'r': + flags = db.DB_RDONLY + elif sflag == 'rw': + flags = 0 + elif sflag == 'w': + flags = db.DB_CREATE + elif sflag == 'c': + flags = db.DB_CREATE + elif sflag == 'n': + flags = db.DB_TRUNCATE | db.DB_CREATE + else: + raise db.DBError, "flags should be one of 'r', 'w', 'c' or 'n' or use the bsddb.db.DB_* flags" + + d = DBShelf(dbenv) + d.open(filename, dbname, filetype, flags, mode) + return d + +#--------------------------------------------------------------------------- + +class DBShelveError(db.DBError): pass + + +class DBShelf(MutableMapping): + """A shelf to hold pickled objects, built upon a bsddb DB object. It + automatically pickles/unpickles data objects going to/from the DB. + """ + def __init__(self, dbenv=None): + self.db = db.DB(dbenv) + self._closed = True + if HIGHEST_PROTOCOL: + self.protocol = HIGHEST_PROTOCOL + else: + self.protocol = 1 + + + def __del__(self): + self.close() + + + def __getattr__(self, name): + """Many methods we can just pass through to the DB object. + (See below) + """ + return getattr(self.db, name) + + + #----------------------------------- + # Dictionary access methods + + def __len__(self): + return len(self.db) + + + def __getitem__(self, key): + data = self.db[key] + return cPickle.loads(data) + + + def __setitem__(self, key, value): + data = _dumps(value, self.protocol) + self.db[key] = data + + + def __delitem__(self, key): + del self.db[key] + + + def keys(self, txn=None): + if txn is not None: + return self.db.keys(txn) + else: + return self.db.keys() + + if sys.version_info >= (2, 6) : + def __iter__(self) : # XXX: Load all keys in memory :-( + for k in self.db.keys() : + yield k + + # Do this when "DB" support iteration + # Or is it enough to pass thru "getattr"? + # + # def __iter__(self) : + # return self.db.__iter__() + + + def open(self, *args, **kwargs): + self.db.open(*args, **kwargs) + self._closed = False + + + def close(self, *args, **kwargs): + self.db.close(*args, **kwargs) + self._closed = True + + + def __repr__(self): + if self._closed: + return '' % (id(self)) + else: + return repr(dict(self.iteritems())) + + + def items(self, txn=None): + if txn is not None: + items = self.db.items(txn) + else: + items = self.db.items() + newitems = [] + + for k, v in items: + newitems.append( (k, cPickle.loads(v)) ) + return newitems + + def values(self, txn=None): + if txn is not None: + values = self.db.values(txn) + else: + values = self.db.values() + + return map(cPickle.loads, values) + + #----------------------------------- + # Other methods + + def __append(self, value, txn=None): + data = _dumps(value, self.protocol) + return self.db.append(data, txn) + + def append(self, value, txn=None): + if self.get_type() == db.DB_RECNO: + return self.__append(value, txn=txn) + raise DBShelveError, "append() only supported when dbshelve opened with filetype=dbshelve.db.DB_RECNO" + + + def associate(self, secondaryDB, callback, flags=0): + def _shelf_callback(priKey, priData, realCallback=callback): + # Safe in Python 2.x because expresion short circuit + if sys.version_info[0] < 3 or isinstance(priData, bytes) : + data = cPickle.loads(priData) + else : + data = cPickle.loads(bytes(priData, "iso8859-1")) # 8 bits + return realCallback(priKey, data) + + return self.db.associate(secondaryDB, _shelf_callback, flags) + + + #def get(self, key, default=None, txn=None, flags=0): + def get(self, *args, **kw): + # We do it with *args and **kw so if the default value wasn't + # given nothing is passed to the extension module. That way + # an exception can be raised if set_get_returns_none is turned + # off. + data = self.db.get(*args, **kw) + try: + return cPickle.loads(data) + except (EOFError, TypeError, cPickle.UnpicklingError): + return data # we may be getting the default value, or None, + # so it doesn't need unpickled. + + def get_both(self, key, value, txn=None, flags=0): + data = _dumps(value, self.protocol) + data = self.db.get(key, data, txn, flags) + return cPickle.loads(data) + + + def cursor(self, txn=None, flags=0): + c = DBShelfCursor(self.db.cursor(txn, flags)) + c.protocol = self.protocol + return c + + + def put(self, key, value, txn=None, flags=0): + data = _dumps(value, self.protocol) + return self.db.put(key, data, txn, flags) + + + def join(self, cursorList, flags=0): + raise NotImplementedError + + + #---------------------------------------------- + # Methods allowed to pass-through to self.db + # + # close, delete, fd, get_byteswapped, get_type, has_key, + # key_range, open, remove, rename, stat, sync, + # upgrade, verify, and all set_* methods. + + +#--------------------------------------------------------------------------- + +class DBShelfCursor: + """ + """ + def __init__(self, cursor): + self.dbc = cursor + + def __del__(self): + self.close() + + + def __getattr__(self, name): + """Some methods we can just pass through to the cursor object. (See below)""" + return getattr(self.dbc, name) + + + #---------------------------------------------- + + def dup(self, flags=0): + c = DBShelfCursor(self.dbc.dup(flags)) + c.protocol = self.protocol + return c + + + def put(self, key, value, flags=0): + data = _dumps(value, self.protocol) + return self.dbc.put(key, data, flags) + + + def get(self, *args): + count = len(args) # a method overloading hack + method = getattr(self, 'get_%d' % count) + method(*args) + + def get_1(self, flags): + rec = self.dbc.get(flags) + return self._extract(rec) + + def get_2(self, key, flags): + rec = self.dbc.get(key, flags) + return self._extract(rec) + + def get_3(self, key, value, flags): + data = _dumps(value, self.protocol) + rec = self.dbc.get(key, flags) + return self._extract(rec) + + + def current(self, flags=0): return self.get_1(flags|db.DB_CURRENT) + def first(self, flags=0): return self.get_1(flags|db.DB_FIRST) + def last(self, flags=0): return self.get_1(flags|db.DB_LAST) + def next(self, flags=0): return self.get_1(flags|db.DB_NEXT) + def prev(self, flags=0): return self.get_1(flags|db.DB_PREV) + def consume(self, flags=0): return self.get_1(flags|db.DB_CONSUME) + def next_dup(self, flags=0): return self.get_1(flags|db.DB_NEXT_DUP) + def next_nodup(self, flags=0): return self.get_1(flags|db.DB_NEXT_NODUP) + def prev_nodup(self, flags=0): return self.get_1(flags|db.DB_PREV_NODUP) + + + def get_both(self, key, value, flags=0): + data = _dumps(value, self.protocol) + rec = self.dbc.get_both(key, flags) + return self._extract(rec) + + + def set(self, key, flags=0): + rec = self.dbc.set(key, flags) + return self._extract(rec) + + def set_range(self, key, flags=0): + rec = self.dbc.set_range(key, flags) + return self._extract(rec) + + def set_recno(self, recno, flags=0): + rec = self.dbc.set_recno(recno, flags) + return self._extract(rec) + + set_both = get_both + + def _extract(self, rec): + if rec is None: + return None + else: + key, data = rec + # Safe in Python 2.x because expresion short circuit + if sys.version_info[0] < 3 or isinstance(data, bytes) : + return key, cPickle.loads(data) + else : + return key, cPickle.loads(bytes(data, "iso8859-1")) # 8 bits + + #---------------------------------------------- + # Methods allowed to pass-through to self.dbc + # + # close, count, delete, get_recno, join_item + + +#--------------------------------------------------------------------------- diff --git a/test/ok_2.7/bsddb/dbutils.py b/test/ok_2.7/bsddb/dbutils.py new file mode 100644 index 00000000..02a686f5 --- /dev/null +++ b/test/ok_2.7/bsddb/dbutils.py @@ -0,0 +1,83 @@ +#------------------------------------------------------------------------ +# +# Copyright (C) 2000 Autonomous Zone Industries +# +# License: This is free software. You may use this software for any +# purpose including modification/redistribution, so long as +# this header remains intact and that you do not claim any +# rights of ownership or authorship of this software. This +# software has been tested, but no warranty is expressed or +# implied. +# +# Author: Gregory P. Smith +# +# Note: I don't know how useful this is in reality since when a +# DBLockDeadlockError happens the current transaction is supposed to be +# aborted. If it doesn't then when the operation is attempted again +# the deadlock is still happening... +# --Robin +# +#------------------------------------------------------------------------ + + +# +# import the time.sleep function in a namespace safe way to allow +# "from bsddb.dbutils import *" +# +from time import sleep as _sleep + +import sys +absolute_import = (sys.version_info[0] >= 3) +if absolute_import : + # Because this syntaxis is not valid before Python 2.5 + exec("from . import db") +else : + import db + +# always sleep at least N seconds between retrys +_deadlock_MinSleepTime = 1.0/128 +# never sleep more than N seconds between retrys +_deadlock_MaxSleepTime = 3.14159 + +# Assign a file object to this for a "sleeping" message to be written to it +# each retry +_deadlock_VerboseFile = None + + +def DeadlockWrap(function, *_args, **_kwargs): + """DeadlockWrap(function, *_args, **_kwargs) - automatically retries + function in case of a database deadlock. + + This is a function intended to be used to wrap database calls such + that they perform retrys with exponentially backing off sleeps in + between when a DBLockDeadlockError exception is raised. + + A 'max_retries' parameter may optionally be passed to prevent it + from retrying forever (in which case the exception will be reraised). + + d = DB(...) + d.open(...) + DeadlockWrap(d.put, "foo", data="bar") # set key "foo" to "bar" + """ + sleeptime = _deadlock_MinSleepTime + max_retries = _kwargs.get('max_retries', -1) + if 'max_retries' in _kwargs: + del _kwargs['max_retries'] + while True: + try: + return function(*_args, **_kwargs) + except db.DBLockDeadlockError: + if _deadlock_VerboseFile: + _deadlock_VerboseFile.write( + 'dbutils.DeadlockWrap: sleeping %1.3f\n' % sleeptime) + _sleep(sleeptime) + # exponential backoff in the sleep time + sleeptime *= 2 + if sleeptime > _deadlock_MaxSleepTime: + sleeptime = _deadlock_MaxSleepTime + max_retries -= 1 + if max_retries == -1: + raise + + +#------------------------------------------------------------------------ diff --git a/test/ok_2.7/calendar.py b/test/ok_2.7/calendar.py new file mode 100644 index 00000000..d3bd2362 --- /dev/null +++ b/test/ok_2.7/calendar.py @@ -0,0 +1,713 @@ +"""Calendar printing functions + +Note when comparing these calendars to the ones printed by cal(1): By +default, these calendars have Monday as the first day of the week, and +Sunday as the last (the European convention). Use setfirstweekday() to +set the first day of the week (0=Monday, 6=Sunday).""" + +import sys +import datetime +import locale as _locale + +__all__ = ["IllegalMonthError", "IllegalWeekdayError", "setfirstweekday", + "firstweekday", "isleap", "leapdays", "weekday", "monthrange", + "monthcalendar", "prmonth", "month", "prcal", "calendar", + "timegm", "month_name", "month_abbr", "day_name", "day_abbr"] + +# Exception raised for bad input (with string parameter for details) +error = ValueError + +# Exceptions raised for bad input +class IllegalMonthError(ValueError): + def __init__(self, month): + self.month = month + def __str__(self): + return "bad month number %r; must be 1-12" % self.month + + +class IllegalWeekdayError(ValueError): + def __init__(self, weekday): + self.weekday = weekday + def __str__(self): + return "bad weekday number %r; must be 0 (Monday) to 6 (Sunday)" % self.weekday + + +# Constants for months referenced later +January = 1 +February = 2 + +# Number of days per month (except for February in leap years) +mdays = [0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] + +# This module used to have hard-coded lists of day and month names, as +# English strings. The classes following emulate a read-only version of +# that, but supply localized names. Note that the values are computed +# fresh on each call, in case the user changes locale between calls. + +class _localized_month: + + _months = [datetime.date(2001, i+1, 1).strftime for i in range(12)] + _months.insert(0, lambda x: "") + + def __init__(self, format): + self.format = format + + def __getitem__(self, i): + funcs = self._months[i] + if isinstance(i, slice): + return [f(self.format) for f in funcs] + else: + return funcs(self.format) + + def __len__(self): + return 13 + + +class _localized_day: + + # January 1, 2001, was a Monday. + _days = [datetime.date(2001, 1, i+1).strftime for i in range(7)] + + def __init__(self, format): + self.format = format + + def __getitem__(self, i): + funcs = self._days[i] + if isinstance(i, slice): + return [f(self.format) for f in funcs] + else: + return funcs(self.format) + + def __len__(self): + return 7 + + +# Full and abbreviated names of weekdays +day_name = _localized_day('%A') +day_abbr = _localized_day('%a') + +# Full and abbreviated names of months (1-based arrays!!!) +month_name = _localized_month('%B') +month_abbr = _localized_month('%b') + +# Constants for weekdays +(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY) = range(7) + + +def isleap(year): + """Return True for leap years, False for non-leap years.""" + return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) + + +def leapdays(y1, y2): + """Return number of leap years in range [y1, y2). + Assume y1 <= y2.""" + y1 -= 1 + y2 -= 1 + return (y2//4 - y1//4) - (y2//100 - y1//100) + (y2//400 - y1//400) + + +def weekday(year, month, day): + """Return weekday (0-6 ~ Mon-Sun) for year (1970-...), month (1-12), + day (1-31).""" + return datetime.date(year, month, day).weekday() + + +def monthrange(year, month): + """Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for + year, month.""" + if not 1 <= month <= 12: + raise IllegalMonthError(month) + day1 = weekday(year, month, 1) + ndays = mdays[month] + (month == February and isleap(year)) + return day1, ndays + + +class Calendar(object): + """ + Base calendar class. This class doesn't do any formatting. It simply + provides data to subclasses. + """ + + def __init__(self, firstweekday=0): + self.firstweekday = firstweekday # 0 = Monday, 6 = Sunday + + def getfirstweekday(self): + return self._firstweekday % 7 + + def setfirstweekday(self, firstweekday): + self._firstweekday = firstweekday + + firstweekday = property(getfirstweekday, setfirstweekday) + + def iterweekdays(self): + """ + Return a iterator for one week of weekday numbers starting with the + configured first one. + """ + for i in range(self.firstweekday, self.firstweekday + 7): + yield i%7 + + def itermonthdates(self, year, month): + """ + Return an iterator for one month. The iterator will yield datetime.date + values and will always iterate through complete weeks, so it will yield + dates outside the specified month. + """ + date = datetime.date(year, month, 1) + # Go back to the beginning of the week + days = (date.weekday() - self.firstweekday) % 7 + date -= datetime.timedelta(days=days) + oneday = datetime.timedelta(days=1) + while True: + yield date + try: + date += oneday + except OverflowError: + # Adding one day could fail after datetime.MAXYEAR + break + if date.month != month and date.weekday() == self.firstweekday: + break + + def itermonthdays2(self, year, month): + """ + Like itermonthdates(), but will yield (day number, weekday number) + tuples. For days outside the specified month the day number is 0. + """ + for date in self.itermonthdates(year, month): + if date.month != month: + yield (0, date.weekday()) + else: + yield (date.day, date.weekday()) + + def itermonthdays(self, year, month): + """ + Like itermonthdates(), but will yield day numbers. For days outside + the specified month the day number is 0. + """ + for date in self.itermonthdates(year, month): + if date.month != month: + yield 0 + else: + yield date.day + + def monthdatescalendar(self, year, month): + """ + Return a matrix (list of lists) representing a month's calendar. + Each row represents a week; week entries are datetime.date values. + """ + dates = list(self.itermonthdates(year, month)) + return [ dates[i:i+7] for i in range(0, len(dates), 7) ] + + def monthdays2calendar(self, year, month): + """ + Return a matrix representing a month's calendar. + Each row represents a week; week entries are + (day number, weekday number) tuples. Day numbers outside this month + are zero. + """ + days = list(self.itermonthdays2(year, month)) + return [ days[i:i+7] for i in range(0, len(days), 7) ] + + def monthdayscalendar(self, year, month): + """ + Return a matrix representing a month's calendar. + Each row represents a week; days outside this month are zero. + """ + days = list(self.itermonthdays(year, month)) + return [ days[i:i+7] for i in range(0, len(days), 7) ] + + def yeardatescalendar(self, year, width=3): + """ + Return the data for the specified year ready for formatting. The return + value is a list of month rows. Each month row contains up to width months. + Each month contains between 4 and 6 weeks and each week contains 1-7 + days. Days are datetime.date objects. + """ + months = [ + self.monthdatescalendar(year, i) + for i in range(January, January+12) + ] + return [months[i:i+width] for i in range(0, len(months), width) ] + + def yeardays2calendar(self, year, width=3): + """ + Return the data for the specified year ready for formatting (similar to + yeardatescalendar()). Entries in the week lists are + (day number, weekday number) tuples. Day numbers outside this month are + zero. + """ + months = [ + self.monthdays2calendar(year, i) + for i in range(January, January+12) + ] + return [months[i:i+width] for i in range(0, len(months), width) ] + + def yeardayscalendar(self, year, width=3): + """ + Return the data for the specified year ready for formatting (similar to + yeardatescalendar()). Entries in the week lists are day numbers. + Day numbers outside this month are zero. + """ + months = [ + self.monthdayscalendar(year, i) + for i in range(January, January+12) + ] + return [months[i:i+width] for i in range(0, len(months), width) ] + + +class TextCalendar(Calendar): + """ + Subclass of Calendar that outputs a calendar as a simple plain text + similar to the UNIX program cal. + """ + + def prweek(self, theweek, width): + """ + Print a single week (no newline). + """ + print self.formatweek(theweek, width), + + def formatday(self, day, weekday, width): + """ + Returns a formatted day. + """ + if day == 0: + s = '' + else: + s = '%2i' % day # right-align single-digit days + return s.center(width) + + def formatweek(self, theweek, width): + """ + Returns a single week in a string (no newline). + """ + return ' '.join(self.formatday(d, wd, width) for (d, wd) in theweek) + + def formatweekday(self, day, width): + """ + Returns a formatted week day name. + """ + if width >= 9: + names = day_name + else: + names = day_abbr + return names[day][:width].center(width) + + def formatweekheader(self, width): + """ + Return a header for a week. + """ + return ' '.join(self.formatweekday(i, width) for i in self.iterweekdays()) + + def formatmonthname(self, theyear, themonth, width, withyear=True): + """ + Return a formatted month name. + """ + s = month_name[themonth] + if withyear: + s = "%s %r" % (s, theyear) + return s.center(width) + + def prmonth(self, theyear, themonth, w=0, l=0): + """ + Print a month's calendar. + """ + print self.formatmonth(theyear, themonth, w, l), + + def formatmonth(self, theyear, themonth, w=0, l=0): + """ + Return a month's calendar string (multi-line). + """ + w = max(2, w) + l = max(1, l) + s = self.formatmonthname(theyear, themonth, 7 * (w + 1) - 1) + s = s.rstrip() + s += '\n' * l + s += self.formatweekheader(w).rstrip() + s += '\n' * l + for week in self.monthdays2calendar(theyear, themonth): + s += self.formatweek(week, w).rstrip() + s += '\n' * l + return s + + def formatyear(self, theyear, w=2, l=1, c=6, m=3): + """ + Returns a year's calendar as a multi-line string. + """ + w = max(2, w) + l = max(1, l) + c = max(2, c) + colwidth = (w + 1) * 7 - 1 + v = [] + a = v.append + a(repr(theyear).center(colwidth*m+c*(m-1)).rstrip()) + a('\n'*l) + header = self.formatweekheader(w) + for (i, row) in enumerate(self.yeardays2calendar(theyear, m)): + # months in this row + months = range(m*i+1, min(m*(i+1)+1, 13)) + a('\n'*l) + names = (self.formatmonthname(theyear, k, colwidth, False) + for k in months) + a(formatstring(names, colwidth, c).rstrip()) + a('\n'*l) + headers = (header for k in months) + a(formatstring(headers, colwidth, c).rstrip()) + a('\n'*l) + # max number of weeks for this row + height = max(len(cal) for cal in row) + for j in range(height): + weeks = [] + for cal in row: + if j >= len(cal): + weeks.append('') + else: + weeks.append(self.formatweek(cal[j], w)) + a(formatstring(weeks, colwidth, c).rstrip()) + a('\n' * l) + return ''.join(v) + + def pryear(self, theyear, w=0, l=0, c=6, m=3): + """Print a year's calendar.""" + print self.formatyear(theyear, w, l, c, m) + + +class HTMLCalendar(Calendar): + """ + This calendar returns complete HTML pages. + """ + + # CSS classes for the day s + cssclasses = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"] + + def formatday(self, day, weekday): + """ + Return a day as a table cell. + """ + if day == 0: + return ' ' # day outside month + else: + return '%d' % (self.cssclasses[weekday], day) + + def formatweek(self, theweek): + """ + Return a complete week as a table row. + """ + s = ''.join(self.formatday(d, wd) for (d, wd) in theweek) + return '%s' % s + + def formatweekday(self, day): + """ + Return a weekday name as a table header. + """ + return '%s' % (self.cssclasses[day], day_abbr[day]) + + def formatweekheader(self): + """ + Return a header for a week as a table row. + """ + s = ''.join(self.formatweekday(i) for i in self.iterweekdays()) + return '%s' % s + + def formatmonthname(self, theyear, themonth, withyear=True): + """ + Return a month name as a table row. + """ + if withyear: + s = '%s %s' % (month_name[themonth], theyear) + else: + s = '%s' % month_name[themonth] + return '%s' % s + + def formatmonth(self, theyear, themonth, withyear=True): + """ + Return a formatted month as a table. + """ + v = [] + a = v.append + a('') + a('\n') + a(self.formatmonthname(theyear, themonth, withyear=withyear)) + a('\n') + a(self.formatweekheader()) + a('\n') + for week in self.monthdays2calendar(theyear, themonth): + a(self.formatweek(week)) + a('\n') + a('
') + a('\n') + return ''.join(v) + + def formatyear(self, theyear, width=3): + """ + Return a formatted year as a table of tables. + """ + v = [] + a = v.append + width = max(width, 1) + a('') + a('\n') + a('' % (width, theyear)) + for i in range(January, January+12, width): + # months in this row + months = range(i, min(i+width, 13)) + a('') + for m in months: + a('') + a('') + a('
%s
') + a(self.formatmonth(theyear, m, withyear=False)) + a('
') + return ''.join(v) + + def formatyearpage(self, theyear, width=3, css='calendar.css', encoding=None): + """ + Return a formatted year as a complete HTML page. + """ + if encoding is None: + encoding = sys.getdefaultencoding() + v = [] + a = v.append + a('\n' % encoding) + a('\n') + a('\n') + a('\n') + a('\n' % encoding) + if css is not None: + a('\n' % css) + a('Calendar for %d\n' % theyear) + a('\n') + a('\n') + a(self.formatyear(theyear, width)) + a('\n') + a('\n') + return ''.join(v).encode(encoding, "xmlcharrefreplace") + + +class TimeEncoding: + def __init__(self, locale): + self.locale = locale + + def __enter__(self): + self.oldlocale = _locale.getlocale(_locale.LC_TIME) + _locale.setlocale(_locale.LC_TIME, self.locale) + return _locale.getlocale(_locale.LC_TIME)[1] + + def __exit__(self, *args): + _locale.setlocale(_locale.LC_TIME, self.oldlocale) + + +class LocaleTextCalendar(TextCalendar): + """ + This class can be passed a locale name in the constructor and will return + month and weekday names in the specified locale. If this locale includes + an encoding all strings containing month and weekday names will be returned + as unicode. + """ + + def __init__(self, firstweekday=0, locale=None): + TextCalendar.__init__(self, firstweekday) + if locale is None: + locale = _locale.getdefaultlocale() + self.locale = locale + + def formatweekday(self, day, width): + with TimeEncoding(self.locale) as encoding: + if width >= 9: + names = day_name + else: + names = day_abbr + name = names[day] + if encoding is not None: + name = name.decode(encoding) + return name[:width].center(width) + + def formatmonthname(self, theyear, themonth, width, withyear=True): + with TimeEncoding(self.locale) as encoding: + s = month_name[themonth] + if encoding is not None: + s = s.decode(encoding) + if withyear: + s = "%s %r" % (s, theyear) + return s.center(width) + + +class LocaleHTMLCalendar(HTMLCalendar): + """ + This class can be passed a locale name in the constructor and will return + month and weekday names in the specified locale. If this locale includes + an encoding all strings containing month and weekday names will be returned + as unicode. + """ + def __init__(self, firstweekday=0, locale=None): + HTMLCalendar.__init__(self, firstweekday) + if locale is None: + locale = _locale.getdefaultlocale() + self.locale = locale + + def formatweekday(self, day): + with TimeEncoding(self.locale) as encoding: + s = day_abbr[day] + if encoding is not None: + s = s.decode(encoding) + return '%s' % (self.cssclasses[day], s) + + def formatmonthname(self, theyear, themonth, withyear=True): + with TimeEncoding(self.locale) as encoding: + s = month_name[themonth] + if encoding is not None: + s = s.decode(encoding) + if withyear: + s = '%s %s' % (s, theyear) + return '%s' % s + + +# Support for old module level interface +c = TextCalendar() + +firstweekday = c.getfirstweekday + +def setfirstweekday(firstweekday): + try: + firstweekday.__index__ + except AttributeError: + raise IllegalWeekdayError(firstweekday) + if not MONDAY <= firstweekday <= SUNDAY: + raise IllegalWeekdayError(firstweekday) + c.firstweekday = firstweekday + +monthcalendar = c.monthdayscalendar +prweek = c.prweek +week = c.formatweek +weekheader = c.formatweekheader +prmonth = c.prmonth +month = c.formatmonth +calendar = c.formatyear +prcal = c.pryear + + +# Spacing of month columns for multi-column year calendar +_colwidth = 7*3 - 1 # Amount printed by prweek() +_spacing = 6 # Number of spaces between columns + + +def format(cols, colwidth=_colwidth, spacing=_spacing): + """Prints multi-column formatting for year calendars""" + print formatstring(cols, colwidth, spacing) + + +def formatstring(cols, colwidth=_colwidth, spacing=_spacing): + """Returns a string formatted from n strings, centered within n columns.""" + spacing *= ' ' + return spacing.join(c.center(colwidth) for c in cols) + + +EPOCH = 1970 +_EPOCH_ORD = datetime.date(EPOCH, 1, 1).toordinal() + + +def timegm(tuple): + """Unrelated but handy function to calculate Unix timestamp from GMT.""" + year, month, day, hour, minute, second = tuple[:6] + days = datetime.date(year, month, 1).toordinal() - _EPOCH_ORD + day - 1 + hours = days*24 + hour + minutes = hours*60 + minute + seconds = minutes*60 + second + return seconds + + +def main(args): + import optparse + parser = optparse.OptionParser(usage="usage: %prog [options] [year [month]]") + parser.add_option( + "-w", "--width", + dest="width", type="int", default=2, + help="width of date column (default 2, text only)" + ) + parser.add_option( + "-l", "--lines", + dest="lines", type="int", default=1, + help="number of lines for each week (default 1, text only)" + ) + parser.add_option( + "-s", "--spacing", + dest="spacing", type="int", default=6, + help="spacing between months (default 6, text only)" + ) + parser.add_option( + "-m", "--months", + dest="months", type="int", default=3, + help="months per row (default 3, text only)" + ) + parser.add_option( + "-c", "--css", + dest="css", default="calendar.css", + help="CSS to use for page (html only)" + ) + parser.add_option( + "-L", "--locale", + dest="locale", default=None, + help="locale to be used from month and weekday names" + ) + parser.add_option( + "-e", "--encoding", + dest="encoding", default=None, + help="Encoding to use for output" + ) + parser.add_option( + "-t", "--type", + dest="type", default="text", + choices=("text", "html"), + help="output type (text or html)" + ) + + (options, args) = parser.parse_args(args) + + if options.locale and not options.encoding: + parser.error("if --locale is specified --encoding is required") + sys.exit(1) + + locale = options.locale, options.encoding + + if options.type == "html": + if options.locale: + cal = LocaleHTMLCalendar(locale=locale) + else: + cal = HTMLCalendar() + encoding = options.encoding + if encoding is None: + encoding = sys.getdefaultencoding() + optdict = dict(encoding=encoding, css=options.css) + if len(args) == 1: + print cal.formatyearpage(datetime.date.today().year, **optdict) + elif len(args) == 2: + print cal.formatyearpage(int(args[1]), **optdict) + else: + parser.error("incorrect number of arguments") + sys.exit(1) + else: + if options.locale: + cal = LocaleTextCalendar(locale=locale) + else: + cal = TextCalendar() + optdict = dict(w=options.width, l=options.lines) + if len(args) != 3: + optdict["c"] = options.spacing + optdict["m"] = options.months + if len(args) == 1: + result = cal.formatyear(datetime.date.today().year, **optdict) + elif len(args) == 2: + result = cal.formatyear(int(args[1]), **optdict) + elif len(args) == 3: + result = cal.formatmonth(int(args[1]), int(args[2]), **optdict) + else: + parser.error("incorrect number of arguments") + sys.exit(1) + if options.encoding: + result = result.encode(options.encoding) + print result + + +if __name__ == "__main__": + main(sys.argv) diff --git a/test/ok_2.7/cgitb.py b/test/ok_2.7/cgitb.py new file mode 100644 index 00000000..8acc4b75 --- /dev/null +++ b/test/ok_2.7/cgitb.py @@ -0,0 +1,323 @@ +"""More comprehensive traceback formatting for Python scripts. + +To enable this module, do: + + import cgitb; cgitb.enable() + +at the top of your script. The optional arguments to enable() are: + + display - if true, tracebacks are displayed in the web browser + logdir - if set, tracebacks are written to files in this directory + context - number of lines of source code to show for each stack frame + format - 'text' or 'html' controls the output format + +By default, tracebacks are displayed but not saved, the context is 5 lines +and the output format is 'html' (for backwards compatibility with the +original use of this module) + +Alternatively, if you have caught an exception and want cgitb to display it +for you, call cgitb.handler(). The optional argument to handler() is a +3-item tuple (etype, evalue, etb) just like the value of sys.exc_info(). +The default handler displays output as HTML. + +""" +import inspect +import keyword +import linecache +import os +import pydoc +import sys +import tempfile +import time +import tokenize +import traceback +import types + +def reset(): + """Return a string that resets the CGI and browser to a known state.""" + return ''' + --> --> + + ''' + +__UNDEF__ = [] # a special sentinel object +def small(text): + if text: + return '' + text + '' + else: + return '' + +def strong(text): + if text: + return '' + text + '' + else: + return '' + +def grey(text): + if text: + return '' + text + '' + else: + return '' + +def lookup(name, frame, locals): + """Find the value for a given name in the given environment.""" + if name in locals: + return 'local', locals[name] + if name in frame.f_globals: + return 'global', frame.f_globals[name] + if '__builtins__' in frame.f_globals: + builtins = frame.f_globals['__builtins__'] + if type(builtins) is type({}): + if name in builtins: + return 'builtin', builtins[name] + else: + if hasattr(builtins, name): + return 'builtin', getattr(builtins, name) + return None, __UNDEF__ + +def scanvars(reader, frame, locals): + """Scan one logical line of Python and look up values of variables used.""" + vars, lasttoken, parent, prefix, value = [], None, None, '', __UNDEF__ + for ttype, token, start, end, line in tokenize.generate_tokens(reader): + if ttype == tokenize.NEWLINE: break + if ttype == tokenize.NAME and token not in keyword.kwlist: + if lasttoken == '.': + if parent is not __UNDEF__: + value = getattr(parent, token, __UNDEF__) + vars.append((prefix + token, prefix, value)) + else: + where, value = lookup(token, frame, locals) + vars.append((token, where, value)) + elif token == '.': + prefix += lasttoken + '.' + parent = value + else: + parent, prefix = None, '' + lasttoken = token + return vars + +def html(einfo, context=5): + """Return a nice HTML document describing a given traceback.""" + etype, evalue, etb = einfo + if type(etype) is types.ClassType: + etype = etype.__name__ + pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable + date = time.ctime(time.time()) + head = '' + pydoc.html.heading( + '%s' % + strong(pydoc.html.escape(str(etype))), + '#ffffff', '#6622aa', pyver + '
' + date) + ''' +

A problem occurred in a Python script. Here is the sequence of +function calls leading up to the error, in the order they occurred.

''' + + indent = '' + small(' ' * 5) + ' ' + frames = [] + records = inspect.getinnerframes(etb, context) + for frame, file, lnum, func, lines, index in records: + if file: + file = os.path.abspath(file) + link = '%s' % (file, pydoc.html.escape(file)) + else: + file = link = '?' + args, varargs, varkw, locals = inspect.getargvalues(frame) + call = '' + if func != '?': + call = 'in ' + strong(func) + \ + inspect.formatargvalues(args, varargs, varkw, locals, + formatvalue=lambda value: '=' + pydoc.html.repr(value)) + + highlight = {} + def reader(lnum=[lnum]): + highlight[lnum[0]] = 1 + try: return linecache.getline(file, lnum[0]) + finally: lnum[0] += 1 + vars = scanvars(reader, frame, locals) + + rows = ['%s%s %s' % + (' ', link, call)] + if index is not None: + i = lnum - index + for line in lines: + num = small(' ' * (5-len(str(i))) + str(i)) + ' ' + if i in highlight: + line = '=>%s%s' % (num, pydoc.html.preformat(line)) + rows.append('%s' % line) + else: + line = '  %s%s' % (num, pydoc.html.preformat(line)) + rows.append('%s' % grey(line)) + i += 1 + + done, dump = {}, [] + for name, where, value in vars: + if name in done: continue + done[name] = 1 + if value is not __UNDEF__: + if where in ('global', 'builtin'): + name = ('%s ' % where) + strong(name) + elif where == 'local': + name = strong(name) + else: + name = where + strong(name.split('.')[-1]) + dump.append('%s = %s' % (name, pydoc.html.repr(value))) + else: + dump.append(name + ' undefined') + + rows.append('%s' % small(grey(', '.join(dump)))) + frames.append(''' + +%s
''' % '\n'.join(rows)) + + exception = ['

%s: %s' % (strong(pydoc.html.escape(str(etype))), + pydoc.html.escape(str(evalue)))] + if isinstance(evalue, BaseException): + for name in dir(evalue): + if name[:1] == '_': continue + value = pydoc.html.repr(getattr(evalue, name)) + exception.append('\n
%s%s =\n%s' % (indent, name, value)) + + return head + ''.join(frames) + ''.join(exception) + ''' + + + +''' % pydoc.html.escape( + ''.join(traceback.format_exception(etype, evalue, etb))) + +def text(einfo, context=5): + """Return a plain text document describing a given traceback.""" + etype, evalue, etb = einfo + if type(etype) is types.ClassType: + etype = etype.__name__ + pyver = 'Python ' + sys.version.split()[0] + ': ' + sys.executable + date = time.ctime(time.time()) + head = "%s\n%s\n%s\n" % (str(etype), pyver, date) + ''' +A problem occurred in a Python script. Here is the sequence of +function calls leading up to the error, in the order they occurred. +''' + + frames = [] + records = inspect.getinnerframes(etb, context) + for frame, file, lnum, func, lines, index in records: + file = file and os.path.abspath(file) or '?' + args, varargs, varkw, locals = inspect.getargvalues(frame) + call = '' + if func != '?': + call = 'in ' + func + \ + inspect.formatargvalues(args, varargs, varkw, locals, + formatvalue=lambda value: '=' + pydoc.text.repr(value)) + + highlight = {} + def reader(lnum=[lnum]): + highlight[lnum[0]] = 1 + try: return linecache.getline(file, lnum[0]) + finally: lnum[0] += 1 + vars = scanvars(reader, frame, locals) + + rows = [' %s %s' % (file, call)] + if index is not None: + i = lnum - index + for line in lines: + num = '%5d ' % i + rows.append(num+line.rstrip()) + i += 1 + + done, dump = {}, [] + for name, where, value in vars: + if name in done: continue + done[name] = 1 + if value is not __UNDEF__: + if where == 'global': name = 'global ' + name + elif where != 'local': name = where + name.split('.')[-1] + dump.append('%s = %s' % (name, pydoc.text.repr(value))) + else: + dump.append(name + ' undefined') + + rows.append('\n'.join(dump)) + frames.append('\n%s\n' % '\n'.join(rows)) + + exception = ['%s: %s' % (str(etype), str(evalue))] + if isinstance(evalue, BaseException): + for name in dir(evalue): + value = pydoc.text.repr(getattr(evalue, name)) + exception.append('\n%s%s = %s' % (" "*4, name, value)) + + return head + ''.join(frames) + ''.join(exception) + ''' + +The above is a description of an error in a Python program. Here is +the original traceback: + +%s +''' % ''.join(traceback.format_exception(etype, evalue, etb)) + +class Hook: + """A hook to replace sys.excepthook that shows tracebacks in HTML.""" + + def __init__(self, display=1, logdir=None, context=5, file=None, + format="html"): + self.display = display # send tracebacks to browser if true + self.logdir = logdir # log tracebacks to files if not None + self.context = context # number of source code lines per frame + self.file = file or sys.stdout # place to send the output + self.format = format + + def __call__(self, etype, evalue, etb): + self.handle((etype, evalue, etb)) + + def handle(self, info=None): + info = info or sys.exc_info() + if self.format == "html": + self.file.write(reset()) + + formatter = (self.format=="html") and html or text + plain = False + try: + doc = formatter(info, self.context) + except: # just in case something goes wrong + doc = ''.join(traceback.format_exception(*info)) + plain = True + + if self.display: + if plain: + doc = doc.replace('&', '&').replace('<', '<') + self.file.write('

' + doc + '
\n') + else: + self.file.write(doc + '\n') + else: + self.file.write('

A problem occurred in a Python script.\n') + + if self.logdir is not None: + suffix = ['.txt', '.html'][self.format=="html"] + (fd, path) = tempfile.mkstemp(suffix=suffix, dir=self.logdir) + + try: + file = os.fdopen(fd, 'w') + file.write(doc) + file.close() + msg = '%s contains the description of this error.' % path + except: + msg = 'Tried to save traceback to %s, but failed.' % path + + if self.format == 'html': + self.file.write('

%s

\n' % msg) + else: + self.file.write(msg + '\n') + try: + self.file.flush() + except: pass + +handler = Hook().handle +def enable(display=1, logdir=None, context=5, format="html"): + """Install an exception handler that formats tracebacks as HTML. + + The optional argument 'display' can be set to 0 to suppress sending the + traceback to the browser, and 'logdir' can be set to a directory to cause + tracebacks to be written to files there.""" + sys.excepthook = Hook(display=display, logdir=logdir, + context=context, format=format) diff --git a/test/ok_2.7/chunk.py b/test/ok_2.7/chunk.py new file mode 100644 index 00000000..a8fbc105 --- /dev/null +++ b/test/ok_2.7/chunk.py @@ -0,0 +1,167 @@ +"""Simple class to read IFF chunks. + +An IFF chunk (used in formats such as AIFF, TIFF, RMFF (RealMedia File +Format)) has the following structure: + ++----------------+ +| ID (4 bytes) | ++----------------+ +| size (4 bytes) | ++----------------+ +| data | +| ... | ++----------------+ + +The ID is a 4-byte string which identifies the type of chunk. + +The size field (a 32-bit value, encoded using big-endian byte order) +gives the size of the whole chunk, including the 8-byte header. + +Usually an IFF-type file consists of one or more chunks. The proposed +usage of the Chunk class defined here is to instantiate an instance at +the start of each chunk and read from the instance until it reaches +the end, after which a new instance can be instantiated. At the end +of the file, creating a new instance will fail with a EOFError +exception. + +Usage: +while True: + try: + chunk = Chunk(file) + except EOFError: + break + chunktype = chunk.getname() + while True: + data = chunk.read(nbytes) + if not data: + pass + # do something with data + +The interface is file-like. The implemented methods are: +read, close, seek, tell, isatty. +Extra methods are: skip() (called by close, skips to the end of the chunk), +getname() (returns the name (ID) of the chunk) + +The __init__ method has one required argument, a file-like object +(including a chunk instance), and one optional argument, a flag which +specifies whether or not chunks are aligned on 2-byte boundaries. The +default is 1, i.e. aligned. +""" + +class Chunk: + def __init__(self, file, align=True, bigendian=True, inclheader=False): + import struct + self.closed = False + self.align = align # whether to align to word (2-byte) boundaries + if bigendian: + strflag = '>' + else: + strflag = '<' + self.file = file + self.chunkname = file.read(4) + if len(self.chunkname) < 4: + raise EOFError + try: + self.chunksize = struct.unpack(strflag+'L', file.read(4))[0] + except struct.error: + raise EOFError + if inclheader: + self.chunksize = self.chunksize - 8 # subtract header + self.size_read = 0 + try: + self.offset = self.file.tell() + except (AttributeError, IOError): + self.seekable = False + else: + self.seekable = True + + def getname(self): + """Return the name (ID) of the current chunk.""" + return self.chunkname + + def getsize(self): + """Return the size of the current chunk.""" + return self.chunksize + + def close(self): + if not self.closed: + self.skip() + self.closed = True + + def isatty(self): + if self.closed: + raise ValueError, "I/O operation on closed file" + return False + + def seek(self, pos, whence=0): + """Seek to specified position into the chunk. + Default position is 0 (start of chunk). + If the file is not seekable, this will result in an error. + """ + + if self.closed: + raise ValueError, "I/O operation on closed file" + if not self.seekable: + raise IOError, "cannot seek" + if whence == 1: + pos = pos + self.size_read + elif whence == 2: + pos = pos + self.chunksize + if pos < 0 or pos > self.chunksize: + raise RuntimeError + self.file.seek(self.offset + pos, 0) + self.size_read = pos + + def tell(self): + if self.closed: + raise ValueError, "I/O operation on closed file" + return self.size_read + + def read(self, size=-1): + """Read at most size bytes from the chunk. + If size is omitted or negative, read until the end + of the chunk. + """ + + if self.closed: + raise ValueError, "I/O operation on closed file" + if self.size_read >= self.chunksize: + return '' + if size < 0: + size = self.chunksize - self.size_read + if size > self.chunksize - self.size_read: + size = self.chunksize - self.size_read + data = self.file.read(size) + self.size_read = self.size_read + len(data) + if self.size_read == self.chunksize and \ + self.align and \ + (self.chunksize & 1): + dummy = self.file.read(1) + self.size_read = self.size_read + len(dummy) + return data + + def skip(self): + """Skip the rest of the chunk. + If you are not interested in the contents of the chunk, + this method should be called so that the file points to + the start of the next chunk. + """ + + if self.closed: + raise ValueError, "I/O operation on closed file" + if self.seekable: + try: + n = self.chunksize - self.size_read + # maybe fix alignment + if self.align and (self.chunksize & 1): + n = n + 1 + self.file.seek(n, 1) + self.size_read = self.size_read + n + return + except IOError: + pass + while self.size_read < self.chunksize: + n = min(8192, self.chunksize - self.size_read) + dummy = self.read(n) + if not dummy: + raise EOFError diff --git a/test/ok_2.7/codeop.py b/test/ok_2.7/codeop.py new file mode 100644 index 00000000..5616d92a --- /dev/null +++ b/test/ok_2.7/codeop.py @@ -0,0 +1,168 @@ +r"""Utilities to compile possibly incomplete Python source code. + +This module provides two interfaces, broadly similar to the builtin +function compile(), which take program text, a filename and a 'mode' +and: + +- Return code object if the command is complete and valid +- Return None if the command is incomplete +- Raise SyntaxError, ValueError or OverflowError if the command is a + syntax error (OverflowError and ValueError can be produced by + malformed literals). + +Approach: + +First, check if the source consists entirely of blank lines and +comments; if so, replace it with 'pass', because the built-in +parser doesn't always do the right thing for these. + +Compile three times: as is, with \n, and with \n\n appended. If it +compiles as is, it's complete. If it compiles with one \n appended, +we expect more. If it doesn't compile either way, we compare the +error we get when compiling with \n or \n\n appended. If the errors +are the same, the code is broken. But if the errors are different, we +expect more. Not intuitive; not even guaranteed to hold in future +releases; but this matches the compiler's behavior from Python 1.4 +through 2.2, at least. + +Caveat: + +It is possible (but not likely) that the parser stops parsing with a +successful outcome before reaching the end of the source; in this +case, trailing symbols may be ignored instead of causing an error. +For example, a backslash followed by two newlines may be followed by +arbitrary garbage. This will be fixed once the API for the parser is +better. + +The two interfaces are: + +compile_command(source, filename, symbol): + + Compiles a single command in the manner described above. + +CommandCompiler(): + + Instances of this class have __call__ methods identical in + signature to compile_command; the difference is that if the + instance compiles program text containing a __future__ statement, + the instance 'remembers' and compiles all subsequent program texts + with the statement in force. + +The module also provides another class: + +Compile(): + + Instances of this class act like the built-in function compile, + but with 'memory' in the sense described above. +""" + +import __future__ + +_features = [getattr(__future__, fname) + for fname in __future__.all_feature_names] + +__all__ = ["compile_command", "Compile", "CommandCompiler"] + +PyCF_DONT_IMPLY_DEDENT = 0x200 # Matches pythonrun.h + +def _maybe_compile(compiler, source, filename, symbol): + # Check for source consisting of only blank lines and comments + for line in source.split("\n"): + line = line.strip() + if line and line[0] != '#': + break # Leave it alone + else: + if symbol != "eval": + source = "pass" # Replace it with a 'pass' statement + + err = err1 = err2 = None + code = code1 = code2 = None + + try: + code = compiler(source, filename, symbol) + except SyntaxError, err: + pass + + try: + code1 = compiler(source + "\n", filename, symbol) + except SyntaxError, err1: + pass + + try: + code2 = compiler(source + "\n\n", filename, symbol) + except SyntaxError, err2: + pass + + if code: + return code + if not code1 and repr(err1) == repr(err2): + raise SyntaxError, err1 + +def _compile(source, filename, symbol): + return compile(source, filename, symbol, PyCF_DONT_IMPLY_DEDENT) + +def compile_command(source, filename="", symbol="single"): + r"""Compile a command and determine whether it is incomplete. + + Arguments: + + source -- the source string; may contain \n characters + filename -- optional filename from which source was read; default + "" + symbol -- optional grammar start symbol; "single" (default) or "eval" + + Return value / exceptions raised: + + - Return a code object if the command is complete and valid + - Return None if the command is incomplete + - Raise SyntaxError, ValueError or OverflowError if the command is a + syntax error (OverflowError and ValueError can be produced by + malformed literals). + """ + return _maybe_compile(_compile, source, filename, symbol) + +class Compile: + """Instances of this class behave much like the built-in compile + function, but if one is used to compile text containing a future + statement, it "remembers" and compiles all subsequent program texts + with the statement in force.""" + def __init__(self): + self.flags = PyCF_DONT_IMPLY_DEDENT + + def __call__(self, source, filename, symbol): + codeob = compile(source, filename, symbol, self.flags, 1) + for feature in _features: + if codeob.co_flags & feature.compiler_flag: + self.flags |= feature.compiler_flag + return codeob + +class CommandCompiler: + """Instances of this class have __call__ methods identical in + signature to compile_command; the difference is that if the + instance compiles program text containing a __future__ statement, + the instance 'remembers' and compiles all subsequent program texts + with the statement in force.""" + + def __init__(self,): + self.compiler = Compile() + + def __call__(self, source, filename="", symbol="single"): + r"""Compile a command and determine whether it is incomplete. + + Arguments: + + source -- the source string; may contain \n characters + filename -- optional filename from which source was read; + default "" + symbol -- optional grammar start symbol; "single" (default) or + "eval" + + Return value / exceptions raised: + + - Return a code object if the command is complete and valid + - Return None if the command is incomplete + - Raise SyntaxError, ValueError or OverflowError if the command is a + syntax error (OverflowError and ValueError can be produced by + malformed literals). + """ + return _maybe_compile(self.compiler, source, filename, symbol) diff --git a/test/ok_2.7/colorsys.py b/test/ok_2.7/colorsys.py new file mode 100644 index 00000000..a6c0cf6a --- /dev/null +++ b/test/ok_2.7/colorsys.py @@ -0,0 +1,156 @@ +"""Conversion functions between RGB and other color systems. + +This modules provides two functions for each color system ABC: + + rgb_to_abc(r, g, b) --> a, b, c + abc_to_rgb(a, b, c) --> r, g, b + +All inputs and outputs are triples of floats in the range [0.0...1.0] +(with the exception of I and Q, which covers a slightly larger range). +Inputs outside the valid range may cause exceptions or invalid outputs. + +Supported color systems: +RGB: Red, Green, Blue components +YIQ: Luminance, Chrominance (used by composite video signals) +HLS: Hue, Luminance, Saturation +HSV: Hue, Saturation, Value +""" + +# References: +# http://en.wikipedia.org/wiki/YIQ +# http://en.wikipedia.org/wiki/HLS_color_space +# http://en.wikipedia.org/wiki/HSV_color_space + +__all__ = ["rgb_to_yiq","yiq_to_rgb","rgb_to_hls","hls_to_rgb", + "rgb_to_hsv","hsv_to_rgb"] + +# Some floating point constants + +ONE_THIRD = 1.0/3.0 +ONE_SIXTH = 1.0/6.0 +TWO_THIRD = 2.0/3.0 + +# YIQ: used by composite video signals (linear combinations of RGB) +# Y: perceived grey level (0.0 == black, 1.0 == white) +# I, Q: color components + +def rgb_to_yiq(r, g, b): + y = 0.30*r + 0.59*g + 0.11*b + i = 0.60*r - 0.28*g - 0.32*b + q = 0.21*r - 0.52*g + 0.31*b + return (y, i, q) + +def yiq_to_rgb(y, i, q): + r = y + 0.948262*i + 0.624013*q + g = y - 0.276066*i - 0.639810*q + b = y - 1.105450*i + 1.729860*q + if r < 0.0: + r = 0.0 + if g < 0.0: + g = 0.0 + if b < 0.0: + b = 0.0 + if r > 1.0: + r = 1.0 + if g > 1.0: + g = 1.0 + if b > 1.0: + b = 1.0 + return (r, g, b) + + +# HLS: Hue, Luminance, Saturation +# H: position in the spectrum +# L: color lightness +# S: color saturation + +def rgb_to_hls(r, g, b): + maxc = max(r, g, b) + minc = min(r, g, b) + # XXX Can optimize (maxc+minc) and (maxc-minc) + l = (minc+maxc)/2.0 + if minc == maxc: + return 0.0, l, 0.0 + if l <= 0.5: + s = (maxc-minc) / (maxc+minc) + else: + s = (maxc-minc) / (2.0-maxc-minc) + rc = (maxc-r) / (maxc-minc) + gc = (maxc-g) / (maxc-minc) + bc = (maxc-b) / (maxc-minc) + if r == maxc: + h = bc-gc + elif g == maxc: + h = 2.0+rc-bc + else: + h = 4.0+gc-rc + h = (h/6.0) % 1.0 + return h, l, s + +def hls_to_rgb(h, l, s): + if s == 0.0: + return l, l, l + if l <= 0.5: + m2 = l * (1.0+s) + else: + m2 = l+s-(l*s) + m1 = 2.0*l - m2 + return (_v(m1, m2, h+ONE_THIRD), _v(m1, m2, h), _v(m1, m2, h-ONE_THIRD)) + +def _v(m1, m2, hue): + hue = hue % 1.0 + if hue < ONE_SIXTH: + return m1 + (m2-m1)*hue*6.0 + if hue < 0.5: + return m2 + if hue < TWO_THIRD: + return m1 + (m2-m1)*(TWO_THIRD-hue)*6.0 + return m1 + + +# HSV: Hue, Saturation, Value +# H: position in the spectrum +# S: color saturation ("purity") +# V: color brightness + +def rgb_to_hsv(r, g, b): + maxc = max(r, g, b) + minc = min(r, g, b) + v = maxc + if minc == maxc: + return 0.0, 0.0, v + s = (maxc-minc) / maxc + rc = (maxc-r) / (maxc-minc) + gc = (maxc-g) / (maxc-minc) + bc = (maxc-b) / (maxc-minc) + if r == maxc: + h = bc-gc + elif g == maxc: + h = 2.0+rc-bc + else: + h = 4.0+gc-rc + h = (h/6.0) % 1.0 + return h, s, v + +def hsv_to_rgb(h, s, v): + if s == 0.0: + return v, v, v + i = int(h*6.0) # XXX assume int() truncates! + f = (h*6.0) - i + p = v*(1.0 - s) + q = v*(1.0 - s*f) + t = v*(1.0 - s*(1.0-f)) + i = i%6 + if i == 0: + return v, t, p + if i == 1: + return q, v, p + if i == 2: + return p, v, t + if i == 3: + return p, q, v + if i == 4: + return t, p, v + if i == 5: + return v, p, q + # Cannot get here diff --git a/test/ok_2.7/commands.py b/test/ok_2.7/commands.py new file mode 100644 index 00000000..d0e8dd5f --- /dev/null +++ b/test/ok_2.7/commands.py @@ -0,0 +1,90 @@ +"""Execute shell commands via os.popen() and return status, output. + +Interface summary: + + import commands + + outtext = commands.getoutput(cmd) + (exitstatus, outtext) = commands.getstatusoutput(cmd) + outtext = commands.getstatus(file) # returns output of "ls -ld file" + +A trailing newline is removed from the output string. + +Encapsulates the basic operation: + + pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') + text = pipe.read() + sts = pipe.close() + + [Note: it would be nice to add functions to interpret the exit status.] +""" +from warnings import warnpy3k +warnpy3k("the commands module has been removed in Python 3.0; " + "use the subprocess module instead", stacklevel=2) +del warnpy3k + +__all__ = ["getstatusoutput","getoutput","getstatus"] + +# Module 'commands' +# +# Various tools for executing commands and looking at their output and status. +# +# NB This only works (and is only relevant) for UNIX. + + +# Get 'ls -l' status for an object into a string +# +def getstatus(file): + """Return output of "ls -ld " in a string.""" + import warnings + warnings.warn("commands.getstatus() is deprecated", DeprecationWarning, 2) + return getoutput('ls -ld' + mkarg(file)) + + +# Get the output from a shell command into a string. +# The exit status is ignored; a trailing newline is stripped. +# Assume the command will work with '{ ... ; } 2>&1' around it.. +# +def getoutput(cmd): + """Return output (stdout or stderr) of executing cmd in a shell.""" + return getstatusoutput(cmd)[1] + + +# Ditto but preserving the exit status. +# Returns a pair (sts, output) +# +def getstatusoutput(cmd): + """Return (status, output) of executing cmd in a shell.""" + import os + pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') + text = pipe.read() + sts = pipe.close() + if sts is None: sts = 0 + if text[-1:] == '\n': text = text[:-1] + return sts, text + + +# Make command argument from directory and pathname (prefix space, add quotes). +# +def mk2arg(head, x): + import os + return mkarg(os.path.join(head, x)) + + +# Make a shell command argument from a string. +# Return a string beginning with a space followed by a shell-quoted +# version of the argument. +# Two strategies: enclose in single quotes if it contains none; +# otherwise, enclose in double quotes and prefix quotable characters +# with backslash. +# +def mkarg(x): + if '\'' not in x: + return ' \'' + x + '\'' + s = ' "' + for c in x: + if c in '\\$"`': + s = s + '\\' + s = s + c + s = s + '"' + return s diff --git a/test/ok_2.7/compileall.py b/test/ok_2.7/compileall.py new file mode 100644 index 00000000..5cfa8bed --- /dev/null +++ b/test/ok_2.7/compileall.py @@ -0,0 +1,227 @@ +"""Module/script to byte-compile all .py files to .pyc (or .pyo) files. + +When called as a script with arguments, this compiles the directories +given as arguments recursively; the -l option prevents it from +recursing into directories. + +Without arguments, if compiles all modules on sys.path, without +recursing into subdirectories. (Even though it should do so for +packages -- for now, you'll have to deal with packages separately.) + +See module py_compile for details of the actual byte-compilation. +""" +import os +import sys +import py_compile +import struct +import imp + +__all__ = ["compile_dir","compile_file","compile_path"] + +def compile_dir(dir, maxlevels=10, ddir=None, + force=0, rx=None, quiet=0): + """Byte-compile all modules in the given directory tree. + + Arguments (only dir is required): + + dir: the directory to byte-compile + maxlevels: maximum recursion level (default 10) + ddir: the directory that will be prepended to the path to the + file as it is compiled into each byte-code file. + force: if 1, force compilation, even if timestamps are up-to-date + quiet: if 1, be quiet during compilation + """ + if not quiet: + print 'Listing', dir, '...' + try: + names = os.listdir(dir) + except os.error: + print "Can't list", dir + names = [] + names.sort() + success = 1 + for name in names: + fullname = os.path.join(dir, name) + if ddir is not None: + dfile = os.path.join(ddir, name) + else: + dfile = None + if not os.path.isdir(fullname): + if not compile_file(fullname, ddir, force, rx, quiet): + success = 0 + elif maxlevels > 0 and \ + name != os.curdir and name != os.pardir and \ + os.path.isdir(fullname) and \ + not os.path.islink(fullname): + if not compile_dir(fullname, maxlevels - 1, dfile, force, rx, + quiet): + success = 0 + return success + +def compile_file(fullname, ddir=None, force=0, rx=None, quiet=0): + """Byte-compile one file. + + Arguments (only fullname is required): + + fullname: the file to byte-compile + ddir: if given, the directory name compiled in to the + byte-code file. + force: if 1, force compilation, even if timestamps are up-to-date + quiet: if 1, be quiet during compilation + """ + success = 1 + name = os.path.basename(fullname) + if ddir is not None: + dfile = os.path.join(ddir, name) + else: + dfile = None + if rx is not None: + mo = rx.search(fullname) + if mo: + return success + if os.path.isfile(fullname): + head, tail = name[:-3], name[-3:] + if tail == '.py': + if not force: + try: + mtime = int(os.stat(fullname).st_mtime) + expect = struct.pack('<4sl', imp.get_magic(), mtime) + cfile = fullname + (__debug__ and 'c' or 'o') + with open(cfile, 'rb') as chandle: + actual = chandle.read(8) + if expect == actual: + return success + except IOError: + pass + if not quiet: + print 'Compiling', fullname, '...' + try: + ok = py_compile.compile(fullname, None, dfile, True) + except py_compile.PyCompileError,err: + if quiet: + print 'Compiling', fullname, '...' + print err.msg + success = 0 + except IOError, e: + print "Sorry", e + success = 0 + else: + if ok == 0: + success = 0 + return success + +def compile_path(skip_curdir=1, maxlevels=0, force=0, quiet=0): + """Byte-compile all module on sys.path. + + Arguments (all optional): + + skip_curdir: if true, skip current directory (default true) + maxlevels: max recursion level (default 0) + force: as for compile_dir() (default 0) + quiet: as for compile_dir() (default 0) + """ + success = 1 + for dir in sys.path: + if (not dir or dir == os.curdir) and skip_curdir: + print 'Skipping current directory' + else: + success = success and compile_dir(dir, maxlevels, None, + force, quiet=quiet) + return success + +def expand_args(args, flist): + """read names in flist and append to args""" + expanded = args[:] + if flist: + try: + if flist == '-': + fd = sys.stdin + else: + fd = open(flist) + while 1: + line = fd.readline() + if not line: + break + expanded.append(line[:-1]) + except IOError: + print "Error reading file list %s" % flist + raise + return expanded + +def main(): + """Script main program.""" + import getopt + try: + opts, args = getopt.getopt(sys.argv[1:], 'lfqd:x:i:') + except getopt.error, msg: + print msg + print "usage: python compileall.py [-l] [-f] [-q] [-d destdir] " \ + "[-x regexp] [-i list] [directory|file ...]" + print + print "arguments: zero or more file and directory names to compile; " \ + "if no arguments given, " + print " defaults to the equivalent of -l sys.path" + print + print "options:" + print "-l: don't recurse into subdirectories" + print "-f: force rebuild even if timestamps are up-to-date" + print "-q: output only error messages" + print "-d destdir: directory to prepend to file paths for use in " \ + "compile-time tracebacks and in" + print " runtime tracebacks in cases where the source " \ + "file is unavailable" + print "-x regexp: skip files matching the regular expression regexp; " \ + "the regexp is searched for" + print " in the full path of each file considered for " \ + "compilation" + print "-i file: add all the files and directories listed in file to " \ + "the list considered for" + print ' compilation; if "-", names are read from stdin' + + sys.exit(2) + maxlevels = 10 + ddir = None + force = 0 + quiet = 0 + rx = None + flist = None + for o, a in opts: + if o == '-l': maxlevels = 0 + if o == '-d': ddir = a + if o == '-f': force = 1 + if o == '-q': quiet = 1 + if o == '-x': + import re + rx = re.compile(a) + if o == '-i': flist = a + if ddir: + if len(args) != 1 and not os.path.isdir(args[0]): + print "-d destdir require exactly one directory argument" + sys.exit(2) + success = 1 + try: + if args or flist: + try: + if flist: + args = expand_args(args, flist) + except IOError: + success = 0 + if success: + for arg in args: + if os.path.isdir(arg): + if not compile_dir(arg, maxlevels, ddir, + force, rx, quiet): + success = 0 + else: + if not compile_file(arg, ddir, force, rx, quiet): + success = 0 + else: + success = compile_path() + except KeyboardInterrupt: + print "\n[interrupted]" + success = 0 + return success + +if __name__ == '__main__': + exit_status = int(not main()) + sys.exit(exit_status) diff --git a/test/ok_2.7/compiler/__init__.py b/test/ok_2.7/compiler/__init__.py new file mode 100644 index 00000000..2a6f64fa --- /dev/null +++ b/test/ok_2.7/compiler/__init__.py @@ -0,0 +1,31 @@ +"""Package for parsing and compiling Python source code + +There are several functions defined at the top level that are imported +from modules contained in the package. + +parse(buf, mode="exec") -> AST + Converts a string containing Python source code to an abstract + syntax tree (AST). The AST is defined in compiler.ast. + +parseFile(path) -> AST + The same as parse(open(path)) + +walk(ast, visitor, verbose=None) + Does a pre-order walk over the ast using the visitor instance. + See compiler.visitor for details. + +compile(source, filename, mode, flags=None, dont_inherit=None) + Returns a code object. A replacement for the builtin compile() function. + +compileFile(filename) + Generates a .pyc file by compiling filename. +""" + +import warnings + +warnings.warn("The compiler package is deprecated and removed in Python 3.x.", + DeprecationWarning, stacklevel=2) + +from compiler.transformer import parse, parseFile +from compiler.visitor import walk +from compiler.pycodegen import compile, compileFile diff --git a/test/ok_2.7/compiler/ast.py b/test/ok_2.7/compiler/ast.py new file mode 100644 index 00000000..4c3fc161 --- /dev/null +++ b/test/ok_2.7/compiler/ast.py @@ -0,0 +1,1419 @@ +"""Python abstract syntax node definitions + +This file is automatically generated by Tools/compiler/astgen.py +""" +from compiler.consts import CO_VARARGS, CO_VARKEYWORDS + +def flatten(seq): + l = [] + for elt in seq: + t = type(elt) + if t is tuple or t is list: + for elt2 in flatten(elt): + l.append(elt2) + else: + l.append(elt) + return l + +def flatten_nodes(seq): + return [n for n in flatten(seq) if isinstance(n, Node)] + +nodes = {} + +class Node: + """Abstract base class for ast nodes.""" + def getChildren(self): + pass # implemented by subclasses + def __iter__(self): + for n in self.getChildren(): + yield n + def asList(self): # for backwards compatibility + return self.getChildren() + def getChildNodes(self): + pass # implemented by subclasses + +class EmptyNode(Node): + pass + +class Expression(Node): + # Expression is an artificial node class to support "eval" + nodes["expression"] = "Expression" + def __init__(self, node): + self.node = node + + def getChildren(self): + return self.node, + + def getChildNodes(self): + return self.node, + + def __repr__(self): + return "Expression(%s)" % (repr(self.node)) + +class Add(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Add((%s, %s))" % (repr(self.left), repr(self.right)) + +class And(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "And(%s)" % (repr(self.nodes),) + +class AssAttr(Node): + def __init__(self, expr, attrname, flags, lineno=None): + self.expr = expr + self.attrname = attrname + self.flags = flags + self.lineno = lineno + + def getChildren(self): + return self.expr, self.attrname, self.flags + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "AssAttr(%s, %s, %s)" % (repr(self.expr), repr(self.attrname), repr(self.flags)) + +class AssList(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "AssList(%s)" % (repr(self.nodes),) + +class AssName(Node): + def __init__(self, name, flags, lineno=None): + self.name = name + self.flags = flags + self.lineno = lineno + + def getChildren(self): + return self.name, self.flags + + def getChildNodes(self): + return () + + def __repr__(self): + return "AssName(%s, %s)" % (repr(self.name), repr(self.flags)) + +class AssTuple(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "AssTuple(%s)" % (repr(self.nodes),) + +class Assert(Node): + def __init__(self, test, fail, lineno=None): + self.test = test + self.fail = fail + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.test) + children.append(self.fail) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.test) + if self.fail is not None: + nodelist.append(self.fail) + return tuple(nodelist) + + def __repr__(self): + return "Assert(%s, %s)" % (repr(self.test), repr(self.fail)) + +class Assign(Node): + def __init__(self, nodes, expr, lineno=None): + self.nodes = nodes + self.expr = expr + self.lineno = lineno + + def getChildren(self): + children = [] + children.extend(flatten(self.nodes)) + children.append(self.expr) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + nodelist.append(self.expr) + return tuple(nodelist) + + def __repr__(self): + return "Assign(%s, %s)" % (repr(self.nodes), repr(self.expr)) + +class AugAssign(Node): + def __init__(self, node, op, expr, lineno=None): + self.node = node + self.op = op + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.node, self.op, self.expr + + def getChildNodes(self): + return self.node, self.expr + + def __repr__(self): + return "AugAssign(%s, %s, %s)" % (repr(self.node), repr(self.op), repr(self.expr)) + +class Backquote(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Backquote(%s)" % (repr(self.expr),) + +class Bitand(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Bitand(%s)" % (repr(self.nodes),) + +class Bitor(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Bitor(%s)" % (repr(self.nodes),) + +class Bitxor(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Bitxor(%s)" % (repr(self.nodes),) + +class Break(Node): + def __init__(self, lineno=None): + self.lineno = lineno + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "Break()" + +class CallFunc(Node): + def __init__(self, node, args, star_args = None, dstar_args = None, lineno=None): + self.node = node + self.args = args + self.star_args = star_args + self.dstar_args = dstar_args + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.node) + children.extend(flatten(self.args)) + children.append(self.star_args) + children.append(self.dstar_args) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.node) + nodelist.extend(flatten_nodes(self.args)) + if self.star_args is not None: + nodelist.append(self.star_args) + if self.dstar_args is not None: + nodelist.append(self.dstar_args) + return tuple(nodelist) + + def __repr__(self): + return "CallFunc(%s, %s, %s, %s)" % (repr(self.node), repr(self.args), repr(self.star_args), repr(self.dstar_args)) + +class Class(Node): + def __init__(self, name, bases, doc, code, decorators = None, lineno=None): + self.name = name + self.bases = bases + self.doc = doc + self.code = code + self.decorators = decorators + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.name) + children.extend(flatten(self.bases)) + children.append(self.doc) + children.append(self.code) + children.append(self.decorators) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.bases)) + nodelist.append(self.code) + if self.decorators is not None: + nodelist.append(self.decorators) + return tuple(nodelist) + + def __repr__(self): + return "Class(%s, %s, %s, %s, %s)" % (repr(self.name), repr(self.bases), repr(self.doc), repr(self.code), repr(self.decorators)) + +class Compare(Node): + def __init__(self, expr, ops, lineno=None): + self.expr = expr + self.ops = ops + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.extend(flatten(self.ops)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.ops)) + return tuple(nodelist) + + def __repr__(self): + return "Compare(%s, %s)" % (repr(self.expr), repr(self.ops)) + +class Const(Node): + def __init__(self, value, lineno=None): + self.value = value + self.lineno = lineno + + def getChildren(self): + return self.value, + + def getChildNodes(self): + return () + + def __repr__(self): + return "Const(%s)" % (repr(self.value),) + +class Continue(Node): + def __init__(self, lineno=None): + self.lineno = lineno + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "Continue()" + +class Decorators(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Decorators(%s)" % (repr(self.nodes),) + +class Dict(Node): + def __init__(self, items, lineno=None): + self.items = items + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.items)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.items)) + return tuple(nodelist) + + def __repr__(self): + return "Dict(%s)" % (repr(self.items),) + +class Discard(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Discard(%s)" % (repr(self.expr),) + +class Div(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Div((%s, %s))" % (repr(self.left), repr(self.right)) + +class Ellipsis(Node): + def __init__(self, lineno=None): + self.lineno = lineno + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "Ellipsis()" + +class Exec(Node): + def __init__(self, expr, locals, globals, lineno=None): + self.expr = expr + self.locals = locals + self.globals = globals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.locals) + children.append(self.globals) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + if self.locals is not None: + nodelist.append(self.locals) + if self.globals is not None: + nodelist.append(self.globals) + return tuple(nodelist) + + def __repr__(self): + return "Exec(%s, %s, %s)" % (repr(self.expr), repr(self.locals), repr(self.globals)) + +class FloorDiv(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "FloorDiv((%s, %s))" % (repr(self.left), repr(self.right)) + +class For(Node): + def __init__(self, assign, list, body, else_, lineno=None): + self.assign = assign + self.list = list + self.body = body + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.assign) + children.append(self.list) + children.append(self.body) + children.append(self.else_) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.assign) + nodelist.append(self.list) + nodelist.append(self.body) + if self.else_ is not None: + nodelist.append(self.else_) + return tuple(nodelist) + + def __repr__(self): + return "For(%s, %s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.body), repr(self.else_)) + +class From(Node): + def __init__(self, modname, names, level, lineno=None): + self.modname = modname + self.names = names + self.level = level + self.lineno = lineno + + def getChildren(self): + return self.modname, self.names, self.level + + def getChildNodes(self): + return () + + def __repr__(self): + return "From(%s, %s, %s)" % (repr(self.modname), repr(self.names), repr(self.level)) + +class Function(Node): + def __init__(self, decorators, name, argnames, defaults, flags, doc, code, lineno=None): + self.decorators = decorators + self.name = name + self.argnames = argnames + self.defaults = defaults + self.flags = flags + self.doc = doc + self.code = code + self.lineno = lineno + self.varargs = self.kwargs = None + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 + + + def getChildren(self): + children = [] + children.append(self.decorators) + children.append(self.name) + children.append(self.argnames) + children.extend(flatten(self.defaults)) + children.append(self.flags) + children.append(self.doc) + children.append(self.code) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + if self.decorators is not None: + nodelist.append(self.decorators) + nodelist.extend(flatten_nodes(self.defaults)) + nodelist.append(self.code) + return tuple(nodelist) + + def __repr__(self): + return "Function(%s, %s, %s, %s, %s, %s, %s)" % (repr(self.decorators), repr(self.name), repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.doc), repr(self.code)) + +class GenExpr(Node): + def __init__(self, code, lineno=None): + self.code = code + self.lineno = lineno + self.argnames = ['.0'] + self.varargs = self.kwargs = None + + + def getChildren(self): + return self.code, + + def getChildNodes(self): + return self.code, + + def __repr__(self): + return "GenExpr(%s)" % (repr(self.code),) + +class GenExprFor(Node): + def __init__(self, assign, iter, ifs, lineno=None): + self.assign = assign + self.iter = iter + self.ifs = ifs + self.lineno = lineno + self.is_outmost = False + + def getChildren(self): + children = [] + children.append(self.assign) + children.append(self.iter) + children.extend(flatten(self.ifs)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.assign) + nodelist.append(self.iter) + nodelist.extend(flatten_nodes(self.ifs)) + return tuple(nodelist) + + def __repr__(self): + return "GenExprFor(%s, %s, %s)" % (repr(self.assign), repr(self.iter), repr(self.ifs)) + +class GenExprIf(Node): + def __init__(self, test, lineno=None): + self.test = test + self.lineno = lineno + + def getChildren(self): + return self.test, + + def getChildNodes(self): + return self.test, + + def __repr__(self): + return "GenExprIf(%s)" % (repr(self.test),) + +class GenExprInner(Node): + def __init__(self, expr, quals, lineno=None): + self.expr = expr + self.quals = quals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.extend(flatten(self.quals)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.quals)) + return tuple(nodelist) + + def __repr__(self): + return "GenExprInner(%s, %s)" % (repr(self.expr), repr(self.quals)) + +class Getattr(Node): + def __init__(self, expr, attrname, lineno=None): + self.expr = expr + self.attrname = attrname + self.lineno = lineno + + def getChildren(self): + return self.expr, self.attrname + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Getattr(%s, %s)" % (repr(self.expr), repr(self.attrname)) + +class Global(Node): + def __init__(self, names, lineno=None): + self.names = names + self.lineno = lineno + + def getChildren(self): + return self.names, + + def getChildNodes(self): + return () + + def __repr__(self): + return "Global(%s)" % (repr(self.names),) + +class If(Node): + def __init__(self, tests, else_, lineno=None): + self.tests = tests + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + children = [] + children.extend(flatten(self.tests)) + children.append(self.else_) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.tests)) + if self.else_ is not None: + nodelist.append(self.else_) + return tuple(nodelist) + + def __repr__(self): + return "If(%s, %s)" % (repr(self.tests), repr(self.else_)) + +class IfExp(Node): + def __init__(self, test, then, else_, lineno=None): + self.test = test + self.then = then + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + return self.test, self.then, self.else_ + + def getChildNodes(self): + return self.test, self.then, self.else_ + + def __repr__(self): + return "IfExp(%s, %s, %s)" % (repr(self.test), repr(self.then), repr(self.else_)) + +class Import(Node): + def __init__(self, names, lineno=None): + self.names = names + self.lineno = lineno + + def getChildren(self): + return self.names, + + def getChildNodes(self): + return () + + def __repr__(self): + return "Import(%s)" % (repr(self.names),) + +class Invert(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Invert(%s)" % (repr(self.expr),) + +class Keyword(Node): + def __init__(self, name, expr, lineno=None): + self.name = name + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.name, self.expr + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Keyword(%s, %s)" % (repr(self.name), repr(self.expr)) + +class Lambda(Node): + def __init__(self, argnames, defaults, flags, code, lineno=None): + self.argnames = argnames + self.defaults = defaults + self.flags = flags + self.code = code + self.lineno = lineno + self.varargs = self.kwargs = None + if flags & CO_VARARGS: + self.varargs = 1 + if flags & CO_VARKEYWORDS: + self.kwargs = 1 + + + def getChildren(self): + children = [] + children.append(self.argnames) + children.extend(flatten(self.defaults)) + children.append(self.flags) + children.append(self.code) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.defaults)) + nodelist.append(self.code) + return tuple(nodelist) + + def __repr__(self): + return "Lambda(%s, %s, %s, %s)" % (repr(self.argnames), repr(self.defaults), repr(self.flags), repr(self.code)) + +class LeftShift(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "LeftShift((%s, %s))" % (repr(self.left), repr(self.right)) + +class List(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "List(%s)" % (repr(self.nodes),) + +class ListComp(Node): + def __init__(self, expr, quals, lineno=None): + self.expr = expr + self.quals = quals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.extend(flatten(self.quals)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.quals)) + return tuple(nodelist) + + def __repr__(self): + return "ListComp(%s, %s)" % (repr(self.expr), repr(self.quals)) + +class ListCompFor(Node): + def __init__(self, assign, list, ifs, lineno=None): + self.assign = assign + self.list = list + self.ifs = ifs + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.assign) + children.append(self.list) + children.extend(flatten(self.ifs)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.assign) + nodelist.append(self.list) + nodelist.extend(flatten_nodes(self.ifs)) + return tuple(nodelist) + + def __repr__(self): + return "ListCompFor(%s, %s, %s)" % (repr(self.assign), repr(self.list), repr(self.ifs)) + +class ListCompIf(Node): + def __init__(self, test, lineno=None): + self.test = test + self.lineno = lineno + + def getChildren(self): + return self.test, + + def getChildNodes(self): + return self.test, + + def __repr__(self): + return "ListCompIf(%s)" % (repr(self.test),) + +class SetComp(Node): + def __init__(self, expr, quals, lineno=None): + self.expr = expr + self.quals = quals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.extend(flatten(self.quals)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.quals)) + return tuple(nodelist) + + def __repr__(self): + return "SetComp(%s, %s)" % (repr(self.expr), repr(self.quals)) + +class DictComp(Node): + def __init__(self, key, value, quals, lineno=None): + self.key = key + self.value = value + self.quals = quals + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.key) + children.append(self.value) + children.extend(flatten(self.quals)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.key) + nodelist.append(self.value) + nodelist.extend(flatten_nodes(self.quals)) + return tuple(nodelist) + + def __repr__(self): + return "DictComp(%s, %s, %s)" % (repr(self.key), repr(self.value), repr(self.quals)) + +class Mod(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Mod((%s, %s))" % (repr(self.left), repr(self.right)) + +class Module(Node): + def __init__(self, doc, node, lineno=None): + self.doc = doc + self.node = node + self.lineno = lineno + + def getChildren(self): + return self.doc, self.node + + def getChildNodes(self): + return self.node, + + def __repr__(self): + return "Module(%s, %s)" % (repr(self.doc), repr(self.node)) + +class Mul(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Mul((%s, %s))" % (repr(self.left), repr(self.right)) + +class Name(Node): + def __init__(self, name, lineno=None): + self.name = name + self.lineno = lineno + + def getChildren(self): + return self.name, + + def getChildNodes(self): + return () + + def __repr__(self): + return "Name(%s)" % (repr(self.name),) + +class Not(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "Not(%s)" % (repr(self.expr),) + +class Or(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Or(%s)" % (repr(self.nodes),) + +class Pass(Node): + def __init__(self, lineno=None): + self.lineno = lineno + + def getChildren(self): + return () + + def getChildNodes(self): + return () + + def __repr__(self): + return "Pass()" + +class Power(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Power((%s, %s))" % (repr(self.left), repr(self.right)) + +class Print(Node): + def __init__(self, nodes, dest, lineno=None): + self.nodes = nodes + self.dest = dest + self.lineno = lineno + + def getChildren(self): + children = [] + children.extend(flatten(self.nodes)) + children.append(self.dest) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + if self.dest is not None: + nodelist.append(self.dest) + return tuple(nodelist) + + def __repr__(self): + return "Print(%s, %s)" % (repr(self.nodes), repr(self.dest)) + +class Printnl(Node): + def __init__(self, nodes, dest, lineno=None): + self.nodes = nodes + self.dest = dest + self.lineno = lineno + + def getChildren(self): + children = [] + children.extend(flatten(self.nodes)) + children.append(self.dest) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + if self.dest is not None: + nodelist.append(self.dest) + return tuple(nodelist) + + def __repr__(self): + return "Printnl(%s, %s)" % (repr(self.nodes), repr(self.dest)) + +class Raise(Node): + def __init__(self, expr1, expr2, expr3, lineno=None): + self.expr1 = expr1 + self.expr2 = expr2 + self.expr3 = expr3 + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr1) + children.append(self.expr2) + children.append(self.expr3) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + if self.expr1 is not None: + nodelist.append(self.expr1) + if self.expr2 is not None: + nodelist.append(self.expr2) + if self.expr3 is not None: + nodelist.append(self.expr3) + return tuple(nodelist) + + def __repr__(self): + return "Raise(%s, %s, %s)" % (repr(self.expr1), repr(self.expr2), repr(self.expr3)) + +class Return(Node): + def __init__(self, value, lineno=None): + self.value = value + self.lineno = lineno + + def getChildren(self): + return self.value, + + def getChildNodes(self): + return self.value, + + def __repr__(self): + return "Return(%s)" % (repr(self.value),) + +class RightShift(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "RightShift((%s, %s))" % (repr(self.left), repr(self.right)) + +class Set(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Set(%s)" % (repr(self.nodes),) + +class Slice(Node): + def __init__(self, expr, flags, lower, upper, lineno=None): + self.expr = expr + self.flags = flags + self.lower = lower + self.upper = upper + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.flags) + children.append(self.lower) + children.append(self.upper) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + if self.lower is not None: + nodelist.append(self.lower) + if self.upper is not None: + nodelist.append(self.upper) + return tuple(nodelist) + + def __repr__(self): + return "Slice(%s, %s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.lower), repr(self.upper)) + +class Sliceobj(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Sliceobj(%s)" % (repr(self.nodes),) + +class Stmt(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Stmt(%s)" % (repr(self.nodes),) + +class Sub(Node): + def __init__(self, leftright, lineno=None): + self.left = leftright[0] + self.right = leftright[1] + self.lineno = lineno + + def getChildren(self): + return self.left, self.right + + def getChildNodes(self): + return self.left, self.right + + def __repr__(self): + return "Sub((%s, %s))" % (repr(self.left), repr(self.right)) + +class Subscript(Node): + def __init__(self, expr, flags, subs, lineno=None): + self.expr = expr + self.flags = flags + self.subs = subs + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.flags) + children.extend(flatten(self.subs)) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + nodelist.extend(flatten_nodes(self.subs)) + return tuple(nodelist) + + def __repr__(self): + return "Subscript(%s, %s, %s)" % (repr(self.expr), repr(self.flags), repr(self.subs)) + +class TryExcept(Node): + def __init__(self, body, handlers, else_, lineno=None): + self.body = body + self.handlers = handlers + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.body) + children.extend(flatten(self.handlers)) + children.append(self.else_) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.body) + nodelist.extend(flatten_nodes(self.handlers)) + if self.else_ is not None: + nodelist.append(self.else_) + return tuple(nodelist) + + def __repr__(self): + return "TryExcept(%s, %s, %s)" % (repr(self.body), repr(self.handlers), repr(self.else_)) + +class TryFinally(Node): + def __init__(self, body, final, lineno=None): + self.body = body + self.final = final + self.lineno = lineno + + def getChildren(self): + return self.body, self.final + + def getChildNodes(self): + return self.body, self.final + + def __repr__(self): + return "TryFinally(%s, %s)" % (repr(self.body), repr(self.final)) + +class Tuple(Node): + def __init__(self, nodes, lineno=None): + self.nodes = nodes + self.lineno = lineno + + def getChildren(self): + return tuple(flatten(self.nodes)) + + def getChildNodes(self): + nodelist = [] + nodelist.extend(flatten_nodes(self.nodes)) + return tuple(nodelist) + + def __repr__(self): + return "Tuple(%s)" % (repr(self.nodes),) + +class UnaryAdd(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "UnaryAdd(%s)" % (repr(self.expr),) + +class UnarySub(Node): + def __init__(self, expr, lineno=None): + self.expr = expr + self.lineno = lineno + + def getChildren(self): + return self.expr, + + def getChildNodes(self): + return self.expr, + + def __repr__(self): + return "UnarySub(%s)" % (repr(self.expr),) + +class While(Node): + def __init__(self, test, body, else_, lineno=None): + self.test = test + self.body = body + self.else_ = else_ + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.test) + children.append(self.body) + children.append(self.else_) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.test) + nodelist.append(self.body) + if self.else_ is not None: + nodelist.append(self.else_) + return tuple(nodelist) + + def __repr__(self): + return "While(%s, %s, %s)" % (repr(self.test), repr(self.body), repr(self.else_)) + +class With(Node): + def __init__(self, expr, vars, body, lineno=None): + self.expr = expr + self.vars = vars + self.body = body + self.lineno = lineno + + def getChildren(self): + children = [] + children.append(self.expr) + children.append(self.vars) + children.append(self.body) + return tuple(children) + + def getChildNodes(self): + nodelist = [] + nodelist.append(self.expr) + if self.vars is not None: + nodelist.append(self.vars) + nodelist.append(self.body) + return tuple(nodelist) + + def __repr__(self): + return "With(%s, %s, %s)" % (repr(self.expr), repr(self.vars), repr(self.body)) + +class Yield(Node): + def __init__(self, value, lineno=None): + self.value = value + self.lineno = lineno + + def getChildren(self): + return self.value, + + def getChildNodes(self): + return self.value, + + def __repr__(self): + return "Yield(%s)" % (repr(self.value),) + +for name, obj in globals().items(): + if isinstance(obj, type) and issubclass(obj, Node): + nodes[name.lower()] = obj diff --git a/test/ok_2.7/compiler/consts.py b/test/ok_2.7/compiler/consts.py new file mode 100644 index 00000000..c60b1d0b --- /dev/null +++ b/test/ok_2.7/compiler/consts.py @@ -0,0 +1,23 @@ +# operation flags +OP_ASSIGN = 'OP_ASSIGN' +OP_DELETE = 'OP_DELETE' +OP_APPLY = 'OP_APPLY' + +SC_LOCAL = 1 +SC_GLOBAL_IMPLICIT = 2 +SC_GLOBAL_EXPLICIT = 3 +SC_FREE = 4 +SC_CELL = 5 +SC_UNKNOWN = 6 + +CO_OPTIMIZED = 0x0001 +CO_NEWLOCALS = 0x0002 +CO_VARARGS = 0x0004 +CO_VARKEYWORDS = 0x0008 +CO_NESTED = 0x0010 +CO_GENERATOR = 0x0020 +CO_GENERATOR_ALLOWED = 0 +CO_FUTURE_DIVISION = 0x2000 +CO_FUTURE_ABSIMPORT = 0x4000 +CO_FUTURE_WITH_STATEMENT = 0x8000 +CO_FUTURE_PRINT_FUNCTION = 0x10000 diff --git a/test/ok_2.7/compiler/future.py b/test/ok_2.7/compiler/future.py new file mode 100644 index 00000000..fd5e5dfb --- /dev/null +++ b/test/ok_2.7/compiler/future.py @@ -0,0 +1,74 @@ +"""Parser for future statements + +""" + +from compiler import ast, walk + +def is_future(stmt): + """Return true if statement is a well-formed future statement""" + if not isinstance(stmt, ast.From): + return 0 + if stmt.modname == "__future__": + return 1 + else: + return 0 + +class FutureParser: + + features = ("nested_scopes", "generators", "division", + "absolute_import", "with_statement", "print_function", + "unicode_literals") + + def __init__(self): + self.found = {} # set + + def visitModule(self, node): + stmt = node.node + for s in stmt.nodes: + if not self.check_stmt(s): + break + + def check_stmt(self, stmt): + if is_future(stmt): + for name, asname in stmt.names: + if name in self.features: + self.found[name] = 1 + else: + raise SyntaxError, \ + "future feature %s is not defined" % name + stmt.valid_future = 1 + return 1 + return 0 + + def get_features(self): + """Return list of features enabled by future statements""" + return self.found.keys() + +class BadFutureParser: + """Check for invalid future statements""" + + def visitFrom(self, node): + if hasattr(node, 'valid_future'): + return + if node.modname != "__future__": + return + raise SyntaxError, "invalid future statement " + repr(node) + +def find_futures(node): + p1 = FutureParser() + p2 = BadFutureParser() + walk(node, p1) + walk(node, p2) + return p1.get_features() + +if __name__ == "__main__": + import sys + from compiler import parseFile, walk + + for file in sys.argv[1:]: + print file + tree = parseFile(file) + v = FutureParser() + walk(tree, v) + print v.found + print diff --git a/test/ok_2.7/compiler/misc.py b/test/ok_2.7/compiler/misc.py new file mode 100644 index 00000000..588c7fbd --- /dev/null +++ b/test/ok_2.7/compiler/misc.py @@ -0,0 +1,73 @@ + +def flatten(tup): + elts = [] + for elt in tup: + if isinstance(elt, tuple): + elts = elts + flatten(elt) + else: + elts.append(elt) + return elts + +class Set: + def __init__(self): + self.elts = {} + def __len__(self): + return len(self.elts) + def __contains__(self, elt): + return elt in self.elts + def add(self, elt): + self.elts[elt] = elt + def elements(self): + return self.elts.keys() + def has_elt(self, elt): + return elt in self.elts + def remove(self, elt): + del self.elts[elt] + def copy(self): + c = Set() + c.elts.update(self.elts) + return c + +class Stack: + def __init__(self): + self.stack = [] + self.pop = self.stack.pop + def __len__(self): + return len(self.stack) + def push(self, elt): + self.stack.append(elt) + def top(self): + return self.stack[-1] + def __getitem__(self, index): # needed by visitContinue() + return self.stack[index] + +MANGLE_LEN = 256 # magic constant from compile.c + +def mangle(name, klass): + if not name.startswith('__'): + return name + if len(name) + 2 >= MANGLE_LEN: + return name + if name.endswith('__'): + return name + try: + i = 0 + while klass[i] == '_': + i = i + 1 + except IndexError: + return name + klass = klass[i:] + + tlen = len(klass) + len(name) + if tlen > MANGLE_LEN: + klass = klass[:MANGLE_LEN-tlen] + + return "_%s%s" % (klass, name) + +def set_filename(filename, tree): + """Set the filename attribute to filename on every node in tree""" + worklist = [tree] + while worklist: + node = worklist.pop(0) + node.filename = filename + worklist.extend(node.getChildNodes()) diff --git a/test/ok_2.7/compiler/syntax.py b/test/ok_2.7/compiler/syntax.py new file mode 100644 index 00000000..a45d9c2c --- /dev/null +++ b/test/ok_2.7/compiler/syntax.py @@ -0,0 +1,46 @@ +"""Check for errs in the AST. + +The Python parser does not catch all syntax errors. Others, like +assignments with invalid targets, are caught in the code generation +phase. + +The compiler package catches some errors in the transformer module. +But it seems clearer to write checkers that use the AST to detect +errors. +""" + +from compiler import ast, walk + +def check(tree, multi=None): + v = SyntaxErrorChecker(multi) + walk(tree, v) + return v.errors + +class SyntaxErrorChecker: + """A visitor to find syntax errors in the AST.""" + + def __init__(self, multi=None): + """Create new visitor object. + + If optional argument multi is not None, then print messages + for each error rather than raising a SyntaxError for the + first. + """ + self.multi = multi + self.errors = 0 + + def error(self, node, msg): + self.errors = self.errors + 1 + if self.multi is not None: + print "%s:%s: %s" % (node.filename, node.lineno, msg) + else: + raise SyntaxError, "%s (%s:%s)" % (msg, node.filename, node.lineno) + + def visitAssign(self, node): + # the transformer module handles many of these + pass +## for target in node.nodes: +## if isinstance(target, ast.AssList): +## if target.lineno is None: +## target.lineno = node.lineno +## self.error(target, "can't assign to list comprehension") diff --git a/test/ok_2.7/ctypes/_endian.py b/test/ok_2.7/ctypes/_endian.py new file mode 100644 index 00000000..f80e675a --- /dev/null +++ b/test/ok_2.7/ctypes/_endian.py @@ -0,0 +1,64 @@ +###################################################################### +# This file should be kept compatible with Python 2.3, see PEP 291. # +###################################################################### +import sys +from ctypes import * + +_array_type = type(Array) + +def _other_endian(typ): + """Return the type with the 'other' byte order. Simple types like + c_int and so on already have __ctype_be__ and __ctype_le__ + attributes which contain the types, for more complicated types + arrays and structures are supported. + """ + # check _OTHER_ENDIAN attribute (present if typ is primitive type) + if hasattr(typ, _OTHER_ENDIAN): + return getattr(typ, _OTHER_ENDIAN) + # if typ is array + if isinstance(typ, _array_type): + return _other_endian(typ._type_) * typ._length_ + # if typ is structure + if issubclass(typ, Structure): + return typ + raise TypeError("This type does not support other endian: %s" % typ) + +class _swapped_meta(type(Structure)): + def __setattr__(self, attrname, value): + if attrname == "_fields_": + fields = [] + for desc in value: + name = desc[0] + typ = desc[1] + rest = desc[2:] + fields.append((name, _other_endian(typ)) + rest) + value = fields + super(_swapped_meta, self).__setattr__(attrname, value) + +################################################################ + +# Note: The Structure metaclass checks for the *presence* (not the +# value!) of a _swapped_bytes_ attribute to determine the bit order in +# structures containing bit fields. + +if sys.byteorder == "little": + _OTHER_ENDIAN = "__ctype_be__" + + LittleEndianStructure = Structure + + class BigEndianStructure(Structure): + """Structure with big endian byte order""" + __metaclass__ = _swapped_meta + _swappedbytes_ = None + +elif sys.byteorder == "big": + _OTHER_ENDIAN = "__ctype_le__" + + BigEndianStructure = Structure + class LittleEndianStructure(Structure): + """Structure with little endian byte order""" + __metaclass__ = _swapped_meta + _swappedbytes_ = None + +else: + raise RuntimeError("Invalid byteorder") diff --git a/test/ok_2.7/ctypes/util.py b/test/ok_2.7/ctypes/util.py new file mode 100644 index 00000000..3430b73a --- /dev/null +++ b/test/ok_2.7/ctypes/util.py @@ -0,0 +1,287 @@ +###################################################################### +# This file should be kept compatible with Python 2.3, see PEP 291. # +###################################################################### +import sys, os + +# find_library(name) returns the pathname of a library, or None. +if os.name == "nt": + + def _get_build_version(): + """Return the version of MSVC that was used to build Python. + + For Python 2.3 and up, the version number is included in + sys.version. For earlier versions, assume the compiler is MSVC 6. + """ + # This function was copied from Lib/distutils/msvccompiler.py + prefix = "MSC v." + i = sys.version.find(prefix) + if i == -1: + return 6 + i = i + len(prefix) + s, rest = sys.version[i:].split(" ", 1) + majorVersion = int(s[:-2]) - 6 + minorVersion = int(s[2:3]) / 10.0 + # I don't think paths are affected by minor version in version 6 + if majorVersion == 6: + minorVersion = 0 + if majorVersion >= 6: + return majorVersion + minorVersion + # else we don't know what version of the compiler this is + return None + + def find_msvcrt(): + """Return the name of the VC runtime dll""" + version = _get_build_version() + if version is None: + # better be safe than sorry + return None + if version <= 6: + clibname = 'msvcrt' + else: + clibname = 'msvcr%d' % (version * 10) + + # If python was built with in debug mode + import imp + if imp.get_suffixes()[0][0] == '_d.pyd': + clibname += 'd' + return clibname+'.dll' + + def find_library(name): + if name in ('c', 'm'): + return find_msvcrt() + # See MSDN for the REAL search order. + for directory in os.environ['PATH'].split(os.pathsep): + fname = os.path.join(directory, name) + if os.path.isfile(fname): + return fname + if fname.lower().endswith(".dll"): + continue + fname = fname + ".dll" + if os.path.isfile(fname): + return fname + return None + +if os.name == "ce": + # search path according to MSDN: + # - absolute path specified by filename + # - The .exe launch directory + # - the Windows directory + # - ROM dll files (where are they?) + # - OEM specified search path: HKLM\Loader\SystemPath + def find_library(name): + return name + +if os.name == "posix" and sys.platform == "darwin": + from ctypes.macholib.dyld import dyld_find as _dyld_find + def find_library(name): + possible = ['lib%s.dylib' % name, + '%s.dylib' % name, + '%s.framework/%s' % (name, name)] + for name in possible: + try: + return _dyld_find(name) + except ValueError: + continue + return None + +elif os.name == "posix": + # Andreas Degert's find functions, using gcc, /sbin/ldconfig, objdump + import re, tempfile, errno + + def _findLib_gcc(name): + expr = r'[^\(\)\s]*lib%s\.[^\(\)\s]*' % re.escape(name) + fdout, ccout = tempfile.mkstemp() + os.close(fdout) + cmd = 'if type gcc >/dev/null 2>&1; then CC=gcc; elif type cc >/dev/null 2>&1; then CC=cc;else exit 10; fi;' \ + 'LANG=C LC_ALL=C $CC -Wl,-t -o ' + ccout + ' 2>&1 -l' + name + try: + f = os.popen(cmd) + try: + trace = f.read() + finally: + rv = f.close() + finally: + try: + os.unlink(ccout) + except OSError, e: + if e.errno != errno.ENOENT: + raise + if rv == 10: + raise OSError, 'gcc or cc command not found' + res = re.search(expr, trace) + if not res: + return None + return res.group(0) + + + if sys.platform == "sunos5": + # use /usr/ccs/bin/dump on solaris + def _get_soname(f): + if not f: + return None + cmd = "/usr/ccs/bin/dump -Lpv 2>/dev/null " + f + f = os.popen(cmd) + try: + data = f.read() + finally: + f.close() + res = re.search(r'\[.*\]\sSONAME\s+([^\s]+)', data) + if not res: + return None + return res.group(1) + else: + def _get_soname(f): + # assuming GNU binutils / ELF + if not f: + return None + cmd = 'if ! type objdump >/dev/null 2>&1; then exit 10; fi;' \ + "objdump -p -j .dynamic 2>/dev/null " + f + f = os.popen(cmd) + dump = f.read() + rv = f.close() + if rv == 10: + raise OSError, 'objdump command not found' + f = os.popen(cmd) + try: + data = f.read() + finally: + f.close() + res = re.search(r'\sSONAME\s+([^\s]+)', data) + if not res: + return None + return res.group(1) + + if (sys.platform.startswith("freebsd") + or sys.platform.startswith("openbsd") + or sys.platform.startswith("dragonfly")): + + def _num_version(libname): + # "libxyz.so.MAJOR.MINOR" => [ MAJOR, MINOR ] + parts = libname.split(".") + nums = [] + try: + while parts: + nums.insert(0, int(parts.pop())) + except ValueError: + pass + return nums or [ sys.maxint ] + + def find_library(name): + ename = re.escape(name) + expr = r':-l%s\.\S+ => \S*/(lib%s\.\S+)' % (ename, ename) + f = os.popen('/sbin/ldconfig -r 2>/dev/null') + try: + data = f.read() + finally: + f.close() + res = re.findall(expr, data) + if not res: + return _get_soname(_findLib_gcc(name)) + res.sort(cmp= lambda x,y: cmp(_num_version(x), _num_version(y))) + return res[-1] + + elif sys.platform == "sunos5": + + def _findLib_crle(name, is64): + if not os.path.exists('/usr/bin/crle'): + return None + + if is64: + cmd = 'env LC_ALL=C /usr/bin/crle -64 2>/dev/null' + else: + cmd = 'env LC_ALL=C /usr/bin/crle 2>/dev/null' + + for line in os.popen(cmd).readlines(): + line = line.strip() + if line.startswith('Default Library Path (ELF):'): + paths = line.split()[4] + + if not paths: + return None + + for dir in paths.split(":"): + libfile = os.path.join(dir, "lib%s.so" % name) + if os.path.exists(libfile): + return libfile + + return None + + def find_library(name, is64 = False): + return _get_soname(_findLib_crle(name, is64) or _findLib_gcc(name)) + + else: + + def _findSoname_ldconfig(name): + import struct + # XXX this code assumes that we know all unames and that a single + # ABI is supported per uname; instead we should find what the + # ABI is (e.g. check ABI of current process) or simply ask libc + # to load the library for us + uname = os.uname()[4] + # ARM has a variety of unames, e.g. armv7l + if uname.startswith("arm"): + uname = "arm" + if struct.calcsize('l') == 4: + machine = uname + '-32' + else: + machine = uname + '-64' + mach_map = { + 'x86_64-64': 'libc6,x86-64', + 'ppc64-64': 'libc6,64bit', + 'sparc64-64': 'libc6,64bit', + 's390x-64': 'libc6,64bit', + 'ia64-64': 'libc6,IA-64', + # this actually breaks on biarch or multiarch as the first + # library wins; uname doesn't tell us which ABI we're using + 'arm-32': 'libc6(,hard-float)?', + } + abi_type = mach_map.get(machine, 'libc6') + + # XXX assuming GLIBC's ldconfig (with option -p) + expr = r'\s+(lib%s\.[^\s]+)\s+\(%s' % (re.escape(name), abi_type) + f = os.popen('/sbin/ldconfig -p 2>/dev/null') + try: + data = f.read() + finally: + f.close() + res = re.search(expr, data) + if not res: + return None + return res.group(1) + + def find_library(name): + return _findSoname_ldconfig(name) or _get_soname(_findLib_gcc(name)) + +################################################################ +# test code + +def test(): + from ctypes import cdll + if os.name == "nt": + print cdll.msvcrt + print cdll.load("msvcrt") + print find_library("msvcrt") + + if os.name == "posix": + # find and load_version + print find_library("m") + print find_library("c") + print find_library("bz2") + + # getattr +## print cdll.m +## print cdll.bz2 + + # load + if sys.platform == "darwin": + print cdll.LoadLibrary("libm.dylib") + print cdll.LoadLibrary("libcrypto.dylib") + print cdll.LoadLibrary("libSystem.dylib") + print cdll.LoadLibrary("System.framework/System") + else: + print cdll.LoadLibrary("libm.so") + print cdll.LoadLibrary("libcrypt.so") + print find_library("crypt") + +if __name__ == "__main__": + test() diff --git a/test/ok_2.7/ctypes/wintypes.py b/test/ok_2.7/ctypes/wintypes.py new file mode 100644 index 00000000..dafbb78b --- /dev/null +++ b/test/ok_2.7/ctypes/wintypes.py @@ -0,0 +1,185 @@ +###################################################################### +# This file should be kept compatible with Python 2.3, see PEP 291. # +###################################################################### + +# The most useful windows datatypes +from ctypes import * + +BYTE = c_byte +WORD = c_ushort +DWORD = c_ulong + +WCHAR = c_wchar +UINT = c_uint +INT = c_int + +DOUBLE = c_double +FLOAT = c_float + +BOOLEAN = BYTE +BOOL = c_long + +from ctypes import _SimpleCData +class VARIANT_BOOL(_SimpleCData): + _type_ = "v" + def __repr__(self): + return "%s(%r)" % (self.__class__.__name__, self.value) + +ULONG = c_ulong +LONG = c_long + +USHORT = c_ushort +SHORT = c_short + +# in the windows header files, these are structures. +_LARGE_INTEGER = LARGE_INTEGER = c_longlong +_ULARGE_INTEGER = ULARGE_INTEGER = c_ulonglong + +LPCOLESTR = LPOLESTR = OLESTR = c_wchar_p +LPCWSTR = LPWSTR = c_wchar_p +LPCSTR = LPSTR = c_char_p +LPCVOID = LPVOID = c_void_p + +# WPARAM is defined as UINT_PTR (unsigned type) +# LPARAM is defined as LONG_PTR (signed type) +if sizeof(c_long) == sizeof(c_void_p): + WPARAM = c_ulong + LPARAM = c_long +elif sizeof(c_longlong) == sizeof(c_void_p): + WPARAM = c_ulonglong + LPARAM = c_longlong + +ATOM = WORD +LANGID = WORD + +COLORREF = DWORD +LGRPID = DWORD +LCTYPE = DWORD + +LCID = DWORD + +################################################################ +# HANDLE types +HANDLE = c_void_p # in the header files: void * + +HACCEL = HANDLE +HBITMAP = HANDLE +HBRUSH = HANDLE +HCOLORSPACE = HANDLE +HDC = HANDLE +HDESK = HANDLE +HDWP = HANDLE +HENHMETAFILE = HANDLE +HFONT = HANDLE +HGDIOBJ = HANDLE +HGLOBAL = HANDLE +HHOOK = HANDLE +HICON = HANDLE +HINSTANCE = HANDLE +HKEY = HANDLE +HKL = HANDLE +HLOCAL = HANDLE +HMENU = HANDLE +HMETAFILE = HANDLE +HMODULE = HANDLE +HMONITOR = HANDLE +HPALETTE = HANDLE +HPEN = HANDLE +HRGN = HANDLE +HRSRC = HANDLE +HSTR = HANDLE +HTASK = HANDLE +HWINSTA = HANDLE +HWND = HANDLE +SC_HANDLE = HANDLE +SERVICE_STATUS_HANDLE = HANDLE + +################################################################ +# Some important structure definitions + +class RECT(Structure): + _fields_ = [("left", c_long), + ("top", c_long), + ("right", c_long), + ("bottom", c_long)] +tagRECT = _RECTL = RECTL = RECT + +class _SMALL_RECT(Structure): + _fields_ = [('Left', c_short), + ('Top', c_short), + ('Right', c_short), + ('Bottom', c_short)] +SMALL_RECT = _SMALL_RECT + +class _COORD(Structure): + _fields_ = [('X', c_short), + ('Y', c_short)] + +class POINT(Structure): + _fields_ = [("x", c_long), + ("y", c_long)] +tagPOINT = _POINTL = POINTL = POINT + +class SIZE(Structure): + _fields_ = [("cx", c_long), + ("cy", c_long)] +tagSIZE = SIZEL = SIZE + +def RGB(red, green, blue): + return red + (green << 8) + (blue << 16) + +class FILETIME(Structure): + _fields_ = [("dwLowDateTime", DWORD), + ("dwHighDateTime", DWORD)] +_FILETIME = FILETIME + +class MSG(Structure): + _fields_ = [("hWnd", HWND), + ("message", c_uint), + ("wParam", WPARAM), + ("lParam", LPARAM), + ("time", DWORD), + ("pt", POINT)] +tagMSG = MSG +MAX_PATH = 260 + +class WIN32_FIND_DATAA(Structure): + _fields_ = [("dwFileAttributes", DWORD), + ("ftCreationTime", FILETIME), + ("ftLastAccessTime", FILETIME), + ("ftLastWriteTime", FILETIME), + ("nFileSizeHigh", DWORD), + ("nFileSizeLow", DWORD), + ("dwReserved0", DWORD), + ("dwReserved1", DWORD), + ("cFileName", c_char * MAX_PATH), + ("cAlternateFileName", c_char * 14)] + +class WIN32_FIND_DATAW(Structure): + _fields_ = [("dwFileAttributes", DWORD), + ("ftCreationTime", FILETIME), + ("ftLastAccessTime", FILETIME), + ("ftLastWriteTime", FILETIME), + ("nFileSizeHigh", DWORD), + ("nFileSizeLow", DWORD), + ("dwReserved0", DWORD), + ("dwReserved1", DWORD), + ("cFileName", c_wchar * MAX_PATH), + ("cAlternateFileName", c_wchar * 14)] + +__all__ = ['ATOM', 'BOOL', 'BOOLEAN', 'BYTE', 'COLORREF', 'DOUBLE', 'DWORD', + 'FILETIME', 'FLOAT', 'HACCEL', 'HANDLE', 'HBITMAP', 'HBRUSH', + 'HCOLORSPACE', 'HDC', 'HDESK', 'HDWP', 'HENHMETAFILE', 'HFONT', + 'HGDIOBJ', 'HGLOBAL', 'HHOOK', 'HICON', 'HINSTANCE', 'HKEY', + 'HKL', 'HLOCAL', 'HMENU', 'HMETAFILE', 'HMODULE', 'HMONITOR', + 'HPALETTE', 'HPEN', 'HRGN', 'HRSRC', 'HSTR', 'HTASK', 'HWINSTA', + 'HWND', 'INT', 'LANGID', 'LARGE_INTEGER', 'LCID', 'LCTYPE', + 'LGRPID', 'LONG', 'LPARAM', 'LPCOLESTR', 'LPCSTR', 'LPCVOID', + 'LPCWSTR', 'LPOLESTR', 'LPSTR', 'LPVOID', 'LPWSTR', 'MAX_PATH', + 'MSG', 'OLESTR', 'POINT', 'POINTL', 'RECT', 'RECTL', 'RGB', + 'SC_HANDLE', 'SERVICE_STATUS_HANDLE', 'SHORT', 'SIZE', 'SIZEL', + 'SMALL_RECT', 'UINT', 'ULARGE_INTEGER', 'ULONG', 'USHORT', + 'VARIANT_BOOL', 'WCHAR', 'WIN32_FIND_DATAA', 'WIN32_FIND_DATAW', + 'WORD', 'WPARAM', '_COORD', '_FILETIME', '_LARGE_INTEGER', + '_POINTL', '_RECTL', '_SMALL_RECT', '_ULARGE_INTEGER', 'tagMSG', + 'tagPOINT', 'tagRECT', 'tagSIZE'] diff --git a/test/ok_2.7/curses/__init__.py b/test/ok_2.7/curses/__init__.py new file mode 100644 index 00000000..ecf59de3 --- /dev/null +++ b/test/ok_2.7/curses/__init__.py @@ -0,0 +1,59 @@ +"""curses + +The main package for curses support for Python. Normally used by importing +the package, and perhaps a particular module inside it. + + import curses + from curses import textpad + curses.initscr() + ... + +""" + +__revision__ = "$Id$" + +from _curses import * +from curses.wrapper import wrapper +import os as _os +import sys as _sys + +# Some constants, most notably the ACS_* ones, are only added to the C +# _curses module's dictionary after initscr() is called. (Some +# versions of SGI's curses don't define values for those constants +# until initscr() has been called.) This wrapper function calls the +# underlying C initscr(), and then copies the constants from the +# _curses module to the curses package's dictionary. Don't do 'from +# curses import *' if you'll be needing the ACS_* constants. + +def initscr(): + import _curses, curses + # we call setupterm() here because it raises an error + # instead of calling exit() in error cases. + setupterm(term=_os.environ.get("TERM", "unknown"), + fd=_sys.__stdout__.fileno()) + stdscr = _curses.initscr() + for key, value in _curses.__dict__.items(): + if key[0:4] == 'ACS_' or key in ('LINES', 'COLS'): + setattr(curses, key, value) + + return stdscr + +# This is a similar wrapper for start_color(), which adds the COLORS and +# COLOR_PAIRS variables which are only available after start_color() is +# called. + +def start_color(): + import _curses, curses + retval = _curses.start_color() + if hasattr(_curses, 'COLORS'): + curses.COLORS = _curses.COLORS + if hasattr(_curses, 'COLOR_PAIRS'): + curses.COLOR_PAIRS = _curses.COLOR_PAIRS + return retval + +# Import Python has_key() implementation if _curses doesn't contain has_key() + +try: + has_key +except NameError: + from has_key import has_key diff --git a/test/ok_2.7/curses/ascii.py b/test/ok_2.7/curses/ascii.py new file mode 100644 index 00000000..800fd8b4 --- /dev/null +++ b/test/ok_2.7/curses/ascii.py @@ -0,0 +1,99 @@ +"""Constants and membership tests for ASCII characters""" + +NUL = 0x00 # ^@ +SOH = 0x01 # ^A +STX = 0x02 # ^B +ETX = 0x03 # ^C +EOT = 0x04 # ^D +ENQ = 0x05 # ^E +ACK = 0x06 # ^F +BEL = 0x07 # ^G +BS = 0x08 # ^H +TAB = 0x09 # ^I +HT = 0x09 # ^I +LF = 0x0a # ^J +NL = 0x0a # ^J +VT = 0x0b # ^K +FF = 0x0c # ^L +CR = 0x0d # ^M +SO = 0x0e # ^N +SI = 0x0f # ^O +DLE = 0x10 # ^P +DC1 = 0x11 # ^Q +DC2 = 0x12 # ^R +DC3 = 0x13 # ^S +DC4 = 0x14 # ^T +NAK = 0x15 # ^U +SYN = 0x16 # ^V +ETB = 0x17 # ^W +CAN = 0x18 # ^X +EM = 0x19 # ^Y +SUB = 0x1a # ^Z +ESC = 0x1b # ^[ +FS = 0x1c # ^\ +GS = 0x1d # ^] +RS = 0x1e # ^^ +US = 0x1f # ^_ +SP = 0x20 # space +DEL = 0x7f # delete + +controlnames = [ +"NUL", "SOH", "STX", "ETX", "EOT", "ENQ", "ACK", "BEL", +"BS", "HT", "LF", "VT", "FF", "CR", "SO", "SI", +"DLE", "DC1", "DC2", "DC3", "DC4", "NAK", "SYN", "ETB", +"CAN", "EM", "SUB", "ESC", "FS", "GS", "RS", "US", +"SP" +] + +def _ctoi(c): + if type(c) == type(""): + return ord(c) + else: + return c + +def isalnum(c): return isalpha(c) or isdigit(c) +def isalpha(c): return isupper(c) or islower(c) +def isascii(c): return _ctoi(c) <= 127 # ? +def isblank(c): return _ctoi(c) in (8,32) +def iscntrl(c): return _ctoi(c) <= 31 +def isdigit(c): return _ctoi(c) >= 48 and _ctoi(c) <= 57 +def isgraph(c): return _ctoi(c) >= 33 and _ctoi(c) <= 126 +def islower(c): return _ctoi(c) >= 97 and _ctoi(c) <= 122 +def isprint(c): return _ctoi(c) >= 32 and _ctoi(c) <= 126 +def ispunct(c): return _ctoi(c) != 32 and not isalnum(c) +def isspace(c): return _ctoi(c) in (9, 10, 11, 12, 13, 32) +def isupper(c): return _ctoi(c) >= 65 and _ctoi(c) <= 90 +def isxdigit(c): return isdigit(c) or \ + (_ctoi(c) >= 65 and _ctoi(c) <= 70) or (_ctoi(c) >= 97 and _ctoi(c) <= 102) +def isctrl(c): return _ctoi(c) < 32 +def ismeta(c): return _ctoi(c) > 127 + +def ascii(c): + if type(c) == type(""): + return chr(_ctoi(c) & 0x7f) + else: + return _ctoi(c) & 0x7f + +def ctrl(c): + if type(c) == type(""): + return chr(_ctoi(c) & 0x1f) + else: + return _ctoi(c) & 0x1f + +def alt(c): + if type(c) == type(""): + return chr(_ctoi(c) | 0x80) + else: + return _ctoi(c) | 0x80 + +def unctrl(c): + bits = _ctoi(c) + if bits == 0x7f: + rep = "^?" + elif isprint(bits & 0x7f): + rep = chr(bits & 0x7f) + else: + rep = "^" + chr(((bits & 0x7f) | 0x20) + 0x20) + if bits & 0x80: + return "!" + rep + return rep diff --git a/test/ok_2.7/curses/has_key.py b/test/ok_2.7/curses/has_key.py new file mode 100644 index 00000000..1dd5a3bd --- /dev/null +++ b/test/ok_2.7/curses/has_key.py @@ -0,0 +1,192 @@ + +# +# Emulation of has_key() function for platforms that don't use ncurses +# + +import _curses + +# Table mapping curses keys to the terminfo capability name + +_capability_names = { + _curses.KEY_A1: 'ka1', + _curses.KEY_A3: 'ka3', + _curses.KEY_B2: 'kb2', + _curses.KEY_BACKSPACE: 'kbs', + _curses.KEY_BEG: 'kbeg', + _curses.KEY_BTAB: 'kcbt', + _curses.KEY_C1: 'kc1', + _curses.KEY_C3: 'kc3', + _curses.KEY_CANCEL: 'kcan', + _curses.KEY_CATAB: 'ktbc', + _curses.KEY_CLEAR: 'kclr', + _curses.KEY_CLOSE: 'kclo', + _curses.KEY_COMMAND: 'kcmd', + _curses.KEY_COPY: 'kcpy', + _curses.KEY_CREATE: 'kcrt', + _curses.KEY_CTAB: 'kctab', + _curses.KEY_DC: 'kdch1', + _curses.KEY_DL: 'kdl1', + _curses.KEY_DOWN: 'kcud1', + _curses.KEY_EIC: 'krmir', + _curses.KEY_END: 'kend', + _curses.KEY_ENTER: 'kent', + _curses.KEY_EOL: 'kel', + _curses.KEY_EOS: 'ked', + _curses.KEY_EXIT: 'kext', + _curses.KEY_F0: 'kf0', + _curses.KEY_F1: 'kf1', + _curses.KEY_F10: 'kf10', + _curses.KEY_F11: 'kf11', + _curses.KEY_F12: 'kf12', + _curses.KEY_F13: 'kf13', + _curses.KEY_F14: 'kf14', + _curses.KEY_F15: 'kf15', + _curses.KEY_F16: 'kf16', + _curses.KEY_F17: 'kf17', + _curses.KEY_F18: 'kf18', + _curses.KEY_F19: 'kf19', + _curses.KEY_F2: 'kf2', + _curses.KEY_F20: 'kf20', + _curses.KEY_F21: 'kf21', + _curses.KEY_F22: 'kf22', + _curses.KEY_F23: 'kf23', + _curses.KEY_F24: 'kf24', + _curses.KEY_F25: 'kf25', + _curses.KEY_F26: 'kf26', + _curses.KEY_F27: 'kf27', + _curses.KEY_F28: 'kf28', + _curses.KEY_F29: 'kf29', + _curses.KEY_F3: 'kf3', + _curses.KEY_F30: 'kf30', + _curses.KEY_F31: 'kf31', + _curses.KEY_F32: 'kf32', + _curses.KEY_F33: 'kf33', + _curses.KEY_F34: 'kf34', + _curses.KEY_F35: 'kf35', + _curses.KEY_F36: 'kf36', + _curses.KEY_F37: 'kf37', + _curses.KEY_F38: 'kf38', + _curses.KEY_F39: 'kf39', + _curses.KEY_F4: 'kf4', + _curses.KEY_F40: 'kf40', + _curses.KEY_F41: 'kf41', + _curses.KEY_F42: 'kf42', + _curses.KEY_F43: 'kf43', + _curses.KEY_F44: 'kf44', + _curses.KEY_F45: 'kf45', + _curses.KEY_F46: 'kf46', + _curses.KEY_F47: 'kf47', + _curses.KEY_F48: 'kf48', + _curses.KEY_F49: 'kf49', + _curses.KEY_F5: 'kf5', + _curses.KEY_F50: 'kf50', + _curses.KEY_F51: 'kf51', + _curses.KEY_F52: 'kf52', + _curses.KEY_F53: 'kf53', + _curses.KEY_F54: 'kf54', + _curses.KEY_F55: 'kf55', + _curses.KEY_F56: 'kf56', + _curses.KEY_F57: 'kf57', + _curses.KEY_F58: 'kf58', + _curses.KEY_F59: 'kf59', + _curses.KEY_F6: 'kf6', + _curses.KEY_F60: 'kf60', + _curses.KEY_F61: 'kf61', + _curses.KEY_F62: 'kf62', + _curses.KEY_F63: 'kf63', + _curses.KEY_F7: 'kf7', + _curses.KEY_F8: 'kf8', + _curses.KEY_F9: 'kf9', + _curses.KEY_FIND: 'kfnd', + _curses.KEY_HELP: 'khlp', + _curses.KEY_HOME: 'khome', + _curses.KEY_IC: 'kich1', + _curses.KEY_IL: 'kil1', + _curses.KEY_LEFT: 'kcub1', + _curses.KEY_LL: 'kll', + _curses.KEY_MARK: 'kmrk', + _curses.KEY_MESSAGE: 'kmsg', + _curses.KEY_MOVE: 'kmov', + _curses.KEY_NEXT: 'knxt', + _curses.KEY_NPAGE: 'knp', + _curses.KEY_OPEN: 'kopn', + _curses.KEY_OPTIONS: 'kopt', + _curses.KEY_PPAGE: 'kpp', + _curses.KEY_PREVIOUS: 'kprv', + _curses.KEY_PRINT: 'kprt', + _curses.KEY_REDO: 'krdo', + _curses.KEY_REFERENCE: 'kref', + _curses.KEY_REFRESH: 'krfr', + _curses.KEY_REPLACE: 'krpl', + _curses.KEY_RESTART: 'krst', + _curses.KEY_RESUME: 'kres', + _curses.KEY_RIGHT: 'kcuf1', + _curses.KEY_SAVE: 'ksav', + _curses.KEY_SBEG: 'kBEG', + _curses.KEY_SCANCEL: 'kCAN', + _curses.KEY_SCOMMAND: 'kCMD', + _curses.KEY_SCOPY: 'kCPY', + _curses.KEY_SCREATE: 'kCRT', + _curses.KEY_SDC: 'kDC', + _curses.KEY_SDL: 'kDL', + _curses.KEY_SELECT: 'kslt', + _curses.KEY_SEND: 'kEND', + _curses.KEY_SEOL: 'kEOL', + _curses.KEY_SEXIT: 'kEXT', + _curses.KEY_SF: 'kind', + _curses.KEY_SFIND: 'kFND', + _curses.KEY_SHELP: 'kHLP', + _curses.KEY_SHOME: 'kHOM', + _curses.KEY_SIC: 'kIC', + _curses.KEY_SLEFT: 'kLFT', + _curses.KEY_SMESSAGE: 'kMSG', + _curses.KEY_SMOVE: 'kMOV', + _curses.KEY_SNEXT: 'kNXT', + _curses.KEY_SOPTIONS: 'kOPT', + _curses.KEY_SPREVIOUS: 'kPRV', + _curses.KEY_SPRINT: 'kPRT', + _curses.KEY_SR: 'kri', + _curses.KEY_SREDO: 'kRDO', + _curses.KEY_SREPLACE: 'kRPL', + _curses.KEY_SRIGHT: 'kRIT', + _curses.KEY_SRSUME: 'kRES', + _curses.KEY_SSAVE: 'kSAV', + _curses.KEY_SSUSPEND: 'kSPD', + _curses.KEY_STAB: 'khts', + _curses.KEY_SUNDO: 'kUND', + _curses.KEY_SUSPEND: 'kspd', + _curses.KEY_UNDO: 'kund', + _curses.KEY_UP: 'kcuu1' + } + +def has_key(ch): + if isinstance(ch, str): + ch = ord(ch) + + # Figure out the correct capability name for the keycode. + capability_name = _capability_names.get(ch) + if capability_name is None: + return False + + #Check the current terminal description for that capability; + #if present, return true, else return false. + if _curses.tigetstr( capability_name ): + return True + else: + return False + +if __name__ == '__main__': + # Compare the output of this implementation and the ncurses has_key, + # on platforms where has_key is already available + try: + L = [] + _curses.initscr() + for key in _capability_names.keys(): + system = key in _curses + python = has_key(key) + if system != python: + L.append( 'Mismatch for key %s, system=%i, Python=%i' + % (_curses.keyname( key ), system, python) ) + finally: + _curses.endwin() + for i in L: print i diff --git a/test/ok_2.7/curses/panel.py b/test/ok_2.7/curses/panel.py new file mode 100644 index 00000000..aacca851 --- /dev/null +++ b/test/ok_2.7/curses/panel.py @@ -0,0 +1,8 @@ +"""curses.panel + +Module for using panels with curses. +""" + +__revision__ = "$Id$" + +from _curses_panel import * diff --git a/test/ok_2.7/curses/wrapper.py b/test/ok_2.7/curses/wrapper.py new file mode 100644 index 00000000..5183ce74 --- /dev/null +++ b/test/ok_2.7/curses/wrapper.py @@ -0,0 +1,50 @@ +"""curses.wrapper + +Contains one function, wrapper(), which runs another function which +should be the rest of your curses-based application. If the +application raises an exception, wrapper() will restore the terminal +to a sane state so you can read the resulting traceback. + +""" + +import curses + +def wrapper(func, *args, **kwds): + """Wrapper function that initializes curses and calls another function, + restoring normal keyboard/screen behavior on error. + The callable object 'func' is then passed the main window 'stdscr' + as its first argument, followed by any other arguments passed to + wrapper(). + """ + + try: + # Initialize curses + stdscr = curses.initscr() + + # Turn off echoing of keys, and enter cbreak mode, + # where no buffering is performed on keyboard input + curses.noecho() + curses.cbreak() + + # In keypad mode, escape sequences for special keys + # (like the cursor keys) will be interpreted and + # a special value like curses.KEY_LEFT will be returned + stdscr.keypad(1) + + # Start color, too. Harmless if the terminal doesn't have + # color; user can test with has_color() later on. The try/catch + # works around a minor bit of over-conscientiousness in the curses + # module -- the error return from C start_color() is ignorable. + try: + curses.start_color() + except: + pass + + return func(stdscr, *args, **kwds) + finally: + # Set everything back to normal + if 'stdscr' in locals(): + stdscr.keypad(0) + curses.echo() + curses.nocbreak() + curses.endwin() diff --git a/test/ok_2.7/dircache.py b/test/ok_2.7/dircache.py new file mode 100644 index 00000000..7e4f0b50 --- /dev/null +++ b/test/ok_2.7/dircache.py @@ -0,0 +1,41 @@ +"""Read and cache directory listings. + +The listdir() routine returns a sorted list of the files in a directory, +using a cache to avoid reading the directory more often than necessary. +The annotate() routine appends slashes to directories.""" +from warnings import warnpy3k +warnpy3k("the dircache module has been removed in Python 3.0", stacklevel=2) +del warnpy3k + +import os + +__all__ = ["listdir", "opendir", "annotate", "reset"] + +cache = {} + +def reset(): + """Reset the cache completely.""" + global cache + cache = {} + +def listdir(path): + """List directory contents, using cache.""" + try: + cached_mtime, list = cache[path] + del cache[path] + except KeyError: + cached_mtime, list = -1, [] + mtime = os.stat(path).st_mtime + if mtime != cached_mtime: + list = os.listdir(path) + list.sort() + cache[path] = mtime, list + return list + +opendir = listdir # XXX backward compatibility + +def annotate(head, list): + """Add '/' suffixes to directories.""" + for i in range(len(list)): + if os.path.isdir(os.path.join(head, list[i])): + list[i] = list[i] + '/' diff --git a/test/ok_2.7/dis.py b/test/ok_2.7/dis.py new file mode 100644 index 00000000..5aa09c95 --- /dev/null +++ b/test/ok_2.7/dis.py @@ -0,0 +1,224 @@ +"""Disassembler of Python byte code into mnemonics.""" + +import sys +import types + +from opcode import * +from opcode import __all__ as _opcodes_all + +__all__ = ["dis", "disassemble", "distb", "disco", + "findlinestarts", "findlabels"] + _opcodes_all +del _opcodes_all + +_have_code = (types.MethodType, types.FunctionType, types.CodeType, + types.ClassType, type) + +def dis(x=None): + """Disassemble classes, methods, functions, or code. + + With no argument, disassemble the last traceback. + + """ + if x is None: + distb() + return + if isinstance(x, types.InstanceType): + x = x.__class__ + if hasattr(x, 'im_func'): + x = x.im_func + if hasattr(x, 'func_code'): + x = x.func_code + if hasattr(x, '__dict__'): + items = x.__dict__.items() + items.sort() + for name, x1 in items: + if isinstance(x1, _have_code): + print "Disassembly of %s:" % name + try: + dis(x1) + except TypeError, msg: + print "Sorry:", msg + print + elif hasattr(x, 'co_code'): + disassemble(x) + elif isinstance(x, str): + disassemble_string(x) + else: + raise TypeError, \ + "don't know how to disassemble %s objects" % \ + type(x).__name__ + +def distb(tb=None): + """Disassemble a traceback (default: last traceback).""" + if tb is None: + try: + tb = sys.last_traceback + except AttributeError: + raise RuntimeError, "no last traceback to disassemble" + while tb.tb_next: tb = tb.tb_next + disassemble(tb.tb_frame.f_code, tb.tb_lasti) + +def disassemble(co, lasti=-1): + """Disassemble a code object.""" + code = co.co_code + labels = findlabels(code) + linestarts = dict(findlinestarts(co)) + n = len(code) + i = 0 + extended_arg = 0 + free = None + while i < n: + c = code[i] + op = ord(c) + if i in linestarts: + if i > 0: + print + print "%3d" % linestarts[i], + else: + print ' ', + + if i == lasti: print '-->', + else: print ' ', + if i in labels: print '>>', + else: print ' ', + print repr(i).rjust(4), + print opname[op].ljust(20), + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg + extended_arg = 0 + i = i+2 + if op == EXTENDED_ARG: + extended_arg = oparg*65536L + print repr(oparg).rjust(5), + if op in hasconst: + print '(' + repr(co.co_consts[oparg]) + ')', + elif op in hasname: + print '(' + co.co_names[oparg] + ')', + elif op in hasjrel: + print '(to ' + repr(i + oparg) + ')', + elif op in haslocal: + print '(' + co.co_varnames[oparg] + ')', + elif op in hascompare: + print '(' + cmp_op[oparg] + ')', + elif op in hasfree: + if free is None: + free = co.co_cellvars + co.co_freevars + print '(' + free[oparg] + ')', + print + +def disassemble_string(code, lasti=-1, varnames=None, names=None, + constants=None): + labels = findlabels(code) + n = len(code) + i = 0 + while i < n: + c = code[i] + op = ord(c) + if i == lasti: print '-->', + else: print ' ', + if i in labels: print '>>', + else: print ' ', + print repr(i).rjust(4), + print opname[op].ljust(15), + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + i = i+2 + print repr(oparg).rjust(5), + if op in hasconst: + if constants: + print '(' + repr(constants[oparg]) + ')', + else: + print '(%d)'%oparg, + elif op in hasname: + if names is not None: + print '(' + names[oparg] + ')', + else: + print '(%d)'%oparg, + elif op in hasjrel: + print '(to ' + repr(i + oparg) + ')', + elif op in haslocal: + if varnames: + print '(' + varnames[oparg] + ')', + else: + print '(%d)' % oparg, + elif op in hascompare: + print '(' + cmp_op[oparg] + ')', + print + +disco = disassemble # XXX For backwards compatibility + +def findlabels(code): + """Detect all offsets in a byte code which are jump targets. + + Return the list of offsets. + + """ + labels = [] + n = len(code) + i = 0 + while i < n: + c = code[i] + op = ord(c) + i = i+1 + if op >= HAVE_ARGUMENT: + oparg = ord(code[i]) + ord(code[i+1])*256 + i = i+2 + label = -1 + if op in hasjrel: + label = i+oparg + elif op in hasjabs: + label = oparg + if label >= 0: + if label not in labels: + labels.append(label) + return labels + +def findlinestarts(code): + """Find the offsets in a byte code which are start of lines in the source. + + Generate pairs (offset, lineno) as described in Python/compile.c. + + """ + byte_increments = [ord(c) for c in code.co_lnotab[0::2]] + line_increments = [ord(c) for c in code.co_lnotab[1::2]] + + lastlineno = None + lineno = code.co_firstlineno + addr = 0 + for byte_incr, line_incr in zip(byte_increments, line_increments): + if byte_incr: + if lineno != lastlineno: + yield (addr, lineno) + lastlineno = lineno + addr += byte_incr + lineno += line_incr + if lineno != lastlineno: + yield (addr, lineno) + +def _test(): + """Simple test program to disassemble a file.""" + if sys.argv[1:]: + if sys.argv[2:]: + sys.stderr.write("usage: python dis.py [-|file]\n") + sys.exit(2) + fn = sys.argv[1] + if not fn or fn == "-": + fn = None + else: + fn = None + if fn is None: + f = sys.stdin + else: + f = open(fn) + source = f.read() + if fn is not None: + f.close() + else: + fn = "" + code = compile(source, fn, "exec") + dis(code) + +if __name__ == "__main__": + _test() diff --git a/test_one b/test/test_one similarity index 100% rename from test_one rename to test/test_one diff --git a/test/test_pythonlib.py b/test/test_pythonlib.py new file mode 100755 index 00000000..931524ca --- /dev/null +++ b/test/test_pythonlib.py @@ -0,0 +1,167 @@ +#!/usr/bin/env python +# emacs-mode: -*-python-*- + +from __future__ import print_function + +''' +test_pythonlib.py -- uncompyle and verify Python libraries + +Usage-Examples: + + test_pythonlib.py --all # decompile all tests (suite + libs) + test_pythonlib.py --all --verify # decomyile all tests and verify results + test_pythonlib.py --test # decompile only the testsuite + test_pythonlib.py --2.2 --verify # decompile and verify python lib 2.2 + +Adding own test-trees: + +Step 1) Edit this file and add a new entry to 'test_options', eg. + test_options['mylib'] = ('/usr/lib/mylib', PYOC, 'mylib') +Step 2: Run the test: + test_pythonlib.py --mylib # decompile 'mylib' + test_pythonlib.py --mylib --verify # decompile verify 'mylib' +''' + +import getopt, os, py_compile, sys, shutil, tempfile, time + +from uncompyle6 import main, verify +from fnmatch import fnmatch + +def get_srcdir(): + filename = os.path.normcase(os.path.dirname(__file__)) + return os.path.realpath(filename) + +src_dir = get_srcdir() + +#----- configure this for your needs + +lib_prefix = [src_dir, '/usr/lib/', '/usr/local/lib/'] + +target_base = tempfile.mkdtemp(prefix='py-dis-') + +PY = ('*.py', ) +PYC = ('*.pyc', ) +PYO = ('*.pyo', ) +PYOC = ('*.pyc', '*.pyo') + +test_options = { + # name: (src_basedir, pattern, output_base_suffix) + 'test': ['test', PYC, 'test'], + '2.7': ['python2.7', PYC, 'python2.7'], + 'ok-2.7': [os.path.join(src_dir, 'ok_2.7'), + PYC, 'ok-2.7'], + 'base2': [os.path.join(src_dir, 'base-tests', 'python2'), + PYC, 'base2'], +} + +#----- + +def help(): + print(""" +Usage-Examples: + test_pythonlib.py --base2 --verify --compile # compile, decompyle and verify short tests + test_pythonlib.py --ok-2.7 --verify # decompile and verify known good python 2.7 + test_pythonlib.py --2.7 # decompile Python's installed lib files +""") + sys.exit(1) + + +def do_tests(src_dir, obj_patterns, target_dir, opts): + + def file_matches(files, root, basenames, patterns): + files.extend( + [os.path.normpath(os.path.join(root, n)) + for n in basenames + for pat in patterns + if fnmatch(n, pat)]) + + files = [] + if opts['do_compile']: + for root, dirs, basenames in os.walk(src_dir): + file_matches(files, root, basenames, PY) + for sfile in files: + py_compile.compile(sfile) + pass + pass + files = [] + + for root, dirs, basenames in os.walk(src_dir): + file_matches(files, root, basenames, obj_patterns) + + if not files: + print("Didn't come up with any files to test! Try with --compile?", + file=sys.stderr) + exit(1) + + files.sort() + + if opts['start_with']: + try: + start_with = files.index(start_with) + files = files[start_with:] + print('>>> starting with file', files[0]) + except ValueError: + pass + + print(time.ctime()) + print('Source directory: ', src_dir) + print('Output directory: ', target_dir) + try: + main(src_dir, target_dir, files, [], do_verify=opts['do_verify']) + except (KeyboardInterrupt, OSError): + print() + exit(1) + +if __name__ == '__main__': + test_dirs = [] + checked_dirs = [] + start_with = None + + test_options_keys = list(test_options.keys()) + test_options_keys.sort() + opts, args = getopt.getopt(sys.argv[1:], '', + ['start-with=', 'verify', 'all', 'compile'] \ + + test_options_keys ) + if not opts: help() + + test_opts = { + 'do_compile': False, + 'do_verify': False, + 'start_with': None, + } + + for opt, val in opts: + if opt == '--verify': + test_opts['do_verify'] = True + elif opt == '--compile': + test_opts['do_compile'] = True + elif opt == '--start-with': + test_opts['start_with'] = val + elif opt[2:] in test_options_keys: + test_dirs.append(test_options[opt[2:]]) + elif opt == '--all': + for val in test_options_keys: + test_dirs.append(test_options[val]) + else: + help() + pass + pass + + for src_dir, pattern, target_dir in test_dirs: + if os.path.isdir(src_dir): + checked_dirs.append([src_dir, pattern, target_dir]) + else: + print("Can't find directory %s. Skipping" % src_dir, + file=sys.stderr) + pass + pass + + if not checked_dirs: + print("No directories found to check", file=sys.stderr) + sys.exit(1) + + for src_dir, pattern, target_dir in checked_dirs: + target_dir = os.path.join(target_base, target_dir) + if os.path.exists(target_dir): + shutil.rmtree(target_dir, ignore_errors=1) + do_tests(src_dir, pattern, target_dir, test_opts) diff --git a/uncompyle-code.py b/test/uncompyle-code.py similarity index 100% rename from uncompyle-code.py rename to test/uncompyle-code.py diff --git a/test_pythonlib.py b/test_pythonlib.py deleted file mode 100755 index 76077b9f..00000000 --- a/test_pythonlib.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python -from __future__ import print_function - -''' -test_pythonlib -- uncompyle and verify Python libraries - -Usage-Examples: - - test_pythonlib --all # decompile all tests (suite + libs) - test_pythonlib --all --verify # decomyile all tests and verify results - test_pythonlib --test # decompile only the testsuite - test_pythonlib --2.2 --verify # decompile and verify python lib 2.2 - -Adding own test-trees: - -Step 1) Edit this file and add a new entry to 'test_options', eg. - test_options['mylib'] = ('/usr/lib/mylib', PYOC, 'mylib') -Step 2: Run the test: - test_pythonlib --mylib # decompile 'mylib' - test_pythonlib --mylib --verify # decompile verify 'mylib' -''' - -from uncompyle6 import main, verify -import getopt, sys -import os, time, shutil -from fnmatch import fnmatch - -#----- configure this for your needs - -lib_prefix = ['.', '/usr/lib/', '/usr/local/lib/'] -target_base = '/tmp/py-dis/' - -PYC = ('*.pyc', ) -PYO = ('*.pyo', ) -PYOC = ('*.pyc', '*.pyo') - -test_options = { - # name: (src_basedir, pattern, output_base_suffix) - 'test': ['test', PYC, 'test'], - '2.5': ['python2.5', PYC, 'python-lib2.5'], - '2.6': ['python2.6', PYC, 'python-lib2.6'], - '2.7': ['python2.7', PYC, 'python-lib2.7'] -} - -#----- - -def help(): - print('Usage-Examples:') - print('test_pythonlib --all # decompile all tests (suite + libs)') - print('test_pythonlib --all --verify # decomyile all tests and verify results') - print('test_pythonlib --test # decompile only the testsuite') - print('test_pythonlib --2.2 --verify # decompile and verify python lib 2.2') - -def do_tests(src_dir, patterns, target_dir, start_with=None, do_verify=0): - def visitor(files, dirname, names): - files.extend( - [os.path.normpath(os.path.join(dirname, n)) - for n in names - for pat in patterns - if fnmatch(n, pat)]) - - files = [] - cwd = os.getcwd() - os.chdir(src_dir) - os.path.walk(os.curdir, visitor, files) - os.chdir(cwd) - files.sort() - - if start_with: - try: - start_with = files.index(start_with) - files = files[start_with:] - print('>>> starting with file', files[0]) - except ValueError: - pass - - print(time.ctime()) - print('Working directory: ', src_dir) - try: - main(src_dir, target_dir, files, [], do_verify=do_verify) - except (KeyboardInterrupt, OSError): - print - exit(1) - -if __name__ == '__main__': - do_verify = 0 - test_dirs = [] - checked_dirs = [] - start_with = None - - test_options_keys = test_options.keys(); test_options_keys.sort() - opts, args = getopt.getopt(sys.argv[1:], '', - ['start-with=', 'verify', 'all', ] \ - + test_options_keys ) - if not opts: - help() - for opt, val in opts: - if opt == '--verify': - do_verify = 1 - elif opt == '--start-with': - start_with = val - elif opt[2:] in test_options_keys: - test_dirs.append(test_options[opt[2:]]) - elif opt == '--all': - for val in test_options_keys: - test_dirs.append(test_options[val]) - else: - help() - - for src_dir, pattern, target_dir in test_dirs: - for libpath in lib_prefix: - testpath = os.path.join(libpath, src_dir) - testlibfile = "%s/%s" % (testpath, 'os.py') - testfile = "%s/%s" % (testpath, 'test_empty.py') - if os.path.exists(testlibfile) or os.path.exists(testfile): - src_dir = testpath - checked_dirs.append([src_dir, pattern, target_dir]) - break - - for src_dir, pattern, target_dir in checked_dirs: - target_dir = os.path.join(target_base, target_dir) - if os.path.exists(target_dir): - shutil.rmtree(target_dir, ignore_errors=1) - do_tests(src_dir, pattern, target_dir, start_with, do_verify) diff --git a/uncompyle6/#spark.py# b/uncompyle6/#spark.py# new file mode 100755 index 00000000..4284e996 --- /dev/null +++ b/uncompyle6/#spark.py# @@ -0,0 +1,704 @@ +from __future__ import print_function +''' +Copyright (c) 1998-2002 John Aycock + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +''' + +__version__ = 'SPARK-0.7 (pre-alpha-7) uncompyle trim' + +def _namelist(instance): + namelist, namedict, classlist = [], {}, [instance.__class__] + for c in classlist: + for b in c.__bases__: + classlist.append(b) + for name in list(c.__dict__.keys()): + if name not in namedict: + namelist.append(name) + namedict[name] = 1 + return namelist + +class _State: + ''' + Extracted from GenericParser and made global so that [un]picking works. + ''' + def __init__(self, stateno, items): + self.T, self.complete, self.items = [], [], items + self.stateno = stateno + +class GenericParser: + ''' + An Earley parser, as per J. Earley, "An Efficient Context-Free + Parsing Algorithm", CACM 13(2), pp. 94-102. Also J. C. Earley, + "An Efficient Context-Free Parsing Algorithm", Ph.D. thesis, + Carnegie-Mellon University, August 1968. New formulation of + the parser according to J. Aycock, "Practical Earley Parsing + and the SPARK Toolkit", Ph.D. thesis, University of Victoria, + 2001, and J. Aycock and R. N. Horspool, "Practical Earley + Parsing", unpublished paper, 2001. + ''' + + def __init__(self, start): + self.rules = {} + self.rule2func = {} + self.rule2name = {} + self.collectRules() + self.augment(start) + self.ruleschanged = 1 + + _NULLABLE = '\e_' + _START = 'START' + _BOF = '|-' + + # + # When pickling, take the time to generate the full state machine; + # some information is then extraneous, too. Unfortunately we + # can't save the rule2func map. + # + def __getstate__(self): + if self.ruleschanged: + # + # XXX - duplicated from parse() + # + self.computeNull() + self.newrules = {} + self.new2old = {} + self.makeNewRules() + self.ruleschanged = 0 + self.edges, self.cores = {}, {} + self.states = { 0: self.makeState0() } + self.makeState(0, self._BOF) + # + # XXX - should find a better way to do this.. + # + changes = 1 + while changes: + changes = 0 + for k, v in list(self.edges.items()): + if v is None: + state, sym = k + if self.states.has_key(state): + self.goto(state, sym) + changes = 1 + rv = self.__dict__.copy() + for s in self.states.values(): + del s.items + del rv['rule2func'] + del rv['nullable'] + del rv['cores'] + return rv + + def __setstate__(self, D): + self.rules = {} + self.rule2func = {} + self.rule2name = {} + self.collectRules() + start = D['rules'][self._START][0][1][1] # Blech. + self.augment(start) + D['rule2func'] = self.rule2func + D['makeSet'] = self.makeSet_fast + self.__dict__ = D + + # + # A hook for GenericASTBuilder and GenericASTMatcher. Mess + # thee not with this; nor shall thee toucheth the _preprocess + # argument to addRule. + # + def preprocess(self, rule, func): return rule, func + + def addRule(self, doc, func, _preprocess=1): + fn = func + rules = doc.split() + + index = [] + for i in range(len(rules)): + if rules[i] == '::=': + index.append(i-1) + index.append(len(rules)) + + for i in range(len(index)-1): + lhs = rules[index[i]] + rhs = rules[index[i]+2:index[i+1]] + rule = (lhs, tuple(rhs)) + + if _preprocess: + rule, fn = self.preprocess(rule, func) + + if lhs in self.rules: + self.rules[lhs].append(rule) + else: + self.rules[lhs] = [ rule ] + self.rule2func[rule] = fn + self.rule2name[rule] = func.__name__[2:] + self.ruleschanged = 1 + + def collectRules(self): + for name in _namelist(self): + if name[:2] == 'p_': + func = getattr(self, name) + doc = func.__doc__ + self.addRule(doc, func) + + def augment(self, start): + rule = '%s ::= %s %s' % (self._START, self._BOF, start) + self.addRule(rule, lambda args: args[1], 0) + + def computeNull(self): + self.nullable = {} + tbd = [] + + for rulelist in list(self.rules.values()): + lhs = rulelist[0][0] + self.nullable[lhs] = 0 + for rule in rulelist: + rhs = rule[1] + if len(rhs) == 0: + self.nullable[lhs] = 1 + continue + # + # We only need to consider rules which + # consist entirely of nonterminal symbols. + # This should be a savings on typical + # grammars. + # + for sym in rhs: + if sym not in self.rules: + break + else: + tbd.append(rule) + changes = 1 + while changes: + changes = 0 + for lhs, rhs in tbd: + if self.nullable[lhs]: + continue + for sym in rhs: + if not self.nullable[sym]: + break + else: + self.nullable[lhs] = 1 + changes = 1 + + def makeState0(self): + s0 = _State(0, []) + for rule in self.newrules[self._START]: + s0.items.append((rule, 0)) + return s0 + + def finalState(self, tokens): + # + # Yuck. + # + if len(self.newrules[self._START]) == 2 and len(tokens) == 0: + return 1 + start = self.rules[self._START][0][1][1] + return self.goto(1, start) + + def makeNewRules(self): + worklist = [] + for rulelist in list(self.rules.values()): + for rule in rulelist: + worklist.append((rule, 0, 1, rule)) + + for rule, i, candidate, oldrule in worklist: + lhs, rhs = rule + n = len(rhs) + while i < n: + sym = rhs[i] + if sym not in self.rules or \ + not self.nullable[sym]: + candidate = 0 + i = i + 1 + continue + + newrhs = list(rhs) + newrhs[i] = self._NULLABLE+sym + newrule = (lhs, tuple(newrhs)) + worklist.append((newrule, i+1, + candidate, oldrule)) + candidate = 0 + i = i + 1 + else: + if candidate: + lhs = self._NULLABLE+lhs + rule = (lhs, rhs) + if lhs in self.newrules: + self.newrules[lhs].append(rule) + else: + self.newrules[lhs] = [ rule ] + self.new2old[rule] = oldrule + + def typestring(self, token): + return None + + def error(self, token): + print("Syntax error at or near `%s' token" % token) + raise SystemExit + + def parse(self, tokens): + sets = [ [(1,0), (2,0)] ] + self.links = {} + + if self.ruleschanged: + self.computeNull() + self.newrules = {} + self.new2old = {} + self.makeNewRules() + self.ruleschanged = 0 + self.edges, self.cores = {}, {} + self.states = { 0: self.makeState0() } + self.makeState(0, self._BOF) + + for i in xrange(len(tokens)): + sets.append([]) + + if sets[i] == []: + break + self.makeSet(tokens[i], sets, i) + else: + sets.append([]) + self.makeSet(None, sets, len(tokens)) + + finalitem = (self.finalState(tokens), 0) + if finalitem not in sets[-2]: + if len(tokens) > 0: + self.error(tokens[i-1]) + else: + self.error(None) + + return self.buildTree(self._START, finalitem, + tokens, len(sets)-2) + + def isnullable(self, sym): + # + # For symbols in G_e only. If we weren't supporting 1.5, + # could just use sym.startswith(). + # + return self._NULLABLE == sym[0:len(self._NULLABLE)] + + def skip(self, xxx_todo_changeme, pos=0): + (lhs, rhs) = xxx_todo_changeme + n = len(rhs) + while pos < n: + if not self.isnullable(rhs[pos]): + break + pos = pos + 1 + return pos + + def makeState(self, state, sym): + assert sym is not None + # + # Compute \epsilon-kernel state's core and see if + # it exists already. + # + kitems = [] + for rule, pos in self.states[state].items: + lhs, rhs = rule + if rhs[pos:pos+1] == (sym,): + kitems.append((rule, self.skip(rule, pos+1))) + + tcore = tuple(sorted(kitems)) + if self.cores.has_key(tcore): + return self.cores[tcore] + # + # Nope, doesn't exist. Compute it and the associated + # \epsilon-nonkernel state together; we'll need it right away. + # + k = self.cores[tcore] = len(self.states) + K, NK = _State(k, kitems), _State(k+1, []) + self.states[k] = K + predicted = {} + + edges = self.edges + rules = self.newrules + for X in K, NK: + worklist = X.items + for item in worklist: + rule, pos = item + lhs, rhs = rule + if pos == len(rhs): + X.complete.append(rule) + continue + + nextSym = rhs[pos] + key = (X.stateno, nextSym) + if not rules.has_key(nextSym): + if not edges.has_key(key): + edges[key] = None + X.T.append(nextSym) + else: + edges[key] = None + if not predicted.has_key(nextSym): + predicted[nextSym] = 1 + for prule in rules[nextSym]: + ppos = self.skip(prule) + new = (prule, ppos) + NK.items.append(new) + # + # Problem: we know K needs generating, but we + # don't yet know about NK. Can't commit anything + # regarding NK to self.edges until we're sure. Should + # we delay committing on both K and NK to avoid this + # hacky code? This creates other problems.. + # + if X is K: + edges = {} + + if NK.items == []: + return k + + # + # Check for \epsilon-nonkernel's core. Unfortunately we + # need to know the entire set of predicted nonterminals + # to do this without accidentally duplicating states. + # + tcore = tuple(sorted(predicted.keys())) + if self.cores.has_key(tcore): + self.edges[(k, None)] = self.cores[tcore] + return k + + nk = self.cores[tcore] = self.edges[(k, None)] = NK.stateno + self.edges.update(edges) + self.states[nk] = NK + return k + + def goto(self, state, sym): + key = (state, sym) + if not self.edges.has_key(key): + # + # No transitions from state on sym. + # + return None + + rv = self.edges[key] + if rv is None: + # + # Target state isn't generated yet. Remedy this. + # + rv = self.makeState(state, sym) + self.edges[key] = rv + return rv + + def gotoT(self, state, t): + return [self.goto(state, t)] + + def gotoST(self, state, st): + rv = [] + for t in self.states[state].T: + if st == t: + rv.append(self.goto(state, t)) + return rv + + def add(self, set, item, i=None, predecessor=None, causal=None): + if predecessor is None: + if item not in set: + set.append(item) + else: + key = (item, i) + if item not in set: + self.links[key] = [] + set.append(item) + self.links[key].append((predecessor, causal)) + + def makeSet(self, token, sets, i): + cur, next = sets[i], sets[i+1] + + ttype = token is not None and self.typestring(token) or None + if ttype is not None: + fn, arg = self.gotoT, ttype + else: + fn, arg = self.gotoST, token + + for item in cur: + ptr = (item, i) + state, parent = item + add = fn(state, arg) + for k in add: + if k is not None: + self.add(next, (k, parent), i+1, ptr) + nk = self.goto(k, None) + if nk is not None: + self.add(next, (nk, i+1)) + + if parent == i: + continue + + for rule in self.states[state].complete: + lhs, rhs = rule + for pitem in sets[parent]: + pstate, pparent = pitem + k = self.goto(pstate, lhs) + if k is not None: + why = (item, i, rule) + pptr = (pitem, parent) + self.add(cur, (k, pparent), + i, pptr, why) + nk = self.goto(k, None) + if nk is not None: + self.add(cur, (nk, i)) + + def makeSet_fast(self, token, sets, i): + # + # Call *only* when the entire state machine has been built! + # It relies on self.edges being filled in completely, and + # then duplicates and inlines code to boost speed at the + # cost of extreme ugliness. + # + cur, next = sets[i], sets[i+1] + ttype = token is not None and self.typestring(token) or None + + for item in cur: + ptr = (item, i) + state, parent = item + if ttype is not None: + k = self.edges.get((state, ttype), None) + if k is not None: + #self.add(next, (k, parent), i+1, ptr) + #INLINED --v + new = (k, parent) + key = (new, i+1) + if new not in next: + self.links[key] = [] + next.append(new) + self.links[key].append((ptr, None)) + #INLINED --^ + #nk = self.goto(k, None) + nk = self.edges.get((k, None), None) + if nk is not None: + #self.add(next, (nk, i+1)) + #INLINED --v + new = (nk, i+1) + if new not in next: + next.append(new) + #INLINED --^ + else: + add = self.gotoST(state, token) + for k in add: + if k is not None: + self.add(next, (k, parent), i+1, ptr) + #nk = self.goto(k, None) + nk = self.edges.get((k, None), None) + if nk is not None: + self.add(next, (nk, i+1)) + + if parent == i: + continue + + for rule in self.states[state].complete: + lhs, rhs = rule + for pitem in sets[parent]: + pstate, pparent = pitem + #k = self.goto(pstate, lhs) + k = self.edges.get((pstate, lhs), None) + if k is not None: + why = (item, i, rule) + pptr = (pitem, parent) + #self.add(cur, (k, pparent), + # i, pptr, why) + #INLINED --v + new = (k, pparent) + key = (new, i) + if new not in cur: + self.links[key] = [] + cur.append(new) + self.links[key].append((pptr, why)) + #INLINED --^ + #nk = self.goto(k, None) + nk = self.edges.get((k, None), None) + if nk is not None: + #self.add(cur, (nk, i)) + #INLINED --v + new = (nk, i) + if new not in cur: + cur.append(new) + #INLINED --^ + + def predecessor(self, key, causal): + for p, c in self.links[key]: + if c == causal: + return p + assert 0 + + def causal(self, key): + links = self.links[key] + if len(links) == 1: + return links[0][1] + choices = [] + rule2cause = {} + for p, c in links: + rule = c[2] + choices.append(rule) + rule2cause[rule] = c + return rule2cause[self.ambiguity(choices)] + + def deriveEpsilon(self, nt): + if len(self.newrules[nt]) > 1: + rule = self.ambiguity(self.newrules[nt]) + else: + rule = self.newrules[nt][0] + # print(rule) + + rhs = rule[1] + attr = [None] * len(rhs) + + for i in range(len(rhs)-1, -1, -1): + attr[i] = self.deriveEpsilon(rhs[i]) + return self.rule2func[self.new2old[rule]](attr) + + def buildTree(self, nt, item, tokens, k): + state, parent = item + + choices = [] + for rule in self.states[state].complete: + if rule[0] == nt: + choices.append(rule) + rule = choices[0] + if len(choices) > 1: + rule = self.ambiguity(choices) + # print(rule) + + rhs = rule[1] + attr = [None] * len(rhs) + + for i in range(len(rhs)-1, -1, -1): + sym = rhs[i] + if not self.newrules.has_key(sym): + if sym != self._BOF: + attr[i] = tokens[k-1] + key = (item, k) + item, k = self.predecessor(key, None) + #elif self.isnullable(sym): + elif self._NULLABLE == sym[0:len(self._NULLABLE)]: + attr[i] = self.deriveEpsilon(sym) + else: + key = (item, k) + why = self.causal(key) + attr[i] = self.buildTree(sym, why[0], + tokens, why[1]) + item, k = self.predecessor(key, why) + return self.rule2func[self.new2old[rule]](attr) + + def ambiguity(self, rules): + # + # XXX - problem here and in collectRules() if the same rule + # appears in >1 method. Also undefined results if rules + # causing the ambiguity appear in the same method. + # + sortlist = [] + name2index = {} + for i in range(len(rules)): + lhs, rhs = rule = rules[i] + name = self.rule2name[self.new2old[rule]] + sortlist.append((len(rhs), name)) + name2index[name] = i + sortlist.sort() + list = [a_b[1] for a_b in sortlist] + return rules[name2index[self.resolve(list)]] + + def resolve(self, list): + ''' + Resolve ambiguity in favor of the shortest RHS. + Since we walk the tree from the top down, this + should effectively resolve in favor of a "shift". + ''' + return list[0] + +# +# GenericASTBuilder automagically constructs a concrete/abstract syntax tree +# for a given input. The extra argument is a class (not an instance!) +# which supports the "__setslice__" and "__len__" methods. +# +# XXX - silently overrides any user code in methods. +# + +class GenericASTBuilder(GenericParser): + def __init__(self, AST, start): + GenericParser.__init__(self, start) + self.AST = AST + + def preprocess(self, rule, func): + rebind = lambda lhs, self=self: \ + lambda args, lhs=lhs, self=self: \ + self.buildASTNode(args, lhs) + lhs, rhs = rule + return rule, rebind(lhs) + + def buildASTNode(self, args, lhs): + children = [] + for arg in args: + if isinstance(arg, self.AST): + children.append(arg) + else: + children.append(self.terminal(arg)) + return self.nonterminal(lhs, children) + + def terminal(self, token): return token + + def nonterminal(self, type, args): + rv = self.AST(type) + rv[:len(args)] = args + return rv + +class GenericASTTraversalPruningException: + pass + +class GenericASTTraversal: + ''' + GenericASTTraversal is a Visitor pattern according to Design Patterns. For + each node it attempts to invoke the method n_, falling + back onto the default() method if the n_* can't be found. The preorder + traversal also looks for an exit hook named n__exit (no default + routine is called if it's not found). To prematurely halt traversal + of a subtree, call the prune() method -- this only makes sense for a + preorder traversal. Node type is determined via the typestring() method. + ''' + def __init__(self, ast): + self.ast = ast + + def typestring(self, node): + return node.type + + def prune(self): + raise GenericASTTraversalPruningException + + def preorder(self, node=None): + if node is None: + node = self.ast + + try: + name = 'n_' + self.typestring(node) + if hasattr(self, name): + func = getattr(self, name) + func(node) + else: + self.default(node) + except GenericASTTraversalPruningException: + return + + for kid in node: + self.preorder(kid) + + name = name + '_exit' + if hasattr(self, name): + func = getattr(self, name) + func(node) + + def default(self, node): + pass diff --git a/uncompyle6/__init__.py b/uncompyle6/__init__.py index 35e81c7f..7d1acc4d 100644 --- a/uncompyle6/__init__.py +++ b/uncompyle6/__init__.py @@ -56,9 +56,9 @@ def _load_file(filename): fp = open(filename, 'rb') source = fp.read()+'\n' try: - co = compile(source, filename, 'exec') + co = compile(source, filename, 'exec', dont_inherit=True) except SyntaxError: - print >> sys.stderr, '>>Syntax error in', filename, '\n' + print('>>Syntax error in %s\n' % filename, file= sys.stderr) raise fp.close() return co diff --git a/uncompyle6/verify.py b/uncompyle6/verify.py index 585b3848..23c12883 100755 --- a/uncompyle6/verify.py +++ b/uncompyle6/verify.py @@ -332,14 +332,14 @@ class Token(scanner.Token): def compare_code_with_srcfile(pyc_filename, src_filename): """Compare a .pyc with a source code file.""" - version, code_obj1 = uncompyle2._load_module(pyc_filename) - code_obj2 = uncompyle2._load_file(src_filename) + version, code_obj1 = uncompyle6._load_module(pyc_filename) + code_obj2 = uncompyle6._load_file(src_filename) cmp_code_objects(version, code_obj1, code_obj2) def compare_files(pyc_filename1, pyc_filename2): """Compare two .pyc files.""" - version, code_obj1 = uncompyle2._load_module(pyc_filename1) - version, code_obj2 = uncompyle2._load_module(pyc_filename2) + version, code_obj1 = uncompyle6._load_module(pyc_filename1) + version, code_obj2 = uncompyle6._load_module(pyc_filename2) cmp_code_objects(version, code_obj1, code_obj2) if __name__ == '__main__':