├── .bumpversion.cfg ├── .gitignore ├── .gitlab-ci.yml ├── .pylintrc ├── .travis.yml ├── AUTHORS.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── bumpversion.readme ├── grumpy-runtime-src ├── AUTHORS.md ├── CONTRIBUTING.md ├── LICENSE ├── MANIFEST.in ├── Makefile ├── README.md ├── __init__.py ├── benchmarks │ ├── bm_call_method.py │ ├── bm_call_simple.py │ ├── call.py │ ├── comprehension.py │ ├── concurrent.py │ ├── dict.py │ ├── generator.py │ ├── list.py │ ├── loop.py │ └── tuple.py ├── grumpy_runtime │ ├── __init__.py │ └── data │ │ └── gopath ├── lib │ ├── README.md │ ├── __builtin__.py │ ├── _random.py │ ├── _socket.py │ ├── _syscall.py │ ├── cStringIO.py │ ├── errno.py │ ├── exceptions.py │ ├── itertools.py │ ├── itertools_test.py │ ├── math.py │ ├── math_test.py │ ├── os │ │ ├── __init__.py │ │ ├── path.py │ │ └── path_test.py │ ├── os_test.py │ ├── random_test.py │ ├── select_.py │ ├── stat.py │ ├── sys.py │ ├── sys_test.py │ ├── tempfile.py │ ├── tempfile_test.py │ ├── thread.py │ ├── time.py │ ├── time_test.py │ ├── token.py │ ├── types_test.py │ ├── weetest.py │ └── weetest_test.py ├── pyproject.toml ├── runtime │ ├── baseexception.go │ ├── baseexception_test.go │ ├── basestring.go │ ├── basestring_test.go │ ├── bool.go │ ├── bool_test.go │ ├── builtin_types.go │ ├── builtin_types_test.go │ ├── bytearray.go │ ├── bytearray_test.go │ ├── callableiter.go │ ├── callableiter_test.go │ ├── code.go │ ├── code_test.go │ ├── complex.go │ ├── complex_test.go │ ├── core.go │ ├── core_test.go │ ├── descriptor.go │ ├── descriptor_test.go │ ├── dict.go │ ├── dict_test.go │ ├── doc.go │ ├── exceptions.go │ ├── file.go │ ├── file_test.go │ ├── float.go │ ├── float_test.go │ ├── frame.go │ ├── frame_test.go │ ├── function.go │ ├── function_test.go │ ├── generator.go │ ├── generator_test.go │ ├── int.go │ ├── int_test.go │ ├── list.go │ ├── list_test.go │ ├── long.go │ ├── long_test.go │ ├── method.go │ ├── method_test.go │ ├── module.go │ ├── module_test.go │ ├── native.go │ ├── native_test.go │ ├── numeric.go │ ├── object.go │ ├── object_test.go │ ├── param.go │ ├── param_test.go │ ├── range.go │ ├── range_test.go │ ├── seq.go │ ├── seq_test.go │ ├── set.go │ ├── set_test.go │ ├── slice.go │ ├── slice_test.go │ ├── slots.go │ ├── slots_test.go │ ├── str.go │ ├── str_test.go │ ├── super.go │ ├── super_test.go │ ├── threading.go │ ├── threading_test.go │ ├── traceback.go │ ├── tuple.go │ ├── tuple_test.go │ ├── type.go │ ├── type_test.go │ ├── unicode.go │ ├── unicode_test.go │ ├── weakref.go │ └── weakref_test.go ├── setup.py ├── testing │ ├── assert_test.py │ ├── assign_test.py │ ├── builtin_test.py │ ├── class_test.py │ ├── compare_test.py │ ├── complex_test.py │ ├── comprehension_test.py │ ├── dict_test.py │ ├── file_test.py │ ├── float_test.py │ ├── for_test.py │ ├── function_test.py │ ├── generator_test.py │ ├── getopt_test.py │ ├── global_test.py │ ├── if_test.py │ ├── import_test.py │ ├── list_test.py │ ├── native_test.py │ ├── op_test.py │ ├── pow_test.py │ ├── scope_test.py │ ├── str_test.py │ ├── struct_test.py │ ├── try_test.py │ ├── tuple_test.py │ ├── while_test.py │ └── with_test.py ├── third_party │ ├── ouroboros │ │ ├── AUTHORS │ │ ├── LICENSE │ │ ├── READEME.md │ │ ├── operator.py │ │ └── test │ │ │ └── test_operator.py │ ├── pypy │ │ ├── LICENSE │ │ ├── README.md │ │ ├── _collections.py │ │ ├── _csv.py │ │ ├── _functools.py │ │ ├── _md5.py │ │ ├── _sha.py │ │ ├── _sha256.py │ │ ├── _sha512.py │ │ ├── _sre.py │ │ ├── _struct.py │ │ ├── binascii.py │ │ └── datetime.py │ └── stdlib │ │ ├── LICENSE │ │ ├── Queue.py │ │ ├── README.md │ │ ├── StringIO.py │ │ ├── UserDict.py │ │ ├── UserList.py │ │ ├── UserString.py │ │ ├── _abcoll.py │ │ ├── _weakrefset.py │ │ ├── abc.py │ │ ├── argparse.py │ │ ├── base64.py │ │ ├── bisect.py │ │ ├── collections.py │ │ ├── colorsys.py │ │ ├── contextlib.py │ │ ├── copy.py │ │ ├── copy_reg.py │ │ ├── csv.py │ │ ├── difflib.py │ │ ├── dircache.py │ │ ├── dummy_thread.py │ │ ├── fnmatch.py │ │ ├── fpformat.py │ │ ├── functools.py │ │ ├── genericpath.py │ │ ├── getopt.py │ │ ├── glob.py │ │ ├── heapq.py │ │ ├── json │ │ ├── __init__.py │ │ ├── decoder.py │ │ └── encoder.py │ │ ├── json_scanner.py │ │ ├── keyword.py │ │ ├── linecache.py │ │ ├── md5.py │ │ ├── mimetools.py │ │ ├── mutex.py │ │ ├── optparse.py │ │ ├── pprint.py │ │ ├── quopri.py │ │ ├── random.py │ │ ├── re.py │ │ ├── re_tests.py │ │ ├── repr.py │ │ ├── rfc822.py │ │ ├── sched.py │ │ ├── sha.py │ │ ├── socket.py │ │ ├── sre_compile.py │ │ ├── sre_constants.py │ │ ├── sre_parse.py │ │ ├── string.py │ │ ├── test │ │ ├── __init__.py │ │ ├── list_tests.py │ │ ├── lock_tests.py │ │ ├── mapping_tests.py │ │ ├── seq_tests.py │ │ ├── string_tests.py │ │ ├── test_argparse.py │ │ ├── test_bisect.py │ │ ├── test_colorsys.py │ │ ├── test_datetime.py │ │ ├── test_dict.py │ │ ├── test_dircache.py │ │ ├── test_dummy_thread.py │ │ ├── test_fpformat.py │ │ ├── test_genericpath.py │ │ ├── test_list.py │ │ ├── test_md5.py │ │ ├── test_mimetools.py │ │ ├── test_mutex.py │ │ ├── test_queue.py │ │ ├── test_quopri.py │ │ ├── test_rfc822.py │ │ ├── test_sched.py │ │ ├── test_select.py │ │ ├── test_slice.py │ │ ├── test_stat.py │ │ ├── test_string.py │ │ ├── test_support.py │ │ ├── test_threading.py │ │ ├── test_tuple.py │ │ └── test_uu.py │ │ ├── textwrap.py │ │ ├── threading.py │ │ ├── traceback.py │ │ ├── types.py │ │ ├── unittest │ │ └── __init__.py │ │ ├── unittest_case.py │ │ ├── unittest_loader.py │ │ ├── unittest_result.py │ │ ├── unittest_runner.py │ │ ├── unittest_signals.py │ │ ├── unittest_suite.py │ │ ├── unittest_util.py │ │ ├── urlparse.py │ │ ├── uu.py │ │ ├── warnings.py │ │ └── weakref.py └── tools │ ├── benchcmp │ ├── coverparse │ ├── diffrange │ ├── genmake │ ├── grumpc │ ├── grumprun │ ├── pkgc.go │ └── pydeps └── grumpy-tools-src ├── .coveragerc ├── AUTHORS.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── grumpy_tools ├── __init__.py ├── benchcmp.py ├── cli.py ├── compiler │ ├── __init__.py │ ├── block.py │ ├── block_test.py │ ├── expr.py │ ├── expr_visitor.py │ ├── expr_visitor_test.py │ ├── imputil.py │ ├── imputil_test.py │ ├── parser.py │ ├── shard_test.py │ ├── stmt.py │ ├── stmt_test.py │ ├── util.py │ └── util_test.py ├── coverparse.py ├── diffrange.py ├── genmake.py ├── grumpc.py ├── grumprun.py ├── grumpy_tools.py ├── pep_support │ ├── __init__.py │ └── pep3147pycache.py ├── pydeps.py └── vendor │ └── __init__.py ├── pytest.ini ├── setup.py └── tests ├── dummymodule ├── __init__.py └── dummysubmodule1 │ ├── __init__.py │ ├── dummysubmodule2 │ └── __init__.py │ └── dummysubmodule2b.py ├── dummyrunner.py ├── havingmainpkg ├── __init__.py └── __main__.py ├── import_havingpkgmain.py └── test_grumpy_tools.py /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 0.3.0 3 | commit = True 4 | tag = True 5 | 6 | [bumpversion:file:grumpy-tools-src/setup.py] 7 | 8 | [bumpversion:file:grumpy-tools-src/grumpy_tools/__init__.py] 9 | 10 | [bumpversion:file:grumpy-runtime-src/setup.py] 11 | 12 | [bumpversion:file:grumpy-runtime-src/grumpy_runtime/__init__.py] 13 | 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | errors.err 3 | *.swp 4 | *.pyc 5 | *.egg 6 | .eggs/ 7 | 8 | grumpy-tools-src/dist/ 9 | grumpy-tools-src/*.egg-info 10 | grumpy-runtime-src/dist 11 | grumpy-runtime-src/*.egg-info 12 | 13 | # Cache 14 | .pytest_cache/ 15 | 16 | # Editors 17 | .vscode/ 18 | 19 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | image: golang:1.10.3-stretch 2 | 3 | cache: 4 | paths: 5 | - /apt-cache 6 | - /go/src/github.com 7 | - /go/src/golang.org 8 | - /go/src/google.golang.org 9 | - /go/src/gopkg.in 10 | 11 | stages: 12 | - test 13 | - build 14 | 15 | before_script: 16 | - apt-get update && apt-get install -y --no-install-recommends python2.7 python2.7-dev python-setuptools 17 | - easy_install pip 18 | - pip2 install pytest pytest-cov 19 | 20 | install_and_test: 21 | stage: test 22 | script: 23 | # Install the thing 24 | - cd grumpy-tools-src 25 | - pip2 install . 26 | - cd ../grumpy-runtime-src 27 | - pip2 install . 28 | # Test the thing 29 | - cd ../grumpy-tools-src 30 | - pytest 31 | - cd ../grumpy-runtime-src 32 | - make gofmt lint && make -j2 test 33 | -------------------------------------------------------------------------------- /.pylintrc: -------------------------------------------------------------------------------- 1 | [BASIC] 2 | argument-rgx=^[a-z][a-z0-9_]*$ 3 | attr-rgx=^_{0,2}[a-z][a-z0-9_]*$ 4 | const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$ 5 | docstring-min-length=10 6 | function-rgx=^(?:(?P_?[A-Z][a-zA-Z0-9]*)|(?P_?[a-z][a-z0-9_]*))$ 7 | good-names=main,_ 8 | method-rgx=^(?:(?P__[a-z0-9_]+__|next|test[A-Z_][A-Za-z0-9_]*)|(?P_{0,2}[A-Z][a-zA-Z0-9]*)|(?P_{0,2}[a-z][a-z0-9_]*))$ 9 | no-docstring-rgx=(__.*__|main|test[A-Z_][A-Za-z0-9_]*|[A-Z][A-Za-z0-9]*Test) 10 | variable-rgx=^[a-z][a-z0-9_]*$ 11 | 12 | [FORMAT] 13 | indent-string=' ' 14 | max-line-length=80 15 | 16 | [MESSAGES CONTROL] 17 | # TODO: Remove cyclic-import once expr_visitor.py -> stmt.py is resolved. 18 | disable=design,similarities,no-self-use,attribute-defined-outside-init,locally-disabled,star-args,pointless-except,bad-option-value,global-statement,fixme,suppressed-message,useless-suppression,locally-enabled,file-ignored,cyclic-import 19 | 20 | [REPORTS] 21 | msg-template={path}:{line}: {msg} ({symbol}) 22 | reports=no 23 | 24 | [TYPECHECK] 25 | # AST classes have dynamic members. Writer does not but for some reason pylint 26 | # barfs on some of its members. 27 | ignored-classes=pythonparser.ast.Module,grumpy.compiler.util.Writer 28 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | 3 | cache: 4 | directories: 5 | - $HOME/.cache/pip 6 | - $HOME/.cache/pre-commit 7 | 8 | matrix: 9 | allow_failures: 10 | - python: 3.8 11 | - env: GO="stable" 12 | include: 13 | - python: 2.7 14 | env: GO=1.10.x 15 | - python: 2.7 16 | env: GO=stable # Currently 1.11 17 | - python: 3.8 18 | env: GO=1.10.x 19 | script: # To detect Python 3 syntax errors in grumpy-tools 20 | - pip install --upgrade flake8 21 | - flake8 --count --select=E901,E999,F821,F822,F823 --show-source --statistics grumpy-tools-src 22 | - os: osx 23 | language: go 24 | go: 1.10.x 25 | env: OSX_PYTHON=2.7 26 | install: HOMEBREW_NO_AUTO_UPDATE=1 brew reinstall python@2 27 | 28 | install: 29 | - | 30 | export GOPATH=~/gopath 31 | export PATH="$GOPATH/bin:$PATH" 32 | export TRAVIS_BUILD_DIR="$GOPATH/src/github.com/$TRAVIS_REPO_SLUG" 33 | mkdir -p "$TRAVIS_BUILD_DIR" 34 | rsync -az . "$TRAVIS_BUILD_DIR" 35 | cd "$TRAVIS_BUILD_DIR" 36 | # Use the current gimme because Travis gimme does not support syntax "1.10.x" and "stable" 37 | eval "$(curl -sL https://raw.githubusercontent.com/travis-ci/gimme/master/gimme | GIMME_GO_VERSION=${GO} bash)" 38 | 39 | before_script: 40 | - go version && python --version && python -m pip --version 41 | # https://github.com/travis-ci/travis-ci/issues/8920#issuecomment-352661024 42 | - python -c "import fcntl; fcntl.fcntl(1, fcntl.F_SETFL, 0)" 43 | - pip install --upgrade pip 44 | - pip install 'pytest==3.8.1' 'pytest-cov==2.6.0' 45 | 46 | script: 47 | # Install the thing 48 | - cd grumpy-tools-src 49 | - pip install . 50 | - which grumpy 51 | - cd ../grumpy-runtime-src 52 | - pip install . 53 | # Test the thing 54 | # Run gofmt and lint serially to avoid confusing output. Run tests in parallel 55 | # for speed. 56 | - cd ../grumpy-tools-src 57 | - pytest 58 | - cd ../grumpy-runtime-src 59 | - make gofmt lint && make -j2 test 60 | 61 | # OSX swallows error logs: https://github.com/travis-ci/travis-ci/issues/6018 62 | after_error: 63 | - echo "== End of test log =="" 64 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | Contributors in the order of first contribution 2 | 3 | * [Dylan Trotter](https://github.com/trotterdylan) 4 | * [Aaron Tubbs](https://github.com/atubbs) 5 | * [Devin Jeanpierre](https://github.com/ssbr) 6 | * [Torin Rudeen](https://github.com/torinmr) 7 | * [Brian Atkinson](https://github.com/nairb774) 8 | * [Matt Harden](https://github.com/nerdatmath) 9 | * [Ryan Kennedy](https://github.com/ryankennedy) 10 | * [Brett Cannon](https://github.com/brettcannon) 11 | * [Alex Koren](https://github.com/AlexEKoren) 12 | * [Steven Maude](https://github.com/StevenMaude) 13 | * [feilengcui008](https://github.com/feilengcui008) 14 | * [Meador Inge](https://github.com/meadori) 15 | * [Kyoung-chan Lee](https://github.com/leekchan) 16 | * [Cholerae Hu](https://github.com/choleraehyq) 17 | * [Jurriaan Bremer](https://github.com/jbremer) 18 | * [Florian Ludwig](https://github.com/FlorianLudwig) 19 | * [ns-cweber](https://github.com/ns-cweber) 20 | * [Paul Smith](https://github.com/paulsmith) 21 | * [Izaak Weiss](https://github.com/lalaithion) 22 | * [YOU](https://github.com/S-YOU) 23 | * [iury](https://github.com/IuryAlves) 24 | * [wuttem](https://github.com/wuttem) 25 | * [cclauss](https://github.com/cclauss) 26 | * [Mirko Dziadzka](https://github.com/MirkoDziadzka) 27 | * [Dong-hee Na](https://github.com/corona10) 28 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Want to contribute? Great! First, read this page. 2 | 3 | ### Before you contribute 4 | Before we can use your code, you must sign the 5 | [Google Individual Contributor License Agreement] 6 | (https://cla.developers.google.com/about/google-individual) 7 | (CLA), which you can do online. The CLA is necessary mainly because you own the 8 | copyright to your changes, even after your contribution becomes part of our 9 | codebase, so we need your permission to use and distribute your code. We also 10 | need to be sure of various other things—for instance that you'll tell us if you 11 | know that your code infringes on other people's patents. You don't have to sign 12 | the CLA until after you've submitted your code for review and a member has 13 | approved it, but you must do it before we can put your code into our codebase. 14 | Before you start working on a larger contribution, you should get in touch with 15 | us first through the issue tracker with your idea so that we can help out and 16 | possibly guide you. Coordinating up front makes it much easier to avoid 17 | frustration later on. 18 | 19 | Contributions made by corporations are covered by a different agreement than 20 | the one above, the 21 | [Software Grant and Corporate Contributor License Agreement] 22 | (https://cla.developers.google.com/about/google-corporate). 23 | 24 | ### Code reviews 25 | All submissions, including submissions by project members, require review. We 26 | use GitHub pull requests for this purpose. 27 | 28 | ### Code Style 29 | We use Google style guides for all our code. Below are the guidelines for each 30 | language we use. 31 | 32 | #### Go 33 | All Go source code must be formatted using gofmt and be lint-clean according to 34 | golint. This will be checked by Travis but can be checked manually from a local 35 | repo via `make gofmt golint`. 36 | 37 | Code is expected to be gofmt- and lint clean before it is submitted for review. 38 | Code reviews can then focus on structural details and higher level style 39 | considerations. Many common mistakes are already documented in the 40 | [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments) 41 | doc so it's worth being familiar with these patterns. 42 | 43 | #### Python 44 | All Python source code must be lint-clean according to pylint. This will be 45 | checked by Travis but can be checked manually from a local repo via 46 | `make pylint`. 47 | 48 | Once code is pylint-clean, it can be submitted for review. In addition to lint 49 | cleanliness, Python code must adhere to the 50 | [Google Python Style Guide](https://google.github.io/styleguide/pyguide.html) 51 | which has a number of additional conventions. Please be familiar with the style 52 | guide and ensure code satisfies its rules before submitting for review. 53 | 54 | ##### Borrowed Standard Library Code 55 | Standard library code that is borrowed from other open source projects such as 56 | CPython and PyPy need not be lint clean or satisfy the style guide. The goal 57 | should be to keep the copied sources as close to the originals as possible 58 | while still being functional. For more details about borrowing this kind of 59 | code from other places see the 60 | [guidelines for integration](https://github.com/google/grumpy/wiki/Standard-libraries:-guidelines-for-integration). 61 | -------------------------------------------------------------------------------- /bumpversion.readme: -------------------------------------------------------------------------------- 1 | bumpversion patch --verbose --dry-run 2 | -------------------------------------------------------------------------------- /grumpy-runtime-src/AUTHORS.md: -------------------------------------------------------------------------------- 1 | ../AUTHORS.md -------------------------------------------------------------------------------- /grumpy-runtime-src/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ../CONTRIBUTING.md -------------------------------------------------------------------------------- /grumpy-runtime-src/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /grumpy-runtime-src/MANIFEST.in: -------------------------------------------------------------------------------- 1 | global-include *.py 2 | global-include *.go 3 | global-include *.mk 4 | global-include Makefile 5 | recursive-include tools * 6 | 7 | global-exclude *.egg-info/* 8 | global-exclude *__pycache__* 9 | 10 | recursive-exclude grumpy-tools-src *.go 11 | 12 | include pyproject.toml 13 | -------------------------------------------------------------------------------- /grumpy-runtime-src/README.md: -------------------------------------------------------------------------------- 1 | This is home for Grumpy runtime, which provides Python stdlib written in Go for programs produced by Grumpy. The runtime consists of two directories. 2 | 3 | * [`runtime/`](runtime) contains Go code 4 | * [`lib/`](lib) contains Python code 5 | 6 | Both are used to implement Python feature on top of Go, such as slices, types, exceptions and so on. When `import` code is encountered, it first looks in these two dirs. 7 | 8 | See [../README.md](../README.md) for details on using Grumpy. 9 | -------------------------------------------------------------------------------- /grumpy-runtime-src/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/bm_call_method.py: -------------------------------------------------------------------------------- 1 | """Microbenchmark for method call overhead. 2 | 3 | This measures simple method calls that are predictable, do not use varargs or 4 | kwargs, and do not use tuple unpacking. 5 | 6 | Taken from: 7 | https://github.com/python/performance/blob/9b8d859/performance/benchmarks/bm_call_method.py 8 | """ 9 | 10 | import weetest 11 | 12 | 13 | class Foo(object): 14 | 15 | def foo(self, a, b, c, d): 16 | # 20 calls 17 | self.bar(a, b, c) 18 | self.bar(a, b, c) 19 | self.bar(a, b, c) 20 | self.bar(a, b, c) 21 | self.bar(a, b, c) 22 | self.bar(a, b, c) 23 | self.bar(a, b, c) 24 | self.bar(a, b, c) 25 | self.bar(a, b, c) 26 | self.bar(a, b, c) 27 | self.bar(a, b, c) 28 | self.bar(a, b, c) 29 | self.bar(a, b, c) 30 | self.bar(a, b, c) 31 | self.bar(a, b, c) 32 | self.bar(a, b, c) 33 | self.bar(a, b, c) 34 | self.bar(a, b, c) 35 | self.bar(a, b, c) 36 | self.bar(a, b, c) 37 | 38 | def bar(self, a, b, c): 39 | # 20 calls 40 | self.baz(a, b) 41 | self.baz(a, b) 42 | self.baz(a, b) 43 | self.baz(a, b) 44 | self.baz(a, b) 45 | self.baz(a, b) 46 | self.baz(a, b) 47 | self.baz(a, b) 48 | self.baz(a, b) 49 | self.baz(a, b) 50 | self.baz(a, b) 51 | self.baz(a, b) 52 | self.baz(a, b) 53 | self.baz(a, b) 54 | self.baz(a, b) 55 | self.baz(a, b) 56 | self.baz(a, b) 57 | self.baz(a, b) 58 | self.baz(a, b) 59 | self.baz(a, b) 60 | 61 | def baz(self, a, b): 62 | # 20 calls 63 | self.quux(a) 64 | self.quux(a) 65 | self.quux(a) 66 | self.quux(a) 67 | self.quux(a) 68 | self.quux(a) 69 | self.quux(a) 70 | self.quux(a) 71 | self.quux(a) 72 | self.quux(a) 73 | self.quux(a) 74 | self.quux(a) 75 | self.quux(a) 76 | self.quux(a) 77 | self.quux(a) 78 | self.quux(a) 79 | self.quux(a) 80 | self.quux(a) 81 | self.quux(a) 82 | self.quux(a) 83 | 84 | def quux(self, a): 85 | # 20 calls 86 | self.qux() 87 | self.qux() 88 | self.qux() 89 | self.qux() 90 | self.qux() 91 | self.qux() 92 | self.qux() 93 | self.qux() 94 | self.qux() 95 | self.qux() 96 | self.qux() 97 | self.qux() 98 | self.qux() 99 | self.qux() 100 | self.qux() 101 | self.qux() 102 | self.qux() 103 | self.qux() 104 | self.qux() 105 | self.qux() 106 | 107 | def qux(self): 108 | pass 109 | 110 | 111 | def BenchmarkCallMethod(b): 112 | f = Foo() 113 | for _ in xrange(b.N): 114 | # 20 calls 115 | f.foo(1, 2, 3, 4) 116 | f.foo(1, 2, 3, 4) 117 | f.foo(1, 2, 3, 4) 118 | f.foo(1, 2, 3, 4) 119 | f.foo(1, 2, 3, 4) 120 | f.foo(1, 2, 3, 4) 121 | f.foo(1, 2, 3, 4) 122 | f.foo(1, 2, 3, 4) 123 | f.foo(1, 2, 3, 4) 124 | f.foo(1, 2, 3, 4) 125 | f.foo(1, 2, 3, 4) 126 | f.foo(1, 2, 3, 4) 127 | f.foo(1, 2, 3, 4) 128 | f.foo(1, 2, 3, 4) 129 | f.foo(1, 2, 3, 4) 130 | f.foo(1, 2, 3, 4) 131 | f.foo(1, 2, 3, 4) 132 | f.foo(1, 2, 3, 4) 133 | f.foo(1, 2, 3, 4) 134 | f.foo(1, 2, 3, 4) 135 | 136 | 137 | if __name__ == '__main__': 138 | weetest.RunBenchmarks() 139 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/bm_call_simple.py: -------------------------------------------------------------------------------- 1 | """Microbenchmark for function call overhead. 2 | 3 | This measures simple function calls that are not methods, do not use varargs or 4 | kwargs, and do not use tuple unpacking. 5 | 6 | Taken from: 7 | https://github.com/python/performance/blob/9b8d859/performance/benchmarks/bm_call_simple.py 8 | """ 9 | 10 | import weetest 11 | 12 | 13 | def foo(a, b, c, d): 14 | # 20 calls 15 | bar(a, b, c) 16 | bar(a, b, c) 17 | bar(a, b, c) 18 | bar(a, b, c) 19 | bar(a, b, c) 20 | bar(a, b, c) 21 | bar(a, b, c) 22 | bar(a, b, c) 23 | bar(a, b, c) 24 | bar(a, b, c) 25 | bar(a, b, c) 26 | bar(a, b, c) 27 | bar(a, b, c) 28 | bar(a, b, c) 29 | bar(a, b, c) 30 | bar(a, b, c) 31 | bar(a, b, c) 32 | bar(a, b, c) 33 | bar(a, b, c) 34 | bar(a, b, c) 35 | 36 | 37 | def bar(a, b, c): 38 | # 20 calls 39 | baz(a, b) 40 | baz(a, b) 41 | baz(a, b) 42 | baz(a, b) 43 | baz(a, b) 44 | baz(a, b) 45 | baz(a, b) 46 | baz(a, b) 47 | baz(a, b) 48 | baz(a, b) 49 | baz(a, b) 50 | baz(a, b) 51 | baz(a, b) 52 | baz(a, b) 53 | baz(a, b) 54 | baz(a, b) 55 | baz(a, b) 56 | baz(a, b) 57 | baz(a, b) 58 | baz(a, b) 59 | 60 | 61 | def baz(a, b): 62 | # 20 calls 63 | quux(a) 64 | quux(a) 65 | quux(a) 66 | quux(a) 67 | quux(a) 68 | quux(a) 69 | quux(a) 70 | quux(a) 71 | quux(a) 72 | quux(a) 73 | quux(a) 74 | quux(a) 75 | quux(a) 76 | quux(a) 77 | quux(a) 78 | quux(a) 79 | quux(a) 80 | quux(a) 81 | quux(a) 82 | quux(a) 83 | 84 | 85 | def quux(a): 86 | # 20 calls 87 | qux() 88 | qux() 89 | qux() 90 | qux() 91 | qux() 92 | qux() 93 | qux() 94 | qux() 95 | qux() 96 | qux() 97 | qux() 98 | qux() 99 | qux() 100 | qux() 101 | qux() 102 | qux() 103 | qux() 104 | qux() 105 | qux() 106 | qux() 107 | 108 | 109 | def qux(): 110 | pass 111 | 112 | 113 | def BenchmarkCallSimple(b): 114 | for _ in xrange(b.N): 115 | # 20 calls 116 | foo(1, 2, 3, 4) 117 | foo(1, 2, 3, 4) 118 | foo(1, 2, 3, 4) 119 | foo(1, 2, 3, 4) 120 | foo(1, 2, 3, 4) 121 | foo(1, 2, 3, 4) 122 | foo(1, 2, 3, 4) 123 | foo(1, 2, 3, 4) 124 | foo(1, 2, 3, 4) 125 | foo(1, 2, 3, 4) 126 | foo(1, 2, 3, 4) 127 | foo(1, 2, 3, 4) 128 | foo(1, 2, 3, 4) 129 | foo(1, 2, 3, 4) 130 | foo(1, 2, 3, 4) 131 | foo(1, 2, 3, 4) 132 | foo(1, 2, 3, 4) 133 | foo(1, 2, 3, 4) 134 | foo(1, 2, 3, 4) 135 | foo(1, 2, 3, 4) 136 | 137 | 138 | if __name__ == '__main__': 139 | weetest.RunBenchmarks() 140 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/call.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Benchmarks for function calls.""" 16 | 17 | # pylint: disable=unused-argument 18 | 19 | import weetest 20 | 21 | 22 | def BenchmarkCallNoArgs(b): 23 | def Foo(): 24 | pass 25 | for _ in xrange(b.N): 26 | Foo() 27 | 28 | 29 | def BenchmarkCallPositionalArgs(b): 30 | def Foo(a, b, c): 31 | pass 32 | for _ in xrange(b.N): 33 | Foo(1, 2, 3) 34 | 35 | 36 | def BenchmarkCallKeywords(b): 37 | def Foo(a, b, c): 38 | pass 39 | for _ in xrange(b.N): 40 | Foo(a=1, b=2, c=3) 41 | 42 | 43 | def BenchmarkCallDefaults(b): 44 | def Foo(a=1, b=2, c=3): 45 | pass 46 | for _ in xrange(b.N): 47 | Foo() 48 | 49 | 50 | def BenchmarkCallVarArgs(b): 51 | def Foo(*args): 52 | pass 53 | for _ in xrange(b.N): 54 | Foo(1, 2, 3) 55 | 56 | 57 | def BenchmarkCallKwargs(b): 58 | def Foo(**kwargs): 59 | pass 60 | for _ in xrange(b.N): 61 | Foo(a=1, b=2, c=3) 62 | 63 | 64 | if __name__ == '__main__': 65 | weetest.RunBenchmarks() 66 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/comprehension.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Benchmarks for comprehensions.""" 16 | 17 | # pylint: disable=unused-argument 18 | 19 | import weetest 20 | 21 | 22 | def BenchmarkGeneratorExpCreate(b): 23 | l = [] 24 | for _ in xrange(b.N): 25 | (x for x in l) # pylint: disable=pointless-statement 26 | 27 | 28 | def BenchmarkGeneratorExpIterate(b): 29 | for _ in (x for x in xrange(b.N)): 30 | pass 31 | 32 | 33 | def BenchmarkListCompCreate(b): 34 | for _ in xrange(b.N): 35 | [x for x in xrange(1000)] # pylint: disable=expression-not-assigned 36 | 37 | 38 | def BenchmarkDictCompCreate(b): 39 | for _ in xrange(b.N): 40 | {x: x for x in xrange(1000)} # pylint: disable=expression-not-assigned 41 | 42 | 43 | if __name__ == '__main__': 44 | weetest.RunBenchmarks() 45 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/concurrent.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Benchmarks for simple parallel calculations.""" 16 | 17 | import threading 18 | 19 | import weetest 20 | 21 | 22 | def Arithmetic(n): 23 | return n * 3 + 2 24 | 25 | 26 | def Fib(n): 27 | if n < 2: 28 | return 1 29 | return Fib(n - 1) + Fib(n - 2) 30 | 31 | 32 | _WORKLOADS = [ 33 | (Arithmetic, 1001), 34 | (Fib, 10), 35 | ] 36 | 37 | 38 | def _MakeParallelBenchmark(p, work_func, *args): 39 | """Create and return a benchmark that runs work_func p times in parallel.""" 40 | def Benchmark(b): # pylint: disable=missing-docstring 41 | e = threading.Event() 42 | def Target(): 43 | e.wait() 44 | for _ in xrange(b.N / p): 45 | work_func(*args) 46 | threads = [] 47 | for _ in xrange(p): 48 | t = threading.Thread(target=Target) 49 | t.start() 50 | threads.append(t) 51 | b.ResetTimer() 52 | e.set() 53 | for t in threads: 54 | t.join() 55 | return Benchmark 56 | 57 | 58 | def _RegisterBenchmarks(): 59 | for p in xrange(1, 13): 60 | for work_func, arg in _WORKLOADS: 61 | name = 'Benchmark' + work_func.__name__ 62 | if p > 1: 63 | name += 'Parallel%s' % p 64 | globals()[name] = _MakeParallelBenchmark(p, work_func, arg) 65 | _RegisterBenchmarks() 66 | 67 | 68 | if __name__ == '__main__': 69 | weetest.RunBenchmarks() 70 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/dict.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Benchmarks for dictionary operations.""" 16 | 17 | # pylint: disable=pointless-statement 18 | 19 | import weetest 20 | 21 | 22 | def BenchmarkDictCreate(b): 23 | for _ in xrange(b.N): 24 | d = {'one': 1, 'two': 2, 'three': 3} 25 | 26 | 27 | def BenchmarkDictCreateFunc(b): 28 | for _ in xrange(b.N): 29 | d = dict(one=1, two=2, three=3) 30 | 31 | 32 | def BenchmarkDictGetItem(b): 33 | d = {42: 123} 34 | for _ in xrange(b.N): 35 | d[42] 36 | 37 | 38 | def BenchmarkDictStringOnlyGetItem(b): 39 | d = {'foo': 123} 40 | for _ in xrange(b.N): 41 | d['foo'] 42 | 43 | 44 | def BenchmarkDictSetItem(b): 45 | d = {} 46 | for _ in xrange(b.N): 47 | d[42] = 123 48 | 49 | 50 | def BenchmarkDictStringOnlySetItem(b): 51 | d = {} 52 | for _ in xrange(b.N): 53 | d['foo'] = 123 54 | 55 | 56 | def BenchmarkHashStrCached(b): 57 | """Hashes the same value repeatedly to exercise any hash caching logic.""" 58 | h = hash # Prevent builtins lookup each iteration. 59 | for _ in xrange(b.N): 60 | h('foobarfoobarfoobar') 61 | 62 | 63 | if __name__ == '__main__': 64 | weetest.RunBenchmarks() 65 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/generator.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Benchmarks for generator functions.""" 16 | 17 | import weetest 18 | 19 | 20 | def BenchmarkGeneratorIterate(b): 21 | def Gen(n): 22 | for i in xrange(n): 23 | yield i 24 | for _ in Gen(b.N): 25 | pass 26 | 27 | 28 | def BenchmarkGeneratorCreate(b): 29 | def Gen(): 30 | yield 1 31 | for _ in xrange(b.N): 32 | Gen() 33 | 34 | 35 | if __name__ == '__main__': 36 | weetest.RunBenchmarks() 37 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/list.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Benchmarks for list operations.""" 16 | 17 | # pylint: disable=pointless-statement 18 | 19 | import weetest 20 | 21 | 22 | def BenchmarkListGetItem(b): 23 | l = [1, 3, 9] 24 | for _ in xrange(b.N): 25 | l[2] 26 | 27 | 28 | def BenchmarkListContains3(b): 29 | l = [1, 3, 9] 30 | for _ in xrange(b.N): 31 | 9 in l 32 | 33 | 34 | def BenchmarkListContains10(b): 35 | l = range(10) 36 | for _ in xrange(b.N): 37 | 9 in l 38 | 39 | 40 | if __name__ == '__main__': 41 | weetest.RunBenchmarks() 42 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/loop.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Benchmarks for simple low overhead loops.""" 16 | 17 | import weetest 18 | 19 | 20 | def BenchmarkForXRange(b): 21 | for _ in xrange(b.N): 22 | pass 23 | 24 | 25 | def BenchmarkWhileCounter(b): 26 | i = 0 27 | while i < b.N: 28 | i += 1 29 | 30 | 31 | def BenchmarkWhileXRange(b): 32 | i = iter(xrange(b.N)) 33 | try: 34 | while True: 35 | i.next() 36 | except StopIteration: 37 | pass 38 | 39 | 40 | if __name__ == '__main__': 41 | weetest.RunBenchmarks() 42 | -------------------------------------------------------------------------------- /grumpy-runtime-src/benchmarks/tuple.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Benchmarks for list operations.""" 16 | 17 | # pylint: disable=pointless-statement 18 | 19 | import weetest 20 | 21 | 22 | def BenchmarkTupleGetItem(b): 23 | l = (1, 3, 9) 24 | for _ in xrange(b.N): 25 | l[2] 26 | 27 | 28 | def BenchmarkTupleContains3(b): 29 | t = (1, 3, 9) 30 | for _ in xrange(b.N): 31 | 9 in t 32 | 33 | 34 | def BenchmarkTupleContains10(b): 35 | t = tuple(range(10)) 36 | for _ in xrange(b.N): 37 | 9 in t 38 | 39 | 40 | if __name__ == '__main__': 41 | weetest.RunBenchmarks() 42 | -------------------------------------------------------------------------------- /grumpy-runtime-src/grumpy_runtime/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | __version__ = '0.3.0' 16 | -------------------------------------------------------------------------------- /grumpy-runtime-src/grumpy_runtime/data/gopath: -------------------------------------------------------------------------------- 1 | ../../build/lib/grumpy_runtime/data/gopath -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/README.md: -------------------------------------------------------------------------------- 1 | This directory contains Grumpy Python standard library code. It is only expected 2 | to run under Grumpy, not CPython. 3 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/__builtin__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Built-in Python identifiers.""" 16 | 17 | # pylint: disable=invalid-name 18 | 19 | from '__go__/grumpy' import Builtins 20 | 21 | 22 | for k, v in Builtins.iteritems(): 23 | globals()[k] = v 24 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/_syscall.py: -------------------------------------------------------------------------------- 1 | # Copyright 2017 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from '__go__/syscall' import EINTR 16 | 17 | 18 | def invoke(func, *args): 19 | while True: 20 | result = func(*args) 21 | if isinstance(result, tuple): 22 | err = result[-1] 23 | result = result[:-1] 24 | else: 25 | err = result 26 | result = () 27 | if err: 28 | if err == EINTR: 29 | continue 30 | raise OSError(err.Error()) 31 | return result 32 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/cStringIO.py: -------------------------------------------------------------------------------- 1 | ../third_party/stdlib/StringIO.py -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/errno.py: -------------------------------------------------------------------------------- 1 | EINVAL = 22 2 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Built-in exception classes.""" 16 | 17 | from '__go__/grumpy' import ExceptionTypes 18 | 19 | 20 | g = globals() 21 | for t in ExceptionTypes: 22 | g[t.__name__] = t 23 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/math_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import math 16 | 17 | import weetest 18 | 19 | # Tests exist for all functions which have logic in the math.py module, instead 20 | # of simply calling the go equivalent. 21 | 22 | 23 | def TestFactorial(): 24 | assert math.factorial(0) == 1 25 | assert math.factorial(1) == 1 26 | assert math.factorial(2) == 2 27 | assert math.factorial(3) == 6 28 | assert math.factorial(4) == 24 29 | assert math.factorial(5) == 120 30 | 31 | 32 | def TestFactorialError(): 33 | try: 34 | math.factorial(-1) 35 | except ValueError: 36 | pass 37 | else: 38 | raise AssertionError 39 | 40 | try: 41 | math.factorial(0.5) 42 | except ValueError: 43 | pass 44 | else: 45 | raise AssertionError 46 | 47 | 48 | def TestLdexp(): 49 | assert math.ldexp(1,1) == 2 50 | assert math.ldexp(1,2) == 4 51 | assert math.ldexp(1.5,1) == 3 52 | assert math.ldexp(1.5,2) == 6 53 | 54 | 55 | def TestLog(): 56 | assert math.log(math.e) == 1 57 | assert math.log(2,2) == 1 58 | assert math.log(10,10) == 1 59 | assert math.log(100,10) == 2 60 | 61 | 62 | def TestRadians(): 63 | assert math.radians(180) == math.pi 64 | assert math.radians(360) == 2 * math.pi 65 | 66 | 67 | def TestDegrees(): 68 | assert math.degrees(math.pi) == 180 69 | assert math.degrees(2 * math.pi) == 360 70 | 71 | 72 | if __name__ == '__main__': 73 | weetest.RunTests() 74 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/os/path.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """"Utilities for manipulating and inspecting OS paths.""" 16 | 17 | from '__go__/os' import Stat 18 | from '__go__/path/filepath' import Abs, Base, Clean, Dir as dirname, IsAbs as isabs, Join, Split # pylint: disable=g-multiple-import,unused-import 19 | 20 | 21 | def abspath(path): 22 | result, err = Abs(path) 23 | if err: 24 | raise OSError(err.Error()) 25 | if isinstance(path, unicode): 26 | # Grumpy compiler encoded the string into utf-8, so the result can be 27 | # decoded using utf-8. 28 | return unicode(result, 'utf-8') 29 | return result 30 | 31 | 32 | def basename(path): 33 | return '' if path.endswith('/') else Base(path) 34 | 35 | 36 | def exists(path): 37 | _, err = Stat(path) 38 | return err is None 39 | 40 | 41 | def isdir(path): 42 | info, err = Stat(path) 43 | if info and err is None: 44 | return info.Mode().IsDir() 45 | return False 46 | 47 | 48 | def isfile(path): 49 | info, err = Stat(path) 50 | if info and err is None: 51 | return info.Mode().IsRegular() 52 | return False 53 | 54 | 55 | # NOTE(compatibility): This method uses Go's filepath.Join() method which 56 | # implicitly normalizes the resulting path (pruning extra /, .., etc.) The usual 57 | # CPython behavior is to leave all the cruft. This deviation is reasonable 58 | # because a) result paths will point to the same files and b) one cannot assume 59 | # much about the results of join anyway since it's platform dependent. 60 | def join(*paths): 61 | if not paths: 62 | raise TypeError('join() takes at least 1 argument (0 given)') 63 | parts = [] 64 | for p in paths: 65 | if isabs(p): 66 | parts = [p] 67 | else: 68 | parts.append(p) 69 | result = Join(*parts) 70 | if result and not paths[-1]: 71 | result += '/' 72 | return result 73 | 74 | 75 | def normpath(path): 76 | result = Clean(path) 77 | if isinstance(path, unicode): 78 | return unicode(result, 'utf-8') 79 | return result 80 | 81 | 82 | def split(path): 83 | head, tail = Split(path) 84 | if len(head) > 1 and head[-1] == '/': 85 | head = head[:-1] 86 | return (head, tail) 87 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/random_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import _random 16 | import random 17 | 18 | import weetest 19 | 20 | 21 | def TestGrumpyRandom(): 22 | assert len(_random._gorandom(5)) == 5 23 | 24 | assert _random._int_bit_length(0) == 0 25 | assert _random._int_bit_length(1) == 1 26 | assert _random._int_bit_length(8) == 4 27 | assert _random._int_bit_length(256) == 9 28 | 29 | assert _random._int_from_bytes([1, 0, 0, 0]) == 1 30 | assert _random._int_from_bytes([0, 0, 0, 0]) == 0 31 | assert _random._int_from_bytes([255, 255, 0, 0]) == 65535 32 | assert _random._int_from_bytes([0, 0, 0, 1]) == 16777216 33 | 34 | r = _random.GrumpyRandom() 35 | assert 0.0 <= r.random() < 1.0 36 | 37 | assert 0 <= r.getrandbits(1) <= 1 38 | assert 0 <= r.getrandbits(2) <= 3 39 | assert 0 <= r.getrandbits(8) <= 255 40 | 41 | assert 0 <= r._randbelow(1) < 1 42 | assert 0 <= r._randbelow(3) < 3 43 | assert 0 <= r._randbelow(1000) < 1000 44 | 45 | 46 | def TestSeed(): 47 | random.seed() 48 | try: 49 | random.seed("wrongtype") 50 | except TypeError: 51 | pass 52 | else: 53 | raise AssertionError("TypeError not raised") 54 | 55 | 56 | def TestRandom(): 57 | a = random.random() 58 | b = random.random() 59 | c = random.random() 60 | assert isinstance(a, float) 61 | assert 0.0 <= a < 1.0 62 | assert not a == b == c 63 | 64 | 65 | def TestRandomUniform(): 66 | for _ in range(10): 67 | a = random.uniform(0, 1000) 68 | assert isinstance(a, float) 69 | assert 0 <= a <= 1000 70 | 71 | 72 | def TestRandomInt(): 73 | for _ in range(10): 74 | a = random.randint(0, 1000000) 75 | assert isinstance(a, int) 76 | assert 0 <= a <= 1000000 77 | 78 | b = random.randint(1, 1) 79 | assert b == 1 80 | 81 | try: 82 | c = random.randint(0.1, 3) 83 | except ValueError: 84 | pass 85 | else: 86 | raise AssertionError("ValueError not raised") 87 | 88 | try: 89 | d = random.randint(4, 3) 90 | except ValueError: 91 | pass 92 | else: 93 | raise AssertionError("ValueError not raised") 94 | 95 | 96 | def TestRandomChoice(): 97 | seq = [i*2 for i in range(5)] 98 | for i in range(10): 99 | item = random.choice(seq) 100 | item_idx = item/2 101 | assert seq[item_idx] == item 102 | 103 | try: 104 | random.choice([]) 105 | except IndexError: 106 | pass 107 | else: 108 | raise AssertionError("IndexError not raised") 109 | 110 | 111 | if __name__ == '__main__': 112 | weetest.RunTests() -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/select_.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | from '__go__/syscall' import ( 16 | FD_SETSIZE as _FD_SETSIZE, 17 | Select as _Select, 18 | FdSet as _FdSet, 19 | Timeval as _Timeval 20 | ) 21 | import _syscall 22 | import math 23 | 24 | 25 | class error(Exception): 26 | pass 27 | 28 | 29 | def select(rlist, wlist, xlist, timeout=None): 30 | rlist_norm = _normalize_fd_list(rlist) 31 | wlist_norm = _normalize_fd_list(wlist) 32 | xlist_norm = _normalize_fd_list(xlist) 33 | all_fds = rlist_norm + wlist_norm + xlist_norm 34 | if not all_fds: 35 | nfd = 0 36 | else: 37 | nfd = max(all_fds) + 1 38 | 39 | rfds = _make_fdset(rlist_norm) 40 | wfds = _make_fdset(wlist_norm) 41 | xfds = _make_fdset(xlist_norm) 42 | 43 | if timeout is None: 44 | timeval = None 45 | else: 46 | timeval = _Timeval.new() 47 | frac, integer = math.modf(timeout) 48 | timeval.Sec = int(integer) 49 | timeval.Usec = int(frac * 1000000.0) 50 | _syscall.invoke(_Select, nfd, rfds, wfds, xfds, timeval) 51 | return ([rlist[i] for i, fd in enumerate(rlist_norm) if _fdset_isset(fd, rfds)], 52 | [wlist[i] for i, fd in enumerate(wlist_norm) if _fdset_isset(fd, wfds)], 53 | [xlist[i] for i, fd in enumerate(xlist_norm) if _fdset_isset(fd, xfds)]) 54 | 55 | 56 | def _fdset_set(fd, fds): 57 | idx = fd / (_FD_SETSIZE / len(fds.Bits)) % len(fds.Bits) 58 | pos = fd % (_FD_SETSIZE / len(fds.Bits)) 59 | fds.Bits[idx] |= 1 << pos 60 | 61 | 62 | def _fdset_isset(fd, fds): 63 | idx = fd / (_FD_SETSIZE / len(fds.Bits)) % len(fds.Bits) 64 | pos = fd % (_FD_SETSIZE / len(fds.Bits)) 65 | return bool(fds.Bits[idx] & (1 << pos)) 66 | 67 | 68 | def _make_fdset(fd_list): 69 | fds = _FdSet.new() 70 | for fd in fd_list: 71 | _fdset_set(fd, fds) 72 | return fds 73 | 74 | 75 | def _normalize_fd_list(fds): 76 | result = [] 77 | # Python permits mutating the select fds list during fileno calls so we can't 78 | # just use simple iteration over the list. See test_select_mutated in 79 | # test_select.py 80 | i = 0 81 | while i < len(fds): 82 | fd = fds[i] 83 | if hasattr(fd, 'fileno'): 84 | fd = fd.fileno() 85 | result.append(fd) 86 | i += 1 87 | return result 88 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/stat.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Interpreting stat() results.""" 16 | 17 | # pylint: disable=g-multiple-import 18 | from '__go__/os' import ModeDir, ModePerm 19 | 20 | 21 | def S_ISDIR(mode): # pylint: disable=invalid-name 22 | return mode & ModeDir != 0 23 | 24 | 25 | def S_IMODE(mode): # pylint: disable=invalid-name 26 | return mode & ModePerm 27 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/sys.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """System-specific parameters and functions.""" 16 | 17 | from '__go__/os' import Args 18 | from '__go__/grumpy' import SysModules, MaxInt, Stdin as stdin, Stdout as stdout, Stderr as stderr # pylint: disable=g-multiple-import 19 | from '__go__/runtime' import (GOOS as platform, Version) 20 | from '__go__/unicode' import MaxRune 21 | 22 | argv = [] 23 | for arg in Args: 24 | argv.append(arg) 25 | 26 | goversion = Version() 27 | maxint = MaxInt 28 | maxsize = maxint 29 | maxunicode = MaxRune 30 | modules = SysModules 31 | py3kwarning = False 32 | warnoptions = [] 33 | # TODO: Support actual byteorder 34 | byteorder = 'little' 35 | version = '2.7.13' 36 | 37 | class _Flags(object): 38 | """Container class for sys.flags.""" 39 | debug = 0 40 | py3k_warning = 0 41 | division_warning = 0 42 | division_new = 0 43 | inspect = 0 44 | interactive = 0 45 | optimize = 0 46 | dont_write_bytecode = 0 47 | no_user_site = 0 48 | no_site = 0 49 | ignore_environment = 0 50 | tabcheck = 0 51 | verbose = 0 52 | unicode = 0 53 | bytes_warning = 0 54 | hash_randomization = 0 55 | 56 | 57 | flags = _Flags() 58 | 59 | 60 | def exc_clear(): 61 | __frame__().__exc_clear__() 62 | 63 | 64 | def exc_info(): 65 | e, tb = __frame__().__exc_info__() # pylint: disable=undefined-variable 66 | t = None 67 | if e: 68 | t = type(e) 69 | return t, e, tb 70 | 71 | 72 | def exit(code=None): # pylint: disable=redefined-builtin 73 | raise SystemExit(code) 74 | 75 | 76 | def _getframe(depth=0): 77 | f = __frame__() 78 | while depth > 0 and f is not None: 79 | f = f.f_back 80 | depth -= 1 81 | if f is None: 82 | raise ValueError('call stack is not deep enough') 83 | return f 84 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/sys_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # pylint: disable=bare-except 16 | 17 | import sys 18 | import types 19 | 20 | import weetest 21 | 22 | 23 | def TestArgv(): 24 | assert sys.argv 25 | 26 | 27 | def TestMaxInt(): 28 | assert sys.maxint > 2000000000 29 | 30 | 31 | def TestSysModules(): 32 | assert sys.modules['sys'] is not None 33 | 34 | 35 | def TestExcClear(): 36 | try: 37 | raise RuntimeError 38 | except: 39 | assert all(sys.exc_info()), sys.exc_info() 40 | sys.exc_clear() 41 | assert not any(sys.exc_info()) 42 | else: 43 | assert False 44 | 45 | 46 | def TestExcInfoNoException(): 47 | assert sys.exc_info() == (None, None, None) 48 | 49 | 50 | def TestExcInfoWithException(): 51 | try: 52 | raise RuntimeError 53 | except: 54 | t, e, tb = sys.exc_info() 55 | else: 56 | assert False 57 | assert t is RuntimeError 58 | assert isinstance(e, t) 59 | assert isinstance(tb, types.TracebackType) 60 | 61 | 62 | def TestExitEmpty(): 63 | try: 64 | sys.exit() 65 | except SystemExit as e: 66 | assert e.code == None, e.code # pylint: disable=g-equals-none 67 | except: 68 | assert False 69 | 70 | 71 | def TestExitCode(): 72 | try: 73 | sys.exit(42) 74 | except SystemExit as e: 75 | assert e.code == 42, e.code 76 | except: 77 | assert False 78 | 79 | 80 | def TestExitInvalidArgs(): 81 | try: 82 | sys.exit(1, 2, 3) 83 | except TypeError as e: 84 | assert str(e) == 'exit() takes 1 arguments (3 given)', str(e) 85 | except: 86 | assert False 87 | 88 | 89 | def TestGetFrame(): 90 | try: 91 | sys._getframe(42, 42) 92 | except TypeError: 93 | pass 94 | else: 95 | assert False 96 | try: 97 | sys._getframe(2000000000) 98 | except ValueError: 99 | pass 100 | else: 101 | assert False 102 | assert sys._getframe().f_code.co_name == '_getframe' 103 | assert sys._getframe(1).f_code.co_name == 'TestGetFrame' 104 | 105 | 106 | if __name__ == '__main__': 107 | # This call will incidentally test sys.exit(). 108 | weetest.RunTests() 109 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/tempfile.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Generate temporary files and directories.""" 16 | 17 | # pylint: disable=g-multiple-import 18 | from '__go__/io/ioutil' import TempDir, TempFile 19 | from '__go__/syscall' import Dup 20 | 21 | 22 | # pylint: disable=redefined-builtin 23 | def mkdtemp(suffix='', prefix='tmp', dir=None): 24 | if dir is None: 25 | dir = '' 26 | # TODO: Make suffix actually follow the rest of the filename. 27 | path, err = TempDir(dir, prefix + '-' + suffix) 28 | if err: 29 | raise OSError(err.Error()) 30 | return path 31 | 32 | 33 | def mkstemp(suffix='', prefix='tmp', dir=None, text=False): 34 | if text: 35 | raise NotImplementedError 36 | if dir is None: 37 | dir = '' 38 | # TODO: Make suffix actually follow the rest of the filename. 39 | f, err = TempFile(dir, prefix + '-' + suffix) 40 | if err: 41 | raise OSError(err.Error()) 42 | try: 43 | fd, err = Dup(f.Fd()) 44 | if err: 45 | raise OSError(err.Error()) 46 | return fd, f.Name() 47 | finally: 48 | f.Close() 49 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/tempfile_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import os 16 | import stat 17 | import tempfile 18 | 19 | import weetest 20 | 21 | 22 | def TestMkdTemp(): 23 | path = tempfile.mkdtemp() 24 | mode = os.stat(path).st_mode 25 | os.rmdir(path) 26 | assert stat.S_ISDIR(mode), mode 27 | assert stat.S_IMODE(mode) == 0o700, mode 28 | 29 | 30 | def TestMkdTempDir(): 31 | tempdir = tempfile.mkdtemp() 32 | path = tempfile.mkdtemp(dir=tempdir) 33 | os.rmdir(path) 34 | os.rmdir(tempdir) 35 | assert path.startswith(tempdir) 36 | 37 | 38 | def TestMkdTempOSError(): 39 | tempdir = tempfile.mkdtemp() 40 | os.chmod(tempdir, 0o500) 41 | 42 | if os.geteuid() == 0: 43 | print ('Warning: Cannot reliable test file readonly-ness with Root user') 44 | mode = os.stat(tempdir).st_mode 45 | assert stat.S_IMODE(mode) == 0o500, ('Wrong file mode "%s" detected' % mode) 46 | 47 | else: 48 | try: 49 | tempfile.mkdtemp(dir=tempdir) 50 | except OSError: 51 | pass 52 | else: 53 | raise AssertionError, 'Should not be able to touch 0o500 paths' 54 | os.rmdir(tempdir) 55 | 56 | 57 | def TestMkdTempPrefixSuffix(): 58 | path = tempfile.mkdtemp(prefix='foo', suffix='bar') 59 | os.rmdir(path) 60 | assert 'foo' in path 61 | assert 'bar' in path 62 | # TODO: assert path.endswith('bar') 63 | 64 | 65 | def TestMksTemp(): 66 | fd, path = tempfile.mkstemp() 67 | f = os.fdopen(fd, 'w') 68 | f.write('foobar') 69 | f.close() 70 | f = open(path) 71 | contents = f.read() 72 | f.close() 73 | os.remove(path) 74 | assert contents == 'foobar', contents 75 | 76 | 77 | def TestMksTempDir(): 78 | tempdir = tempfile.mkdtemp() 79 | fd, path = tempfile.mkstemp(dir=tempdir) 80 | os.close(fd) 81 | os.remove(path) 82 | os.rmdir(tempdir) 83 | assert path.startswith(tempdir) 84 | 85 | 86 | def TestMksTempOSError(): 87 | tempdir = tempfile.mkdtemp() 88 | os.chmod(tempdir, 0o500) 89 | 90 | if os.geteuid() == 0: 91 | print ('Warning: Cannot reliable test file readonly-ness with Root user') 92 | mode = os.stat(tempdir).st_mode 93 | assert stat.S_IMODE(mode) == 0o500, ('Wrong file mode "%s" detected' % mode) 94 | 95 | else: 96 | try: 97 | tempfile.mkstemp(dir=tempdir) 98 | except OSError: 99 | pass 100 | else: 101 | raise AssertionError 102 | os.rmdir(tempdir) 103 | 104 | 105 | def TestMksTempPerms(): 106 | fd, path = tempfile.mkstemp() 107 | os.close(fd) 108 | mode = os.stat(path).st_mode 109 | os.remove(path) 110 | assert stat.S_IMODE(mode) == 0o600, mode 111 | 112 | 113 | def TestMksTempPrefixSuffix(): 114 | fd, path = tempfile.mkstemp(prefix='foo', suffix='bar') 115 | os.close(fd) 116 | os.remove(path) 117 | assert 'foo' in path 118 | assert 'bar' in path 119 | # TODO: assert path.endswith('bar') 120 | 121 | 122 | if __name__ == '__main__': 123 | weetest.RunTests() 124 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/thread.py: -------------------------------------------------------------------------------- 1 | from '__go__/grumpy' import NewTryableMutex, StartThread, ThreadCount 2 | 3 | 4 | class error(Exception): 5 | pass 6 | 7 | 8 | def get_ident(): 9 | f = __frame__() 10 | while f.f_back: 11 | f = f.f_back 12 | return id(f) 13 | 14 | 15 | class LockType(object): 16 | def __init__(self): 17 | self._mutex = NewTryableMutex() 18 | 19 | def acquire(self, waitflag=1): 20 | if waitflag: 21 | self._mutex.Lock() 22 | return True 23 | return self._mutex.TryLock() 24 | 25 | def release(self): 26 | self._mutex.Unlock() 27 | 28 | def __enter__(self): 29 | self.acquire() 30 | 31 | def __exit__(self, *args): 32 | self.release() 33 | 34 | 35 | def allocate_lock(): 36 | """Dummy implementation of thread.allocate_lock().""" 37 | return LockType() 38 | 39 | 40 | def start_new_thread(func, args, kwargs=None): 41 | if kwargs is None: 42 | kwargs = {} 43 | l = allocate_lock() 44 | ident = [] 45 | def thread_func(): 46 | ident.append(get_ident()) 47 | l.release() 48 | func(*args, **kwargs) 49 | l.acquire() 50 | StartThread(thread_func) 51 | l.acquire() 52 | return ident[0] 53 | 54 | 55 | def stack_size(n=0): 56 | if n: 57 | raise error('grumpy does not support setting stack size') 58 | return 0 59 | 60 | 61 | def _count(): 62 | return ThreadCount 63 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/time_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import time 16 | 17 | assert time.time() > 1000000000 18 | assert time.time() < 3000000000 19 | 20 | time_struct = (1999, 9, 19, 0, 0, 0, 6, 262, 0) 21 | got = time.localtime(time.mktime(time_struct)) 22 | assert got == time_struct, got 23 | -------------------------------------------------------------------------------- /grumpy-runtime-src/lib/types_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import types 16 | 17 | from '__go__/grumpy' import (FunctionType, MethodType, ModuleType, StrType, # pylint: disable=g-multiple-import 18 | TracebackType, TypeType) 19 | 20 | # Verify a sample of all types as a sanity check. 21 | assert types.FunctionType is FunctionType 22 | assert types.MethodType is MethodType 23 | assert types.UnboundMethodType is MethodType 24 | assert types.ModuleType is ModuleType 25 | assert types.StringType is StrType 26 | assert types.TracebackType is TracebackType 27 | assert types.TypeType is TypeType 28 | -------------------------------------------------------------------------------- /grumpy-runtime-src/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["setuptools", "wheel", "grumpy-tools>0.2.2"] 3 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/baseexception.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "reflect" 19 | ) 20 | 21 | // BaseException represents Python 'BaseException' objects. 22 | type BaseException struct { 23 | Object 24 | args *Tuple 25 | } 26 | 27 | func toBaseExceptionUnsafe(o *Object) *BaseException { 28 | return (*BaseException)(o.toPointer()) 29 | } 30 | 31 | // ToObject upcasts e to an Object. 32 | func (e *BaseException) ToObject() *Object { 33 | return &e.Object 34 | } 35 | 36 | // BaseExceptionType corresponds to the Python type 'BaseException'. 37 | var BaseExceptionType = newBasisType("BaseException", reflect.TypeOf(BaseException{}), toBaseExceptionUnsafe, ObjectType) 38 | 39 | func baseExceptionInit(f *Frame, o *Object, args Args, kwargs KWArgs) (*Object, *BaseException) { 40 | e := toBaseExceptionUnsafe(o) 41 | e.args = NewTuple(args.makeCopy()...) 42 | return None, nil 43 | } 44 | 45 | func baseExceptionRepr(f *Frame, o *Object) (*Object, *BaseException) { 46 | e := toBaseExceptionUnsafe(o) 47 | argsString := "()" 48 | if e.args != nil { 49 | s, raised := Repr(f, e.args.ToObject()) 50 | if raised != nil { 51 | return nil, raised 52 | } 53 | argsString = s.Value() 54 | } 55 | return NewStr(e.typ.Name() + argsString).ToObject(), nil 56 | } 57 | 58 | func baseExceptionStr(f *Frame, o *Object) (*Object, *BaseException) { 59 | e := toBaseExceptionUnsafe(o) 60 | if e.args == nil || len(e.args.elems) == 0 { 61 | return NewStr("").ToObject(), nil 62 | } 63 | if len(e.args.elems) == 1 { 64 | s, raised := ToStr(f, e.args.elems[0]) 65 | return s.ToObject(), raised 66 | } 67 | s, raised := ToStr(f, e.args.ToObject()) 68 | return s.ToObject(), raised 69 | } 70 | 71 | func initBaseExceptionType(map[string]*Object) { 72 | BaseExceptionType.slots.Init = &initSlot{baseExceptionInit} 73 | BaseExceptionType.slots.Repr = &unaryOpSlot{baseExceptionRepr} 74 | BaseExceptionType.slots.Str = &unaryOpSlot{baseExceptionStr} 75 | } 76 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/baseexception_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestBaseExceptionCreate(t *testing.T) { 22 | emptyExc := toBaseExceptionUnsafe(newObject(ExceptionType)) 23 | emptyExc.args = NewTuple() 24 | cases := []struct { 25 | t *Type 26 | args *Tuple 27 | wantRet *Object 28 | }{ 29 | {ExceptionType, NewTuple(), emptyExc.ToObject()}, 30 | {TypeErrorType, NewTuple(NewStr("abc").ToObject()), mustCreateException(TypeErrorType, "abc").ToObject()}, 31 | } 32 | for _, cas := range cases { 33 | got, match := checkInvokeResult(cas.t.ToObject(), cas.args.elems, cas.wantRet, nil) 34 | if match == checkInvokeResultExceptionMismatch { 35 | t.Errorf("%s%v raised %v, want none", cas.t.Name(), cas.args, got) 36 | } else if match == checkInvokeResultReturnValueMismatch { 37 | t.Errorf("%s%v = %v, want %v", cas.t.Name(), cas.args, got, cas.wantRet) 38 | } 39 | } 40 | } 41 | 42 | func TestBaseExceptionInitRaise(t *testing.T) { 43 | cas := invokeTestCase{ 44 | args: nil, 45 | wantExc: mustCreateException(TypeErrorType, "unbound method __init__() must be called with BaseException instance as first argument (got nothing instead)"), 46 | } 47 | if err := runInvokeMethodTestCase(BaseExceptionType, "__init__", &cas); err != "" { 48 | t.Error(err) 49 | } 50 | } 51 | 52 | func TestBaseExceptionRepr(t *testing.T) { 53 | fooExc := toBaseExceptionUnsafe(newObject(ExceptionType)) 54 | fooExc.args = NewTuple(NewStr("foo").ToObject()) 55 | recursiveExc := toBaseExceptionUnsafe(newObject(ExceptionType)) 56 | recursiveExc.args = NewTuple(recursiveExc.ToObject()) 57 | cases := []invokeTestCase{ 58 | {args: wrapArgs(newObject(TypeErrorType)), want: NewStr("TypeError()").ToObject()}, 59 | {args: wrapArgs(fooExc), want: NewStr("Exception('foo',)").ToObject()}, 60 | {args: wrapArgs(recursiveExc), want: NewStr("Exception(Exception(...),)").ToObject()}, 61 | } 62 | for _, cas := range cases { 63 | if err := runInvokeTestCase(wrapFuncForTest(Repr), &cas); err != "" { 64 | t.Error(err) 65 | } 66 | } 67 | } 68 | 69 | func TestBaseExceptionStr(t *testing.T) { 70 | f := NewRootFrame() 71 | cases := []invokeTestCase{ 72 | {args: wrapArgs(newObject(TypeErrorType)), want: NewStr("").ToObject()}, 73 | {args: wrapArgs(mustNotRaise(ExceptionType.Call(f, wrapArgs(""), nil))), want: NewStr("").ToObject()}, 74 | {args: wrapArgs(mustNotRaise(ExceptionType.Call(f, wrapArgs("foo"), nil))), want: NewStr("foo").ToObject()}, 75 | {args: wrapArgs(mustNotRaise(TypeErrorType.Call(f, wrapArgs(NewTuple(), 3), nil))), want: NewStr("((), 3)").ToObject()}, 76 | } 77 | for _, cas := range cases { 78 | if err := runInvokeTestCase(wrapFuncForTest(ToStr), &cas); err != "" { 79 | t.Error(err) 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/basestring.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "regexp" 19 | "strings" 20 | ) 21 | 22 | // EncodeDefault is the system default encoding. 23 | const EncodeDefault = "utf8" 24 | 25 | // Error handling modes that dictate the behavior of *Str.Decode and 26 | // *Unicode.Encode when they encounter bad chars. 27 | const ( 28 | // EncodeStrict causes UnicodeError to be raised on bad chars. 29 | EncodeStrict = "strict" 30 | // EncodeReplace replaces bad chars with "\ufffd". 31 | EncodeReplace = "replace" 32 | // EncodeIgnore discards bad chars. 33 | EncodeIgnore = "ignore" 34 | ) 35 | 36 | var ( 37 | // BaseStringType is the object representing the Python 'basestring' 38 | // type. 39 | BaseStringType = newSimpleType("basestring", ObjectType) 40 | encodingGarbageRegexp = regexp.MustCompile(`[^A-Za-z0-9]+`) 41 | escapeMap = map[rune]string{ 42 | '\\': `\\`, 43 | '\'': `\'`, 44 | '\n': `\n`, 45 | '\r': `\r`, 46 | '\t': `\t`, 47 | } 48 | ) 49 | 50 | func initBaseStringType(map[string]*Object) { 51 | BaseStringType.flags &^= typeFlagInstantiable 52 | } 53 | 54 | func normalizeEncoding(encoding string) string { 55 | return strings.ToLower(encodingGarbageRegexp.ReplaceAllString(encoding, "")) 56 | } 57 | 58 | func escapeRune(r rune) []byte { 59 | const hexTable = "0123456789abcdef" 60 | 61 | if r < 0x100 { 62 | return []byte{'\\', 'x', hexTable[r>>4], hexTable[r&0x0F]} 63 | } 64 | 65 | if r < 0x10000 { 66 | return []byte{'\\', 'u', 67 | hexTable[r>>12], hexTable[r>>8&0x0F], 68 | hexTable[r>>4&0x0F], hexTable[r&0x0F]} 69 | } 70 | 71 | return []byte{'\\', 'U', 72 | hexTable[r>>28], hexTable[r>>24&0x0F], 73 | hexTable[r>>20&0x0F], hexTable[r>>16&0x0F], 74 | hexTable[r>>12&0x0F], hexTable[r>>8&0x0F], 75 | hexTable[r>>4&0x0F], hexTable[r&0x0F]} 76 | } 77 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/basestring_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestNormalizeEncoding(t *testing.T) { 22 | cases := []struct { 23 | encoding string 24 | want string 25 | }{ 26 | {"utf8", "utf8"}, 27 | {"UTF-16 ", "utf16"}, 28 | {" __Ascii__", "ascii"}, 29 | {"utf@#(%*#(*%16 ", "utf16"}, 30 | {"", ""}, 31 | } 32 | for _, cas := range cases { 33 | if got := normalizeEncoding(cas.encoding); got != cas.want { 34 | t.Errorf("normalizeEncoding(%q) = %q, want %q", cas.encoding, got, cas.want) 35 | } 36 | } 37 | } 38 | 39 | func BenchmarkEscapeRune(b *testing.B) { 40 | b.Run("low values", func(b *testing.B) { 41 | for i := 0; i < b.N; i++ { 42 | escapeRune(0x10) 43 | } 44 | }) 45 | 46 | b.Run("mid values", func(b *testing.B) { 47 | for i := 0; i < b.N; i++ { 48 | escapeRune(0x200) 49 | } 50 | }) 51 | 52 | b.Run("high values", func(b *testing.B) { 53 | for i := 0; i < b.N; i++ { 54 | escapeRune(0x20000) 55 | } 56 | }) 57 | } 58 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/bool.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "fmt" 19 | "reflect" 20 | ) 21 | 22 | // GetBool returns True if v is true, False otherwise. 23 | func GetBool(v bool) *Int { 24 | if v { 25 | return True 26 | } 27 | return False 28 | } 29 | 30 | // BoolType is the object representing the Python 'bool' type. 31 | var BoolType = newSimpleType("bool", IntType) 32 | 33 | func boolNative(_ *Frame, o *Object) (reflect.Value, *BaseException) { 34 | return reflect.ValueOf(toIntUnsafe(o).Value() != 0), nil 35 | } 36 | 37 | func boolNew(f *Frame, _ *Type, args Args, _ KWArgs) (*Object, *BaseException) { 38 | argc := len(args) 39 | if argc == 0 { 40 | return False.ToObject(), nil 41 | } 42 | if argc != 1 { 43 | return nil, f.RaiseType(TypeErrorType, fmt.Sprintf("bool() takes at most 1 argument (%d given)", argc)) 44 | } 45 | ret, raised := IsTrue(f, args[0]) 46 | if raised != nil { 47 | return nil, raised 48 | } 49 | return GetBool(ret).ToObject(), nil 50 | } 51 | 52 | func boolRepr(_ *Frame, o *Object) (*Object, *BaseException) { 53 | i := toIntUnsafe(o) 54 | if i.Value() != 0 { 55 | return trueStr, nil 56 | } 57 | return falseStr, nil 58 | } 59 | 60 | func initBoolType(map[string]*Object) { 61 | BoolType.flags &= ^(typeFlagInstantiable | typeFlagBasetype) 62 | BoolType.slots.Native = &nativeSlot{boolNative} 63 | BoolType.slots.New = &newSlot{boolNew} 64 | BoolType.slots.Repr = &unaryOpSlot{boolRepr} 65 | } 66 | 67 | var ( 68 | // True is the singleton bool object representing the Python 'True' 69 | // object. 70 | True = &Int{Object{typ: BoolType}, 1} 71 | // False is the singleton bool object representing the Python 'False' 72 | // object. 73 | False = &Int{Object{typ: BoolType}, 0} 74 | trueStr = NewStr("True").ToObject() 75 | falseStr = NewStr("False").ToObject() 76 | ) 77 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/bool_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestBoolCompare(t *testing.T) { 22 | cases := []invokeTestCase{ 23 | {args: wrapArgs(true, true), want: compareAllResultEq}, 24 | {args: wrapArgs(true, false), want: compareAllResultGT}, 25 | {args: wrapArgs(true, 1), want: compareAllResultEq}, 26 | {args: wrapArgs(true, -1), want: compareAllResultGT}, 27 | {args: wrapArgs(false, 0), want: compareAllResultEq}, 28 | {args: wrapArgs(false, 1000), want: compareAllResultLT}, 29 | } 30 | for _, cas := range cases { 31 | if err := runInvokeTestCase(compareAll, &cas); err != "" { 32 | t.Error(err) 33 | } 34 | } 35 | } 36 | 37 | func TestBoolCreate(t *testing.T) { 38 | cases := []invokeTestCase{ 39 | {args: wrapArgs(None), wantExc: mustCreateException(TypeErrorType, `'__new__' requires a 'type' object but received a "NoneType"`)}, 40 | {args: wrapArgs(BoolType), want: False.ToObject()}, 41 | {args: wrapArgs(BoolType, None), want: False.ToObject()}, 42 | {args: wrapArgs(BoolType, ""), want: False.ToObject()}, 43 | {args: wrapArgs(BoolType, true), want: True.ToObject()}, 44 | {args: wrapArgs(BoolType, newObject(ObjectType)), want: True.ToObject()}, 45 | {args: wrapArgs(ObjectType), wantExc: mustCreateException(TypeErrorType, "bool.__new__(object): object is not a subtype of bool")}, 46 | {args: wrapArgs(BoolType, "foo", "bar"), wantExc: mustCreateException(TypeErrorType, "bool() takes at most 1 argument (2 given)")}, 47 | } 48 | for _, cas := range cases { 49 | if err := runInvokeMethodTestCase(BoolType, "__new__", &cas); err != "" { 50 | t.Error(err) 51 | } 52 | } 53 | } 54 | 55 | func TestBoolStrRepr(t *testing.T) { 56 | cases := []invokeTestCase{ 57 | {args: wrapArgs(true), want: NewStr("True").ToObject()}, 58 | {args: wrapArgs(false), want: NewStr("False").ToObject()}, 59 | } 60 | for _, cas := range cases { 61 | if err := runInvokeTestCase(wrapFuncForTest(ToStr), &cas); err != "" { 62 | t.Error(err) 63 | } 64 | if err := runInvokeTestCase(wrapFuncForTest(Repr), &cas); err != "" { 65 | t.Error(err) 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/callableiter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "reflect" 19 | "sync" 20 | ) 21 | 22 | var ( 23 | callableIteratorType = newBasisType("callable-iterator", reflect.TypeOf(callableIterator{}), toCallableIteratorUnsafe, ObjectType) 24 | ) 25 | 26 | type callableIterator struct { 27 | Object 28 | callable *Object 29 | sentinel *Object 30 | mutex sync.Mutex 31 | } 32 | 33 | func newCallableIterator(callable *Object, sentinel *Object) *Object { 34 | iter := &callableIterator{Object: Object{typ: callableIteratorType}, callable: callable, sentinel: sentinel} 35 | return &iter.Object 36 | } 37 | 38 | func toCallableIteratorUnsafe(o *Object) *callableIterator { 39 | return (*callableIterator)(o.toPointer()) 40 | } 41 | 42 | func callableIteratorIter(f *Frame, o *Object) (*Object, *BaseException) { 43 | return o, nil 44 | } 45 | 46 | func callableIteratorNext(f *Frame, o *Object) (item *Object, raised *BaseException) { 47 | i := toCallableIteratorUnsafe(o) 48 | i.mutex.Lock() 49 | defer i.mutex.Unlock() 50 | if i.callable == nil { 51 | raised = f.Raise(StopIterationType.ToObject(), nil, nil) 52 | } else if item, raised = i.callable.Call(f, Args{}, nil); raised == nil { 53 | var eq *Object 54 | if eq, raised = Eq(f, item, i.sentinel); raised == nil && eq == True.ToObject() { 55 | i.callable = nil 56 | item = nil 57 | raised = f.Raise(StopIterationType.ToObject(), nil, nil) 58 | } 59 | } 60 | return item, raised 61 | } 62 | 63 | func initCallableIteratorType(map[string]*Object) { 64 | callableIteratorType.flags &= ^(typeFlagBasetype | typeFlagInstantiable) 65 | callableIteratorType.slots.Iter = &unaryOpSlot{callableIteratorIter} 66 | callableIteratorType.slots.Next = &unaryOpSlot{callableIteratorNext} 67 | } 68 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/callableiter_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestCallableIterator(t *testing.T) { 22 | fun := newBuiltinFunction("TestCallableIterator", func(f *Frame, args Args, _ KWArgs) (*Object, *BaseException) { 23 | return TupleType.Call(f, args, nil) 24 | }).ToObject() 25 | makeCounter := func() *Object { 26 | cnt := 0 27 | return newBuiltinFunction("counter", func(f *Frame, _ Args, _ KWArgs) (*Object, *BaseException) { 28 | cnt++ 29 | return NewInt(cnt).ToObject(), nil 30 | }).ToObject() 31 | } 32 | exhaustedIter := newCallableIterator(makeCounter(), NewInt(2).ToObject()) 33 | TupleType.Call(NewRootFrame(), []*Object{exhaustedIter}, nil) 34 | cases := []invokeTestCase{ 35 | {args: wrapArgs(newCallableIterator(makeCounter(), NewInt(4).ToObject())), want: newTestTuple(1, 2, 3).ToObject()}, 36 | {args: wrapArgs(newCallableIterator(makeCounter(), NewInt(1).ToObject())), want: newTestTuple().ToObject()}, 37 | {args: wrapArgs(exhaustedIter), want: NewTuple().ToObject()}, 38 | } 39 | for _, cas := range cases { 40 | if err := runInvokeTestCase(fun, &cas); err != "" { 41 | t.Error(err) 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/code.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "reflect" 19 | ) 20 | 21 | // CodeType is the object representing the Python 'code' type. 22 | var CodeType = newBasisType("code", reflect.TypeOf(Code{}), toCodeUnsafe, ObjectType) 23 | 24 | // CodeFlag is a switch controlling the behavior of a Code object. 25 | type CodeFlag int 26 | 27 | const ( 28 | // CodeFlagVarArg means a Code object accepts *arg parameters. 29 | CodeFlagVarArg CodeFlag = 4 30 | // CodeFlagKWArg means a Code object accepts **kwarg parameters. 31 | CodeFlagKWArg CodeFlag = 8 32 | ) 33 | 34 | // Code represents Python 'code' objects. 35 | type Code struct { 36 | Object 37 | name string `attr:"co_name"` 38 | filename string `attr:"co_filename"` 39 | // argc is the number of positional arguments. 40 | argc int `attr:"co_argcount"` 41 | flags CodeFlag `attr:"co_flags"` 42 | paramSpec *ParamSpec 43 | fn func(*Frame, []*Object) (*Object, *BaseException) 44 | } 45 | 46 | // NewCode creates a new Code object that executes the given fn. 47 | func NewCode(name, filename string, params []Param, flags CodeFlag, fn func(*Frame, []*Object) (*Object, *BaseException)) *Code { 48 | s := NewParamSpec(name, params, flags&CodeFlagVarArg != 0, flags&CodeFlagKWArg != 0) 49 | return &Code{Object{typ: CodeType}, name, filename, len(params), flags, s, fn} 50 | } 51 | 52 | func toCodeUnsafe(o *Object) *Code { 53 | return (*Code)(o.toPointer()) 54 | } 55 | 56 | // Eval runs the code object c in the context of the given globals. 57 | func (c *Code) Eval(f *Frame, globals *Dict, args Args, kwargs KWArgs) (*Object, *BaseException) { 58 | validated := f.MakeArgs(c.paramSpec.Count) 59 | if raised := c.paramSpec.Validate(f, validated, args, kwargs); raised != nil { 60 | return nil, raised 61 | } 62 | oldExc, oldTraceback := f.ExcInfo() 63 | next := newChildFrame(f) 64 | next.code = c 65 | next.globals = globals 66 | ret, raised := c.fn(next, validated) 67 | next.release() 68 | f.FreeArgs(validated) 69 | if raised == nil { 70 | // Restore exc_info to what it was when we left the previous 71 | // frame. 72 | f.RestoreExc(oldExc, oldTraceback) 73 | if ret == nil { 74 | ret = None 75 | } 76 | } else { 77 | _, tb := f.ExcInfo() 78 | if f.code != nil { 79 | // The root frame has no code object so don't include it 80 | // in the traceback. 81 | tb = newTraceback(f, tb) 82 | } 83 | f.RestoreExc(raised, tb) 84 | } 85 | return ret, raised 86 | } 87 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/generator_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestGeneratorNext(t *testing.T) { 22 | f := NewRootFrame() 23 | var recursive *Object 24 | recursiveFn := func(*Object) (*Object, *BaseException) { 25 | next, raised := GetAttr(f, recursive, NewStr("next"), nil) 26 | if raised != nil { 27 | return nil, raised 28 | } 29 | return next.Call(f, nil, nil) 30 | } 31 | recursive = NewGenerator(f, recursiveFn).ToObject() 32 | emptyFn := func(*Object) (*Object, *BaseException) { 33 | return nil, nil 34 | } 35 | exhausted := NewGenerator(NewRootFrame(), emptyFn).ToObject() 36 | mustNotRaise(ListType.Call(NewRootFrame(), Args{exhausted}, nil)) 37 | cases := []invokeTestCase{ 38 | invokeTestCase{args: wrapArgs(recursive), wantExc: mustCreateException(ValueErrorType, "generator already executing")}, 39 | invokeTestCase{args: wrapArgs(exhausted), wantExc: toBaseExceptionUnsafe(mustNotRaise(StopIterationType.Call(NewRootFrame(), nil, nil)))}, 40 | } 41 | for _, cas := range cases { 42 | if err := runInvokeMethodTestCase(GeneratorType, "next", &cas); err != "" { 43 | t.Error(err) 44 | } 45 | } 46 | } 47 | 48 | func TestGeneratorSend(t *testing.T) { 49 | emptyFn := func(*Object) (*Object, *BaseException) { 50 | return nil, nil 51 | } 52 | cases := []invokeTestCase{ 53 | invokeTestCase{args: wrapArgs(NewGenerator(NewRootFrame(), emptyFn), 123), wantExc: mustCreateException(TypeErrorType, "can't send non-None value to a just-started generator")}, 54 | invokeTestCase{args: wrapArgs(NewGenerator(NewRootFrame(), emptyFn), "foo", "bar"), wantExc: mustCreateException(TypeErrorType, "'send' of 'generator' requires 2 arguments")}, 55 | } 56 | for _, cas := range cases { 57 | if err := runInvokeMethodTestCase(GeneratorType, "send", &cas); err != "" { 58 | t.Error(err) 59 | } 60 | } 61 | } 62 | 63 | func TestGeneratorSimple(t *testing.T) { 64 | f := NewRootFrame() 65 | fn := func(*Object) (*Object, *BaseException) { 66 | switch f.State() { 67 | case 0: 68 | goto Start 69 | case 1: 70 | goto Yield1 71 | case 2: 72 | goto Yield2 73 | default: 74 | t.Fatalf("got invalid state %d", f.State()) 75 | } 76 | Start: 77 | f.PushCheckpoint(1) 78 | return NewStr("foo").ToObject(), nil 79 | Yield1: 80 | f.PushCheckpoint(2) 81 | return NewStr("bar").ToObject(), nil 82 | Yield2: 83 | return nil, nil 84 | } 85 | cas := &invokeTestCase{ 86 | args: wrapArgs(NewGenerator(f, fn)), 87 | want: newTestList("foo", "bar").ToObject(), 88 | } 89 | if err := runInvokeTestCase(ListType.ToObject(), cas); err != "" { 90 | t.Error(err) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/numeric.go: -------------------------------------------------------------------------------- 1 | package grumpy 2 | 3 | import ( 4 | "math/big" 5 | "strings" 6 | ) 7 | 8 | const ( 9 | // Here we calculate the number of bits in a uint and use that to 10 | // create a typeless constant _maxuint which is the largest value that 11 | // can be held by a uint. We then use that to create the constants 12 | // MaxInt and MinInt below. 13 | // Because these constants are typeless, they can be used wherever 14 | // a numeric value is needed, without a conversion like int64(). 15 | // A typeless number remains untyped when shifted, even if the shift 16 | // count is typed. 17 | // Start with the two's complement of 0 as a uint which is 0xffff...ff. 18 | // This is the number we are after, but it currently has a type (uint). 19 | // Dividing it by 0xff gives us 0x0101...01 for the length of a uint. 20 | // Taking that mod 15 is effectively counting the ones - one for each 21 | // byte in a uint, so we have either 4 or 8. 22 | // We multiply by 8 and shift, and now we have 2^32 or 2^64 as a 23 | // typeless constant number. 24 | // We subtract 1 from that to get maxuint. 25 | _maxuint = 1<<(^uint(0)/0xff%15*8) - 1 26 | 27 | // MaxInt is the largest (most positive) number that can be stored as an int. 28 | MaxInt = _maxuint >> 1 29 | // MinInt is the smallest (most negative) number that can be stored as an int. 30 | // The absolute value of MinInt is Maxint+1, thus it can be tricky to deal with. 31 | MinInt = -(_maxuint + 1) >> 1 32 | ) 33 | 34 | var ( 35 | maxIntBig = big.NewInt(MaxInt) 36 | minIntBig = big.NewInt(MinInt) 37 | ) 38 | 39 | func numParseInteger(z *big.Int, s string, base int) (*big.Int, bool) { 40 | s = strings.TrimSpace(s) 41 | if len(s) > 2 && s[0] == '0' { 42 | switch s[1] { 43 | case 'b', 'B': 44 | if base == 0 || base == 2 { 45 | base = 2 46 | s = s[2:] 47 | } 48 | case 'o', 'O': 49 | if base == 0 || base == 8 { 50 | base = 8 51 | s = s[2:] 52 | } 53 | case 'x', 'X': 54 | if base == 0 || base == 16 { 55 | base = 16 56 | s = s[2:] 57 | } 58 | default: 59 | base = 8 60 | } 61 | } 62 | if base == 0 { 63 | base = 10 64 | } 65 | return z.SetString(s, base) 66 | } 67 | 68 | func numInIntRange(i *big.Int) bool { 69 | return i.Cmp(minIntBig) >= 0 && i.Cmp(maxIntBig) <= 0 70 | } 71 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/super.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "reflect" 19 | ) 20 | 21 | var ( 22 | // superType is the object representing the Python 'super' type. 23 | superType = newBasisType("super", reflect.TypeOf(super{}), toSuperUnsafe, ObjectType) 24 | ) 25 | 26 | type super struct { 27 | Object 28 | sub *Type 29 | obj *Object 30 | objType *Type 31 | } 32 | 33 | func toSuperUnsafe(o *Object) *super { 34 | return (*super)(o.toPointer()) 35 | } 36 | 37 | func superInit(f *Frame, o *Object, args Args, _ KWArgs) (*Object, *BaseException) { 38 | // TODO: Support the unbound form of super. 39 | if raised := checkFunctionArgs(f, "__init__", args, TypeType, ObjectType); raised != nil { 40 | return nil, raised 41 | } 42 | sup := toSuperUnsafe(o) 43 | sub := toTypeUnsafe(args[0]) 44 | obj := args[1] 45 | var objType *Type 46 | if obj.isInstance(TypeType) && toTypeUnsafe(obj).isSubclass(sub) { 47 | objType = toTypeUnsafe(obj) 48 | } else if obj.isInstance(sub) { 49 | objType = obj.typ 50 | } else { 51 | return nil, f.RaiseType(TypeErrorType, "super(type, obj): obj must be an instance or subtype of type") 52 | } 53 | sup.sub = sub 54 | sup.obj = obj 55 | sup.objType = objType 56 | return None, nil 57 | } 58 | 59 | func superGetAttribute(f *Frame, o *Object, name *Str) (*Object, *BaseException) { 60 | sup := toSuperUnsafe(o) 61 | // Tell the truth about the __class__ attribute. 62 | if sup.objType != nil && name.Value() != "__class__" { 63 | mro := sup.objType.mro 64 | n := len(mro) 65 | // Start from the immediate mro successor to the specified type. 66 | i := 0 67 | for i < n && mro[i] != sup.sub { 68 | i++ 69 | } 70 | i++ 71 | var inst *Object 72 | if sup.obj != sup.objType.ToObject() { 73 | inst = sup.obj 74 | } 75 | // Now do normal mro lookup from the successor type. 76 | for ; i < n; i++ { 77 | dict := mro[i].Dict() 78 | res, raised := dict.GetItem(f, name.ToObject()) 79 | if raised != nil { 80 | return nil, raised 81 | } 82 | if res != nil { 83 | if get := res.typ.slots.Get; get != nil { 84 | // Found a descriptor so invoke it. 85 | return get.Fn(f, res, inst, sup.objType) 86 | } 87 | return res, nil 88 | } 89 | } 90 | } 91 | // Attribute not found on base classes so lookup the attr on the super 92 | // object itself. Most likely will AttributeError. 93 | return objectGetAttribute(f, o, name) 94 | } 95 | 96 | func initSuperType(map[string]*Object) { 97 | superType.slots.GetAttribute = &getAttributeSlot{superGetAttribute} 98 | superType.slots.Init = &initSlot{superInit} 99 | } 100 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/threading_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "testing" 19 | ) 20 | 21 | func TestRecursiveMutex(t *testing.T) { 22 | var m recursiveMutex 23 | f := NewRootFrame() 24 | m.Lock(f) 25 | m.Lock(f) 26 | m.Unlock(f) 27 | m.Unlock(f) 28 | } 29 | 30 | func TestRecursiveMutexUnlockedTooManyTimes(t *testing.T) { 31 | var m recursiveMutex 32 | f := NewRootFrame() 33 | m.Lock(f) 34 | m.Unlock(f) 35 | oldLogFatal := logFatal 36 | logFatal = func(msg string) { panic(msg) } 37 | defer func() { 38 | logFatal = oldLogFatal 39 | if e := recover(); e == nil { 40 | t.Error("Unlock didn't call logFatal") 41 | } 42 | }() 43 | m.Unlock(f) 44 | } 45 | 46 | func TestRecursiveMutexUnlockFrameMismatch(t *testing.T) { 47 | var m recursiveMutex 48 | m.Lock(NewRootFrame()) 49 | oldLogFatal := logFatal 50 | logFatal = func(msg string) { panic(msg) } 51 | defer func() { 52 | logFatal = oldLogFatal 53 | if e := recover(); e == nil { 54 | t.Error("Unlock didn't call logFatal") 55 | } 56 | }() 57 | m.Unlock(NewRootFrame()) 58 | } 59 | -------------------------------------------------------------------------------- /grumpy-runtime-src/runtime/traceback.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All Rights Reserved. 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | package grumpy 16 | 17 | import ( 18 | "reflect" 19 | ) 20 | 21 | // Traceback represents Python 'traceback' objects. 22 | type Traceback struct { 23 | Object 24 | frame *Frame `attr:"tb_frame"` 25 | next *Traceback `attr:"tb_next"` 26 | lineno int `attr:"tb_lineno"` 27 | } 28 | 29 | func newTraceback(f *Frame, next *Traceback) *Traceback { 30 | f.taken = true 31 | return &Traceback{Object{typ: TracebackType}, f, next, f.lineno} 32 | } 33 | 34 | func toTracebackUnsafe(o *Object) *Traceback { 35 | return (*Traceback)(o.toPointer()) 36 | } 37 | 38 | // ToObject upcasts f to an Object. 39 | func (f *Traceback) ToObject() *Object { 40 | return &f.Object 41 | } 42 | 43 | // TracebackType is the object representing the Python 'traceback' type. 44 | var TracebackType = newBasisType("traceback", reflect.TypeOf(Traceback{}), toTracebackUnsafe, ObjectType) 45 | 46 | func initTracebackType(map[string]*Object) { 47 | TracebackType.flags &^= typeFlagInstantiable | typeFlagBasetype 48 | } 49 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/assert_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # pylint: disable=g-equals-none 16 | 17 | assert object() 18 | assert True 19 | assert not False 20 | assert not None 21 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/assign_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # pylint: disable=unbalanced-tuple-unpacking 16 | 17 | 18 | class Foo(object): 19 | pass 20 | 21 | 22 | foo = 1 23 | assert foo == 1 24 | 25 | foo, bar = 2, 3 26 | assert foo == 2 27 | assert bar == 3 28 | 29 | (foo, bar), baz = (4, 5), 6 30 | assert foo == 4 31 | assert bar == 5 32 | assert baz == 6 33 | 34 | foo = [7, 8, 9] 35 | bar = foo 36 | assert bar == [7, 8, 9] 37 | 38 | try: 39 | bar, baz = foo 40 | except ValueError as e: 41 | assert str(e) == 'too many values to unpack' 42 | else: 43 | raise AssertionError('this was supposed to raise an exception') 44 | 45 | try: 46 | bar, baz, qux, quux = foo 47 | except ValueError as e: 48 | assert str(e) == 'need more than 3 values to unpack' 49 | else: 50 | raise AssertionError('this was supposed to raise an exception') 51 | 52 | foo = Foo() 53 | 54 | foo.bar = 1 55 | assert foo.bar == 1 56 | 57 | foo.bar, baz = 2, 3 58 | assert foo.bar == 2 59 | assert baz == 3 60 | 61 | foo.bar, (foo.baz, qux) = 4, (5, 6) 62 | assert foo.bar == 4 63 | assert foo.baz == 5 64 | assert qux == 6 65 | 66 | foo = bar = baz = 7 67 | assert foo == 7 68 | assert bar == 7 69 | assert baz == 7 70 | 71 | foo, bar = baz = 8, 9 72 | assert foo == 8 73 | assert bar == 9 74 | assert baz == (8, 9) 75 | 76 | foo = 1 77 | foo += 3 78 | assert foo == 4 79 | foo /= 2 80 | assert foo == 2 81 | foo *= 6 82 | assert foo == 12 83 | foo %= 5 84 | assert foo == 2 85 | foo -= 3 86 | assert foo == -1 87 | 88 | foo = [] 89 | bar = foo 90 | foo += ["bar", "baz"] 91 | assert foo == ["bar", "baz"] 92 | foo *= 2 93 | assert foo == ["bar", "baz", "bar", "baz"] 94 | assert bar is foo 95 | 96 | 97 | # Multiple target assignment should only evaluate rhs once. 98 | def foo(): # pylint: disable=function-redefined 99 | foo_ran[0] += 1 100 | return 'bar' 101 | 102 | 103 | foo_ran = [0] 104 | baz = qux = foo() 105 | assert baz == 'bar' 106 | assert qux == 'bar' 107 | assert foo_ran == [1] 108 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/class_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | 16 | class Foo(object): 17 | 18 | a = 3 19 | assert a == 3 20 | 21 | def bar(self): 22 | assert isinstance(self, Foo) 23 | return 'bar' 24 | 25 | baz = bar 26 | 27 | 28 | assert Foo.a == 3 29 | 30 | Foo.a = 4 31 | assert Foo.a == 4 32 | 33 | foo = Foo() 34 | assert isinstance(foo, Foo) 35 | assert foo.a == 4 36 | foo.a = 5 37 | assert foo.a == 5 38 | assert Foo.a == 4 39 | assert foo.bar() == 'bar' 40 | assert foo.baz() == 'bar' 41 | 42 | foo.b = 10 43 | del foo.b 44 | assert not hasattr(foo, 'b') 45 | try: 46 | del foo.b 47 | except AttributeError: 48 | pass 49 | else: 50 | raise AssertionError 51 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/compare_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | assert 1 < 100 16 | assert -10 <= "foo" 17 | assert "bar" <= "bar" 18 | assert (1, "a", 3) == (1, "a", 3) 19 | assert 15 != 16 20 | assert [] != None # pylint: disable=g-equals-none,g-explicit-bool-comparison 21 | assert int >= "az" 22 | assert "foo" >= "foo" 23 | assert True > False 24 | 25 | # Test rich comparisons. 26 | 27 | class RichCmp(object): 28 | def __init__(self, x): 29 | self.x = x 30 | self.lt_called = False 31 | self.le_called = False 32 | self.eq_called = False 33 | self.ge_called = False 34 | self.gt_called = False 35 | 36 | def __lt__(self, other): 37 | self.lt_called = True 38 | return self.x < other.x 39 | 40 | def __le__(self, other): 41 | self.le_called = True 42 | return self.x <= other.x 43 | 44 | def __eq__(self, other): 45 | self.eq_called = True 46 | return self.x == other.x 47 | 48 | def __ge__(self, other): 49 | self.ge_called = True 50 | return self.x >= other.x 51 | 52 | def __gt__(self, other): 53 | self.gt_called = True 54 | return self.x > other.x 55 | 56 | class Cmp(object): 57 | def __init__(self, x): 58 | self.cmp_called = False 59 | self.x = x 60 | 61 | def __cmp__(self, other): 62 | self.cmp_called = True 63 | return cmp(self.x, other.x) 64 | 65 | # Test that rich comparison methods are called. 66 | 67 | a, b = RichCmp(1), RichCmp(2) 68 | assert a < b 69 | assert a.lt_called 70 | 71 | a, b = RichCmp(1), RichCmp(2) 72 | assert a <= b 73 | assert a.le_called 74 | 75 | a, b = RichCmp(3), RichCmp(3) 76 | assert a == b 77 | assert a.eq_called 78 | 79 | a, b = RichCmp(5), RichCmp(4) 80 | assert a >= b 81 | assert a.ge_called 82 | 83 | a, b = RichCmp(5), RichCmp(4) 84 | assert a > b 85 | assert a.gt_called 86 | 87 | # Test rich comparison falling back to a 3-way comparison 88 | 89 | a, b = Cmp(1), Cmp(2) 90 | assert a < b 91 | assert a.cmp_called 92 | 93 | a, b = Cmp(1), Cmp(2) 94 | assert a <= b 95 | assert a.cmp_called 96 | 97 | a, b = Cmp(3), Cmp(3) 98 | assert a == b 99 | assert a.cmp_called 100 | 101 | a, b = Cmp(5), Cmp(4) 102 | assert a > b 103 | assert a.cmp_called 104 | 105 | a, b = Cmp(5), Cmp(4) 106 | assert a >= b 107 | assert a.cmp_called 108 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/comprehension_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import types 16 | 17 | 18 | assert isinstance((x for x in ()), types.GeneratorType) 19 | assert list(c for c in 'abc') == ['a', 'b', 'c'] 20 | assert [c for c in 'abc'] == ['a', 'b', 'c'] 21 | assert [i + j for i in range(2) for j in range(2)] == [0, 1, 1, 2] 22 | assert [c for c in 'foobar' if c in 'aeiou'] == ['o', 'o', 'a'] 23 | assert {i: str(i) for i in range(2)} == {0: '0', 1: '1'} 24 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/dict_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | import sys 15 | 16 | d = {'foo': 1, 'bar': 2, 'baz': 3} 17 | try: 18 | d['qux'] 19 | except KeyError: 20 | pass 21 | 22 | assert d['foo'] == 1 23 | assert d['bar'] == 2 24 | assert d['baz'] == 3 25 | 26 | d['qux'] = 4 27 | assert d['qux'] == 4 28 | 29 | d['foo'] = 5 30 | assert d['foo'] == 5 31 | 32 | l = [] 33 | for k in d: 34 | l.append(k) 35 | if hasattr(sys, "goversion"): 36 | assert l == ['foo', 'bar', 'baz', 'qux'] 37 | else: 38 | assert l == ['baz', 'foo', 'bar', 'qux'] 39 | 40 | try: 41 | for k in d: 42 | d['quux'] = 6 43 | except RuntimeError: 44 | pass 45 | else: 46 | raise AssertionError 47 | 48 | d = {'foo': 1, 'bar': 2, 'baz': 3} 49 | del d['bar'] 50 | assert d == {'foo': 1, 'baz': 3} 51 | try: 52 | del d['bar'] 53 | except KeyError: 54 | pass 55 | else: 56 | raise AssertionError 57 | 58 | # Test clear 59 | d = {1: 1, 2: 2, 3: 3} 60 | d.clear() 61 | assert d == {} 62 | 63 | try: 64 | d.clear() 65 | assert AssertionError 66 | except TypeError: 67 | pass 68 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/file_test.py: -------------------------------------------------------------------------------- 1 | f = open('/tmp/file_test__someunlikelyexistingfile', 'w') 2 | assert f.softspace == 0 3 | 4 | f.softspace = 1 5 | assert f.softspace == 1 6 | 7 | try: 8 | f.softspace = '4321' # should not be converted automatically 9 | except TypeError as e: 10 | if not str(e).endswith('is required'): 11 | raise e # Wrong exception arrived to us! 12 | else: 13 | raise RuntimeError('a TypeError should had raised.') 14 | 15 | assert f.softspace == 1 16 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/float_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | assert 5.5 == 5.5e0 16 | assert 5. == 5.0 17 | assert 0.5 == 5e-1 18 | assert 1e6 == 1000000.0 19 | assert 1E6 == 1e6 20 | assert -1E6 == -1e6 21 | assert 1E+6 == 1e6 22 | assert 1E-6 == 0.000001 23 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/for_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | l = [] 16 | for i in (1, 2, 3): 17 | l.append(i) 18 | assert l == [1, 2, 3] 19 | 20 | l = [] 21 | for i in (): 22 | l.append(1) 23 | else: # pylint: disable=useless-else-on-loop 24 | l.append(2) 25 | assert l == [2] 26 | 27 | l = [] 28 | for i in (1,): 29 | l.append(i) 30 | else: # pylint: disable=useless-else-on-loop 31 | l.append(2) 32 | assert l == [1, 2] 33 | 34 | l = [] 35 | for i in (1,): 36 | l.append(i) 37 | break 38 | else: 39 | l.append(2) 40 | assert l == [1] 41 | 42 | l = [] 43 | for i in (1, 2): 44 | l.append(i) 45 | continue 46 | l.append(3) # pylint: disable=unreachable 47 | assert l == [1, 2] 48 | 49 | l = [] 50 | for i, j in [('a', 1), ('b', 2)]: 51 | l.append(i) 52 | l.append(j) 53 | assert l == ['a', 1, 'b', 2] 54 | 55 | # break and continue statements in an else clause applies to the outer loop. 56 | # See: https://github.com/google/grumpy/issues/123 57 | l = [] 58 | for i in range(2): 59 | l.append(i) 60 | for j in range(10, 12): 61 | l.append(j) 62 | else: 63 | l.append(12) 64 | continue 65 | l.append(-1) 66 | assert l == [0, 10, 11, 12, 1, 10, 11, 12] 67 | 68 | l = [] 69 | for i in range(10): 70 | l.append(i) 71 | for j in range(10, 12): 72 | l.append(j) 73 | else: 74 | break 75 | l.append(-1) 76 | assert l == [0, 10, 11] 77 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/function_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # pylint: disable=no-value-for-parameter,function-redefined 16 | 17 | 18 | def foo(a): 19 | return {'a': a} 20 | 21 | 22 | assert foo(123) == {'a': 123} 23 | assert foo(a='apple') == {'a': 'apple'} 24 | assert foo(*('bar',)) == {'a': 'bar'} 25 | assert foo(**{'a': 42}) == {'a': 42} 26 | try: 27 | foo(b='bear') # pylint: disable=unexpected-keyword-arg 28 | raise AssertionError 29 | except TypeError as e: 30 | assert str(e) == "foo() got an unexpected keyword argument 'b'" 31 | try: 32 | foo() 33 | raise AssertionError 34 | except TypeError: 35 | pass 36 | try: 37 | foo(1, 2, 3) # pylint: disable=too-many-function-args 38 | raise AssertionError 39 | except TypeError: 40 | pass 41 | 42 | 43 | def foo(a, b): 44 | return {'a': a, 'b': b} 45 | 46 | 47 | assert foo(1, 2) == {'a': 1, 'b': 2} 48 | assert foo(1, b='bear') == {'a': 1, 'b': 'bear'} 49 | assert foo(b='bear', a='apple') == {'a': 'apple', 'b': 'bear'} 50 | try: 51 | foo(1, a='alpha') # pylint: disable=redundant-keyword-arg 52 | raise AssertionError 53 | except TypeError as e: 54 | assert str(e) == "foo() got multiple values for keyword argument 'a'" 55 | try: 56 | foo(**{123: 'bar'}) 57 | pass 58 | except TypeError: 59 | pass 60 | 61 | 62 | def foo(a, b=None): 63 | return {'a': a, 'b': b} 64 | 65 | 66 | assert foo(123) == {'a': 123, 'b': None} 67 | assert foo(123, 'bar') == {'a': 123, 'b': 'bar'} 68 | assert foo(a=123, b='bar') == {'a': 123, 'b': 'bar'} 69 | assert foo(*('apple',), **{'b': 'bear'}) == {'a': 'apple', 'b': 'bear'} 70 | 71 | 72 | def foo(a, *args): 73 | return {'a': a, 'args': args} 74 | 75 | 76 | assert foo(1) == {'a': 1, 'args': ()} 77 | assert foo(1, 2, 3) == {'a': 1, 'args': (2, 3)} 78 | 79 | 80 | def foo(a, **kwargs): 81 | return {'a': a, 'kwargs': kwargs} 82 | 83 | 84 | assert foo('bar') == {'a': 'bar', 'kwargs': {}} 85 | assert (foo(**{'a': 'apple', 'b': 'bear'}) == 86 | {'a': 'apple', 'kwargs': {'b': 'bear'}}) 87 | assert (foo('bar', b='baz', c='qux') == 88 | {'a': 'bar', 'kwargs': {'b': 'baz', 'c': 'qux'}}) 89 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/generator_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import types 16 | 17 | 18 | def gen1(): 19 | yield 1 20 | yield 2 21 | yield 3 22 | g = gen1() 23 | assert isinstance(g, types.GeneratorType) 24 | assert list(g) == [1, 2, 3] 25 | assert list(g) == [] # pylint: disable=g-explicit-bool-comparison 26 | 27 | 28 | def gen2(): 29 | for c in 'foobar': 30 | yield c 31 | yield '!' 32 | g = gen2() 33 | assert list(g) == ['f', 'o', 'o', 'b', 'a', 'r', '!'] 34 | assert list(g) == [] # pylint: disable=g-explicit-bool-comparison 35 | 36 | 37 | def gen3(): 38 | raise RuntimeError 39 | yield 1 # pylint: disable=unreachable 40 | g = gen3() 41 | try: 42 | g.next() 43 | except RuntimeError: 44 | pass 45 | assert list(g) == [] # pylint: disable=g-explicit-bool-comparison 46 | 47 | 48 | def gen4(): 49 | yield g.next() 50 | g = gen4() 51 | try: 52 | g.next() 53 | except ValueError as e: 54 | assert 'generator already executing' in str(e), str(e) 55 | else: 56 | raise AssertionError 57 | 58 | 59 | def gen5(): 60 | yield 61 | g = gen5() 62 | try: 63 | g.send('foo') 64 | except TypeError as e: 65 | assert "can't send non-None value to a just-started generator" in str(e) 66 | else: 67 | raise AssertionError 68 | 69 | 70 | def gen6(): 71 | yield 1 72 | return 73 | yield 2 74 | g = gen6() 75 | assert list(g) == [1] 76 | assert list(g) == [] 77 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/getopt_test.py: -------------------------------------------------------------------------------- 1 | import getopt 2 | 3 | args = '-a -b -cfoo -d bar a1 a2'.split() 4 | optlist, args = getopt.getopt(args, 'abc:d:') 5 | assert optlist == [('-a', ''), ('-b', ''), ('-c', 'foo'), ('-d', 'bar')] 6 | 7 | # TODO: str.index has to be implemented 8 | # s = '--condition=foo --testing --output-file abc.def -x a1 a2' 9 | # args = s.split() 10 | # optlist, args = getopt.getopt( 11 | # args, 'x', ['condition=', 'output-file=', 'testing']) 12 | 13 | # assert optlist == [('--condition', 'foo'), ('--testing', ''), 14 | # ('--output-file', 'abc.def'), ('-x', '')] 15 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/global_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # pylint: disable=g-wrong-blank-lines,global-variable-not-assigned,invalid-name,redefined-outer-name,unused-variable 16 | 17 | x = 123 18 | def f1(): 19 | global x 20 | x = 'abc' 21 | f1() 22 | assert x == 'abc' 23 | 24 | 25 | x = 'foo' 26 | def f2(): 27 | global x 28 | class x(object): 29 | pass 30 | f2() 31 | assert isinstance(x, type) 32 | assert x.__name__ == 'x' 33 | 34 | 35 | x = 3.14 36 | class C1(object): 37 | global x 38 | x = 'foo' 39 | assert x == 'foo' 40 | 41 | 42 | x = 42 43 | def f3(): 44 | global x 45 | del x 46 | f3() 47 | try: 48 | print x 49 | raise AssertionError 50 | except NameError: 51 | pass 52 | 53 | 54 | x = 'foo' 55 | def f4(): 56 | x = 'bar' 57 | def g(): 58 | global x 59 | def h(): 60 | return x 61 | return h() 62 | return g() 63 | assert f4() == 'foo' 64 | 65 | 66 | x = 3.14 67 | def f5(): 68 | x = 'foo' 69 | class C(object): 70 | global x 71 | y = x 72 | return C.y 73 | assert f5() == 3.14 74 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/if_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # pylint: disable=using-constant-test 16 | 17 | foo = [] 18 | if True: 19 | foo.append(1) 20 | else: 21 | foo.append(2) 22 | assert foo == [1] 23 | 24 | foo = [] 25 | if False: 26 | foo.append(1) 27 | else: 28 | foo.append(2) 29 | assert foo == [2] 30 | 31 | foo = [] 32 | if False: 33 | foo.append(1) 34 | elif False: 35 | foo.append(2) 36 | elif True: 37 | foo.append(3) 38 | assert foo == [3] 39 | 40 | foo = [] 41 | if False: 42 | foo.append(1) 43 | elif True: 44 | foo.append(2) 45 | elif True: 46 | foo.append(3) 47 | else: 48 | foo.append(4) 49 | assert foo == [2] 50 | 51 | foo = [] 52 | if False: 53 | foo.append(1) 54 | elif False: 55 | foo.append(2) 56 | elif False: 57 | foo.append(3) 58 | else: 59 | foo.append(4) 60 | assert foo == [4] 61 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/import_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import sys 16 | 17 | print sys.maxint 18 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/list_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | a = [0, 1, 2, 3] 16 | b = list(a) 17 | assert a == b 18 | assert a is not b 19 | assert list(()) == [] 20 | assert list((0, 1, 2, 3)) == [0, 1, 2, 3] 21 | assert list('') == [] 22 | assert list('spam') == ['s', 'p', 'a', 'm'] 23 | 24 | assert [] is not True 25 | assert [42] 26 | 27 | assert [] is not [] 28 | 29 | assert len([]) == 0 30 | assert len([0]) == 1 31 | assert len([0, 1, 2]) == 3 32 | 33 | a = [3, 2, 4, 1] 34 | b = [] 35 | c = ["a", "e", "c", "b"] 36 | 37 | a.sort() 38 | assert a == [1, 2, 3, 4] 39 | b.sort() 40 | assert b == [] 41 | c.sort() 42 | assert c == ["a", "b", "c", "e"] 43 | 44 | # Test pop 45 | a = [-1, 0, 1] 46 | assert a.pop() == 1 47 | assert a == [-1, 0] 48 | assert a == [-1, 0] 49 | assert a.pop(0) == -1 50 | assert a == [0] 51 | try: 52 | a.pop(5) 53 | assert False, "Exception: 'pop index out of range' was not raised" 54 | except IndexError: 55 | pass 56 | assert a.pop(0) == 0 57 | assert a == [] 58 | try: 59 | a.pop() 60 | assert False, "Exception: 'pop from empty list' was not raised" 61 | except IndexError: 62 | pass 63 | try: 64 | a.pop(42, 42) 65 | assert False, "Exception: 'pop takes at most 1 argument' was not raised" 66 | except TypeError: 67 | pass 68 | a = [-1, 0, 1] 69 | assert a.pop(1) == 0 70 | assert a == [-1, 1] 71 | 72 | # Test extend 73 | a = aa = [3, 2, 4, 1] 74 | b = bb = [] 75 | c = cc = ["a", "e", "c", "b"] 76 | a.extend(b) 77 | assert a == [3, 2, 4, 1] 78 | assert a == aa 79 | assert a is aa 80 | b.extend(c) 81 | assert b == ["a", "e", "c", "b"] 82 | assert b is bb 83 | a.extend(tuple()) 84 | assert a == [3, 2, 4, 1] 85 | a.extend((6, 7)) 86 | assert a == [3, 2, 4, 1, 6, 7] 87 | a.extend(range(3)) 88 | assert a == [3, 2, 4, 1, 6, 7, 0, 1, 2] 89 | 90 | try: 91 | a.extend() 92 | assert False, "Exception: 'extend() takes exactly one argument' was not raised" 93 | except TypeError: 94 | pass 95 | 96 | try: 97 | a.extend([], []) 98 | assert False, "Exception: 'extend() takes exactly one argument' was not raised" 99 | except TypeError: 100 | pass 101 | 102 | # Test count 103 | assert [].count(0) == 0 104 | assert [1, 2, 3].count(2) == 1 105 | assert ["a", "b", "a", "a"].count("a") == 3 106 | assert ([2] * 20).count(2) == 20 107 | 108 | try: 109 | [].count() 110 | assert False, "Exception: 'count() takes exactly one argument' was not raised" 111 | except TypeError: 112 | pass 113 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/native_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # pylint: disable=g-multiple-import 16 | 17 | from '__go__/math' import MaxInt32, Pow10, Signbit 18 | from '__go__/strings' import Count, IndexAny, Repeat 19 | from '__go__/encoding/csv' import NewReader as NewCSVReader 20 | from '__go__/image' import Pt 21 | from '__go__/strings' import NewReader as NewStringReader 22 | 23 | assert Count('foo,bar,baz', ',') == 2 24 | assert IndexAny('foobar', 'obr') == 1 25 | assert Repeat('foo', 3) == 'foofoofoo' 26 | assert MaxInt32 == 2147483647 27 | assert Pow10(2.0) == 100.0 28 | assert Signbit(-42.0) == True # pylint: disable=g-explicit-bool-comparison 29 | 30 | # Can access field on unreferenced struct (Pt returns an image.Point struct) 31 | assert Pt(1, 0).X == 1 32 | 33 | # Can access field on pointer to struct (NewCSVReader returns a pointer to a 34 | # csv.Reader struct) 35 | assert NewCSVReader(NewStringReader("foo")).LazyQuotes == False 36 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/op_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Arithmetic and boolean operator tests.""" 16 | 17 | import math 18 | 19 | import weetest 20 | 21 | 22 | def TestBoolOps(): 23 | assert ('foo' or 'bar') == 'foo' 24 | assert ('' or 123) == 123 25 | assert (0 and 3.14) == 0 26 | assert (True and False) is False 27 | assert (0 or 'a' and 'b') == 'b' 28 | assert (1 and 'a' or 'b') == 'a' 29 | 30 | 31 | def TestBoolOpsLazyEval(): 32 | def Yes(): 33 | ran.append('Yes') 34 | return True 35 | 36 | def No(): 37 | ran.append('No') 38 | return False 39 | 40 | ran = [] 41 | assert Yes() or No() 42 | assert ran == ['Yes'] 43 | 44 | ran = [] 45 | assert not (Yes() and Yes() and No()) 46 | assert ran == ['Yes', 'Yes', 'No'] 47 | 48 | ran = [] 49 | assert not (Yes() and No() and Yes()) 50 | assert ran == ['Yes', 'No'] 51 | 52 | ran = [] 53 | assert No() or No() or Yes() 54 | assert ran == ['No', 'No', 'Yes'] 55 | 56 | ran = [] 57 | assert Yes() or Yes() or Yes() 58 | assert ran == ['Yes'] 59 | 60 | 61 | def TestNeg(): 62 | x = 12 63 | assert -x == -12 64 | 65 | x = 1.1 66 | assert -x == -1.1 67 | 68 | x = 0.0 69 | assert -x == -0.0 70 | 71 | x = float('inf') 72 | assert math.isinf(-x) 73 | 74 | x = -float('inf') 75 | assert math.isinf(-x) 76 | 77 | x = float('nan') 78 | assert math.isnan(-x) 79 | 80 | x = long(100) 81 | assert -x == -100 82 | 83 | 84 | def TestPos(): 85 | x = 12 86 | assert +x == 12 87 | 88 | x = 1.1 89 | assert +x == 1.1 90 | 91 | x = 0.0 92 | assert +x == 0.0 93 | 94 | x = float('inf') 95 | assert math.isinf(+x) 96 | 97 | x = +float('inf') 98 | assert math.isinf(+x) 99 | 100 | x = float('nan') 101 | assert math.isnan(+x) 102 | 103 | x = long(100) 104 | assert +x == 100 105 | 106 | 107 | if __name__ == '__main__': 108 | weetest.RunTests() 109 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/pow_test.py: -------------------------------------------------------------------------------- 1 | # 2 | # Licensed under the Apache License, Version 2.0 (the "License"); 3 | # you may not use this file except in compliance with the License. 4 | # You may obtain a copy of the License at 5 | # 6 | # http://www.apache.org/licenses/LICENSE-2.0 7 | # 8 | # Unless required by applicable law or agreed to in writing, software 9 | # distributed under the License is distributed on an "AS IS" BASIS, 10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 | # See the License for the specific language governing permissions and 12 | # limitations under the License. 13 | 14 | assert 2.0 ** -2 == 0.25, "2.0 ** -2" 15 | assert 2.0 ** -1 == 0.5, "2.0 ** -1" 16 | assert 2.0 ** 0 == 1, "2.0 ** 0" 17 | assert 2.0 ** 1 == 2, "2.0 ** 1" 18 | assert 2.0 ** 2 == 4, "2.0 ** 2" 19 | 20 | assert (-2.0) ** -2 == 0.25, "(-2.0) ** -2" 21 | assert (-2.0) ** -1 == -0.5, "(-2.0) ** -1" 22 | assert (-2.0) ** 0 == 1, "(-2.0) ** 0" 23 | assert (-2.0) ** 1 == -2, "(-2.0) ** 1" 24 | assert (-2.0) ** 2 == 4, "(-2.0) ** 2" 25 | 26 | assert 2 ** -2 == 0.25, "2 ** -2" 27 | assert 2 ** -1 == 0.5, "2 ** -1" 28 | assert 2 ** 0 == 1, "2 ** 0" 29 | assert 2 ** 1 == 2, "2 ** 1" 30 | assert 2 ** 2 == 4, "2 ** 2" 31 | 32 | assert 2L ** -2 == 0.25, "2L ** -2" 33 | assert 2L ** -1 == 0.5, "2L ** -1" 34 | assert 2L ** 0 == 1, "2L ** 0" 35 | assert 2L ** 1 == 2, "2L ** 1" 36 | assert 2L ** 2 == 4, "2L ** 2" 37 | 38 | # Test the rpow operator on long 39 | assert 2 ** -2L == 0.25, "2 ** -2L" 40 | assert 2 ** -1L == 0.5, "2 ** -1L" 41 | assert 2 ** 0L == 1, "2 ** 0L" 42 | assert 2 ** 1L == 2, "2 ** 1L" 43 | assert 2 ** 2L == 4, "2 ** 2L" 44 | 45 | for zero in (0, 0L, 0.0): 46 | try: 47 | result = zero ** -2 48 | assert "0 ** -2" 49 | except ZeroDivisionError: 50 | pass 51 | 52 | try: 53 | result = zero ** -1 54 | assert "0 ** -1" 55 | except ZeroDivisionError: 56 | pass 57 | 58 | assert zero ** 0 == 1, '0 ** 0' 59 | assert zero ** 1 == 0, '0 ** 1' 60 | assert zero ** 2 == 0, '0 ** 2' 61 | 62 | assert 2 ** zero == 1 63 | assert (-2.0) ** zero == 1 64 | assert 3L ** zero == 1 65 | 66 | assert (-2) ** -2 == 0.25, '(-2) ** -2' 67 | assert (-2) ** -1 == -0.5, '(-2) ** -1' 68 | assert (-2) ** 0 == 1, '(-2) ** 0' 69 | assert (-2) ** 1 == -2, '(-2) ** 1' 70 | assert (-2) ** 2 == 4, '(-2) ** 2' 71 | 72 | assert 2 ** 128 == 340282366920938463463374607431768211456, "2 ** 128" 73 | 74 | # chose something which can be represented exact as an IEEE floating point number 75 | large_number = (2 ** 128 + 2 ** 127) 76 | 77 | assert large_number ** -1 == (1.0 / large_number), "large_number ** -1 == (1.0 / large_number)" 78 | assert large_number ** 0 == 1, "large_number ** 0 == 1" 79 | assert large_number ** 1 == large_number, "large_number ** 1 == large_number" 80 | 81 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/scope_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # pylint: disable=redefined-outer-name 16 | 17 | x = 'foo' 18 | y = 'wut' 19 | assert x == 'foo' 20 | assert y == 'wut' 21 | 22 | 23 | def f(): 24 | x = 'bar' 25 | z = 'baz' 26 | assert x == 'bar' 27 | assert y == 'wut' 28 | assert z == 'baz' 29 | def g(arg): 30 | x = 'qux' 31 | assert x == 'qux' 32 | assert y == 'wut' 33 | assert z == 'baz' 34 | assert arg == 'quux' 35 | arg = None 36 | g('quux') 37 | 38 | 39 | f() 40 | 41 | 42 | # Delete a local var. 43 | def g(): 44 | foo = 'bar' 45 | del foo 46 | try: 47 | foo 48 | except UnboundLocalError: 49 | pass 50 | else: 51 | raise AssertionError 52 | 53 | 54 | g() 55 | 56 | 57 | # Delete a global. 58 | foo = 'bar' 59 | del foo 60 | try: 61 | foo 62 | except NameError: 63 | pass 64 | else: 65 | raise AssertionError 66 | 67 | 68 | # Delete a class var. 69 | class Foo(object): 70 | foo = 'bar' 71 | del foo 72 | try: 73 | foo 74 | except NameError: 75 | pass 76 | else: 77 | raise AssertionError 78 | -------------------------------------------------------------------------------- /grumpy-runtime-src/testing/struct_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | import _struct as struct 16 | 17 | # struct test 18 | A = 0x67452301 19 | B = 0xefcdab89 20 | C = 0x98badcfe 21 | D = 0x10325476 22 | 23 | expected = '\x01#Eg\x89\xab\xcd\xef\xfe\xdc\xba\x98vT2\x10' 24 | 25 | assert struct.pack(" x. So if x already appears in the list, a.insert(x) will 29 | insert just after the rightmost x already there. 30 | 31 | Optional args lo (default 0) and hi (default len(a)) bound the 32 | slice of a to be searched. 33 | """ 34 | 35 | if lo < 0: 36 | raise ValueError('lo must be non-negative') 37 | if hi is None: 38 | hi = len(a) 39 | while lo < hi: 40 | mid = (lo+hi)//2 41 | if x < a[mid]: hi = mid 42 | else: lo = mid+1 43 | return lo 44 | 45 | bisect = bisect_right # backward compatibility 46 | 47 | def insort_left(a, x, lo=0, hi=None): 48 | """Insert item x in list a, and keep it sorted assuming a is sorted. 49 | 50 | If x is already in a, insert it to the left of the leftmost x. 51 | 52 | Optional args lo (default 0) and hi (default len(a)) bound the 53 | slice of a to be searched. 54 | """ 55 | 56 | if lo < 0: 57 | raise ValueError('lo must be non-negative') 58 | if hi is None: 59 | hi = len(a) 60 | while lo < hi: 61 | mid = (lo+hi)//2 62 | if a[mid] < x: lo = mid+1 63 | else: hi = mid 64 | a.insert(lo, x) 65 | 66 | 67 | def bisect_left(a, x, lo=0, hi=None): 68 | """Return the index where to insert item x in list a, assuming a is sorted. 69 | 70 | The return value i is such that all e in a[:i] have e < x, and all e in 71 | a[i:] have e >= x. So if x already appears in the list, a.insert(x) will 72 | insert just before the leftmost x already there. 73 | 74 | Optional args lo (default 0) and hi (default len(a)) bound the 75 | slice of a to be searched. 76 | """ 77 | 78 | if lo < 0: 79 | raise ValueError('lo must be non-negative') 80 | if hi is None: 81 | hi = len(a) 82 | while lo < hi: 83 | mid = (lo+hi)//2 84 | if a[mid] < x: lo = mid+1 85 | else: hi = mid 86 | return lo 87 | 88 | # Overwrite above definitions with a fast C implementation 89 | # try: 90 | # from _bisect import * 91 | # except ImportError: 92 | # pass 93 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/dircache.py: -------------------------------------------------------------------------------- 1 | """Read and cache directory listings. 2 | 3 | The listdir() routine returns a sorted list of the files in a directory, 4 | using a cache to avoid reading the directory more often than necessary. 5 | The annotate() routine appends slashes to directories.""" 6 | from warnings import warnpy3k 7 | warnpy3k("the dircache module has been removed in Python 3.0", stacklevel=2) 8 | del warnpy3k 9 | 10 | import os 11 | 12 | __all__ = ["listdir", "opendir", "annotate", "reset"] 13 | 14 | cache = {} 15 | 16 | def reset(): 17 | """Reset the cache completely.""" 18 | global cache 19 | cache = {} 20 | 21 | def listdir(path): 22 | """List directory contents, using cache.""" 23 | try: 24 | cached_mtime, list = cache[path] 25 | del cache[path] 26 | except KeyError: 27 | cached_mtime, list = -1, [] 28 | mtime = os.stat(path).st_mtime 29 | if mtime != cached_mtime: 30 | list = os.listdir(path) 31 | list.sort() 32 | cache[path] = mtime, list 33 | return list 34 | 35 | opendir = listdir # XXX backward compatibility 36 | 37 | def annotate(head, list): 38 | """Add '/' suffixes to directories.""" 39 | for i in range(len(list)): 40 | if os.path.isdir(os.path.join(head, list[i])): 41 | list[i] = list[i] + '/' 42 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/heapq.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grumpyhome/grumpy/7b775405bdf1694c2fb24cde7efc891283fa4354/grumpy-runtime-src/third_party/stdlib/heapq.py -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/json_scanner.py: -------------------------------------------------------------------------------- 1 | """JSON token scanner 2 | """ 3 | import re 4 | # try: 5 | # from _json import make_scanner as c_make_scanner 6 | # except ImportError: 7 | # c_make_scanner = None 8 | c_make_scanner = None 9 | 10 | __all__ = ['make_scanner'] 11 | 12 | NUMBER_RE = re.compile( 13 | r'(-?(?:0|[1-9]\d*))(\.\d+)?([eE][-+]?\d+)?', 14 | (re.VERBOSE | re.MULTILINE | re.DOTALL)) 15 | 16 | def py_make_scanner(context): 17 | parse_object = context.parse_object 18 | parse_array = context.parse_array 19 | parse_string = context.parse_string 20 | match_number = NUMBER_RE.match 21 | encoding = context.encoding 22 | strict = context.strict 23 | parse_float = context.parse_float 24 | parse_int = context.parse_int 25 | parse_constant = context.parse_constant 26 | object_hook = context.object_hook 27 | object_pairs_hook = context.object_pairs_hook 28 | 29 | def _scan_once(string, idx): 30 | try: 31 | nextchar = string[idx] 32 | except IndexError: 33 | raise StopIteration 34 | 35 | if nextchar == '"': 36 | return parse_string(string, idx + 1, encoding, strict) 37 | elif nextchar == '{': 38 | return parse_object((string, idx + 1), encoding, strict, 39 | _scan_once, object_hook, object_pairs_hook) 40 | elif nextchar == '[': 41 | return parse_array((string, idx + 1), _scan_once) 42 | elif nextchar == 'n' and string[idx:idx + 4] == 'null': 43 | return None, idx + 4 44 | elif nextchar == 't' and string[idx:idx + 4] == 'true': 45 | return True, idx + 4 46 | elif nextchar == 'f' and string[idx:idx + 5] == 'false': 47 | return False, idx + 5 48 | 49 | m = match_number(string, idx) 50 | if m is not None: 51 | integer, frac, exp = m.groups() 52 | if frac or exp: 53 | res = parse_float(integer + (frac or '') + (exp or '')) 54 | else: 55 | res = parse_int(integer) 56 | return res, m.end() 57 | elif nextchar == 'N' and string[idx:idx + 3] == 'NaN': 58 | return parse_constant('NaN'), idx + 3 59 | elif nextchar == 'I' and string[idx:idx + 8] == 'Infinity': 60 | return parse_constant('Infinity'), idx + 8 61 | elif nextchar == '-' and string[idx:idx + 9] == '-Infinity': 62 | return parse_constant('-Infinity'), idx + 9 63 | else: 64 | raise StopIteration 65 | 66 | return _scan_once 67 | 68 | make_scanner = c_make_scanner or py_make_scanner 69 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/keyword.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | """Keywords (from "graminit.c") 4 | 5 | This file is automatically generated; please don't muck it up! 6 | 7 | To update the symbols in this file, 'cd' to the top directory of 8 | the python source tree after building the interpreter and run: 9 | 10 | ./python Lib/keyword.py 11 | """ 12 | 13 | __all__ = ["iskeyword", "kwlist"] 14 | 15 | kwlist = [ 16 | #--start keywords-- 17 | 'and', 18 | 'as', 19 | 'assert', 20 | 'break', 21 | 'class', 22 | 'continue', 23 | 'def', 24 | 'del', 25 | 'elif', 26 | 'else', 27 | 'except', 28 | 'exec', 29 | 'finally', 30 | 'for', 31 | 'from', 32 | 'global', 33 | 'if', 34 | 'import', 35 | 'in', 36 | 'is', 37 | 'lambda', 38 | 'not', 39 | 'or', 40 | 'pass', 41 | 'print', 42 | 'raise', 43 | 'return', 44 | 'try', 45 | 'while', 46 | 'with', 47 | 'yield', 48 | #--end keywords-- 49 | ] 50 | 51 | iskeyword = frozenset(kwlist).__contains__ 52 | 53 | def main(): 54 | import sys, re 55 | 56 | args = sys.argv[1:] 57 | iptfile = args and args[0] or "Python/graminit.c" 58 | if len(args) > 1: optfile = args[1] 59 | else: optfile = "Lib/keyword.py" 60 | 61 | # scan the source file for keywords 62 | fp = open(iptfile) 63 | strprog = re.compile('"([^"]+)"') 64 | lines = [] 65 | for line in fp: 66 | if '{1, "' in line: 67 | match = strprog.search(line) 68 | if match: 69 | lines.append(" '" + match.group(1) + "',\n") 70 | fp.close() 71 | lines.sort() 72 | 73 | # load the output skeleton from the target 74 | fp = open(optfile) 75 | format = fp.readlines() 76 | fp.close() 77 | 78 | # insert the lines of keywords 79 | try: 80 | start = format.index("#--start keywords--\n") + 1 81 | end = format.index("#--end keywords--\n") 82 | format[start:end] = lines 83 | except ValueError: 84 | sys.stderr.write("target does not contain format markers\n") 85 | sys.exit(1) 86 | 87 | # write the output file 88 | fp = open(optfile, 'w') 89 | fp.write(''.join(format)) 90 | fp.close() 91 | 92 | if __name__ == "__main__": 93 | main() 94 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/md5.py: -------------------------------------------------------------------------------- 1 | # $Id$ 2 | # 3 | # Copyright (C) 2005 Gregory P. Smith (greg@krypto.org) 4 | # Licensed to PSF under a Contributor Agreement. 5 | 6 | # import warnings 7 | # warnings.warn("the md5 module is deprecated; use hashlib instead", 8 | # DeprecationWarning, 2) 9 | 10 | # from hashlib import md5 11 | import _md5 12 | 13 | new = _md5.new 14 | md5 = _md5.new 15 | digest_size = 16 16 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/mutex.py: -------------------------------------------------------------------------------- 1 | """Mutual exclusion -- for use with module sched 2 | 3 | A mutex has two pieces of state -- a 'locked' bit and a queue. 4 | When the mutex is not locked, the queue is empty. 5 | Otherwise, the queue contains 0 or more (function, argument) pairs 6 | representing functions (or methods) waiting to acquire the lock. 7 | When the mutex is unlocked while the queue is not empty, 8 | the first queue entry is removed and its function(argument) pair called, 9 | implying it now has the lock. 10 | 11 | Of course, no multi-threading is implied -- hence the funny interface 12 | for lock, where a function is called once the lock is acquired. 13 | """ 14 | from warnings import warnpy3k 15 | warnpy3k("the mutex module has been removed in Python 3.0", stacklevel=2) 16 | del warnpy3k 17 | 18 | from collections import deque 19 | 20 | class mutex(object): 21 | def __init__(self): 22 | """Create a new mutex -- initially unlocked.""" 23 | self.locked = False 24 | self.queue = deque() 25 | 26 | def test(self): 27 | """Test the locked bit of the mutex.""" 28 | return self.locked 29 | 30 | def testandset(self): 31 | """Atomic test-and-set -- grab the lock if it is not set, 32 | return True if it succeeded.""" 33 | if not self.locked: 34 | self.locked = True 35 | return True 36 | else: 37 | return False 38 | 39 | def lock(self, function, argument): 40 | """Lock a mutex, call the function with supplied argument 41 | when it is acquired. If the mutex is already locked, place 42 | function and argument in the queue.""" 43 | if self.testandset(): 44 | function(argument) 45 | else: 46 | self.queue.append((function, argument)) 47 | 48 | def unlock(self): 49 | """Unlock a mutex. If the queue is not empty, call the next 50 | function with its argument.""" 51 | if self.queue: 52 | function, argument = self.queue.popleft() 53 | function(argument) 54 | else: 55 | self.locked = False 56 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/sha.py: -------------------------------------------------------------------------------- 1 | # $Id$ 2 | # 3 | # Copyright (C) 2005 Gregory P. Smith (greg@krypto.org) 4 | # Licensed to PSF under a Contributor Agreement. 5 | 6 | # import warnings 7 | # warnings.warn("the sha module is deprecated; use the hashlib module instead", 8 | # DeprecationWarning, 2) 9 | 10 | import _sha 11 | 12 | sha = _sha.new 13 | new = _sha.new 14 | 15 | blocksize = 1 # legacy value (wrong in any useful sense) 16 | digest_size = 20 17 | digestsize = 20 18 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/test/__init__.py: -------------------------------------------------------------------------------- 1 | # Dummy file to make this directory a package. 2 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/test/test_dircache.py: -------------------------------------------------------------------------------- 1 | """ 2 | Test cases for the dircache module 3 | Nick Mathewson 4 | """ 5 | 6 | import unittest 7 | from test.test_support import run_unittest # , import_module 8 | # dircache = import_module('dircache', deprecated=True) 9 | import dircache 10 | import os, time, sys, tempfile 11 | 12 | 13 | class DircacheTests(unittest.TestCase): 14 | def setUp(self): 15 | self.tempdir = tempfile.mkdtemp() 16 | 17 | def tearDown(self): 18 | for fname in os.listdir(self.tempdir): 19 | self.delTemp(fname) 20 | os.rmdir(self.tempdir) 21 | 22 | def writeTemp(self, fname): 23 | f = open(os.path.join(self.tempdir, fname), 'w') 24 | f.close() 25 | 26 | def mkdirTemp(self, fname): 27 | os.mkdir(os.path.join(self.tempdir, fname)) 28 | 29 | def delTemp(self, fname): 30 | fname = os.path.join(self.tempdir, fname) 31 | if os.path.isdir(fname): 32 | os.rmdir(fname) 33 | else: 34 | os.unlink(fname) 35 | 36 | def test_listdir(self): 37 | ## SUCCESSFUL CASES 38 | entries = dircache.listdir(self.tempdir) 39 | self.assertEqual(entries, []) 40 | 41 | # Check that cache is actually caching, not just passing through. 42 | self.assertTrue(dircache.listdir(self.tempdir) is entries) 43 | 44 | # Directories aren't "files" on Windows, and directory mtime has 45 | # nothing to do with when files under a directory get created. 46 | # That is, this test can't possibly work under Windows -- dircache 47 | # is only good for capturing a one-shot snapshot there. 48 | 49 | if sys.platform[:3] not in ('win', 'os2'): 50 | # Sadly, dircache has the same granularity as stat.mtime, and so 51 | # can't notice any changes that occurred within 1 sec of the last 52 | # time it examined a directory. 53 | time.sleep(1) 54 | self.writeTemp("test1") 55 | entries = dircache.listdir(self.tempdir) 56 | self.assertEqual(entries, ['test1']) 57 | self.assertTrue(dircache.listdir(self.tempdir) is entries) 58 | 59 | ## UNSUCCESSFUL CASES 60 | self.assertRaises(OSError, dircache.listdir, self.tempdir+"_nonexistent") 61 | 62 | def test_annotate(self): 63 | self.writeTemp("test2") 64 | self.mkdirTemp("A") 65 | lst = ['A', 'test2', 'test_nonexistent'] 66 | dircache.annotate(self.tempdir, lst) 67 | self.assertEqual(lst, ['A/', 'test2', 'test_nonexistent']) 68 | 69 | 70 | def test_main(): 71 | try: 72 | run_unittest(DircacheTests) 73 | finally: 74 | dircache.reset() 75 | 76 | 77 | if __name__ == "__main__": 78 | test_main() 79 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/test/test_fpformat.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Tests for fpformat module 3 | Nick Mathewson 4 | ''' 5 | from test.test_support import run_unittest #, import_module 6 | import unittest 7 | # fpformat = import_module('fpformat', deprecated=True) 8 | import fpformat 9 | fix, sci, NotANumber = fpformat.fix, fpformat.sci, fpformat.NotANumber 10 | 11 | StringType = type('') 12 | 13 | # Test the old and obsolescent fpformat module. 14 | # 15 | # (It's obsolescent because fix(n,d) == "%.*f"%(d,n) and 16 | # sci(n,d) == "%.*e"%(d,n) 17 | # for all reasonable numeric n and d, except that sci gives 3 exponent 18 | # digits instead of 2. 19 | # 20 | # Differences only occur for unreasonable n and d. <.2 wink>) 21 | 22 | class FpformatTest(unittest.TestCase): 23 | 24 | def checkFix(self, n, digits): 25 | result = fix(n, digits) 26 | if isinstance(n, StringType): 27 | n = repr(n) 28 | expected = "%.*f" % (digits, float(n)) 29 | 30 | self.assertEqual(result, expected) 31 | 32 | def checkSci(self, n, digits): 33 | result = sci(n, digits) 34 | if isinstance(n, StringType): 35 | n = repr(n) 36 | expected = "%.*e" % (digits, float(n)) 37 | # add the extra 0 if needed 38 | num, exp = expected.split("e") 39 | if len(exp) < 4: 40 | exp = exp[0] + "0" + exp[1:] 41 | expected = "%se%s" % (num, exp) 42 | 43 | self.assertEqual(result, expected) 44 | 45 | def test_basic_cases(self): 46 | self.assertEqual(fix(100.0/3, 3), '33.333') 47 | self.assertEqual(sci(100.0/3, 3), '3.333e+001') 48 | 49 | @unittest.skip('grumpy') 50 | def test_reasonable_values(self): 51 | for d in range(7): 52 | for val in (1000.0/3, 1000, 1000.0, .002, 1.0/3, 1e10): 53 | for realVal in (val, 1.0/val, -val, -1.0/val): 54 | self.checkFix(realVal, d) 55 | self.checkSci(realVal, d) 56 | 57 | def test_failing_values(self): 58 | # Now for 'unreasonable n and d' 59 | self.assertEqual(fix(1.0, 1000), '1.'+('0'*1000)) 60 | self.assertEqual(sci("1"+('0'*1000), 0), '1e+1000') 61 | 62 | # This behavior is inconsistent. sci raises an exception; fix doesn't. 63 | yacht = "Throatwobbler Mangrove" 64 | self.assertEqual(fix(yacht, 10), yacht) 65 | try: 66 | sci(yacht, 10) 67 | except NotANumber: 68 | pass 69 | else: 70 | self.fail("No exception on non-numeric sci") 71 | 72 | 73 | def test_main(): 74 | run_unittest(FpformatTest) 75 | 76 | 77 | if __name__ == "__main__": 78 | test_main() 79 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/test/test_list.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import unittest 3 | from test import test_support, list_tests 4 | 5 | class ListTest(list_tests.CommonTest): 6 | type2test = list 7 | 8 | def test_basic(self): 9 | self.assertEqual(list([]), []) 10 | l0_3 = [0, 1, 2, 3] 11 | l0_3_bis = list(l0_3) 12 | self.assertEqual(l0_3, l0_3_bis) 13 | self.assertTrue(l0_3 is not l0_3_bis) 14 | self.assertEqual(list(()), []) 15 | self.assertEqual(list((0, 1, 2, 3)), [0, 1, 2, 3]) 16 | self.assertEqual(list(''), []) 17 | self.assertEqual(list('spam'), ['s', 'p', 'a', 'm']) 18 | 19 | if sys.maxsize == 0x7fffffff: 20 | # This test can currently only work on 32-bit machines. 21 | # XXX If/when PySequence_Length() returns a ssize_t, it should be 22 | # XXX re-enabled. 23 | # Verify clearing of bug #556025. 24 | # This assumes that the max data size (sys.maxint) == max 25 | # address size this also assumes that the address size is at 26 | # least 4 bytes with 8 byte addresses, the bug is not well 27 | # tested 28 | # 29 | # Note: This test is expected to SEGV under Cygwin 1.3.12 or 30 | # earlier due to a newlib bug. See the following mailing list 31 | # thread for the details: 32 | 33 | # http://sources.redhat.com/ml/newlib/2002/msg00369.html 34 | self.assertRaises(MemoryError, list, xrange(sys.maxint // 2)) 35 | 36 | # This code used to segfault in Py2.4a3 37 | x = [] 38 | x.extend(-y for y in x) 39 | self.assertEqual(x, []) 40 | 41 | def test_truth(self): 42 | super(ListTest, self).test_truth() 43 | self.assertTrue(not []) 44 | self.assertTrue([42]) 45 | 46 | def test_identity(self): 47 | self.assertTrue([] is not []) 48 | 49 | def test_len(self): 50 | super(ListTest, self).test_len() 51 | self.assertEqual(len([]), 0) 52 | self.assertEqual(len([0]), 1) 53 | self.assertEqual(len([0, 1, 2]), 3) 54 | 55 | @unittest.expectedFailure 56 | def test_overflow(self): 57 | lst = [4, 5, 6, 7] 58 | n = int((sys.maxsize*2+2) // len(lst)) 59 | def mul(a, b): return a * b 60 | def imul(a, b): a *= b 61 | self.assertRaises((MemoryError, OverflowError), mul, lst, n) 62 | self.assertRaises((MemoryError, OverflowError), imul, lst, n) 63 | 64 | def test_main(verbose=None): 65 | test_support.run_unittest(ListTest) 66 | 67 | # verify reference counting 68 | # import sys 69 | # if verbose and hasattr(sys, "gettotalrefcount"): 70 | # import gc 71 | # counts = [None] * 5 72 | # for i in xrange(len(counts)): 73 | # test_support.run_unittest(ListTest) 74 | # gc.collect() 75 | # counts[i] = sys.gettotalrefcount() 76 | # print counts 77 | 78 | 79 | if __name__ == "__main__": 80 | test_main(verbose=True) 81 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/test/test_md5.py: -------------------------------------------------------------------------------- 1 | # Testing md5 module 2 | import warnings 3 | warnings.filterwarnings("ignore", "the md5 module is deprecated.*", 4 | DeprecationWarning) 5 | 6 | import unittest 7 | # from md5 import md5 8 | import md5 as _md5 9 | md5 = _md5.md5 10 | from test import test_support 11 | 12 | def hexstr(s): 13 | import string 14 | h = string.hexdigits 15 | r = '' 16 | for c in s: 17 | i = ord(c) 18 | r = r + h[(i >> 4) & 0xF] + h[i & 0xF] 19 | return r 20 | 21 | class MD5_Test(unittest.TestCase): 22 | 23 | def md5test(self, s, expected): 24 | self.assertEqual(hexstr(md5(s).digest()), expected) 25 | self.assertEqual(md5(s).hexdigest(), expected) 26 | 27 | def test_basics(self): 28 | eq = self.md5test 29 | eq('', 'd41d8cd98f00b204e9800998ecf8427e') 30 | eq('a', '0cc175b9c0f1b6a831c399e269772661') 31 | eq('abc', '900150983cd24fb0d6963f7d28e17f72') 32 | eq('message digest', 'f96b697d7cb7938d525a2f31aaf161d0') 33 | eq('abcdefghijklmnopqrstuvwxyz', 'c3fcd3d76192e4007dfb496cca67e13b') 34 | eq('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', 35 | 'd174ab98d277d9f5a5611c2c9f419d9f') 36 | eq('12345678901234567890123456789012345678901234567890123456789012345678901234567890', 37 | '57edf4a22be3c955ac49da2e2107b67a') 38 | 39 | def test_hexdigest(self): 40 | # hexdigest is new with Python 2.0 41 | m = md5('testing the hexdigest method') 42 | h = m.hexdigest() 43 | self.assertEqual(hexstr(m.digest()), h) 44 | 45 | def test_large_update(self): 46 | aas = 'a' * 64 47 | bees = 'b' * 64 48 | cees = 'c' * 64 49 | 50 | m1 = md5() 51 | m1.update(aas) 52 | m1.update(bees) 53 | m1.update(cees) 54 | 55 | m2 = md5() 56 | m2.update(aas + bees + cees) 57 | self.assertEqual(m1.digest(), m2.digest()) 58 | 59 | def test_main(): 60 | test_support.run_unittest(MD5_Test) 61 | 62 | if __name__ == '__main__': 63 | test_main() 64 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/test/test_mimetools.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | from test import test_support 3 | 4 | import string 5 | import StringIO 6 | 7 | #mimetools = test_support.import_module("mimetools", deprecated=True) 8 | import mimetools 9 | 10 | msgtext1 = mimetools.Message(StringIO.StringIO( 11 | """Content-Type: text/plain; charset=iso-8859-1; format=flowed 12 | Content-Transfer-Encoding: 8bit 13 | 14 | Foo! 15 | """)) 16 | 17 | class MimeToolsTest(unittest.TestCase): 18 | 19 | def test_decodeencode(self): 20 | start = string.ascii_letters + "=" + string.digits + "\n" 21 | for enc in ['7bit','8bit','base64','quoted-printable', 22 | 'uuencode', 'x-uuencode', 'uue', 'x-uue']: 23 | i = StringIO.StringIO(start) 24 | o = StringIO.StringIO() 25 | mimetools.encode(i, o, enc) 26 | i = StringIO.StringIO(o.getvalue()) 27 | o = StringIO.StringIO() 28 | mimetools.decode(i, o, enc) 29 | self.assertEqual(o.getvalue(), start) 30 | 31 | @unittest.expectedFailure 32 | def test_boundary(self): 33 | s = set([""]) 34 | for i in xrange(100): 35 | nb = mimetools.choose_boundary() 36 | self.assertNotIn(nb, s) 37 | s.add(nb) 38 | 39 | def test_message(self): 40 | msg = mimetools.Message(StringIO.StringIO(msgtext1)) 41 | self.assertEqual(msg.gettype(), "text/plain") 42 | self.assertEqual(msg.getmaintype(), "text") 43 | self.assertEqual(msg.getsubtype(), "plain") 44 | self.assertEqual(msg.getplist(), ["charset=iso-8859-1", "format=flowed"]) 45 | self.assertEqual(msg.getparamnames(), ["charset", "format"]) 46 | self.assertEqual(msg.getparam("charset"), "iso-8859-1") 47 | self.assertEqual(msg.getparam("format"), "flowed") 48 | self.assertEqual(msg.getparam("spam"), None) 49 | self.assertEqual(msg.getencoding(), "8bit") 50 | 51 | def test_main(): 52 | test_support.run_unittest(MimeToolsTest) 53 | 54 | if __name__=="__main__": 55 | test_main() 56 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/test/test_mutex.py: -------------------------------------------------------------------------------- 1 | import unittest 2 | import test.test_support 3 | 4 | # mutex = test.test_support.import_module("mutex", deprecated=True) 5 | import mutex 6 | 7 | class MutexTest(unittest.TestCase): 8 | 9 | def test_lock_and_unlock(self): 10 | 11 | def called_by_mutex(some_data): 12 | self.assertEqual(some_data, "spam") 13 | self.assertTrue(m.test(), "mutex not held") 14 | # Nested locking 15 | m.lock(called_by_mutex2, "eggs") 16 | 17 | def called_by_mutex2(some_data): 18 | self.assertEqual(some_data, "eggs") 19 | self.assertTrue(m.test(), "mutex not held") 20 | self.assertTrue(ready_for_2, 21 | "called_by_mutex2 called too soon") 22 | 23 | m = mutex.mutex() 24 | read_for_2 = False 25 | m.lock(called_by_mutex, "spam") 26 | ready_for_2 = True 27 | # unlock both locks 28 | m.unlock() 29 | m.unlock() 30 | self.assertFalse(m.test(), "mutex still held") 31 | 32 | def test_main(): 33 | test.test_support.run_unittest(MutexTest) 34 | 35 | if __name__ == "__main__": 36 | test_main() 37 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/test/test_select.py: -------------------------------------------------------------------------------- 1 | from test import test_support 2 | import unittest 3 | import select_ as select 4 | import os 5 | import sys 6 | 7 | @unittest.skipIf(sys.platform[:3] in ('win', 'os2', 'riscos'), 8 | "can't easily test on this system") 9 | class SelectTestCase(unittest.TestCase): 10 | 11 | class Nope(object): 12 | pass 13 | 14 | class Almost(object): 15 | def fileno(self): 16 | return 'fileno' 17 | 18 | def test_error_conditions(self): 19 | self.assertRaises(TypeError, select.select, 1, 2, 3) 20 | self.assertRaises(TypeError, select.select, [self.Nope()], [], []) 21 | self.assertRaises(TypeError, select.select, [self.Almost()], [], []) 22 | self.assertRaises(ValueError, select.select, [], [], [], "not a number") 23 | 24 | def test_returned_list_identity(self): 25 | # See issue #8329 26 | r, w, x = select.select([], [], [], 1) 27 | self.assertIsNot(r, w) 28 | self.assertIsNot(r, x) 29 | self.assertIsNot(w, x) 30 | 31 | def test_select(self): 32 | cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done' 33 | p = os.popen(cmd, 'r') 34 | for tout in (0, 1, 2, 4, 8, 16) + (None,)*10: 35 | if test_support.verbose: 36 | print 'timeout =', tout 37 | rfd, wfd, xfd = select.select([p], [], [], tout) 38 | if (rfd, wfd, xfd) == ([], [], []): 39 | continue 40 | if (rfd, wfd, xfd) == ([p], [], []): 41 | line = p.readline() 42 | if test_support.verbose: 43 | print repr(line) 44 | if not line: 45 | if test_support.verbose: 46 | print 'EOF' 47 | break 48 | continue 49 | self.fail('Unexpected return values from select():', rfd, wfd, xfd) 50 | p.close() 51 | 52 | # Issue 16230: Crash on select resized list 53 | def test_select_mutated(self): 54 | a = [] 55 | class F(object): 56 | def fileno(self): 57 | del a[-1] 58 | return sys.stdout.fileno() 59 | a[:] = [F()] * 10 60 | self.assertEqual(select.select([], a, []), ([], a[:5], [])) 61 | 62 | def test_main(): 63 | test_support.run_unittest(SelectTestCase) 64 | test_support.reap_children() 65 | 66 | if __name__ == "__main__": 67 | test_main() 68 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/types.py: -------------------------------------------------------------------------------- 1 | """Define names for all type symbols known in the standard interpreter. 2 | 3 | Types that are part of optional modules (e.g. array) are not listed. 4 | """ 5 | import sys 6 | 7 | # Iterators in Python aren't a matter of type but of protocol. A large 8 | # and changing number of builtin types implement *some* flavor of 9 | # iterator. Don't check the type! Use hasattr to check for both 10 | # "__iter__" and "next" attributes instead. 11 | 12 | NoneType = type(None) 13 | TypeType = type 14 | ObjectType = object 15 | 16 | IntType = int 17 | #LongType = long 18 | FloatType = float 19 | BooleanType = bool 20 | try: 21 | ComplexType = complex 22 | except NameError: 23 | pass 24 | 25 | StringType = str 26 | 27 | # StringTypes is already outdated. Instead of writing "type(x) in 28 | # types.StringTypes", you should use "isinstance(x, basestring)". But 29 | # we keep around for compatibility with Python 2.2. 30 | try: 31 | UnicodeType = unicode 32 | StringTypes = (StringType, UnicodeType) 33 | except NameError: 34 | StringTypes = (StringType,) 35 | 36 | #BufferType = buffer 37 | 38 | TupleType = tuple 39 | ListType = list 40 | DictType = DictionaryType = dict 41 | 42 | def _f(): pass 43 | FunctionType = type(_f) 44 | #LambdaType = type(lambda: None) # Same as FunctionType 45 | #CodeType = type(_f.func_code) 46 | 47 | def _g(): 48 | yield 1 49 | GeneratorType = type(_g()) 50 | 51 | class _C(object): 52 | def _m(self): pass 53 | ClassType = type(_C) 54 | UnboundMethodType = type(_C._m) # Same as MethodType 55 | _x = _C() 56 | #InstanceType = type(_x) 57 | MethodType = type(_x._m) 58 | 59 | BuiltinFunctionType = type(len) 60 | BuiltinMethodType = type([].append) # Same as BuiltinFunctionType 61 | 62 | ModuleType = type(sys) 63 | FileType = file 64 | XRangeType = xrange 65 | 66 | try: 67 | raise TypeError 68 | except TypeError: 69 | tb = sys.exc_info()[2] 70 | TracebackType = type(tb) 71 | FrameType = type(tb.tb_frame) 72 | del tb 73 | 74 | SliceType = slice 75 | EllipsisType = type(Ellipsis) 76 | 77 | #DictProxyType = type(TypeType.__dict__) 78 | NotImplementedType = type(NotImplemented) 79 | 80 | # For Jython, the following two types are identical 81 | #GetSetDescriptorType = type(FunctionType.func_code) 82 | #MemberDescriptorType = type(FunctionType.func_globals) 83 | 84 | del sys, _C, _x # Not for export 85 | #del _f, _g 86 | -------------------------------------------------------------------------------- /grumpy-runtime-src/third_party/stdlib/unittest_signals.py: -------------------------------------------------------------------------------- 1 | # TODO: support signal 2 | # import signal 3 | # import weakref 4 | 5 | # from functools import wraps 6 | import functools 7 | wraps = functools.wraps 8 | 9 | __unittest = True 10 | 11 | 12 | class _InterruptHandler(object): 13 | pass 14 | # def __init__(self, default_handler): 15 | # self.called = False 16 | # self.original_handler = default_handler 17 | # if isinstance(default_handler, int): 18 | # print 'signal not supported yet' 19 | # if default_handler == signal.SIG_DFL: 20 | # # Pretend it's signal.default_int_handler instead. 21 | # default_handler = signal.default_int_handler 22 | # elif default_handler == signal.SIG_IGN: 23 | # # Not quite the same thing as SIG_IGN, but the closest we 24 | # # can make it: do nothing. 25 | # def default_handler(unused_signum, unused_frame): 26 | # pass 27 | # else: 28 | # raise TypeError("expected SIGINT signal handler to be " 29 | # "signal.SIG_IGN, signal.SIG_DFL, or a " 30 | # "callable object") 31 | # self.default_handler = default_handler 32 | 33 | # def __call__(self, signum, frame): 34 | # installed_handler = signal.getsignal(signal.SIGINT) 35 | # if installed_handler is not self: 36 | # # if we aren't the installed handler, then delegate immediately 37 | # # to the default handler 38 | # self.default_handler(signum, frame) 39 | 40 | # if self.called: 41 | # self.default_handler(signum, frame) 42 | # self.called = True 43 | # for result in _results.keys(): 44 | # result.stop() 45 | 46 | # _results = weakref.WeakKeyDictionary() 47 | _results = {} 48 | def registerResult(result): 49 | _results[result] = 1 50 | 51 | def removeResult(result): 52 | return bool(_results.pop(result, None)) 53 | 54 | _interrupt_handler = None 55 | def installHandler(): 56 | global _interrupt_handler 57 | pass 58 | # if _interrupt_handler is None: 59 | # default_handler = signal.getsignal(signal.SIGINT) 60 | # _interrupt_handler = _InterruptHandler(default_handler) 61 | # signal.signal(signal.SIGINT, _interrupt_handler) 62 | 63 | 64 | def removeHandler(method=None): 65 | pass 66 | # if method is not None: 67 | # # @wraps(method) 68 | # def inner(*args, **kwargs): 69 | # initial = signal.getsignal(signal.SIGINT) 70 | # removeHandler() 71 | # try: 72 | # return method(*args, **kwargs) 73 | # finally: 74 | # signal.signal(signal.SIGINT, initial) 75 | # inner = wraps(method)(inner) 76 | # return inner 77 | 78 | # global _interrupt_handler 79 | # if _interrupt_handler is not None: 80 | # signal.signal(signal.SIGINT, _interrupt_handler.original_handler) 81 | -------------------------------------------------------------------------------- /grumpy-runtime-src/tools/benchcmp: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Runs two benchmark programs and compares their results.""" 18 | 19 | import argparse 20 | import subprocess 21 | import sys 22 | 23 | 24 | parser = argparse.ArgumentParser() 25 | parser.add_argument('prog1') 26 | parser.add_argument('prog2') 27 | parser.add_argument('--runs', default=1, type=int, 28 | help='number of times to run each program') 29 | 30 | 31 | def main(args): 32 | results1 = _RunBenchmark(args.prog1) 33 | benchmarks = set(results1.keys()) 34 | results2 = {} 35 | for _ in xrange(args.runs - 1): 36 | _MergeResults(results1, _RunBenchmark(args.prog1), benchmarks) 37 | _MergeResults(results2, _RunBenchmark(args.prog2), benchmarks) 38 | _MergeResults(results2, _RunBenchmark(args.prog2), benchmarks) 39 | for b in sorted(benchmarks): 40 | print b, '{:+.1%}'.format(results2[b] / results1[b] - 1) 41 | 42 | 43 | def _MergeResults(merged, results, benchmarks): 44 | benchmarks = set(benchmarks) 45 | for k, v in results.iteritems(): 46 | if k not in benchmarks: 47 | _Die('unmatched benchmark: {}', k) 48 | merged[k] = max(merged.get(k, 0), v) 49 | benchmarks.remove(k) 50 | if benchmarks: 51 | _Die('missing benchmark(s): {}', ', '.join(benchmarks)) 52 | 53 | 54 | def _RunBenchmark(prog): 55 | """Executes prog and returns a dict mapping benchmark name -> result.""" 56 | try: 57 | p = subprocess.Popen([prog], shell=True, stdout=subprocess.PIPE) 58 | except OSError as e: 59 | _Die(e) 60 | out, _ = p.communicate() 61 | if p.returncode: 62 | _Die('{} exited with status: {}', prog, p.returncode) 63 | results = {} 64 | for line in out.splitlines(): 65 | line = line.strip() 66 | if not line: 67 | continue 68 | parts = line.split() 69 | if len(parts) != 3: 70 | _Die('invalid benchmark output: {}', line) 71 | name, status, result = parts 72 | if status != 'PASSED': 73 | _Die('benchmark failed: {}', line) 74 | try: 75 | result = float(result) 76 | except ValueError: 77 | _Die('invalid benchmark result: {}', line) 78 | results[name] = result 79 | return results 80 | 81 | 82 | def _Die(msg, *args): 83 | if args: 84 | msg = msg.format(*args) 85 | print >> sys.stderr, msg 86 | sys.exit(1) 87 | 88 | 89 | if __name__ == '__main__': 90 | main(parser.parse_args()) 91 | -------------------------------------------------------------------------------- /grumpy-runtime-src/tools/coverparse: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Parse a Go coverage file and prints a message for lines missing coverage.""" 18 | 19 | import collections 20 | import re 21 | import sys 22 | 23 | 24 | cover_re = re.compile(r'([^:]+):(\d+)\.\d+,(\d+).\d+ \d+ (\d+)$') 25 | 26 | 27 | def _ParseCover(f): 28 | """Return a dict of sets with uncovered line numbers from a Go cover file.""" 29 | uncovered = collections.defaultdict(set) 30 | for line in f: 31 | match = cover_re.match(line.rstrip()) 32 | if not match: 33 | raise RuntimeError('invalid coverage line: {!r}'.format(line)) 34 | filename, line_start, line_end, count = match.groups() 35 | if not int(count): 36 | for i in xrange(int(line_start), int(line_end) + 1): 37 | uncovered[filename].add(i) 38 | return uncovered 39 | 40 | 41 | def main(): 42 | with open(sys.argv[1]) as f: 43 | f.readline() 44 | uncovered = _ParseCover(f) 45 | for filename in sorted(uncovered.keys()): 46 | for lineno in sorted(uncovered[filename]): 47 | print '{}:{}'.format(filename, lineno) 48 | 49 | 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /grumpy-runtime-src/tools/diffrange: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Convert a unified diff into a list of modified files and line numbers.""" 18 | 19 | import sys 20 | 21 | 22 | class _LineBuffer(object): 23 | """Iterator over lines in a file supporting one-step rewind.""" 24 | 25 | def __init__(self, f): 26 | self._f = f 27 | self._prev = None 28 | self._next = None 29 | 30 | def __iter__(self): 31 | return self 32 | 33 | def next(self): 34 | if self._next is not None: 35 | cur = self._next 36 | else: 37 | cur = self._f.readline() 38 | if not cur: 39 | raise StopIteration 40 | self._next = None 41 | self._prev = cur 42 | return cur 43 | 44 | def Rewind(self): 45 | assert self._prev is not None 46 | self._next = self._prev 47 | self._prev = None 48 | 49 | 50 | def _ReadHunks(buf): 51 | for line in buf: 52 | if not line.startswith('@@'): 53 | break 54 | base = int(line.split()[2].split(',')[0]) 55 | for offset in _ReadHunkBody(buf): 56 | yield base + offset 57 | 58 | 59 | def _ReadHunkBody(buf): 60 | n = 0 61 | for line in buf: 62 | prefix = line[0] 63 | if prefix == ' ': 64 | n += 1 65 | elif prefix == '+': 66 | yield n 67 | n += 1 68 | elif prefix != '-' or line.startswith('---'): 69 | buf.Rewind() 70 | break 71 | 72 | 73 | def main(): 74 | buf = _LineBuffer(sys.stdin) 75 | for line in buf: 76 | if line.startswith('+++'): 77 | filename = line.split()[1] 78 | for n in _ReadHunks(buf): 79 | print '{}:{}'.format(filename, n) 80 | 81 | 82 | if __name__ == '__main__': 83 | main() 84 | -------------------------------------------------------------------------------- /grumpy-runtime-src/tools/genmake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Generate a Makefile for Python targets in a GOPATH directory.""" 18 | 19 | import argparse 20 | import os 21 | import subprocess 22 | import sys 23 | 24 | 25 | parser = argparse.ArgumentParser() 26 | parser.add_argument('dir', help='GOPATH dir to scan for Python modules') 27 | parser.add_argument('-all_target', default='all', 28 | help='make target that will build all modules') 29 | 30 | 31 | def _PrintRule(target, prereqs, rules): 32 | print '{}: {}'.format(target, ' '.join(prereqs)) 33 | if rules: 34 | print '\t@mkdir -p $(@D)' 35 | for rule in rules: 36 | print '\t@{}'.format(rule) 37 | print 38 | 39 | 40 | def main(args): 41 | try: 42 | proc = subprocess.Popen('go env GOOS GOARCH', shell=True, 43 | stdout=subprocess.PIPE) 44 | except OSError as e: 45 | print >> sys.stderr, str(e) 46 | return 1 47 | out, _ = proc.communicate() 48 | if proc.returncode: 49 | print >> sys.stderr, 'go exited with status: {}'.format(proc.returncode) 50 | return 1 51 | goos, goarch = out.split() 52 | 53 | if args.all_target: 54 | print '{}:\n'.format(args.all_target) 55 | 56 | gopath = os.path.normpath(args.dir) 57 | pkg_dir = os.path.join(gopath, 'pkg', '{}_{}'.format(goos, goarch)) 58 | pydir = os.path.join(gopath, 'src', '__python__') 59 | for dirpath, _, filenames in os.walk(pydir): 60 | for filename in filenames: 61 | if not filename.endswith('.py'): 62 | continue 63 | basename = os.path.relpath(dirpath, pydir) 64 | if filename != '__init__.py': 65 | basename = os.path.normpath( 66 | os.path.join(basename, filename[:-3])) 67 | modname = basename.replace(os.sep, '.') 68 | ar_name = os.path.join(pkg_dir, '__python__', basename + '.a') 69 | go_file = os.path.join(pydir, basename, 'module.go') 70 | _PrintRule(go_file, 71 | [os.path.join(dirpath, filename)], 72 | ['grumpc -modname={} $< > $@'.format(modname)]) 73 | recipe = (r"""pydeps -modname=%s $< | awk '{gsub(/\./, "/", $$0); """ 74 | r"""print "%s: %s/__python__/" $$0 ".a"}' > $@""") 75 | dep_file = os.path.join(pydir, basename, 'module.d') 76 | _PrintRule(dep_file, [os.path.join(dirpath, filename)], 77 | [recipe % (modname, ar_name, pkg_dir)]) 78 | go_package = '__python__/' + basename.replace(os.sep, '/') 79 | recipe = 'go tool compile -o $@ -p {} -complete -I {} -pack $<' 80 | _PrintRule(ar_name, [go_file], [recipe.format(go_package, pkg_dir)]) 81 | if args.all_target: 82 | _PrintRule(args.all_target, [ar_name], []) 83 | print '-include {}\n'.format(dep_file) 84 | 85 | 86 | if __name__ == '__main__': 87 | sys.exit(main(parser.parse_args())) 88 | -------------------------------------------------------------------------------- /grumpy-runtime-src/tools/grumpc: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ## Import boilerplate 3 | import os 4 | import sys 5 | from grumpy_tools import cli 6 | 7 | sys.argv = ['grumpy', 'transpile'] + sys.argv[1:] 8 | sys.exit(cli.main()) 9 | -------------------------------------------------------------------------------- /grumpy-runtime-src/tools/grumprun: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ## Import boilerplate 3 | import os 4 | import sys 5 | from grumpy_tools import cli 6 | 7 | sys.argv = ['grumpy', 'run'] + sys.argv[1:] 8 | sys.exit(cli.main()) 9 | -------------------------------------------------------------------------------- /grumpy-runtime-src/tools/pkgc.go: -------------------------------------------------------------------------------- 1 | // pkgc is a tool for generating wrappers for Go packages imported by Grumpy 2 | // programs. 3 | // 4 | // usage: pkgc PACKAGE 5 | // 6 | // Where PACKAGE is the full Go package name. Generated code is dumped to 7 | // stdout. Packages generated in this way can be imported by Grumpy programs 8 | // using string literal import syntax, e.g.: 9 | // 10 | // import "__go__/encoding/json" 11 | // 12 | // Or: 13 | // 14 | // from "__go__/time" import Duration 15 | 16 | package main 17 | 18 | import ( 19 | "bytes" 20 | "fmt" 21 | "go/constant" 22 | "go/importer" 23 | "go/types" 24 | "math" 25 | "os" 26 | "path" 27 | ) 28 | 29 | const packageTemplate = `package %[1]s 30 | import ( 31 | "grumpy" 32 | "reflect" 33 | mod %[2]q 34 | ) 35 | func fun(f *grumpy.Frame, _ []*grumpy.Object) (*grumpy.Object, *grumpy.BaseException) { 36 | %[3]s 37 | return nil, nil 38 | } 39 | var Code = grumpy.NewCode("", %[2]q, nil, 0, fun) 40 | func init() { 41 | grumpy.RegisterModule("__go__/%[2]s", Code) 42 | } 43 | ` 44 | 45 | const typeTemplate = ` if true { 46 | var x mod.%[1]s 47 | if o, raised := grumpy.WrapNative(f, reflect.ValueOf(x)); raised != nil { 48 | return nil, raised 49 | } else if raised = f.Globals().SetItemString(f, %[1]q, o.Type().ToObject()); raised != nil { 50 | return nil, raised 51 | } 52 | } 53 | ` 54 | 55 | const varTemplate = ` if o, raised := grumpy.WrapNative(f, reflect.ValueOf(%[1]s)); raised != nil { 56 | return nil, raised 57 | } else if raised = f.Globals().SetItemString(f, %[2]q, o); raised != nil { 58 | return nil, raised 59 | } 60 | ` 61 | 62 | func getConst(name string, v constant.Value) string { 63 | format := "%s" 64 | switch v.Kind() { 65 | case constant.Int: 66 | if constant.Sign(v) >= 0 { 67 | if i, exact := constant.Uint64Val(v); exact { 68 | if i < math.MaxInt8 { 69 | format = "uint(%s)" 70 | } else if i < math.MaxInt32 { 71 | format = "uint32(%s)" 72 | } else { 73 | format = "uint64(%s)" 74 | } 75 | } else { 76 | format = "float64(%s)" 77 | } 78 | } else { 79 | if i, exact := constant.Int64Val(v); exact { 80 | if i > math.MinInt8 { 81 | format = "int(%s)" 82 | } else if i > math.MinInt32 { 83 | format = "int32(%s)" 84 | } else { 85 | format = "int64(%s)" 86 | } 87 | } 88 | } 89 | case constant.Float: 90 | format = "float64(%s)" 91 | } 92 | return fmt.Sprintf(format, name) 93 | } 94 | 95 | func main() { 96 | if len(os.Args) != 2 { 97 | fmt.Fprint(os.Stderr, "usage: pkgc PACKAGE") 98 | os.Exit(1) 99 | } 100 | pkgPath := os.Args[1] 101 | pkg, err := importer.Default().Import(pkgPath) 102 | if err != nil { 103 | fmt.Fprintf(os.Stderr, "failed to import: %q: %v\n", pkgPath, err) 104 | os.Exit(2) 105 | } 106 | var buf bytes.Buffer 107 | scope := pkg.Scope() 108 | for _, name := range scope.Names() { 109 | o := scope.Lookup(name) 110 | if !o.Exported() { 111 | continue 112 | } 113 | switch x := o.(type) { 114 | case *types.TypeName: 115 | if types.IsInterface(x.Type()) { 116 | continue 117 | } 118 | buf.WriteString(fmt.Sprintf(typeTemplate, name)) 119 | case *types.Const: 120 | expr := getConst("mod." + name, x.Val()) 121 | buf.WriteString(fmt.Sprintf(varTemplate, expr, name)) 122 | default: 123 | expr := "mod." + name 124 | buf.WriteString(fmt.Sprintf(varTemplate, expr, name)) 125 | } 126 | } 127 | fmt.Printf(packageTemplate, path.Base(pkgPath), pkgPath, buf.Bytes()) 128 | } 129 | -------------------------------------------------------------------------------- /grumpy-runtime-src/tools/pydeps: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import os 3 | import sys 4 | 5 | from grumpy_tools import cli 6 | 7 | sys.argv = ['grumpy', 'depends'] + sys.argv[1:] 8 | sys.exit(cli.main()) 9 | -------------------------------------------------------------------------------- /grumpy-tools-src/.coveragerc: -------------------------------------------------------------------------------- 1 | [run] 2 | branch = True 3 | parallel = True 4 | disable_warnings = no-data-collected 5 | include = 6 | ./* 7 | omit = 8 | venv/* 9 | */tests* 10 | */migrations/* 11 | project/environments/* 12 | .git 13 | conf/* 14 | grumpy_tools/vendor/ 15 | 16 | [report] 17 | #skip_covered = True 18 | 19 | [html] 20 | directory = .coverage_html 21 | 22 | -------------------------------------------------------------------------------- /grumpy-tools-src/AUTHORS.md: -------------------------------------------------------------------------------- 1 | ../AUTHORS.md -------------------------------------------------------------------------------- /grumpy-tools-src/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ../CONTRIBUTING.md -------------------------------------------------------------------------------- /grumpy-tools-src/LICENSE: -------------------------------------------------------------------------------- 1 | ../LICENSE -------------------------------------------------------------------------------- /grumpy-tools-src/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """Top-level package for Grumpy Tools.""" 4 | 5 | __author__ = """Alan Justino et al.""" 6 | __email__ = 'alan.justino@yahoo.com.br' 7 | __version__ = '0.3.0' 8 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/benchcmp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Runs two benchmark programs and compares their results.""" 18 | 19 | from __future__ import print_function 20 | 21 | import argparse 22 | import subprocess 23 | import sys 24 | 25 | try: 26 | xrange # Python 2 27 | except NameError: 28 | xrange = range # Python 3 29 | 30 | parser = argparse.ArgumentParser() 31 | parser.add_argument('prog1') 32 | parser.add_argument('prog2') 33 | parser.add_argument('--runs', default=1, type=int, 34 | help='number of times to run each program') 35 | 36 | 37 | def main(args): 38 | results1 = _RunBenchmark(args.prog1) 39 | benchmarks = set(results1.keys()) 40 | results2 = {} 41 | for _ in xrange(args.runs - 1): 42 | _MergeResults(results1, _RunBenchmark(args.prog1), benchmarks) 43 | _MergeResults(results2, _RunBenchmark(args.prog2), benchmarks) 44 | _MergeResults(results2, _RunBenchmark(args.prog2), benchmarks) 45 | for b in sorted(benchmarks): 46 | print(b, '{:+.1%}'.format(results2[b] / results1[b] - 1)) 47 | 48 | 49 | def _MergeResults(merged, results, benchmarks): 50 | benchmarks = set(benchmarks) 51 | for k, v in results.iteritems(): 52 | if k not in benchmarks: 53 | _Die('unmatched benchmark: {}', k) 54 | merged[k] = max(merged.get(k, 0), v) 55 | benchmarks.remove(k) 56 | if benchmarks: 57 | _Die('missing benchmark(s): {}', ', '.join(benchmarks)) 58 | 59 | 60 | def _RunBenchmark(prog): 61 | """Executes prog and returns a dict mapping benchmark name -> result.""" 62 | try: 63 | p = subprocess.Popen([prog], shell=True, stdout=subprocess.PIPE) 64 | except OSError as e: 65 | _Die(e) 66 | out, _ = p.communicate() 67 | if p.returncode: 68 | _Die('{} exited with status: {}', prog, p.returncode) 69 | results = {} 70 | for line in out.splitlines(): 71 | line = line.strip() 72 | if not line: 73 | continue 74 | try: 75 | name, status, result = line.split() 76 | except ValueError: 77 | _Die('invalid benchmark output: {}', line) 78 | if status != 'PASSED': 79 | _Die('benchmark failed: {}', line) 80 | try: 81 | result = float(result) 82 | except ValueError: 83 | _Die('invalid benchmark result: {}', line) 84 | results[name] = result 85 | return results 86 | 87 | 88 | def _Die(msg, *args): 89 | if args: 90 | msg = msg.format(*args) 91 | print(msg, file=sys.stderr) 92 | sys.exit(1) 93 | 94 | 95 | if __name__ == '__main__': 96 | main(parser.parse_args()) 97 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/compiler/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/compiler/expr.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Classes representing generated expressions.""" 18 | 19 | from __future__ import unicode_literals 20 | 21 | import abc 22 | 23 | from grumpy_tools.compiler import util 24 | 25 | 26 | class GeneratedExpr(object): 27 | """GeneratedExpr is a generated Go expression in transcompiled output.""" 28 | 29 | __metaclass__ = abc.ABCMeta 30 | 31 | def __enter__(self): 32 | return self 33 | 34 | def __exit__(self, unused_type, unused_value, unused_traceback): 35 | self.free() 36 | 37 | @abc.abstractproperty 38 | def expr(self): 39 | pass 40 | 41 | def free(self): 42 | pass 43 | 44 | 45 | class GeneratedTempVar(GeneratedExpr): 46 | """GeneratedTempVar is an expression result stored in a temporary value.""" 47 | 48 | def __init__(self, block_, name, type_): 49 | self.block = block_ 50 | self.name = name 51 | self.type_ = type_ 52 | 53 | @property 54 | def expr(self): 55 | return self.name 56 | 57 | def free(self): 58 | self.block.free_temp(self) 59 | 60 | 61 | class GeneratedLocalVar(GeneratedExpr): 62 | """GeneratedLocalVar is the Go local var corresponding to a Python local.""" 63 | 64 | def __init__(self, name): 65 | self._name = name 66 | 67 | @property 68 | def expr(self): 69 | return util.adjust_local_name(self._name) 70 | 71 | 72 | class GeneratedLiteral(GeneratedExpr): 73 | """GeneratedLiteral is a generated literal Go expression.""" 74 | 75 | def __init__(self, expr): 76 | self._expr = expr 77 | 78 | @property 79 | def expr(self): 80 | return self._expr 81 | 82 | 83 | nil_expr = GeneratedLiteral('nil') 84 | 85 | 86 | class BlankVar(GeneratedExpr): 87 | def __init__(self): 88 | self.name = '_' 89 | 90 | @property 91 | def expr(self): 92 | return '_' 93 | 94 | 95 | blank_var = BlankVar() 96 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/compiler/shard_test.py: -------------------------------------------------------------------------------- 1 | # Copyright 2016 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | """Wrapper for unit tests that loads a subset of all test methods.""" 16 | 17 | from __future__ import unicode_literals 18 | 19 | import argparse 20 | import random 21 | import re 22 | import sys 23 | import unittest 24 | 25 | 26 | class _ShardAction(argparse.Action): 27 | 28 | def __call__(self, parser, args, values, option_string=None): 29 | match = re.match(r'(\d+)of(\d+)$', values) 30 | if not match: 31 | raise argparse.ArgumentError(self, 'bad shard spec: {}'.format(values)) 32 | shard = int(match.group(1)) 33 | count = int(match.group(2)) 34 | if shard < 1 or count < 1 or shard > count: 35 | raise argparse.ArgumentError(self, 'bad shard spec: {}'.format(values)) 36 | setattr(args, self.dest, (shard, count)) 37 | 38 | 39 | class _ShardTestLoader(unittest.TestLoader): 40 | 41 | def __init__(self, shard, count): 42 | super(_ShardTestLoader, self).__init__() 43 | self.shard = shard 44 | self.count = count 45 | 46 | def getTestCaseNames(self, test_case_cls): 47 | names = super(_ShardTestLoader, self).getTestCaseNames(test_case_cls) 48 | state = random.getstate() 49 | random.seed(self.count) 50 | random.shuffle(names) 51 | random.setstate(state) 52 | n = len(names) 53 | # self.shard is one-based. 54 | return names[(self.shard - 1) * n / self.count:self.shard * n / self.count] 55 | 56 | 57 | class _ShardTestRunner(object): 58 | 59 | def run(self, test): 60 | result = unittest.TestResult() 61 | unittest.registerResult(result) 62 | test(result) 63 | for kind, errors in [('FAIL', result.failures), ('ERROR', result.errors)]: 64 | for test, err in errors: 65 | sys.stderr.write('{} {}\n{}'.format(test, kind, err)) 66 | return result 67 | 68 | 69 | def main(): 70 | parser = argparse.ArgumentParser() 71 | parser.add_argument('--shard', default=(1, 1), action=_ShardAction) 72 | parser.add_argument('unittest_args', nargs='*') 73 | args = parser.parse_args() 74 | unittest.main(argv=[sys.argv[0]] + args.unittest_args, 75 | testLoader=_ShardTestLoader(*args.shard), 76 | testRunner=_ShardTestRunner) 77 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/compiler/util_test.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Tests Writer and other utils.""" 18 | 19 | from __future__ import unicode_literals 20 | 21 | import unittest 22 | 23 | from grumpy_tools.compiler import block 24 | from grumpy_tools.compiler import imputil 25 | from grumpy_tools.compiler import util 26 | 27 | 28 | class WriterTest(unittest.TestCase): 29 | 30 | def testIndentBlock(self): 31 | writer = util.Writer() 32 | writer.write('foo') 33 | with writer.indent_block(n=2): 34 | writer.write('bar') 35 | writer.write('baz') 36 | self.assertEqual(writer.getvalue(), 'foo\n\t\tbar\nbaz\n') 37 | 38 | def testWriteBlock(self): 39 | writer = util.Writer() 40 | mod_block = block.ModuleBlock(None, '__main__', '', '', 41 | imputil.FutureFeatures()) 42 | writer.write_block(mod_block, 'BODY') 43 | output = writer.getvalue() 44 | dispatch = 'switch πF.State() {\n\tcase 0:\n\tdefault: panic' 45 | self.assertIn(dispatch, output) 46 | 47 | def testWriteMultiline(self): 48 | writer = util.Writer() 49 | writer.indent(2) 50 | writer.write('foo\nbar\nbaz\n') 51 | self.assertEqual(writer.getvalue(), '\t\tfoo\n\t\tbar\n\t\tbaz\n') 52 | 53 | def testWritePyContext(self): 54 | writer = util.Writer() 55 | writer.write_py_context(12, 'print "foo"') 56 | self.assertEqual(writer.getvalue(), '// line 12: print "foo"\n') 57 | 58 | def testWriteSkipBlankLine(self): 59 | writer = util.Writer() 60 | writer.write('foo\n\nbar') 61 | self.assertEqual(writer.getvalue(), 'foo\nbar\n') 62 | 63 | def testWriteTmpl(self): 64 | writer = util.Writer() 65 | writer.write_tmpl('$foo, $bar\n$baz', foo=1, bar=2, baz=3) 66 | self.assertEqual(writer.getvalue(), '1, 2\n3\n') 67 | 68 | def testIndent(self): 69 | writer = util.Writer() 70 | writer.indent(2) 71 | writer.write('foo') 72 | self.assertEqual(writer.getvalue(), '\t\tfoo\n') 73 | 74 | def testDedent(self): 75 | writer = util.Writer() 76 | writer.indent(4) 77 | writer.dedent(3) 78 | writer.write('foo') 79 | self.assertEqual(writer.getvalue(), '\tfoo\n') 80 | 81 | 82 | if __name__ == '__main__': 83 | unittest.main() 84 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/coverparse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Parse a Go coverage file and prints a message for lines missing coverage.""" 18 | 19 | from __future__ import print_function 20 | 21 | import collections 22 | import re 23 | import sys 24 | 25 | try: 26 | xrange # Python 2 27 | except NameError: 28 | xrange = range # Python 3 29 | 30 | cover_re = re.compile(r'([^:]+):(\d+)\.\d+,(\d+).\d+ \d+ (\d+)$') 31 | 32 | 33 | def _ParseCover(f): 34 | """Return a dict of sets with uncovered line numbers from a Go cover file.""" 35 | uncovered = collections.defaultdict(set) 36 | for line in f: 37 | match = cover_re.match(line.rstrip()) 38 | if not match: 39 | raise RuntimeError('invalid coverage line: {!r}'.format(line)) 40 | filename, line_start, line_end, count = match.groups() 41 | if not int(count): 42 | for i in xrange(int(line_start), int(line_end) + 1): 43 | uncovered[filename].add(i) 44 | return uncovered 45 | 46 | 47 | def main(): 48 | with open(sys.argv[1]) as f: 49 | f.readline() 50 | uncovered = _ParseCover(f) 51 | for filename in sorted(uncovered.keys()): 52 | for lineno in sorted(uncovered[filename]): 53 | print('{}:{}'.format(filename, lineno)) 54 | 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/diffrange.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Convert a unified diff into a list of modified files and line numbers.""" 18 | 19 | from __future__ import print_function 20 | 21 | import sys 22 | 23 | 24 | class _LineBuffer(object): 25 | """Iterator over lines in a file supporting one-step rewind.""" 26 | 27 | def __init__(self, f): 28 | self._f = f 29 | self._prev = None 30 | self._next = None 31 | 32 | def __iter__(self): 33 | return self 34 | 35 | def next(self): 36 | if self._next is not None: 37 | cur = self._next 38 | else: 39 | cur = self._f.readline() 40 | if not cur: 41 | raise StopIteration 42 | self._next = None 43 | self._prev = cur 44 | return cur 45 | 46 | def Rewind(self): 47 | assert self._prev is not None 48 | self._next = self._prev 49 | self._prev = None 50 | 51 | 52 | def _ReadHunks(buf): 53 | for line in buf: 54 | if not line.startswith('@@'): 55 | break 56 | base = int(line.split()[2].split(',')[0]) 57 | for offset in _ReadHunkBody(buf): 58 | yield base + offset 59 | 60 | 61 | def _ReadHunkBody(buf): 62 | n = 0 63 | for line in buf: 64 | prefix = line[0] 65 | if prefix == ' ': 66 | n += 1 67 | elif prefix == '+': 68 | yield n 69 | n += 1 70 | elif prefix != '-' or line.startswith('---'): 71 | buf.Rewind() 72 | break 73 | 74 | 75 | def main(): 76 | buf = _LineBuffer(sys.stdin) 77 | for line in buf: 78 | if line.startswith('+++'): 79 | filename = line.split()[1] 80 | for n in _ReadHunks(buf): 81 | print('{}:{}'.format(filename, n)) 82 | 83 | 84 | if __name__ == '__main__': 85 | main() 86 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/genmake.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Generate a Makefile for Python targets in a GOPATH directory.""" 18 | 19 | from __future__ import print_function 20 | 21 | import argparse 22 | import os 23 | import subprocess 24 | import sys 25 | 26 | 27 | parser = argparse.ArgumentParser() 28 | parser.add_argument('dir', help='GOPATH dir to scan for Python modules') 29 | parser.add_argument('-all_target', default='all', 30 | help='make target that will build all modules') 31 | 32 | 33 | def _PrintRule(target, prereqs, rules): 34 | print('{}: {}'.format(target, ' '.join(prereqs))) 35 | if rules: 36 | print('\t@mkdir -p $(@D)') 37 | for rule in rules: 38 | print('\t@{}'.format(rule)) 39 | print() 40 | 41 | 42 | def main(args): 43 | try: 44 | proc = subprocess.Popen('go env GOOS GOARCH', shell=True, 45 | stdout=subprocess.PIPE) 46 | except OSError as e: 47 | print(str(e), file=sys.stderr) 48 | return 1 49 | out, _ = proc.communicate() 50 | if proc.returncode: 51 | print('go exited with status: {}'.format(proc.returncode), file=sys.stderr) 52 | return 1 53 | goos, goarch = out.split() 54 | 55 | if args.all_target: 56 | print('{}:\n'.format(args.all_target)) 57 | 58 | gopath = os.path.normpath(args.dir) 59 | pkg_dir = os.path.join(gopath, 'pkg', '{}_{}'.format(goos, goarch)) 60 | pydir = os.path.join(gopath, 'src', '__python__') 61 | for dirpath, _, filenames in os.walk(pydir): 62 | for filename in filenames: 63 | if not filename.endswith('.py'): 64 | continue 65 | basename = os.path.relpath(dirpath, pydir) 66 | if filename != '__init__.py': 67 | basename = os.path.normpath( 68 | os.path.join(basename, filename[:-3])) 69 | modname = basename.replace(os.sep, '.') 70 | ar_name = os.path.join(pkg_dir, '__python__', basename + '.a') 71 | go_file = os.path.join(pydir, basename, 'module.go') 72 | _PrintRule(go_file, 73 | [os.path.join(dirpath, filename)], 74 | ['grumpc -modname={} $< > $@'.format(modname)]) 75 | recipe = (r"""pydeps -modname=%s $< | awk '{gsub(/\./, "/", $$0); """ 76 | r"""print "%s: %s/__python__/" $$0 ".a"}' > $@""") 77 | dep_file = os.path.join(pydir, basename, 'module.d') 78 | _PrintRule(dep_file, [os.path.join(dirpath, filename)], 79 | [recipe % (modname, ar_name, pkg_dir)]) 80 | go_package = '__python__/' + basename.replace(os.sep, '/') 81 | recipe = 'go tool compile -o $@ -p {} -complete -I {} -pack $<' 82 | _PrintRule(ar_name, [go_file], [recipe.format(go_package, pkg_dir)]) 83 | if args.all_target: 84 | _PrintRule(args.all_target, [ar_name], []) 85 | print('-include {}\n'.format(dep_file)) 86 | 87 | 88 | if __name__ == '__main__': 89 | sys.exit(main(parser.parse_args())) 90 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/grumpy_tools.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """Main module.""" 4 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/pep_support/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grumpyhome/grumpy/7b775405bdf1694c2fb24cde7efc891283fa4354/grumpy-tools-src/grumpy_tools/pep_support/__init__.py -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/pydeps.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright 2016 Google Inc. All Rights Reserved. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | """Outputs names of modules imported by a script.""" 18 | from __future__ import absolute_import 19 | 20 | import os 21 | import sys 22 | 23 | from .compiler import imputil 24 | from .compiler import util 25 | 26 | try: 27 | xrange # Python 2 28 | except NameError: 29 | xrange = range # Python 3 30 | 31 | 32 | def main(script=None, modname=None, package_dir='', with_imports=False): 33 | gopath = os.environ['GOPATH'] 34 | 35 | imports = imputil.collect_imports(modname, script, gopath, package_dir=package_dir) 36 | 37 | def _deps(): 38 | names = set([modname]) 39 | for imp in imports: 40 | if imp.is_native and imp.name: 41 | yield imp.name 42 | else: 43 | if not imp.script: 44 | continue # Let the ImportError raise on run time 45 | 46 | parts = imp.name.split('.') 47 | # Iterate over all packages and the leaf module. 48 | for i in xrange(len(parts)): 49 | name = '.'.join(parts[:i+1]) 50 | if name and name not in names: 51 | names.add(name) 52 | if name.startswith('.'): 53 | name = name[1:] 54 | yield name 55 | 56 | if with_imports: 57 | return _deps(), imports 58 | else: 59 | return _deps() 60 | 61 | -------------------------------------------------------------------------------- /grumpy-tools-src/grumpy_tools/vendor/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/grumpyhome/grumpy/7b775405bdf1694c2fb24cde7efc891283fa4354/grumpy-tools-src/grumpy_tools/vendor/__init__.py -------------------------------------------------------------------------------- /grumpy-tools-src/pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | python_files=tests.py test_*.py tests/*.py grumpy_tools/* 3 | norecursedirs=.git conf src build __pycache__ 4 | doctest_optionflags=NORMALIZE_WHITESPACE ALLOW_UNICODE ALLOW_BYTES 5 | addopts = 6 | -v -s 7 | --cov --no-cov-on-fail --cov-report=term-missing --cov-report=html --cov-config=.coveragerc 8 | 9 | -------------------------------------------------------------------------------- /grumpy-tools-src/setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # 4 | # Copyright 2016 Google Inc. All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | 18 | """The setup script.""" 19 | 20 | import sys 21 | from setuptools import setup, find_packages 22 | 23 | try: 24 | with open('README.md') as readme_file: 25 | readme = readme_file.read() 26 | except: 27 | readme = '' 28 | 29 | requirements = [ 30 | 'Click>=6.0', 31 | 'importlib2>=3.5.0.2', 32 | 'click-default-group>=1.2', 33 | 'click-log>=0.3.2', 34 | 'dill>=0.2.7.1', 35 | 'pythonparser>=1.1', 36 | 'backports.functools-lru-cache>=1.5', 37 | 'backports.tempfile==1.0', 38 | ] 39 | 40 | setup_requirements = [ 41 | # TODO(alanjds): Put setup requirements (distutils extensions, etc.) here 42 | ] 43 | 44 | test_requirements = [ 45 | 'pytest>=3.3', 46 | 'pytest-cov>=2.5.1', 47 | # TODO: Put package test requirements here 48 | ] 49 | 50 | needs_pytest = {'pytest', 'test', 'ptr'}.intersection(sys.argv) 51 | if needs_pytest: 52 | setup_requirements += ['pytest-runner'] 53 | 54 | 55 | COMMON_OPTIONS = dict( 56 | version='0.3.0', 57 | description="Grumpy (Python to Go Transpiler) Tools", 58 | long_description=readme, 59 | author="Dylan Trotter et al.", 60 | maintainer="Alan Justino et al.", 61 | maintainer_email="alan.justino@yahoo.com.br", 62 | url='https://github.com/grumpyhome/grumpy', 63 | install_requires=requirements, 64 | license="Apache Software License 2.0", 65 | zip_safe=False, 66 | keywords='grumpy_runtime', 67 | python_requires='~=2.7.0', 68 | classifiers=[ 69 | 'Development Status :: 2 - Pre-Alpha', 70 | 'Intended Audience :: Developers', 71 | 'License :: OSI Approved :: Apache Software License', 72 | 'Natural Language :: English', 73 | "Programming Language :: Python :: 2", 74 | 'Programming Language :: Python :: 2.7', 75 | ], 76 | test_suite='tests', 77 | tests_require=test_requirements, 78 | setup_requires=setup_requirements, 79 | ) 80 | 81 | GRUMPY_TOOLS_OPTIONS = dict( 82 | name='grumpy-tools', 83 | packages=find_packages( 84 | exclude=["*.tests", "*.tests.*", "tests.*", "tests"], 85 | ), 86 | include_package_data=False, 87 | entry_points={ 88 | 'console_scripts': [ 89 | 'grumpy=grumpy_tools.cli:main', 90 | ], 91 | }, 92 | ) 93 | 94 | GRUMPY_TOOLS_OPTIONS.update(COMMON_OPTIONS) 95 | 96 | setup(**GRUMPY_TOOLS_OPTIONS) 97 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/dummymodule/__init__.py: -------------------------------------------------------------------------------- 1 | import dummysubmodule1 2 | 3 | def dummyfunc0(): 4 | print("Func0") 5 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/dummymodule/dummysubmodule1/__init__.py: -------------------------------------------------------------------------------- 1 | import dummysubmodule2 2 | import dummysubmodule2b 3 | 4 | def dummyfunc1(): 5 | print("Func1") 6 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/dummymodule/dummysubmodule1/dummysubmodule2/__init__.py: -------------------------------------------------------------------------------- 1 | def dummyfunc2(): 2 | print("Func2") 3 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/dummymodule/dummysubmodule1/dummysubmodule2b.py: -------------------------------------------------------------------------------- 1 | #import dummysubmodule2 2 | 3 | def dummyfunc2b(): 4 | print("Func2b") 5 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/dummyrunner.py: -------------------------------------------------------------------------------- 1 | import dummymodule 2 | 3 | print("START") 4 | dummymodule.dummyfunc0() 5 | print("END") 6 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/havingmainpkg/__init__.py: -------------------------------------------------------------------------------- 1 | SPAM = 'eggs' 2 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/havingmainpkg/__main__.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | 4 | def main(): 5 | print('__name__ is', __name__) 6 | print('__package__ is', __package__) 7 | from . import SPAM 8 | print(SPAM) 9 | 10 | 11 | if __name__ == '__main__': 12 | print('__name__ IS __main__') 13 | print('__package__ is', __package__) 14 | main() 15 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/import_havingpkgmain.py: -------------------------------------------------------------------------------- 1 | from __future__ import print_function 2 | 3 | print('STARTING') 4 | from havingmainpkg.__main__ import main 5 | print('IMPORTED') 6 | 7 | main() 8 | print('CALLED main()') 9 | -------------------------------------------------------------------------------- /grumpy-tools-src/tests/test_grumpy_tools.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """Tests for `grumpy_tools` package.""" 5 | 6 | import tempfile 7 | import unittest 8 | 9 | import pytest 10 | 11 | from click.testing import CliRunner 12 | 13 | from grumpy_tools import cli 14 | 15 | 16 | @pytest.fixture 17 | def response(): 18 | """Sample pytest fixture. 19 | 20 | See more at: http://doc.pytest.org/en/latest/fixture.html 21 | """ 22 | # import requests 23 | # return requests.get('https://github.com/audreyr/cookiecutter-pypackage') 24 | 25 | 26 | def test_content(response): 27 | """Sample pytest test function with the pytest fixture as an argument.""" 28 | # from bs4 import BeautifulSoup 29 | # assert 'GitHub' in BeautifulSoup(response.content).title.string 30 | 31 | 32 | @pytest.mark.xfail 33 | def test_command_line_interface(capfd): 34 | """Test the CLI.""" 35 | runner = CliRunner() 36 | out, err = capfd.readouterr() 37 | 38 | help_result = runner.invoke(cli.main, ['--help']) 39 | assert help_result.exit_code == 0 40 | 41 | result = runner.invoke(cli.main) 42 | assert result.exit_code == 0 43 | assert '>>> ' in out, (result.output, out, err) 44 | 45 | 46 | def test_run_input_inline(capfd): 47 | runner = CliRunner() 48 | result = runner.invoke(cli.main, ['run', '-c', "print('Hello World')",]) 49 | out, err = capfd.readouterr() 50 | assert out == 'Hello World\n', (err, result.output) 51 | assert result.exit_code == 0 52 | 53 | 54 | def test_run_input_stdin(capfd): 55 | runner = CliRunner() 56 | result = runner.invoke(cli.main, ['run'], input="print('Hello World')") 57 | 58 | out, err = capfd.readouterr() 59 | assert out == 'Hello World\n', (err, result.output) 60 | assert result.exit_code == 0 61 | 62 | 63 | def test_run_input_file(capfd): 64 | runner = CliRunner() 65 | with tempfile.NamedTemporaryFile() as script_file: 66 | script_file.write("print('Hello World')") 67 | script_file.flush() 68 | 69 | result = runner.invoke(cli.main, ['run', script_file.name]) 70 | 71 | out, err = capfd.readouterr() 72 | assert out == 'Hello World\n', (err, result.output) 73 | assert result.exit_code == 0 74 | --------------------------------------------------------------------------------