mirror of
				https://github.com/graphql-python/graphene.git
				synced 2025-11-04 09:57:41 +03:00 
			
		
		
		
	Merge pull request #56 from graphql-python/docs-playground
Docs playground
This commit is contained in:
		
						commit
						79b8870618
					
				
							
								
								
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| 
						 | 
					@ -63,5 +63,12 @@ target/
 | 
				
			||||||
/tests/django.sqlite
 | 
					/tests/django.sqlite
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/graphene/index.json
 | 
					/graphene/index.json
 | 
				
			||||||
 | 
					 | 
				
			||||||
/graphene/meta.json
 | 
					/graphene/meta.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/meta.json
 | 
				
			||||||
 | 
					/index.json
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/docs/playground/graphene-js/pypyjs-release-nojit/
 | 
				
			||||||
 | 
					/docs/static/playground/lib
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/docs/static/playground
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								.travis.yml
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								.travis.yml
									
									
									
									
									
								
							| 
						 | 
					@ -26,30 +26,35 @@ install:
 | 
				
			||||||
    pip install --download-cache $HOME/.cache/pip/ pytest pytest-cov coveralls six pytest-django
 | 
					    pip install --download-cache $HOME/.cache/pip/ pytest pytest-cov coveralls six pytest-django
 | 
				
			||||||
    pip install --download-cache $HOME/.cache/pip/ -e .[django]
 | 
					    pip install --download-cache $HOME/.cache/pip/ -e .[django]
 | 
				
			||||||
    python setup.py develop
 | 
					    python setup.py develop
 | 
				
			||||||
 | 
					  elif [ "$TEST_TYPE" = build_website ]; then
 | 
				
			||||||
 | 
					    pip install --download-cache $HOME/.cache/pip/ -e .
 | 
				
			||||||
 | 
					    python setup.py develop
 | 
				
			||||||
  elif [ "$TEST_TYPE" = lint ]; then
 | 
					  elif [ "$TEST_TYPE" = lint ]; then
 | 
				
			||||||
    pip install --download-cache $HOME/.cache/pip/ flake8
 | 
					    pip install --download-cache $HOME/.cache/pip/ flake8
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
script:
 | 
					script:
 | 
				
			||||||
- |
 | 
					- |
 | 
				
			||||||
  if [ "$TEST_TYPE" = build_website ]; then
 | 
					  if [ "$TEST_TYPE" = build_website ]; then
 | 
				
			||||||
    if [ "$TRAVIS_BRANCH" = "master" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
 | 
					    if [ "$TRAVIS_BRANCH" = "docs-playground" ] && [ "$TRAVIS_PULL_REQUEST" = false ]; then
 | 
				
			||||||
      echo "Building the web."
 | 
					      echo "Building the web."
 | 
				
			||||||
      nvm install 4.0
 | 
					      nvm install 4.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      GH_PAGES_DIR="$TRAVIS_BUILD_DIR"/docs/public
 | 
					      GH_PAGES_DIR="$TRAVIS_BUILD_DIR"/docs/public
 | 
				
			||||||
      git config --global user.name "Travis CI"
 | 
					      git config --global user.name "Travis CI"
 | 
				
			||||||
      git config --global user.email "travis@graphene-python.org"
 | 
					      git config --global user.email "travis@graphene-python.org"
 | 
				
			||||||
      git clone --branch gh-pages --depth=50 \
 | 
					      git clone --branch gh-pages-seg --depth=50 \
 | 
				
			||||||
        https://graphql-python-bot@github.com/graphql-python/graphene.git \
 | 
					        https://graphql-python-bot@github.com/graphql-python/graphene.git \
 | 
				
			||||||
        $GH_PAGES_DIR
 | 
					        $GH_PAGES_DIR
 | 
				
			||||||
      cd docs
 | 
					      cd docs
 | 
				
			||||||
      npm run build
 | 
					      ./playground/graphene-js/build.sh
 | 
				
			||||||
 | 
					      npm run deploy
 | 
				
			||||||
      cd $GH_PAGES_DIR
 | 
					      cd $GH_PAGES_DIR
 | 
				
			||||||
      git status
 | 
					      git status
 | 
				
			||||||
 | 
					      git add --intent-to-add .
 | 
				
			||||||
      if ! git diff-index --quiet HEAD --; then
 | 
					      if ! git diff-index --quiet HEAD --; then
 | 
				
			||||||
        git add -A .
 | 
					        git add -A .
 | 
				
			||||||
        git commit -m "Rebuild website"
 | 
					        git commit -m "Rebuild website"
 | 
				
			||||||
        git push "https://${GITHUB_TOKEN}@github.com/graphql-python/graphene.git" gh-pages
 | 
					        git push "https://${GITHUB_TOKEN}@github.com/graphql-python/graphene.git" gh-pages-seg
 | 
				
			||||||
      fi
 | 
					      fi
 | 
				
			||||||
      exit
 | 
					      exit
 | 
				
			||||||
    fi
 | 
					    fi
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1079
									
								
								docs/css/graphiql.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1079
									
								
								docs/css/graphiql.css
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -1,12 +1,13 @@
 | 
				
			||||||
@import 'nib'
 | 
					@import 'nib'
 | 
				
			||||||
@import 'jeet'
 | 
					@import 'jeet'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@import 'hljs.css'
 | 
					 | 
				
			||||||
@import 'bm.css'
 | 
					 | 
				
			||||||
@import 'https://fonts.googleapis.com/css?family=Raleway:400,500,600,200,100&.css'
 | 
					@import 'https://fonts.googleapis.com/css?family=Raleway:400,500,600,200,100&.css'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
normalize-css()
 | 
					normalize-css()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@import 'hljs.css'
 | 
				
			||||||
 | 
					@import 'bm.css'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$wrapper
 | 
					$wrapper
 | 
				
			||||||
  center(960px, pad:20px)
 | 
					  center(960px, pad:20px)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,6 +30,9 @@ html, body
 | 
				
			||||||
  font-size 16px
 | 
					  font-size 16px
 | 
				
			||||||
  color #606060
 | 
					  color #606060
 | 
				
			||||||
  line-height 1.5
 | 
					  line-height 1.5
 | 
				
			||||||
 | 
					  height 100%
 | 
				
			||||||
 | 
					  margin 0
 | 
				
			||||||
 | 
					  width 100%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.header
 | 
					.header
 | 
				
			||||||
  clearfix()
 | 
					  clearfix()
 | 
				
			||||||
| 
						 | 
					@ -339,7 +343,7 @@ $title
 | 
				
			||||||
  margin-top 0
 | 
					  margin-top 0
 | 
				
			||||||
  padding-top 0
 | 
					  padding-top 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.title
 | 
					.page-title
 | 
				
			||||||
  background: #F9F9F9;
 | 
					  background: #F9F9F9;
 | 
				
			||||||
  padding 48px 0
 | 
					  padding 48px 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										147
									
								
								docs/css/playground.styl
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										147
									
								
								docs/css/playground.styl
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,147 @@
 | 
				
			||||||
 | 
					@import 'graphiql.css'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.playground
 | 
				
			||||||
 | 
					  position absolute
 | 
				
			||||||
 | 
					  top 106px
 | 
				
			||||||
 | 
					  left 0
 | 
				
			||||||
 | 
					  right 0
 | 
				
			||||||
 | 
					  bottom 0
 | 
				
			||||||
 | 
					  display flex
 | 
				
			||||||
 | 
					  flex-direction row
 | 
				
			||||||
 | 
					  min-width 960px
 | 
				
			||||||
 | 
					  .loading
 | 
				
			||||||
 | 
					    position absolute
 | 
				
			||||||
 | 
					    display block
 | 
				
			||||||
 | 
					    left 0
 | 
				
			||||||
 | 
					    right 0
 | 
				
			||||||
 | 
					    bottom 0
 | 
				
			||||||
 | 
					    top 0
 | 
				
			||||||
 | 
					    z-index 10000
 | 
				
			||||||
 | 
					    background rgba(255,255,255,.6)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.playground-schema
 | 
				
			||||||
 | 
					  min-width 400px
 | 
				
			||||||
 | 
					  width 36%
 | 
				
			||||||
 | 
					  border-right 1px solid #E0E0E0
 | 
				
			||||||
 | 
					  // box-shadow 0 0 8px rgba(0, 0, 0, 0.15)
 | 
				
			||||||
 | 
					  position relative
 | 
				
			||||||
 | 
					  z-index 100
 | 
				
			||||||
 | 
					  display flex
 | 
				
			||||||
 | 
					  flex-direction: column
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .cm-def
 | 
				
			||||||
 | 
					  .cm-variable + .cm-keyword // lambda
 | 
				
			||||||
 | 
					    &:not(.CodeMirror-lint-mark-error)
 | 
				
			||||||
 | 
					      transition all .3s ease-in-out
 | 
				
			||||||
 | 
					      background transparent
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .activeline
 | 
				
			||||||
 | 
					    .cm-def
 | 
				
			||||||
 | 
					    .cm-variable + .cm-keyword // lambda
 | 
				
			||||||
 | 
					      $color = #D7D3F1
 | 
				
			||||||
 | 
					      // $color = rgba(219, 89, 76, .2)
 | 
				
			||||||
 | 
					      background $color
 | 
				
			||||||
 | 
					      border-radius 1px
 | 
				
			||||||
 | 
					      box-shadow 0 0 0 2px $color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.playground-schema-editor
 | 
				
			||||||
 | 
					  flex 1
 | 
				
			||||||
 | 
					  position relative
 | 
				
			||||||
 | 
					  .CodeMirror
 | 
				
			||||||
 | 
					    font-size: 13px;
 | 
				
			||||||
 | 
					    position absolute
 | 
				
			||||||
 | 
					    height 100%
 | 
				
			||||||
 | 
					    width 100%
 | 
				
			||||||
 | 
					    top 0
 | 
				
			||||||
 | 
					    left 0
 | 
				
			||||||
 | 
					    right 0
 | 
				
			||||||
 | 
					    bottom 0
 | 
				
			||||||
 | 
					    font-family: 'Consolas', 'Inconsolata', 'Droid Sans Mono', 'Monaco', monospace;
 | 
				
			||||||
 | 
					    color: #141823;
 | 
				
			||||||
 | 
					  .CodeMirror-lines
 | 
				
			||||||
 | 
					    padding 20px 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.playground-schema-header
 | 
				
			||||||
 | 
					  // height 48px
 | 
				
			||||||
 | 
					  // font-family 'Raleway', sans-serif
 | 
				
			||||||
 | 
					  // font-weight 300
 | 
				
			||||||
 | 
					  // line-height 48px
 | 
				
			||||||
 | 
					  // padding 0 10px
 | 
				
			||||||
 | 
					  // border-bottom solid 1px #d0d0d0
 | 
				
			||||||
 | 
					  height: 48px;
 | 
				
			||||||
 | 
					  box-sizing border-box
 | 
				
			||||||
 | 
					  font-family: 'Raleway', sans-serif;
 | 
				
			||||||
 | 
					  color: #999;
 | 
				
			||||||
 | 
					  font-weight: 600;
 | 
				
			||||||
 | 
					  font-size: 12px;
 | 
				
			||||||
 | 
					  text-transform: uppercase;
 | 
				
			||||||
 | 
					  line-height: 52px;
 | 
				
			||||||
 | 
					  padding: 0 12px;
 | 
				
			||||||
 | 
					  border-bottom: solid 1px #d0d0d0;
 | 
				
			||||||
 | 
					  background: #F9F9F9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.playground-graphiql
 | 
				
			||||||
 | 
					  flex 1
 | 
				
			||||||
 | 
					  height 100%
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.cm-s-graphene
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					/* Comment */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-comment
 | 
				
			||||||
 | 
					  color: #999;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Punctuation */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-punctuation
 | 
				
			||||||
 | 
					  color: #555;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Keyword */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-keyword
 | 
				
			||||||
 | 
					  // color: #B11A04;
 | 
				
			||||||
 | 
					  // color #D2054E
 | 
				
			||||||
 | 
					  color #a71d5d
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* OperationName, FragmentName */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-def
 | 
				
			||||||
 | 
					  // color: #D2054E;
 | 
				
			||||||
 | 
					  color: #1F61A0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* FieldName */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-property
 | 
				
			||||||
 | 
					  color: #333;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* FieldAlias */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-qualifier
 | 
				
			||||||
 | 
					  color: #1C92A9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* ArgumentName and ObjectFieldName */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-attribute
 | 
				
			||||||
 | 
					  color: #8B2BB9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Number */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-number
 | 
				
			||||||
 | 
					  color: #2882F9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* String */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-string
 | 
				
			||||||
 | 
					  color: #D64292;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Boolean */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-builtin
 | 
				
			||||||
 | 
					  color: #D47509;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* EnumValue */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-string-2
 | 
				
			||||||
 | 
					  color: #0B7FC7;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Variable */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-variable
 | 
				
			||||||
 | 
					  color: #333;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Directive */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-meta
 | 
				
			||||||
 | 
					  color: #B33086;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Type */
 | 
				
			||||||
 | 
					.cm-s-graphene .cm-atom
 | 
				
			||||||
 | 
					  color: #CA9800;
 | 
				
			||||||
| 
						 | 
					@ -3,27 +3,39 @@ var jeet = require("jeet");
 | 
				
			||||||
var rupture = require("rupture");
 | 
					var rupture = require("rupture");
 | 
				
			||||||
var path = require("path");
 | 
					var path = require("path");
 | 
				
			||||||
var ExtractTextPlugin = require("extract-text-webpack-plugin");
 | 
					var ExtractTextPlugin = require("extract-text-webpack-plugin");
 | 
				
			||||||
 | 
					var webpack = require("webpack");
 | 
				
			||||||
var CopyWebpackPlugin = require('copy-webpack-plugin');
 | 
					var CopyWebpackPlugin = require('copy-webpack-plugin');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = function(config, env) {
 | 
					module.exports = function(config, env) {
 | 
				
			||||||
  var IS_STATIC = env === 'static';
 | 
					  var IS_STATIC = env === 'static';
 | 
				
			||||||
 | 
					  var entry = config._config.entry.slice();
 | 
				
			||||||
 | 
					  var publicPath = config._config.output.publicPath;
 | 
				
			||||||
 | 
					  // var output = config._config.output;
 | 
				
			||||||
 | 
					  // output.filename = "[name].js";
 | 
				
			||||||
 | 
					  config._config.entry = {
 | 
				
			||||||
 | 
					    bundle: entry,
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
  config.merge({
 | 
					  config.merge({
 | 
				
			||||||
    stylus: {
 | 
					    stylus: {
 | 
				
			||||||
      use: [nib(), jeet(), rupture()]
 | 
					      use: [nib(), jeet(), rupture()]
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    output: {
 | 
				
			||||||
 | 
					      filename: "[name].js",
 | 
				
			||||||
 | 
					      publicPath: "/",
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    resolveLoader: {
 | 
					    resolveLoader: {
 | 
				
			||||||
      root: path.join(__dirname, "node_modules"),
 | 
					      root: path.join(__dirname, "node_modules"),
 | 
				
			||||||
      modulesDirectories: ['./'],
 | 
					      modulesDirectories: ['./'],
 | 
				
			||||||
      alias: {
 | 
					 | 
				
			||||||
        'copy': 'file-loader?name=[path][name].[ext]&context=./static',
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    resolve: {
 | 
					    resolve: {
 | 
				
			||||||
      root: path.join(__dirname, "node_modules"),
 | 
					      root: path.join(__dirname, "node_modules"),
 | 
				
			||||||
      alias: {
 | 
					      alias: {
 | 
				
			||||||
        'original-react': path.join(__dirname, "node_modules", "react"),
 | 
					        'original-react': path.join(__dirname, "node_modules", "react"),
 | 
				
			||||||
        'react/lib': path.join(__dirname, "node_modules", "react", "lib"),
 | 
					        'react/lib': path.join(__dirname, "node_modules", "react", "lib"),
 | 
				
			||||||
        'react': path.join(__dirname, 'patched-react.js')
 | 
					        'react': path.join(__dirname, 'patched-react.js'),
 | 
				
			||||||
 | 
					        'pypyjs': '../playground/graphene-js/pypyjs',
 | 
				
			||||||
 | 
					        'playground-page': (env != "static")?'../playground/page':'../pages/_empty',
 | 
				
			||||||
 | 
					        'playground-wrapper': (env == "develop")?'../playground/page':'../playground/wrapper',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      modulesDirectories: ['./']
 | 
					      modulesDirectories: ['./']
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -32,6 +44,13 @@ module.exports = function(config, env) {
 | 
				
			||||||
    config.plugin('extract-css', ExtractTextPlugin, ["app.css"]);
 | 
					    config.plugin('extract-css', ExtractTextPlugin, ["app.css"]);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  config.plugin('static', CopyWebpackPlugin, [[{ from: '../static'}]]);
 | 
					  config.plugin('static', CopyWebpackPlugin, [[{ from: '../static'}]]);
 | 
				
			||||||
 | 
					  config.plugin('define-env', webpack.DefinePlugin, [{
 | 
				
			||||||
 | 
					    "ENV": JSON.stringify(env),
 | 
				
			||||||
 | 
					    "PUBLIC_PATH": JSON.stringify(publicPath),
 | 
				
			||||||
 | 
					  }]);
 | 
				
			||||||
 | 
					  // if (env != "static") {
 | 
				
			||||||
 | 
					  //   config.plugin('commons', webpack.optimize.CommonsChunkPlugin, ["commons.js"]);
 | 
				
			||||||
 | 
					  // }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  config.loader('stylus', function(cfg) {
 | 
					  config.loader('stylus', function(cfg) {
 | 
				
			||||||
    cfg.test = /\.styl$/;
 | 
					    cfg.test = /\.styl$/;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,7 +5,7 @@ export default class Html extends React.Component {
 | 
				
			||||||
  render() {
 | 
					  render() {
 | 
				
			||||||
    var title = this.props.title || DocumentTitle.rewind();
 | 
					    var title = this.props.title || DocumentTitle.rewind();
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <html lang={this.props.lang}>
 | 
					      <html lang={this.props.lang} manifest="/graphene.appcache">
 | 
				
			||||||
        <head>
 | 
					        <head>
 | 
				
			||||||
          <meta charSet="utf-8"/>
 | 
					          <meta charSet="utf-8"/>
 | 
				
			||||||
          <meta httpEquiv="X-UA-Compatible" content="IE=edge"/>
 | 
					          <meta httpEquiv="X-UA-Compatible" content="IE=edge"/>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,9 +13,13 @@
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
  "license": "MIT",
 | 
					  "license": "MIT",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "codemirror": "5.9.0",
 | 
				
			||||||
    "copy-webpack-plugin": "^0.2.0",
 | 
					    "copy-webpack-plugin": "^0.2.0",
 | 
				
			||||||
 | 
					    "es6-promise": "^3.0.2",
 | 
				
			||||||
    "extract-text-webpack-plugin": "^0.9.1",
 | 
					    "extract-text-webpack-plugin": "^0.9.1",
 | 
				
			||||||
    "gatsby": "^0.7.2",
 | 
					    "gatsby": "^0.7.3",
 | 
				
			||||||
 | 
					    "graphiql": "^0.4.2",
 | 
				
			||||||
 | 
					    "graphql": "^0.4.13",
 | 
				
			||||||
    "jeet": "^6.1.2",
 | 
					    "jeet": "^6.1.2",
 | 
				
			||||||
    "lodash": "^3.10.1",
 | 
					    "lodash": "^3.10.1",
 | 
				
			||||||
    "nib": "^1.1.0",
 | 
					    "nib": "^1.1.0",
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										9
									
								
								docs/pages/_empty.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								docs/pages/_empty.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Empty extends React.Component {
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					      return <div />;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = Empty;
 | 
				
			||||||
| 
						 | 
					@ -14,7 +14,7 @@ class Template extends React.Component {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
        <Menu width={200} right>
 | 
					        <Menu width={200} right>
 | 
				
			||||||
            <span><Link to="/try/">Try it out</Link></span>
 | 
					            <span><Link to="/playground/" className={path.indexOf('/playground')==0?"active":null}>Try it out</Link></span>
 | 
				
			||||||
            <span><Link to="/docs/quickstart/" className={path.indexOf('/docs')==0?"active":null}>Docs</Link></span>
 | 
					            <span><Link to="/docs/quickstart/" className={path.indexOf('/docs')==0?"active":null}>Docs</Link></span>
 | 
				
			||||||
            <span><Link to="/community/">Community</Link></span>
 | 
					            <span><Link to="/community/">Community</Link></span>
 | 
				
			||||||
            <a href="https://github.com/graphql-python/graphene/">Github</a>
 | 
					            <a href="https://github.com/graphql-python/graphene/">Github</a>
 | 
				
			||||||
| 
						 | 
					@ -26,7 +26,7 @@ class Template extends React.Component {
 | 
				
			||||||
                    Graphene
 | 
					                    Graphene
 | 
				
			||||||
                </Link>
 | 
					                </Link>
 | 
				
			||||||
                <nav className="header-nav">
 | 
					                <nav className="header-nav">
 | 
				
			||||||
                    <Link to="/try/">Try it out</Link>
 | 
					                    <Link to="/playground/" className={path.indexOf('/playground')==0?"active":null}>Try it out</Link>
 | 
				
			||||||
                    <Link to="/docs/quickstart/" className={path.indexOf('/docs')==0?"active":null}>Docs</Link>
 | 
					                    <Link to="/docs/quickstart/" className={path.indexOf('/docs')==0?"active":null}>Docs</Link>
 | 
				
			||||||
                    <Link to="/community/">Community</Link>
 | 
					                    <Link to="/community/">Community</Link>
 | 
				
			||||||
                    <a href="https://github.com/graphql-python/graphene/">Github</a>
 | 
					                    <a href="https://github.com/graphql-python/graphene/">Github</a>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -34,7 +34,7 @@ class Template extends React.Component {
 | 
				
			||||||
    var next_page = pages[next_page_index];
 | 
					    var next_page = pages[next_page_index];
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <div>
 | 
					      <div>
 | 
				
			||||||
        <div className="title"><h1>Documentation</h1></div>
 | 
					        <div className="page-title"><h1>Documentation</h1></div>
 | 
				
			||||||
        <div className="docs">
 | 
					        <div className="docs">
 | 
				
			||||||
          <aside className="docs-aside">
 | 
					          <aside className="docs-aside">
 | 
				
			||||||
              {aside_links}
 | 
					              {aside_links}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										13
									
								
								docs/pages/playground.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docs/pages/playground.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import DocumentTitle from 'react-document-title';
 | 
				
			||||||
 | 
					import PlaygroundWrapper from 'playground-wrapper';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Playground extends React.Component {
 | 
				
			||||||
 | 
					  render() {
 | 
				
			||||||
 | 
					    return <DocumentTitle title="Playground - Graphene">
 | 
				
			||||||
 | 
					      <PlaygroundWrapper />
 | 
				
			||||||
 | 
					    </DocumentTitle>;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = Playground;
 | 
				
			||||||
							
								
								
									
										234
									
								
								docs/playground/GraphenePlayground.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										234
									
								
								docs/playground/GraphenePlayground.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,234 @@
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import ReactDOM from 'react-dom';
 | 
				
			||||||
 | 
					import { RouteHandler, Link, State } from 'react-router';
 | 
				
			||||||
 | 
					import CodeMirror from 'codemirror';
 | 
				
			||||||
 | 
					import { graphql } from 'graphql';
 | 
				
			||||||
 | 
					import GraphiQL from 'graphiql';
 | 
				
			||||||
 | 
					import schema from './schema';
 | 
				
			||||||
 | 
					import pypyjs_vm from 'pypyjs';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'codemirror/mode/python/python';
 | 
				
			||||||
 | 
					import 'codemirror/addon/lint/lint';
 | 
				
			||||||
 | 
					import '../css/playground.styl';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (typeof PUBLIC_PATH === "undefined") {
 | 
				
			||||||
 | 
					  var PUBLIC_PATH = '';
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypyjs_vm.rootURL = `${PUBLIC_PATH}/playground/lib/`;
 | 
				
			||||||
 | 
					pypyjs_vm.cacheKey = 'graphene';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CodeMirror.registerHelper('lint', 'python', function (text, options, editor) {
 | 
				
			||||||
 | 
					  return (options.errors || []).map((error) => {
 | 
				
			||||||
 | 
					    var tokens = editor.getLineTokens(error.line - 1);
 | 
				
			||||||
 | 
					    tokens = tokens.filter((token, pos) => {
 | 
				
			||||||
 | 
					      return !!token.type || token.string.trim().length > 0;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    if (!tokens) return [];
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      message: `${error.name}: ${error.message}`,
 | 
				
			||||||
 | 
					      severity: 'error',
 | 
				
			||||||
 | 
					      type: 'syntax',
 | 
				
			||||||
 | 
					      from: CodeMirror.Pos(error.line - 1, tokens[0].start),
 | 
				
			||||||
 | 
					      to: CodeMirror.Pos(error.line - 1, tokens[tokens.length-1].end),
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function graphQLFetcher(graphQLParams) {
 | 
				
			||||||
 | 
					  return graphql(schema, graphQLParams.query);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var default_interpreter;
 | 
				
			||||||
 | 
					class Playground extends React.Component {
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    super();
 | 
				
			||||||
 | 
					    this.state = {pypyjs: false, stdout: '', response:''};
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  stdout() {
 | 
				
			||||||
 | 
					    console.log('stdout', arguments);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  componentDidMount() {
 | 
				
			||||||
 | 
					    if (default_interpreter) {
 | 
				
			||||||
 | 
					      this.pypy_interpreter = default_interpreter;
 | 
				
			||||||
 | 
					      this.pypy_interpreter.stdout = this.stdout.bind(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					      this.pypy_interpreter = new pypyjs_vm({
 | 
				
			||||||
 | 
					        stdin: function(){},
 | 
				
			||||||
 | 
					        stdout: this.stdout.bind(this),
 | 
				
			||||||
 | 
					        stderr: function(){},
 | 
				
			||||||
 | 
					        rootURL: `${PUBLIC_PATH}/playground/lib/`
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					      default_interpreter = this.pypy_interpreter;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.pypyjs = this.pypy_interpreter.ready().then(() => {
 | 
				
			||||||
 | 
					      return this.pypy_interpreter.exec(`
 | 
				
			||||||
 | 
					import graphene
 | 
				
			||||||
 | 
					import js
 | 
				
			||||||
 | 
					from collections import OrderedDict
 | 
				
			||||||
 | 
					from graphql.core.execution.executor import Executor
 | 
				
			||||||
 | 
					from graphql.core.execution.middlewares.sync import SynchronousExecutionMiddleware
 | 
				
			||||||
 | 
					from graphql.core.error import GraphQLError, format_error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def get_wrapped(f):
 | 
				
			||||||
 | 
					    if hasattr(f, 'func_closure') and f.func_closure:
 | 
				
			||||||
 | 
					        return get_wrapped(f.func_closure[0].cell_contents)
 | 
				
			||||||
 | 
					    return f
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class TrackResolver(SynchronousExecutionMiddleware):
 | 
				
			||||||
 | 
					    @staticmethod
 | 
				
			||||||
 | 
					    def run_resolve_fn(resolver, original_resolver):
 | 
				
			||||||
 | 
					        if resolver.func.__module__ == '__main__':
 | 
				
			||||||
 | 
					            line = get_wrapped(resolver.func).resolver.func_code.co_firstlineno
 | 
				
			||||||
 | 
					            js.globals.markLine(line-3)
 | 
				
			||||||
 | 
					        return SynchronousExecutionMiddleware.run_resolve_fn(resolver, original_resolver)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					__graphene_executor = Executor([TrackResolver()], map_type=OrderedDict)
 | 
				
			||||||
 | 
					`);
 | 
				
			||||||
 | 
					    }).then(() => {
 | 
				
			||||||
 | 
					      this.createSchema(this.props.initialSchema);
 | 
				
			||||||
 | 
					    }).then(() => {
 | 
				
			||||||
 | 
					      this.setState({pypyjs: true, response:'"Execute the query for see the results"'});
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    window.markLine = (lineNo) => {
 | 
				
			||||||
 | 
					      this.markLine(lineNo);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.editor = CodeMirror(ReactDOM.findDOMNode(this.refs.schemaCode), {
 | 
				
			||||||
 | 
					      value: this.props.initialSchema,
 | 
				
			||||||
 | 
					      mode:  "python",
 | 
				
			||||||
 | 
					      theme: "graphene",
 | 
				
			||||||
 | 
					      lineNumbers: true,
 | 
				
			||||||
 | 
					      tabSize: 4,
 | 
				
			||||||
 | 
					      indentUnit: 4,
 | 
				
			||||||
 | 
					      gutters: ["CodeMirror-linenumbers", "breakpoints"],
 | 
				
			||||||
 | 
					      lint: {
 | 
				
			||||||
 | 
					        errors: [],
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    this.editor.on("change", this.onEditorChange.bind(this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  onEditorChange() {
 | 
				
			||||||
 | 
					    if (this.changeTimeout) {
 | 
				
			||||||
 | 
					      clearTimeout(this.changeTimeout);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (this.props.onEditSchema) {
 | 
				
			||||||
 | 
					      var value = this.editor.getValue();
 | 
				
			||||||
 | 
					      if (value != this.props.initialSchema) {
 | 
				
			||||||
 | 
					        this.props.onEditSchema(value)
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    this.changeTimeout = setTimeout(() =>
 | 
				
			||||||
 | 
					      this.updateSchema()
 | 
				
			||||||
 | 
					    , 300);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  updateSchema() {
 | 
				
			||||||
 | 
					    this.createSchema(this.editor.getValue());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  createSchema(code) {
 | 
				
			||||||
 | 
					    if (this.previousCode == code) return;
 | 
				
			||||||
 | 
					    console.log('createSchema');
 | 
				
			||||||
 | 
					    this.validSchema = null;
 | 
				
			||||||
 | 
					    this.pypyjs.then(() => {
 | 
				
			||||||
 | 
					      return this.pypy_interpreter.exec(`
 | 
				
			||||||
 | 
					schema = None
 | 
				
			||||||
 | 
					${code}
 | 
				
			||||||
 | 
					assert schema, 'You have to define a schema'
 | 
				
			||||||
 | 
					`)
 | 
				
			||||||
 | 
					    }).then(() => {
 | 
				
			||||||
 | 
					      console.log('NO ERRORS');
 | 
				
			||||||
 | 
					      this.removeErrors();
 | 
				
			||||||
 | 
					      this.validSchema = true;
 | 
				
			||||||
 | 
					    }, (err) => {
 | 
				
			||||||
 | 
					      this.editor.options.lint.errors = [];
 | 
				
			||||||
 | 
					      console.log('ERRORS', err);
 | 
				
			||||||
 | 
					      this.logError(err);
 | 
				
			||||||
 | 
					      this.validSchema = false;
 | 
				
			||||||
 | 
					    }).then(this.updateGraphiQL.bind(this));
 | 
				
			||||||
 | 
					    this.previousCode = code;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  updateGraphiQL() {
 | 
				
			||||||
 | 
					    if (this.validSchema) {
 | 
				
			||||||
 | 
					      this.refs.graphiql.state.schema = null;
 | 
				
			||||||
 | 
					      this.refs.graphiql.componentDidMount();
 | 
				
			||||||
 | 
					      this.refs.graphiql.forceUpdate();
 | 
				
			||||||
 | 
					      this.refs.graphiql.refs.docExplorer.forceUpdate();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  logError(error) {
 | 
				
			||||||
 | 
					    var lines = error.trace.split('\n');
 | 
				
			||||||
 | 
					    var file_errors = lines.map((errorLine) => {
 | 
				
			||||||
 | 
					      return errorLine.match(/File "<string>", line (\d+)/);
 | 
				
			||||||
 | 
					    }).filter((x) => !! x);
 | 
				
			||||||
 | 
					    if (!file_errors.length) return;
 | 
				
			||||||
 | 
					    var line = parseInt(file_errors[file_errors.length-1][1]);
 | 
				
			||||||
 | 
					    error.line = line-2;
 | 
				
			||||||
 | 
					    if (error.name == "ImportError" && error.message == "No module named django") {
 | 
				
			||||||
 | 
					      error.message = "Django is not supported yet in Playground editor";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.editor.options.lint.errors.push(error);
 | 
				
			||||||
 | 
					    CodeMirror.signal(this.editor, 'change', this.editor);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  removeErrors() {
 | 
				
			||||||
 | 
					    this.editor.options.lint.errors = [];
 | 
				
			||||||
 | 
					    CodeMirror.signal(this.editor, 'change', this.editor);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  fetcher (graphQLParams) {
 | 
				
			||||||
 | 
					    if (!this.validSchema) {
 | 
				
			||||||
 | 
					      return graphQLFetcher(arguments);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return this.execute(graphQLParams.query);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  execute(query) {
 | 
				
			||||||
 | 
					    // console.log('execute', query);
 | 
				
			||||||
 | 
					    return this.pypyjs.then(() => {
 | 
				
			||||||
 | 
					      var x = `
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					result = __graphene_executor.execute(schema.schema, '''${query}''')
 | 
				
			||||||
 | 
					result_dict = {};
 | 
				
			||||||
 | 
					if result.errors:
 | 
				
			||||||
 | 
					  result_dict['errors'] = [format_error(e) for e in result.errors]
 | 
				
			||||||
 | 
					if result.data:
 | 
				
			||||||
 | 
					  result_dict['data'] = result.data
 | 
				
			||||||
 | 
					result_json = json.dumps(result_dict)
 | 
				
			||||||
 | 
					`;
 | 
				
			||||||
 | 
					      return this.pypy_interpreter.exec(x)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ).then(() =>
 | 
				
			||||||
 | 
					      this.pypy_interpreter.get(`result_json`)
 | 
				
			||||||
 | 
					    ).then((data) => {
 | 
				
			||||||
 | 
					      var json_data = JSON.parse(data);
 | 
				
			||||||
 | 
					      return json_data;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  markLine(lineNo) {
 | 
				
			||||||
 | 
					    console.log(lineNo);
 | 
				
			||||||
 | 
					    var hlLine = this.editor.addLineClass(lineNo, "text", "activeline");
 | 
				
			||||||
 | 
					    // var mark = this.editor.markText({line: lineNo, ch: 0}, {line: lineNo, ch: 10}, {className: "called-function"});
 | 
				
			||||||
 | 
					    setTimeout(() => {
 | 
				
			||||||
 | 
					        this.editor.removeLineClass(lineNo, "text", "activeline");
 | 
				
			||||||
 | 
					    }, 1200);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  render() {
 | 
				
			||||||
 | 
					    return (
 | 
				
			||||||
 | 
					      <div className="playground">
 | 
				
			||||||
 | 
					        {!this.state.pypyjs?<div className="loading" />:null}
 | 
				
			||||||
 | 
					        <div className="playground-schema">
 | 
				
			||||||
 | 
					          <header className="playground-schema-header">
 | 
				
			||||||
 | 
					            Schema
 | 
				
			||||||
 | 
					          </header>
 | 
				
			||||||
 | 
					          <div className="playground-schema-editor" ref="schemaCode" />
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div className="playground-graphiql">
 | 
				
			||||||
 | 
					            <GraphiQL ref="graphiql" fetcher={this.fetcher.bind(this)} response={this.state.response} onEditQuery={this.props.onEditQuery} query={this.props.initialQuery}/>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					      </div>
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = Playground;
 | 
				
			||||||
							
								
								
									
										4
									
								
								docs/playground/examples/hello.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								docs/playground/examples/hello.graphql
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,4 @@
 | 
				
			||||||
 | 
					query {
 | 
				
			||||||
 | 
					  hello
 | 
				
			||||||
 | 
					  ping(to:"Peter")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								docs/playground/examples/hello.schema.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								docs/playground/examples/hello.schema.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,13 @@
 | 
				
			||||||
 | 
					import graphene
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
 | 
					    hello = graphene.String()
 | 
				
			||||||
 | 
					    ping = graphene.String(to=graphene.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_hello(self, args, info):
 | 
				
			||||||
 | 
					        return 'World'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_ping(self, args, info):
 | 
				
			||||||
 | 
					        return 'Pinging {}'.format(args.get('to'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema = graphene.Schema(query=Query)
 | 
				
			||||||
							
								
								
									
										8
									
								
								docs/playground/examples/tea_store.graphql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docs/playground/examples/tea_store.graphql
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					query {
 | 
				
			||||||
 | 
					  store {
 | 
				
			||||||
 | 
					    teas(orderBy:"name") {
 | 
				
			||||||
 | 
					      name
 | 
				
			||||||
 | 
					      steepingTime
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										38
									
								
								docs/playground/examples/tea_store.schema.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								docs/playground/examples/tea_store.schema.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,38 @@
 | 
				
			||||||
 | 
					import graphene
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Tea(graphene.ObjectType):
 | 
				
			||||||
 | 
					    name = graphene.String()
 | 
				
			||||||
 | 
					    steeping_time = graphene.Int()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TEAS = [
 | 
				
			||||||
 | 
					    Tea(name='Earl Grey Blue Star', steeping_time=5),
 | 
				
			||||||
 | 
					    Tea(name='Milk Oolong', steeping_time=3),
 | 
				
			||||||
 | 
					    Tea(name='Gunpowder Golden Temple', steeping_time=3),
 | 
				
			||||||
 | 
					    Tea(name='Assam Hatimara', steeping_time=5),
 | 
				
			||||||
 | 
					    Tea(name='Bancha', steeping_time=2),
 | 
				
			||||||
 | 
					    Tea(name='Ceylon New Vithanakande', steeping_time=5),
 | 
				
			||||||
 | 
					    Tea(name='Golden Tip Yunnan', steeping_time=5),
 | 
				
			||||||
 | 
					    Tea(name='Jasmine Phoenix Pearls', steeping_time=3),
 | 
				
			||||||
 | 
					    Tea(name='Kenya Milima', steeping_time=5),
 | 
				
			||||||
 | 
					    Tea(name='Pu Erh First Grade', steeping_time=4),
 | 
				
			||||||
 | 
					    Tea(name='Sencha Makoto', steeping_time=3),
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Store(graphene.ObjectType):
 | 
				
			||||||
 | 
					    teas = graphene.List(Tea, order_by=graphene.String())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_teas(self, args, info):
 | 
				
			||||||
 | 
					        order_by = args.get("order_by")
 | 
				
			||||||
 | 
					        if order_by == "steepingTime":
 | 
				
			||||||
 | 
					            return sorted(self.teas, key=lambda tea: tea.steeping_time)
 | 
				
			||||||
 | 
					        elif order_by == "name":
 | 
				
			||||||
 | 
					            return sorted(self.teas, key=lambda tea: tea.name)
 | 
				
			||||||
 | 
					        return self.teas
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
 | 
					    store = graphene.Field(Store)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_store(self, args, info):
 | 
				
			||||||
 | 
					        return Store(teas=TEAS) 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema = graphene.Schema(query=Query)
 | 
				
			||||||
							
								
								
									
										1
									
								
								docs/playground/graphene-js/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								docs/playground/graphene-js/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1 @@
 | 
				
			||||||
 | 
					pypy-release-nojit
 | 
				
			||||||
							
								
								
									
										107
									
								
								docs/playground/graphene-js/FunctionPromise.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								docs/playground/graphene-js/FunctionPromise.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,107 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// FunctionPromise: possibly-asynchronous function constructor.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This is a prototype polyfill for a FunctionPromise object as described in:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    https://bugzilla.mozilla.org/show_bug.cgi?id=854627
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Where possible it will arrange for the function body to be parsed/compiled
 | 
				
			||||||
 | 
					// off of the main thread, with the function object returned asynchronously
 | 
				
			||||||
 | 
					// via a promise.  The fallback implementation processes just falls back to
 | 
				
			||||||
 | 
					// the standard synchronous Function() constructor.
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					// It doesn't (yet) have the following features from the linked proposal:
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//    * ability to copy to different workers
 | 
				
			||||||
 | 
					//    * ability to store in IndexedDB
 | 
				
			||||||
 | 
					// 
 | 
				
			||||||
 | 
					function FunctionPromise(/* [args1[, args2[, ...argN]],], functionBody) */) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var useFallback =
 | 
				
			||||||
 | 
					    typeof window === "undefined" ||
 | 
				
			||||||
 | 
					    window.FunctionPromise !== FunctionPromise ||
 | 
				
			||||||
 | 
					    typeof document === "undefined" ||
 | 
				
			||||||
 | 
					    typeof document.createElement === "undefined" ||
 | 
				
			||||||
 | 
					    typeof document.head === "undefined" ||
 | 
				
			||||||
 | 
					    typeof document.head.appendChild === "undefined" ||
 | 
				
			||||||
 | 
					    typeof Blob === "undefined" ||
 | 
				
			||||||
 | 
					    typeof URL === "undefined" ||
 | 
				
			||||||
 | 
					    typeof URL.createObjectURL === "undefined";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var args = Array.prototype.slice.call(arguments);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // For the fallback case, we just use the normal Function constructor.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (useFallback) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      var fn = Function.apply(null, args);
 | 
				
			||||||
 | 
					      return Promise.resolve(fn);
 | 
				
			||||||
 | 
					    } catch (err) {
 | 
				
			||||||
 | 
					      return Promise.reject(err);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // If we have all the necessary pieces, we can do this asynchronously
 | 
				
			||||||
 | 
					  // by writing a <script> tag into the DOM.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  var funcid = FunctionPromise._nextid++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  return new Promise(function(resolve, reject) {
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      var funcSrc = [];
 | 
				
			||||||
 | 
					      funcSrc.push("window.FunctionPromise._results[" + funcid + "]=");
 | 
				
			||||||
 | 
					      funcSrc.push("function(");
 | 
				
			||||||
 | 
					      if (args.length > 1) {
 | 
				
			||||||
 | 
					        funcSrc.push(args[0]);
 | 
				
			||||||
 | 
					        for (var i = 1; i < args.length - 1; i++) {
 | 
				
			||||||
 | 
					          funcSrc.push(",");
 | 
				
			||||||
 | 
					          funcSrc.push(args[i]);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      funcSrc.push("){");
 | 
				
			||||||
 | 
					      funcSrc.push(args[args.length - 1]);
 | 
				
			||||||
 | 
					      funcSrc.push("}");
 | 
				
			||||||
 | 
					      var dataUrl = URL.createObjectURL(new Blob(funcSrc));
 | 
				
			||||||
 | 
					      var scriptTag = document.createElement("script");
 | 
				
			||||||
 | 
					      var cleanup = function() {
 | 
				
			||||||
 | 
					        URL.revokeObjectURL(dataUrl);
 | 
				
			||||||
 | 
					        scriptTag.remove();
 | 
				
			||||||
 | 
					        delete window.FunctionPromise._results[funcid];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      scriptTag.onerror = function() {
 | 
				
			||||||
 | 
					        reject(new Error("unknown error loading FunctionPromise"))
 | 
				
			||||||
 | 
					        cleanup();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      scriptTag.onload = function() {
 | 
				
			||||||
 | 
					        if (window.FunctionPromise._results[funcid]) {
 | 
				
			||||||
 | 
					          resolve(window.FunctionPromise._results[funcid]);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          // No function, something must have gone wrong.
 | 
				
			||||||
 | 
					          // Likely a syntax error in the function body string.
 | 
				
			||||||
 | 
					          // Fall back to Function() constructor to surface it.
 | 
				
			||||||
 | 
					          try {
 | 
				
			||||||
 | 
					            Function.apply(null, args);
 | 
				
			||||||
 | 
					            reject(new Error("unknown error fulfilling FunctionPromise"));
 | 
				
			||||||
 | 
					          } catch (err) {
 | 
				
			||||||
 | 
					            reject(err);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        cleanup();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      scriptTag.src = dataUrl;
 | 
				
			||||||
 | 
					      document.head.appendChild(scriptTag);
 | 
				
			||||||
 | 
					    } catch (err) {
 | 
				
			||||||
 | 
					      reject(err);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					FunctionPromise._nextid = 0;
 | 
				
			||||||
 | 
					FunctionPromise._results = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (typeof module !== "undefined" && typeof module.exports !== "undefined") {
 | 
				
			||||||
 | 
					  if (typeof Promise === "undefined") {
 | 
				
			||||||
 | 
					    Promise = require('es6-promise').Promise;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  module.exports = FunctionPromise;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										36
									
								
								docs/playground/graphene-js/build.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										36
									
								
								docs/playground/graphene-js/build.sh
									
									
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cd "$(dirname "$0")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ ! -d pypyjs-release-nojit ] ; then
 | 
				
			||||||
 | 
						git clone https://github.com/pypyjs/pypyjs-release-nojit.git
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					GRAPHENE_DIR="$(python -c "import os; import graphene; print os.path.dirname(graphene.__file__)")"
 | 
				
			||||||
 | 
					GRAPHQL_DIR="$(python -c "import os; import graphql; print os.path.dirname(graphql.__file__)")"
 | 
				
			||||||
 | 
					GRAPHQL_RELAY_DIR="$(python -c "import os; import graphql_relay; print os.path.dirname(graphql_relay.__file__)")"
 | 
				
			||||||
 | 
					SIX_DIR="$(python -c "import os; import six; print six.__file__.rstrip('c')")"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cd pypyjs-release-nojit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					eval python tools/module_bundler.py add ./lib/modules "$GRAPHENE_DIR"
 | 
				
			||||||
 | 
					eval python tools/module_bundler.py add ./lib/modules "$GRAPHQL_DIR"
 | 
				
			||||||
 | 
					eval python tools/module_bundler.py add ./lib/modules "$GRAPHQL_RELAY_DIR"
 | 
				
			||||||
 | 
					eval python tools/module_bundler.py add ./lib/modules "$SIX_DIR"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					python ./tools/module_bundler.py preload ./lib/modules graphene
 | 
				
			||||||
 | 
					python ./tools/module_bundler.py preload ./lib/modules graphql
 | 
				
			||||||
 | 
					python ./tools/module_bundler.py preload ./lib/modules graphql_relay
 | 
				
			||||||
 | 
					python ./tools/module_bundler.py preload ./lib/modules six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					python ./tools/module_bundler.py remove ./lib/modules unittest
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					lib_dirname=`perl -e 'use Cwd "abs_path";print abs_path(shift)' lib/`
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ -d ../../../static/playground/lib ] ; then
 | 
				
			||||||
 | 
						rm ../../../static/playground/lib
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mkdir -p ../../../static/playground
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exec ln -s "$lib_dirname/" ../../../static/playground/lib
 | 
				
			||||||
							
								
								
									
										976
									
								
								docs/playground/graphene-js/pypyjs.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										976
									
								
								docs/playground/graphene-js/pypyjs.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,976 @@
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					//  pypyjs:  an experimental in-browser python environment.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					(function() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Expose the main pypyjs function at global scope for this file,
 | 
				
			||||||
 | 
					// as well as in any module exports or 'window' object we can find.
 | 
				
			||||||
 | 
					if (this) {
 | 
				
			||||||
 | 
					  this.pypyjs = pypyjs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					if (typeof window !== "undefined") {
 | 
				
			||||||
 | 
					  window.pypyjs = pypyjs;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					if (typeof module !== "undefined") {
 | 
				
			||||||
 | 
					  if (typeof module.exports !== "undefined") {
 | 
				
			||||||
 | 
					    module.exports = pypyjs;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Generic debugging printf.
 | 
				
			||||||
 | 
					var debug = function(){};
 | 
				
			||||||
 | 
					if (typeof console !== "undefined") {
 | 
				
			||||||
 | 
					  debug = console.log.bind(console);
 | 
				
			||||||
 | 
					} else if (typeof print !== "undefined" && typeof window === "undefined") {
 | 
				
			||||||
 | 
					  debug = print;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Find the directory containing this very file.
 | 
				
			||||||
 | 
					// It can be quite difficult depending on execution environment...
 | 
				
			||||||
 | 
					if (typeof __dirname === "undefined" || true) {
 | 
				
			||||||
 | 
					  var __dirname = "./";
 | 
				
			||||||
 | 
					  // A little hackery to find the URL of this very file.
 | 
				
			||||||
 | 
					  // Throw an error, then parse the stack trace looking for filenames.
 | 
				
			||||||
 | 
					  var errlines = (new Error()).stack.split("\n");
 | 
				
			||||||
 | 
					  for (var i = 0; i < errlines.length; i++) {
 | 
				
			||||||
 | 
					    var match = /(at Anonymous function \(|at |@)(.+\/)pypyjs.js/.exec(errlines[i]);
 | 
				
			||||||
 | 
					    if (match) {
 | 
				
			||||||
 | 
					      __dirname = match[2];
 | 
				
			||||||
 | 
					      break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					if (__dirname.charAt(__dirname.length - 1) !== "/") {
 | 
				
			||||||
 | 
					  __dirname += "/";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (typeof Promise === "undefined") {
 | 
				
			||||||
 | 
					  var Promise = require('es6-promise').Promise;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Ensure we have reference to a 'FunctionPromise' constructor.
 | 
				
			||||||
 | 
					var FunctionPromise = require("./FunctionPromise.js");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (typeof FunctionPromise === "undefined") {
 | 
				
			||||||
 | 
					  throw "FunctionPromise object not found";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Create functions for handling default stdio streams.
 | 
				
			||||||
 | 
					// These will be shared by all VM instances by default.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// We default stdout and stderr to process outputs if available,
 | 
				
			||||||
 | 
					// printing/logging functions otherwise, and /dev/null if nothing
 | 
				
			||||||
 | 
					// else is available.  Unfortunately there's no good way to read
 | 
				
			||||||
 | 
					// synchronously from stdin in javascript, so that's always /dev/null.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var devNull = {
 | 
				
			||||||
 | 
					  stdin: function() { return null; },
 | 
				
			||||||
 | 
					  stdout: function() { },
 | 
				
			||||||
 | 
					  stderr: function() { }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var stdio = {
 | 
				
			||||||
 | 
					  stdin: null,
 | 
				
			||||||
 | 
					  stdout: null,
 | 
				
			||||||
 | 
					  stderr: null
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					stdio.stdin = devNull.stdin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (typeof process !== "undefined") {
 | 
				
			||||||
 | 
					  if (typeof process.stdout !== "undefined") {
 | 
				
			||||||
 | 
					    stdio.stdout = function(x) { process.stdout.write(x); }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (typeof process.stderr !== "undefined") {
 | 
				
			||||||
 | 
					    stdio.stderr = function(x) { process.stderr.write(x); }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var _print, _printErr;
 | 
				
			||||||
 | 
					if (typeof window === "undefined") {
 | 
				
			||||||
 | 
					  // print, printErr from v8, spidermonkey
 | 
				
			||||||
 | 
					  if (typeof print !== "undefined") {
 | 
				
			||||||
 | 
					    _print = print;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (typeof printErr !== "undefined") {
 | 
				
			||||||
 | 
					    _printErr = printErr;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					if (typeof console !== "undefined") {
 | 
				
			||||||
 | 
					  if (typeof _print === "undefined") {
 | 
				
			||||||
 | 
					    _print = console.log.bind(console);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (typeof _printErr === "undefined") {
 | 
				
			||||||
 | 
					    _printErr = console.error.bind(console);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (stdio.stdout == null && typeof _print !== "undefined") {
 | 
				
			||||||
 | 
					  // print()/console.log() will add a newline, so we buffer until we
 | 
				
			||||||
 | 
					  // receive one and then let it add it for us.
 | 
				
			||||||
 | 
					  stdio.stdout = (function() {
 | 
				
			||||||
 | 
					    var buffer = [];
 | 
				
			||||||
 | 
					    return function(data) {
 | 
				
			||||||
 | 
					      for (var i = 0; i < data.length; i++) {
 | 
				
			||||||
 | 
					        var x = data.charAt(i);
 | 
				
			||||||
 | 
					        if (x !== "\n") {
 | 
				
			||||||
 | 
					          buffer.push(x);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          _print(buffer.join(""));
 | 
				
			||||||
 | 
					          buffer.splice(undefined, buffer.length);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (stdio.stderr == null && typeof _printErr !== "undefined") {
 | 
				
			||||||
 | 
					  // printErr()/console.error() will add a newline, so we buffer until we
 | 
				
			||||||
 | 
					  // receive one and then let it add it for us.
 | 
				
			||||||
 | 
					  stdio.stderr = (function() {
 | 
				
			||||||
 | 
					    var buffer = [];
 | 
				
			||||||
 | 
					    return function(data) {
 | 
				
			||||||
 | 
					      for (var i = 0; i < data.length; i++) {
 | 
				
			||||||
 | 
					        var x = data.charAt(i);
 | 
				
			||||||
 | 
					        if (x !== "\n") {
 | 
				
			||||||
 | 
					          buffer.push(x);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          _printErr(buffer.join(""));
 | 
				
			||||||
 | 
					          buffer.splice(undefined, buffer.length);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  })();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (stdio.stdout === null) {
 | 
				
			||||||
 | 
					  stdio.stdout = devNull.stdout;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (stdio.stderr === null) {
 | 
				
			||||||
 | 
					  stdio.stderr = devNull.stderr;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function pypyjs(opts) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  opts = opts || {};
 | 
				
			||||||
 | 
					  this.rootURL = opts.rootURL;
 | 
				
			||||||
 | 
					  this.totalMemory = opts.totalMemory || 128 * 1024 * 1024;
 | 
				
			||||||
 | 
					  this.autoLoadModules = opts.autoLoadModules || true;
 | 
				
			||||||
 | 
					  this._pendingModules = {};
 | 
				
			||||||
 | 
					  this._loadedModules = {};
 | 
				
			||||||
 | 
					  this._allModules = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Allow opts to override default IO streams.
 | 
				
			||||||
 | 
					  this.stdin = opts.stdin || stdio.stdin;
 | 
				
			||||||
 | 
					  this.stdout = opts.stdout || stdio.stdout;
 | 
				
			||||||
 | 
					  this.stderr = opts.stderr || stdio.stderr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Default to finding files relative to this very file.
 | 
				
			||||||
 | 
					  if (!this.rootURL && !pypyjs.rootURL) {
 | 
				
			||||||
 | 
					    pypyjs.rootURL = __dirname;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (this.rootURL && this.rootURL.charAt(this.rootURL.length - 1) !== "/") {
 | 
				
			||||||
 | 
					    this.rootURL += "/";
 | 
				
			||||||
 | 
					  } 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // If we haven't already done so, fetch and load the code for the VM.
 | 
				
			||||||
 | 
					  // We do this once and cache the result for re-use, so that we don't
 | 
				
			||||||
 | 
					  // have to pay asmjs compilation overhead each time we create the VM.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (! pypyjs._vmBuilderPromise) {
 | 
				
			||||||
 | 
					    pypyjs._vmBuilderPromise = this.fetch("pypyjs.vm.js").then((function(xhr) {
 | 
				
			||||||
 | 
					      // Parse the compiled code, hopefully asynchronously.
 | 
				
			||||||
 | 
					      // Unfortunately our use of Function constructor here doesn't
 | 
				
			||||||
 | 
					      // play very well with nodejs, where things like 'module' and
 | 
				
			||||||
 | 
					      // 'require' are not in the global scope.  We have to pass them
 | 
				
			||||||
 | 
					      // in explicitly as arguments.
 | 
				
			||||||
 | 
					      var funcBody = [
 | 
				
			||||||
 | 
					        // This is the compiled code for the VM.
 | 
				
			||||||
 | 
					        xhr.responseText,
 | 
				
			||||||
 | 
					        '\n',
 | 
				
			||||||
 | 
					        // Ensure that some functions are available on the Module,
 | 
				
			||||||
 | 
					        // for linking with jitted code.
 | 
				
			||||||
 | 
					        'if (!Module._jitInvoke && typeof _jitInvoke !== "undefined") {',
 | 
				
			||||||
 | 
					        '  Module._jitInvoke = _jitInvoke;',
 | 
				
			||||||
 | 
					        '}',
 | 
				
			||||||
 | 
					        // Keep some functions that are not exported by default, but
 | 
				
			||||||
 | 
					        // which appear in this scope when evaluating the above.
 | 
				
			||||||
 | 
					        "Module._emjs_make_handle = _emjs_make_handle;",
 | 
				
			||||||
 | 
					        "Module._emjs_free = _emjs_free;",
 | 
				
			||||||
 | 
					        // Call dependenciesFulfilled if it won't be done automatically.
 | 
				
			||||||
 | 
					        "dependenciesFulfilled=function() { inDependenciesFulfilled(FS); };",
 | 
				
			||||||
 | 
					        "if(!memoryInitializer||(!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER))dependenciesFulfilled();",
 | 
				
			||||||
 | 
					      ].join("");
 | 
				
			||||||
 | 
					      return FunctionPromise("Module", "inDependenciesFulfilled", "require",
 | 
				
			||||||
 | 
					                             "module", "__filename", "__dirname", funcBody)
 | 
				
			||||||
 | 
					    }).bind(this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Create a new instance of the compiled VM, bound to local state
 | 
				
			||||||
 | 
					  // and a local Module object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  this._ready = new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initialize the Module object.
 | 
				
			||||||
 | 
					    // We make it available on this object so that we can use
 | 
				
			||||||
 | 
					    // its methods to execute code in the VM.
 | 
				
			||||||
 | 
					    var Module = {};
 | 
				
			||||||
 | 
					    this._module = Module;
 | 
				
			||||||
 | 
					    Module.TOTAL_MEMORY = this.totalMemory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // We will set up the filesystem manually when we're ready.
 | 
				
			||||||
 | 
					    Module.noFSInit = true;
 | 
				
			||||||
 | 
					    Module.thisProgram = "/lib/pypyjs/pypyjs.js";
 | 
				
			||||||
 | 
					    Module.filePackagePrefixURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					    Module.memoryInitializerPrefixURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					    Module.locateFile = function(name) {
 | 
				
			||||||
 | 
					      return (this.rootURL || pypyjs.rootURL) + name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Don't start or stop the program, just set it up.
 | 
				
			||||||
 | 
					    // We'll call the API functions ourself.
 | 
				
			||||||
 | 
					    Module.noInitialRun = true;
 | 
				
			||||||
 | 
					    Module.noExitRuntime = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Route stdin to an overridable method on the object.
 | 
				
			||||||
 | 
					    var stdin = (function stdin() {
 | 
				
			||||||
 | 
					      return this.stdin();
 | 
				
			||||||
 | 
					    }).bind(this);
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    // Route stdout to an overridable method on the object.
 | 
				
			||||||
 | 
					    // We buffer the output for efficiency.
 | 
				
			||||||
 | 
					    var stdout_buffer = []
 | 
				
			||||||
 | 
					    var stdout = (function stdout(x) {
 | 
				
			||||||
 | 
					      var c = String.fromCharCode(x);
 | 
				
			||||||
 | 
					      stdout_buffer.push(c);
 | 
				
			||||||
 | 
					      if (c === "\n" || stdout_buffer.length >= 128) {
 | 
				
			||||||
 | 
					        this.stdout(stdout_buffer.join(""));
 | 
				
			||||||
 | 
					        stdout_buffer = [];
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }).bind(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Route stderr to an overridable method on the object.
 | 
				
			||||||
 | 
					    // We do not buffer stderr.
 | 
				
			||||||
 | 
					    var stderr = (function stderr(x) {
 | 
				
			||||||
 | 
					      var c = String.fromCharCode(x);
 | 
				
			||||||
 | 
					      this.stderr(c);
 | 
				
			||||||
 | 
					    }).bind(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // This is where execution will continue after loading
 | 
				
			||||||
 | 
					    // the memory initialization data, if any.
 | 
				
			||||||
 | 
					    var initializedResolve, initializedReject;
 | 
				
			||||||
 | 
					    var initializedP = new Promise(function(resolve, reject) {
 | 
				
			||||||
 | 
					      initializedResolve = resolve;
 | 
				
			||||||
 | 
					      initializedReject = reject;
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    var FS;
 | 
				
			||||||
 | 
					    var dependenciesFulfilled = function(fs) {
 | 
				
			||||||
 | 
					      FS = fs;
 | 
				
			||||||
 | 
					      // Initialize the filesystem state.
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        FS.init(stdin, stdout, stderr);
 | 
				
			||||||
 | 
					        Module.FS_createPath("/", "lib/pypyjs/lib_pypy", true, false);
 | 
				
			||||||
 | 
					        Module.FS_createPath("/", "lib/pypyjs/lib-python/2.7", true, false);
 | 
				
			||||||
 | 
					        initializedResolve();
 | 
				
			||||||
 | 
					      } catch (err) {
 | 
				
			||||||
 | 
					        initializedReject(err);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					 
 | 
				
			||||||
 | 
					    // Begin fetching the metadata for available python modules.
 | 
				
			||||||
 | 
					    // With luck these can download while we jank around compiling
 | 
				
			||||||
 | 
					    // all of that javascript.
 | 
				
			||||||
 | 
					    // XXX TODO: also load memory initializer this way.
 | 
				
			||||||
 | 
					    var moduleDataP = this.fetch("modules/index.json");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pypyjs._vmBuilderPromise.then((function(vmBuilder) {
 | 
				
			||||||
 | 
					      var args = [
 | 
				
			||||||
 | 
					        Module,
 | 
				
			||||||
 | 
					        dependenciesFulfilled,
 | 
				
			||||||
 | 
					        typeof undefined,
 | 
				
			||||||
 | 
					        typeof undefined,
 | 
				
			||||||
 | 
					        typeof undefined,
 | 
				
			||||||
 | 
					        typeof __dirname
 | 
				
			||||||
 | 
					      ];
 | 
				
			||||||
 | 
					      // This links the async-compiled module into our Module object.
 | 
				
			||||||
 | 
					      vmBuilder.apply(null, args);
 | 
				
			||||||
 | 
					      return initializedP;
 | 
				
			||||||
 | 
					    }).bind(this)).then((function() {
 | 
				
			||||||
 | 
					      // Continue with processing the downloaded module metadata.
 | 
				
			||||||
 | 
					      return moduleDataP.then((function(xhr) {
 | 
				
			||||||
 | 
					        // Store the module index, and load any preload modules.
 | 
				
			||||||
 | 
					        var modIndex = JSON.parse(xhr.responseText);
 | 
				
			||||||
 | 
					        this._allModules = modIndex.modules;
 | 
				
			||||||
 | 
					        if (modIndex.preload) {
 | 
				
			||||||
 | 
					          for (var name in modIndex.preload) {
 | 
				
			||||||
 | 
					            this._writeModuleFile(name, modIndex.preload[name]);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        // It's finally safe to launch the VM.
 | 
				
			||||||
 | 
					        Module.run();
 | 
				
			||||||
 | 
					        Module._rpython_startup_code();
 | 
				
			||||||
 | 
					        var pypy_home = Module.intArrayFromString("/lib/pypyjs/pypyjs.js");
 | 
				
			||||||
 | 
					        pypy_home = Module.allocate(pypy_home, 'i8', Module.ALLOC_NORMAL);
 | 
				
			||||||
 | 
					        Module._pypy_setup_home(pypy_home, 0);
 | 
				
			||||||
 | 
					        Module._free(pypy_home);
 | 
				
			||||||
 | 
					        var initCode = [
 | 
				
			||||||
 | 
					          "import js",
 | 
				
			||||||
 | 
					          "import sys; sys.platform = 'js'",
 | 
				
			||||||
 | 
					          "import traceback",
 | 
				
			||||||
 | 
					          "top_level_scope = {'__name__': '__main__'}"
 | 
				
			||||||
 | 
					        ];
 | 
				
			||||||
 | 
					        initCode.forEach(function(codeStr) {
 | 
				
			||||||
 | 
					          var code = Module.intArrayFromString(codeStr);
 | 
				
			||||||
 | 
					          var code = Module.allocate(code, 'i8', Module.ALLOC_NORMAL);
 | 
				
			||||||
 | 
					          if (!code) {
 | 
				
			||||||
 | 
					            throw new pypyjs.Error('Failed to allocate memory');
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          var res = Module._pypy_execute_source(code);
 | 
				
			||||||
 | 
					          if (res < 0) {
 | 
				
			||||||
 | 
					            throw new pypyjs.Error('Failed to execute python code');
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          Module._free(code);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      }).bind(this))
 | 
				
			||||||
 | 
					    }).bind(this))
 | 
				
			||||||
 | 
					    .then(resolve, reject);
 | 
				
			||||||
 | 
					  }).bind(this));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// A simple file-fetching wrapper around XMLHttpRequest,
 | 
				
			||||||
 | 
					// that treats paths as relative to the pypyjs.js root url.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype.fetch = function (relpath, responseType) {
 | 
				
			||||||
 | 
					  if (typeof window === "undefined") {
 | 
				
			||||||
 | 
					    var localStorage = false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  else {
 | 
				
			||||||
 | 
					    var localStorage = window.localStorage;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  var use_cache = pypyjs.cacheKey && localStorage && relpath != "pypyjs.vm.js";
 | 
				
			||||||
 | 
					  if (use_cache) {
 | 
				
			||||||
 | 
					    var item = localStorage.getItem(pypyjs.cacheKey+':'+relpath);
 | 
				
			||||||
 | 
					    if (item) {
 | 
				
			||||||
 | 
					      return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					        resolve({ responseText: item });
 | 
				
			||||||
 | 
					      }))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // For the web, use XMLHttpRequest.
 | 
				
			||||||
 | 
					  if (typeof XMLHttpRequest !== "undefined") {
 | 
				
			||||||
 | 
					    return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					      var xhr = new XMLHttpRequest();
 | 
				
			||||||
 | 
					      xhr.onload = function() {
 | 
				
			||||||
 | 
					        if (xhr.status >= 400) {
 | 
				
			||||||
 | 
					          reject(xhr)
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          if (use_cache && xhr.responseText) {
 | 
				
			||||||
 | 
					            localStorage.setItem(pypyjs.cacheKey+':'+relpath, xhr.responseText);
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          resolve(xhr);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					      var rootURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					      xhr.open('GET', rootURL + relpath, true);
 | 
				
			||||||
 | 
					      xhr.responseType = responseType || "text";
 | 
				
			||||||
 | 
					      xhr.send(null);
 | 
				
			||||||
 | 
					    }).bind(this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // For nodejs, use fs.readFile.
 | 
				
			||||||
 | 
					  if (typeof fs !== "undefined" && typeof fs.readFile !== "undefined") {
 | 
				
			||||||
 | 
					    return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					      var rootURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					      fs.readFile(path.join(rootURL, relpath), function(err, data) {
 | 
				
			||||||
 | 
					        if (err) return reject(err);
 | 
				
			||||||
 | 
					        resolve({ responseText: data.toString() });
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }).bind(this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // For spidermonkey, use snarf (which has a binary read mode).
 | 
				
			||||||
 | 
					  if (typeof snarf !== "undefined") {
 | 
				
			||||||
 | 
					    return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					      var rootURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					      var data = snarf(rootURL + relpath);
 | 
				
			||||||
 | 
					      resolve({ responseText: data });
 | 
				
			||||||
 | 
					    }).bind(this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // For d8, use read() and readbuffer().
 | 
				
			||||||
 | 
					  if (typeof read !== "undefined" && typeof readbuffer !== "undefined") {
 | 
				
			||||||
 | 
					    return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					      var rootURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					      var data = read(rootURL + relpath);
 | 
				
			||||||
 | 
					      resolve({ responseText: data });
 | 
				
			||||||
 | 
					    }).bind(this));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return new Promise(function(resolve, reject) {
 | 
				
			||||||
 | 
					    reject("unable to fetch files");
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if (typeof localStorage !== "undefined") {
 | 
				
			||||||
 | 
					  var localStorage = false;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// pypyjs.prototype.fetch = function fetch(relpath, responseType) {
 | 
				
			||||||
 | 
					//   // For the web, use XMLHttpRequest.
 | 
				
			||||||
 | 
					//   var use_cache = pypyjs.cacheKey && localStorage;
 | 
				
			||||||
 | 
					//   if (use_cache) {
 | 
				
			||||||
 | 
					//     if (var item = localStorage.getItem(pypyjs.cacheKey+'-'+relpath)) {
 | 
				
			||||||
 | 
					//       resolve({ responseText: item });
 | 
				
			||||||
 | 
					//     }
 | 
				
			||||||
 | 
					//   }
 | 
				
			||||||
 | 
					//   if (typeof XMLHttpRequest !== "undefined") {
 | 
				
			||||||
 | 
					//     return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					//       var xhr = new XMLHttpRequest();
 | 
				
			||||||
 | 
					//       xhr.onload = function() {
 | 
				
			||||||
 | 
					//         if (xhr.status >= 400) {
 | 
				
			||||||
 | 
					//           reject(xhr)
 | 
				
			||||||
 | 
					//         } else {
 | 
				
			||||||
 | 
					//           console.log(xhr.responseText);
 | 
				
			||||||
 | 
					//           if (use_cache && xhr.responseText) {
 | 
				
			||||||
 | 
					//             localStorage.setItem(pypyjs.cacheKey+'-'+relpath, xhr.responseText);
 | 
				
			||||||
 | 
					//           }
 | 
				
			||||||
 | 
					//           resolve(xhr);
 | 
				
			||||||
 | 
					//         }
 | 
				
			||||||
 | 
					//       };
 | 
				
			||||||
 | 
					//       var rootURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					//       xhr.open('GET', rootURL + relpath, true);
 | 
				
			||||||
 | 
					//       xhr.responseType = responseType || "text";
 | 
				
			||||||
 | 
					//       xhr.send(null);
 | 
				
			||||||
 | 
					//     }).bind(this));
 | 
				
			||||||
 | 
					//   }
 | 
				
			||||||
 | 
					//   // For nodejs, use fs.readFile.
 | 
				
			||||||
 | 
					//   if (typeof fs !== "undefined" && typeof fs.readFile !== "undefined") {
 | 
				
			||||||
 | 
					//     return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					//       var rootURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					//       fs.readFile(path.join(rootURL, relpath), function(err, data) {
 | 
				
			||||||
 | 
					//         if (err) return reject(err);
 | 
				
			||||||
 | 
					//         resolve({ responseText: data.toString() });
 | 
				
			||||||
 | 
					//       });
 | 
				
			||||||
 | 
					//     }).bind(this));
 | 
				
			||||||
 | 
					//   }
 | 
				
			||||||
 | 
					//   // For spidermonkey, use snarf (which has a binary read mode).
 | 
				
			||||||
 | 
					//   if (typeof snarf !== "undefined") {
 | 
				
			||||||
 | 
					//     return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					//       var rootURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					//       var data = snarf(rootURL + relpath);
 | 
				
			||||||
 | 
					//       resolve({ responseText: data });
 | 
				
			||||||
 | 
					//     }).bind(this));
 | 
				
			||||||
 | 
					//   }
 | 
				
			||||||
 | 
					//   // For d8, use read() and readbuffer().
 | 
				
			||||||
 | 
					//   if (typeof read !== "undefined" && typeof readbuffer !== "undefined") {
 | 
				
			||||||
 | 
					//     return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					//       var rootURL = this.rootURL || pypyjs.rootURL;
 | 
				
			||||||
 | 
					//       var data = read(rootURL + relpath);
 | 
				
			||||||
 | 
					//       resolve({ responseText: data });
 | 
				
			||||||
 | 
					//     }).bind(this));
 | 
				
			||||||
 | 
					//   }
 | 
				
			||||||
 | 
					//   return new Promise(function(resolve, reject) {
 | 
				
			||||||
 | 
					//     reject("unable to fetch files");
 | 
				
			||||||
 | 
					//   });
 | 
				
			||||||
 | 
					// };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to execute python source directly in the VM.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This is the basic way to push code into the pypyjs VM.
 | 
				
			||||||
 | 
					// Calling code should not use it directly; rather we use it
 | 
				
			||||||
 | 
					// as a primitive to build up a nicer execution API.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype._execute_source = function _execute_source(code) {
 | 
				
			||||||
 | 
					  var Module = this._module;
 | 
				
			||||||
 | 
					  code = "try:\n" +
 | 
				
			||||||
 | 
					         "  " + code + "\n" +
 | 
				
			||||||
 | 
					         "except Exception:\n" +
 | 
				
			||||||
 | 
					         "  typ, val, tb = sys.exc_info()\n" +
 | 
				
			||||||
 | 
					         "  err_name = getattr(typ, '__name__', str(typ))\n" +
 | 
				
			||||||
 | 
					         "  err_msg = str(val)\n" +
 | 
				
			||||||
 | 
					         "  err_trace = traceback.format_exception(typ, val, tb)\n" +
 | 
				
			||||||
 | 
					         "  err_trace = ''.join(err_trace)\n" +
 | 
				
			||||||
 | 
					         "  js.globals['pypyjs']._lastErrorName = err_name\n" +
 | 
				
			||||||
 | 
					         "  js.globals['pypyjs']._lastErrorMessage = err_msg\n" +
 | 
				
			||||||
 | 
					         "  js.globals['pypyjs']._lastErrorTrace = err_trace\n";
 | 
				
			||||||
 | 
					  var code_chars = Module.intArrayFromString(code);
 | 
				
			||||||
 | 
					  var code_ptr = Module.allocate(code_chars, 'i8', Module.ALLOC_NORMAL);
 | 
				
			||||||
 | 
					  if (!code_ptr) {
 | 
				
			||||||
 | 
					    return Promise.reject(new pypyjs.Error("Failed to allocate memory"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  var res = Module._pypy_execute_source(code_ptr);
 | 
				
			||||||
 | 
					  Module._free(code_ptr);
 | 
				
			||||||
 | 
					  // XXX TODO: races/re-entrancy on _lastError?
 | 
				
			||||||
 | 
					  if (pypyjs._lastErrorName) {
 | 
				
			||||||
 | 
					    var err = new pypyjs.Error(
 | 
				
			||||||
 | 
					      pypyjs._lastErrorName,
 | 
				
			||||||
 | 
					      pypyjs._lastErrorMessage,
 | 
				
			||||||
 | 
					      pypyjs._lastErrorTrace
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    pypyjs._lastErrorName = null;
 | 
				
			||||||
 | 
					    pypyjs._lastErrorMessage = null;
 | 
				
			||||||
 | 
					    pypyjs._lastErrorTrace = null;
 | 
				
			||||||
 | 
					    return Promise.reject(err);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (res < 0) {
 | 
				
			||||||
 | 
					    return Promise.reject(new pypyjs.Error("Error executing python code"));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return Promise.resolve(null);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function _escape(value) {
 | 
				
			||||||
 | 
					  return value.replace(/\\/g, "\\\\").replace(/'/g, "\\'");
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to determine when the interpreter is ready.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This method returns a promise that will resolve once the interpreter
 | 
				
			||||||
 | 
					// is ready for use.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype.ready = function ready() {
 | 
				
			||||||
 | 
					  return this._ready;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to execute some python code.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This passes the given python code to the VM for execution.
 | 
				
			||||||
 | 
					// It's fairly directly analogous to the "exec" statement in python.
 | 
				
			||||||
 | 
					// It is not possible to directly access the result of the code, if any.
 | 
				
			||||||
 | 
					// Rather you should store it into a variable and then use the get() method.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype.exec = function exec(code) {
 | 
				
			||||||
 | 
					  return this._ready.then((function() {
 | 
				
			||||||
 | 
					    var p = Promise.resolve();
 | 
				
			||||||
 | 
					    // Find any "import" statements in the code,
 | 
				
			||||||
 | 
					    // and ensure the modules are ready for loading.
 | 
				
			||||||
 | 
					    if (this.autoLoadModules) {
 | 
				
			||||||
 | 
					      p = p.then((function() {
 | 
				
			||||||
 | 
					        return this.findImportedNames(code);
 | 
				
			||||||
 | 
					      }).bind(this))
 | 
				
			||||||
 | 
					      .then((function(imports) {
 | 
				
			||||||
 | 
					        return this.loadModuleData.apply(this, imports);
 | 
				
			||||||
 | 
					      }).bind(this))
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // Now we can execute the code in custom top-level scope.
 | 
				
			||||||
 | 
					    code = 'exec \'\'\'' + _escape(code) + '\'\'\' in top_level_scope';
 | 
				
			||||||
 | 
					    p = p.then((function() {
 | 
				
			||||||
 | 
					      return this._execute_source(code);
 | 
				
			||||||
 | 
					    }).bind(this));
 | 
				
			||||||
 | 
					    return p;
 | 
				
			||||||
 | 
					  }).bind(this));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to evaluate an expression.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This method evaluates an expression and returns its value (assuming the
 | 
				
			||||||
 | 
					// value can be translated into javascript).  It's fairly directly analogous
 | 
				
			||||||
 | 
					// to the "eval" function in python.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// For backwards-compatibility reasons, it will also evaluate statements.
 | 
				
			||||||
 | 
					// This behaviour is deprecated and will be removed in a future release.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype.eval = function (expr) {
 | 
				
			||||||
 | 
					  return this._ready.then((function() {
 | 
				
			||||||
 | 
					    // First try to execute it as an expression.
 | 
				
			||||||
 | 
					    code = "r = eval('" + _escape(expr) + "', top_level_scope)";
 | 
				
			||||||
 | 
					    return this._execute_source(code);
 | 
				
			||||||
 | 
					  }).bind(this)).then(
 | 
				
			||||||
 | 
					    (function() {
 | 
				
			||||||
 | 
					      // If that succeeded, return the result.
 | 
				
			||||||
 | 
					      return this.get("r", true)
 | 
				
			||||||
 | 
					    }).bind(this),
 | 
				
			||||||
 | 
					    (function(err) {
 | 
				
			||||||
 | 
					      if (err && err.name && err.name !== "SyntaxError") {
 | 
				
			||||||
 | 
					        throw err;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      // If that failed, try again via exec().
 | 
				
			||||||
 | 
					      if (typeof console !== "undefined") {
 | 
				
			||||||
 | 
					        console.warn("Calling pypyjs.eval() with statements is deprecated.");
 | 
				
			||||||
 | 
					        console.warn("Use eval() for expressions, exec() for statements.");
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      return this.exec(expr);
 | 
				
			||||||
 | 
					    }).bind(this)
 | 
				
			||||||
 | 
					  )
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to evaluate some python code from a file..
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This fetches the named file and passes it to the VM for execution.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype.execfile = function execfile(filename) {
 | 
				
			||||||
 | 
					  return this.fetch(filename).then((function(xhr) {
 | 
				
			||||||
 | 
					    var code = xhr.responseText;
 | 
				
			||||||
 | 
					    return this.exec(code);
 | 
				
			||||||
 | 
					  }).bind(this));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to read a python variable.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This tries to convert the value in the named python variable into an
 | 
				
			||||||
 | 
					// equivalent javascript value and returns it.  It will fail if the variable
 | 
				
			||||||
 | 
					// does not exist or contains a value that cannot be converted.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs._resultsID = 0;
 | 
				
			||||||
 | 
					pypyjs._resultsMap = {};
 | 
				
			||||||
 | 
					pypyjs.prototype.get = function get(name, _fromGlobals) {
 | 
				
			||||||
 | 
					  var resid = ""+(pypyjs._resultsID++);
 | 
				
			||||||
 | 
					  // We can read from global scope for internal use; don't do this from calling code!
 | 
				
			||||||
 | 
					  if (_fromGlobals) {
 | 
				
			||||||
 | 
					    var namespace = "globals()";
 | 
				
			||||||
 | 
					  } else {
 | 
				
			||||||
 | 
					    var namespace = "top_level_scope";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return this._ready.then((function() {
 | 
				
			||||||
 | 
					    var code = namespace + ".get('" + _escape(name) + "', js.undefined)";
 | 
				
			||||||
 | 
					    code = "js.convert(" + code + ")"
 | 
				
			||||||
 | 
					    code = "js.globals['pypyjs']._resultsMap['" + resid + "'] = " + code;
 | 
				
			||||||
 | 
					    return this._execute_source(code);
 | 
				
			||||||
 | 
					  }).bind(this)).then((function() {
 | 
				
			||||||
 | 
					    var res = pypyjs._resultsMap[resid];
 | 
				
			||||||
 | 
					    delete pypyjs._resultsMap[resid];
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
 | 
					  }).bind(this));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to set a python variable to a javascript value.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This generates a handle to the given object, and arranges for the named
 | 
				
			||||||
 | 
					// python variable to reference it via that handle.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype.set = function set(name, value) {
 | 
				
			||||||
 | 
					  return this._ready.then((function() {
 | 
				
			||||||
 | 
					    var Module = this._module;
 | 
				
			||||||
 | 
					    var h = Module._emjs_make_handle(value);
 | 
				
			||||||
 | 
					    name = _escape(name);
 | 
				
			||||||
 | 
					    var code = "top_level_scope['" + name + "'] = js.Value(" + h + ")";
 | 
				
			||||||
 | 
					    return this._execute_source(code);
 | 
				
			||||||
 | 
					  }).bind(this));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to run an interactive REPL.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This method takes takes callback function implementing the user
 | 
				
			||||||
 | 
					// input prompt, and runs a REPL loop using it.  The prompt function
 | 
				
			||||||
 | 
					// may either return the input as a string, or a promise resolving to
 | 
				
			||||||
 | 
					// the input as a string.  If not specified, we read from stdin (which
 | 
				
			||||||
 | 
					// works fine in e.g. nodejs, but is almost certainly not what you want
 | 
				
			||||||
 | 
					// in the browser, because it's blocking).
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype.repl = function repl(prmpt) {
 | 
				
			||||||
 | 
					  if (!prmpt) {
 | 
				
			||||||
 | 
					    // If there's a custom stdin, or we're not in nodejs, then we should
 | 
				
			||||||
 | 
					    // default to prompting on stdin/stdout.  For nodejs, we can build
 | 
				
			||||||
 | 
					    // an async prompt atop process.stdin.
 | 
				
			||||||
 | 
					    var buffer = "";
 | 
				
			||||||
 | 
					    if (this.stdin !== devNull.stdin || typeof process === "undefined") {
 | 
				
			||||||
 | 
					      prmpt = (function(ps1) {
 | 
				
			||||||
 | 
					        var input;
 | 
				
			||||||
 | 
					        this.stdout(ps1);
 | 
				
			||||||
 | 
					        var c = this.stdin();
 | 
				
			||||||
 | 
					        while (c) {
 | 
				
			||||||
 | 
					          var idx = c.indexOf("\n");
 | 
				
			||||||
 | 
					          if (idx >= 0) {
 | 
				
			||||||
 | 
					            var input = buffer + c.substr(0, idx + 1);
 | 
				
			||||||
 | 
					            buffer = c.substr(idx + 1);
 | 
				
			||||||
 | 
					            return input;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          buffer += c;
 | 
				
			||||||
 | 
					          c = this.stdin();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        input = buffer;
 | 
				
			||||||
 | 
					        buffer = "";
 | 
				
			||||||
 | 
					        return input;
 | 
				
			||||||
 | 
					      }).bind(this);
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      prmpt = (function(ps1) {
 | 
				
			||||||
 | 
					        return new Promise((function(resolve, reject) {
 | 
				
			||||||
 | 
					          this.stdout(ps1);
 | 
				
			||||||
 | 
					          var slurp = function() {
 | 
				
			||||||
 | 
					            process.stdin.once("readable", function() {
 | 
				
			||||||
 | 
					              var chunk = process.stdin.read();
 | 
				
			||||||
 | 
					              if (chunk === null) {
 | 
				
			||||||
 | 
					                slurp();
 | 
				
			||||||
 | 
					              } else {
 | 
				
			||||||
 | 
					                chunk = chunk.toString();
 | 
				
			||||||
 | 
					                var idx = chunk.indexOf("\n");
 | 
				
			||||||
 | 
					                if (idx < 0) {
 | 
				
			||||||
 | 
					                  buffer += chunk;
 | 
				
			||||||
 | 
					                  slurp();
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  resolve(buffer + chunk.substr(0, idx + 1));
 | 
				
			||||||
 | 
					                  buffer = chunk.substr(idx + 1);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          slurp();
 | 
				
			||||||
 | 
					        }).bind(this));
 | 
				
			||||||
 | 
					      }).bind(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // Set up an InteractiveConsole instance,
 | 
				
			||||||
 | 
					  // then loop forever via recursive promises.
 | 
				
			||||||
 | 
					  return this._ready.then((function() {
 | 
				
			||||||
 | 
					    return this.loadModuleData("code");
 | 
				
			||||||
 | 
					  }).bind(this)).then((function() {
 | 
				
			||||||
 | 
					    return this._execute_source("import code");
 | 
				
			||||||
 | 
					  }).bind(this)).then((function() {
 | 
				
			||||||
 | 
					    return this._execute_source("c = code.InteractiveConsole(top_level_scope)");
 | 
				
			||||||
 | 
					  }).bind(this)).then((function() {
 | 
				
			||||||
 | 
					    return this._repl_loop(prmpt, ">>> ");
 | 
				
			||||||
 | 
					  }).bind(this));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypyjs.prototype._repl_loop = function _repl_loop(prmpt, ps1) {
 | 
				
			||||||
 | 
					  return Promise.resolve().then((function() {
 | 
				
			||||||
 | 
					    // Prompt for input, which may happen via async promise.
 | 
				
			||||||
 | 
					    return prmpt.call(this, ps1);
 | 
				
			||||||
 | 
					  }).bind(this)).then((function(input) {
 | 
				
			||||||
 | 
					    // Push it into the InteractiveConsole, a line at a time.
 | 
				
			||||||
 | 
					    var p = Promise.resolve();
 | 
				
			||||||
 | 
					    input.split("\n").forEach((function(line) {
 | 
				
			||||||
 | 
					      // Find any "import" statements in the code,
 | 
				
			||||||
 | 
					      // and ensure the modules are ready for loading.
 | 
				
			||||||
 | 
					      if (this.autoLoadModules) {
 | 
				
			||||||
 | 
					        p = p.then((function() {
 | 
				
			||||||
 | 
					          return this.findImportedNames(line);
 | 
				
			||||||
 | 
					        }).bind(this))
 | 
				
			||||||
 | 
					        .then((function(imports) {
 | 
				
			||||||
 | 
					          return this.loadModuleData.apply(this, imports);
 | 
				
			||||||
 | 
					        }).bind(this))
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      var code = 'r = c.push(\'' + _escape(line) + '\')';
 | 
				
			||||||
 | 
					      p = p.then((function() {
 | 
				
			||||||
 | 
					        return this._execute_source(code);
 | 
				
			||||||
 | 
					      }).bind(this));
 | 
				
			||||||
 | 
					    }).bind(this));
 | 
				
			||||||
 | 
					    return p;
 | 
				
			||||||
 | 
					  }).bind(this)).then((function() {
 | 
				
			||||||
 | 
					    // Check the result from the final push.
 | 
				
			||||||
 | 
					    return this.get("r", true)
 | 
				
			||||||
 | 
					  }).bind(this)).then((function(r) {
 | 
				
			||||||
 | 
					    // If r == 1, we're in a multi-line definition.
 | 
				
			||||||
 | 
					    // Adjust the prompt accordingly.
 | 
				
			||||||
 | 
					    if (r) {
 | 
				
			||||||
 | 
					      return this._repl_loop(prmpt, "... ");
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      return this._repl_loop(prmpt, ">>> ");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }).bind(this));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to look for "import" statements in a code string.
 | 
				
			||||||
 | 
					// Returns a promise that will resolve to a list of imported module names.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// XXX TODO: this is far from complete and should not be done with a regex.
 | 
				
			||||||
 | 
					// Perhaps we can call into python's "ast" module for this parsing?
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					var importStatementRE = /(from\s+([a-zA-Z0-9_\.]+)\s+)?import\s+\(?\s*([a-zA-Z0-9_\.\*]+(\s+as\s+[a-zA-Z0-9_]+)?[ \t]*,?[ \t]*)+[ \t]*\)?/g
 | 
				
			||||||
 | 
					pypyjs.prototype.findImportedNames = function findImportedNames(code) {
 | 
				
			||||||
 | 
					  var match = null;
 | 
				
			||||||
 | 
					  var imports = [];
 | 
				
			||||||
 | 
					  importStatementRE.lastIndex = 0;
 | 
				
			||||||
 | 
					  while ((match = importStatementRE.exec(code)) !== null) {
 | 
				
			||||||
 | 
					    var relmod = match[2];
 | 
				
			||||||
 | 
					    if (relmod) {
 | 
				
			||||||
 | 
					      relmod = relmod + ".";
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      relmod = "";
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    var submods = match[0].split("import")[1];
 | 
				
			||||||
 | 
					    while (submods && /[\s(]/.test(submods.charAt(0))) {
 | 
				
			||||||
 | 
					      submods = submods.substr(1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    while (submods && /[\s)]/.test(submods.charAt(submods.length - 1))) {
 | 
				
			||||||
 | 
					      submods = submods.substr(0, submods.length - 1);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    submods = submods.split(/\s*,\s*/);
 | 
				
			||||||
 | 
					    for (var i = 0; i < submods.length; i++) {
 | 
				
			||||||
 | 
					      var submod = submods[i];
 | 
				
			||||||
 | 
					      submod = submod.split(/\s*as\s*/)[0];
 | 
				
			||||||
 | 
					      imports.push(relmod + submod);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return Promise.resolve(imports);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Method to load the contents of a python module, along with
 | 
				
			||||||
 | 
					// any dependencies.  This populates the relevant paths within
 | 
				
			||||||
 | 
					// the VMs simulated filesystem so that is can find and import
 | 
				
			||||||
 | 
					// the specified module.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					pypyjs.prototype.loadModuleData = function loadModuleData(/* names */) {
 | 
				
			||||||
 | 
					  // Each argument is a name that we want to import.
 | 
				
			||||||
 | 
					  // We must find the longest prefix that is an available module
 | 
				
			||||||
 | 
					  // and load it along with all its dependencies.
 | 
				
			||||||
 | 
					  var modules = Array.prototype.slice.call(arguments);
 | 
				
			||||||
 | 
					  return this._ready.then((function() {
 | 
				
			||||||
 | 
					    var toLoad = {};
 | 
				
			||||||
 | 
					    NEXTNAME: for (var i = 0; i < modules.length; i++) {
 | 
				
			||||||
 | 
					      var name = modules[i];
 | 
				
			||||||
 | 
					      // Find the nearest containing module for the given name.
 | 
				
			||||||
 | 
					      // Note that it may not match a module at all, in which case we ignore it.
 | 
				
			||||||
 | 
					      while (true) {
 | 
				
			||||||
 | 
					        if (this._allModules[name]) {
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        name = name.substr(0, name.lastIndexOf("."));
 | 
				
			||||||
 | 
					        if (!name) continue NEXTNAME;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      this._findModuleDeps(name, toLoad);
 | 
				
			||||||
 | 
					    } 
 | 
				
			||||||
 | 
					    // Now ensure that each module gets loaded.
 | 
				
			||||||
 | 
					    // XXX TODO: we could load these concurrently.
 | 
				
			||||||
 | 
					    var p = Promise.resolve();
 | 
				
			||||||
 | 
					    for (var name in toLoad) {
 | 
				
			||||||
 | 
					      p = p.then(this._makeLoadModuleData(name));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return p;
 | 
				
			||||||
 | 
					  }).bind(this));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypyjs.prototype._findModuleDeps = function _findModuleDeps(name, seen) {
 | 
				
			||||||
 | 
					  if (!seen) seen = {};
 | 
				
			||||||
 | 
					  var deps = [];
 | 
				
			||||||
 | 
					  // If we don't know about this module, ignore it.
 | 
				
			||||||
 | 
					  if (!this._allModules[name]) {
 | 
				
			||||||
 | 
					    return seen;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // Depend on any explicitly-named imports.
 | 
				
			||||||
 | 
					  var imports = this._allModules[name].imports;
 | 
				
			||||||
 | 
					  if (imports) {
 | 
				
			||||||
 | 
					    for (var i = 0; i < imports.length; i++) {
 | 
				
			||||||
 | 
					      deps.push(imports[i]);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // Depend on the __init__.py for packages.
 | 
				
			||||||
 | 
					  if (this._allModules[name].dir) {
 | 
				
			||||||
 | 
					    deps.push(name + ".__init__");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // Include the parent package, if any.
 | 
				
			||||||
 | 
					  var idx = name.lastIndexOf(".");
 | 
				
			||||||
 | 
					  if (idx !== -1) {
 | 
				
			||||||
 | 
					    deps.push(name.substr(0, idx));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  // Recurse for any previously-unseen dependencies.
 | 
				
			||||||
 | 
					  seen[name] = true;
 | 
				
			||||||
 | 
					  for (var i = 0; i < deps.length; i++) {
 | 
				
			||||||
 | 
					    if (!seen[deps[i]]) {
 | 
				
			||||||
 | 
					      this._findModuleDeps(deps[i], seen);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return seen;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypyjs.prototype._makeLoadModuleData = function _makeLoadModuleData(name) {
 | 
				
			||||||
 | 
					  return (function() {
 | 
				
			||||||
 | 
					    // If we've already loaded this module, we're done.
 | 
				
			||||||
 | 
					    if (this._loadedModules[name]) {
 | 
				
			||||||
 | 
					      return Promise.resolve();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // If we're already in the process of loading it, use the existing promise.
 | 
				
			||||||
 | 
					    if (this._pendingModules[name]) {
 | 
				
			||||||
 | 
					      return this._pendingModules[name];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // If it's a package directory, there's not actually anything to do.
 | 
				
			||||||
 | 
					    if (this._allModules[name].dir) {
 | 
				
			||||||
 | 
					      return Promise.resolve();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // We need to fetch the module file and write it out.
 | 
				
			||||||
 | 
					    var modfile = this._allModules[name].file;
 | 
				
			||||||
 | 
					    var p = this.fetch("modules/" + modfile)
 | 
				
			||||||
 | 
					    .then((function(xhr) {
 | 
				
			||||||
 | 
					      var contents = xhr.responseText;
 | 
				
			||||||
 | 
					      this._writeModuleFile(name, contents)
 | 
				
			||||||
 | 
					      delete this._pendingModules[name];
 | 
				
			||||||
 | 
					    }).bind(this))
 | 
				
			||||||
 | 
					    this._pendingModules[name] = p;
 | 
				
			||||||
 | 
					    return p;
 | 
				
			||||||
 | 
					  }).bind(this);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypyjs.prototype._writeModuleFile = function _writeModuleFile(name, data) {
 | 
				
			||||||
 | 
					  var Module = this._module;
 | 
				
			||||||
 | 
					  var file = this._allModules[name].file;
 | 
				
			||||||
 | 
					  // Create the containing directory first.
 | 
				
			||||||
 | 
					  var dir = file.split("/").slice(0, -1).join("/")
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    Module.FS_createPath("/lib/pypyjs/lib_pypy", dir, true, false);
 | 
				
			||||||
 | 
					  } catch (e) { }
 | 
				
			||||||
 | 
					  // Now we can safely create the file.
 | 
				
			||||||
 | 
					  var fullpath = "/lib/pypyjs/lib_pypy/" + file;
 | 
				
			||||||
 | 
					  Module.FS_createDataFile(fullpath, "", data, true, false, true);
 | 
				
			||||||
 | 
					  this._loadedModules[name] = true;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// An error class for reporting python exceptions back to calling code.
 | 
				
			||||||
 | 
					// XXX TODO: this could be a lot more user-friendly than a opaque error...
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypyjs.Error = function pypyjsError(name, message, trace) {
 | 
				
			||||||
 | 
					  if (name && typeof message === "undefined") {
 | 
				
			||||||
 | 
					    message = name;
 | 
				
			||||||
 | 
					    name = "";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  this.name = name || "pypyjs.Error";
 | 
				
			||||||
 | 
					  this.message = message || "pypyjs Unknown Error";
 | 
				
			||||||
 | 
					  this.trace = trace || "";
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					pypyjs.Error.prototype = new Error();
 | 
				
			||||||
 | 
					pypyjs.Error.prototype.constructor = pypyjs.Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// XXX TODO: expose the filesystem for manipulation by calling code.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Add convenience methods directly on the 'pypyjs' function, that
 | 
				
			||||||
 | 
					// will invoke corresponding methods on a default VM instance.
 | 
				
			||||||
 | 
					// This makes it look like 'pypyjs' is a singleton VM instance.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pypyjs._defaultVM = null;
 | 
				
			||||||
 | 
					pypyjs.stdin = stdio.stdin
 | 
				
			||||||
 | 
					pypyjs.stdout = stdio.stdout
 | 
				
			||||||
 | 
					pypyjs.stderr = stdio.stderr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var PUBLIC_NAMES = ['ready', 'exec', 'eval', 'execfile', 'get', 'set',
 | 
				
			||||||
 | 
					                    'repl', 'loadModuleData'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PUBLIC_NAMES.forEach(function(name) {
 | 
				
			||||||
 | 
					  pypyjs[name] = function() {
 | 
				
			||||||
 | 
					    if (!pypyjs._defaultVM) {
 | 
				
			||||||
 | 
					      pypyjs._defaultVM = new pypyjs({
 | 
				
			||||||
 | 
					        stdin: function(){ return pypyjs.stdin.apply(this, arguments); },
 | 
				
			||||||
 | 
					        stdout: function(){ return pypyjs.stdout.apply(this, arguments); },
 | 
				
			||||||
 | 
					        stderr: function(){ return pypyjs.stderr.apply(this, arguments); },
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return pypyjs._defaultVM[name].apply(pypyjs._defaultVM, arguments)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// For nodejs, run a repl when invoked directly from the command-line.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					return pypyjs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					})();
 | 
				
			||||||
							
								
								
									
										150
									
								
								docs/playground/page.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										150
									
								
								docs/playground/page.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,150 @@
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import GraphenePlayground from './GraphenePlayground';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import _ from 'lodash';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const DEFAULT_CACHE_KEY = 'default';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function filterObject(object, callback, context) {
 | 
				
			||||||
 | 
					  if (!object) {
 | 
				
			||||||
 | 
					    return null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  var result = {};
 | 
				
			||||||
 | 
					  for (var name in object) {
 | 
				
			||||||
 | 
					    if (hasOwnProperty.call(object, name) &&
 | 
				
			||||||
 | 
					        callback.call(context, object[name], name, object)) {
 | 
				
			||||||
 | 
					      result[name] = object[name];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return result;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Playground extends React.Component {
 | 
				
			||||||
 | 
					  componentWillMount() {
 | 
				
			||||||
 | 
					    var sourceWasInjected = false;
 | 
				
			||||||
 | 
					    var queryParams = this.context.router.getCurrentQuery();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var {
 | 
				
			||||||
 | 
					      cacheKey,
 | 
				
			||||||
 | 
					      noCache,
 | 
				
			||||||
 | 
					    } = queryParams;
 | 
				
			||||||
 | 
					    noCache = (noCache !== undefined) && (noCache !== 'false');
 | 
				
			||||||
 | 
					    if (noCache) {
 | 
				
			||||||
 | 
					      cacheKey = undefined;
 | 
				
			||||||
 | 
					    } else if (!cacheKey) {
 | 
				
			||||||
 | 
					      cacheKey = DEFAULT_CACHE_KEY;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.schemaCacheKey = `rp-${cacheKey}-schema`;
 | 
				
			||||||
 | 
					    this.queryCacheKey = `rp-${cacheKey}-query`;
 | 
				
			||||||
 | 
					    this.cacheKey = cacheKey;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    var initialSchema;
 | 
				
			||||||
 | 
					    var initialQuery;
 | 
				
			||||||
 | 
					    var storedSchema = localStorage.getItem(this.schemaCacheKey);
 | 
				
			||||||
 | 
					    var storedQuery = localStorage.getItem(this.queryCacheKey);
 | 
				
			||||||
 | 
					    if (noCache) {
 | 
				
			||||||
 | 
					      // Use case #1
 | 
				
			||||||
 | 
					      // We use the noCache param to force a playground to have certain contents.
 | 
				
			||||||
 | 
					      // eg. static example apps
 | 
				
			||||||
 | 
					      initialSchema = queryParams.schema || '';
 | 
				
			||||||
 | 
					      initialQuery = queryParams.query || '';
 | 
				
			||||||
 | 
					      sourceWasInjected = true;
 | 
				
			||||||
 | 
					      queryParams = {};
 | 
				
			||||||
 | 
					    } else if (cacheKey === DEFAULT_CACHE_KEY) {
 | 
				
			||||||
 | 
					      // Use case #2
 | 
				
			||||||
 | 
					      // The user loaded the playground without a custom cache key.
 | 
				
			||||||
 | 
					      //   Allow code injection via the URL
 | 
				
			||||||
 | 
					      //   OR load code from localStorage
 | 
				
			||||||
 | 
					      //   OR prime the playground with some default 'hello world' code
 | 
				
			||||||
 | 
					      if (queryParams.schema != null) {
 | 
				
			||||||
 | 
					        initialSchema = queryParams.schema;
 | 
				
			||||||
 | 
					        sourceWasInjected = queryParams.schema !== storedSchema;
 | 
				
			||||||
 | 
					      } else if (storedSchema != null) {
 | 
				
			||||||
 | 
					        initialSchema = storedSchema;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        initialSchema = require('!raw!./examples/hello.schema.py');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (queryParams.query != null) {
 | 
				
			||||||
 | 
					        initialQuery = queryParams.query;
 | 
				
			||||||
 | 
					        sourceWasInjected = queryParams.query !== storedQuery;
 | 
				
			||||||
 | 
					      } else if (storedQuery != null) {
 | 
				
			||||||
 | 
					        initialQuery = storedQuery;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        initialQuery = require('!raw!./examples/hello.graphql');
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      queryParams = filterObject({
 | 
				
			||||||
 | 
					        schema: queryParams.schema,
 | 
				
			||||||
 | 
					        query: queryParams.query,
 | 
				
			||||||
 | 
					      }, v => v !== undefined);
 | 
				
			||||||
 | 
					    } else if (cacheKey) {
 | 
				
			||||||
 | 
					      // Use case #3
 | 
				
			||||||
 | 
					      // Custom cache keys are useful in cases where you want to embed a playground
 | 
				
			||||||
 | 
					      // that features both custom boilerplate code AND saves the developer's
 | 
				
			||||||
 | 
					      // progress, without overwriting the default code cache. eg. a tutorial.
 | 
				
			||||||
 | 
					      if (storedSchema != null) {
 | 
				
			||||||
 | 
					        initialSchema = storedSchema;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        initialSchema = queryParams[`schema_${cacheKey}`];
 | 
				
			||||||
 | 
					        if (initialSchema != null) {
 | 
				
			||||||
 | 
					          sourceWasInjected = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      if (storedQuery != null) {
 | 
				
			||||||
 | 
					        initialQuery = storedQuery;
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        initialQuery = queryParams[`query_${cacheKey}`];
 | 
				
			||||||
 | 
					        if (initialQuery != null) {
 | 
				
			||||||
 | 
					          sourceWasInjected = true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      queryParams = {};
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    this.changeParams(queryParams);
 | 
				
			||||||
 | 
					    this.state = {initialSchema, initialQuery, sourceWasInjected};
 | 
				
			||||||
 | 
					    this.queryParams = queryParams;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  shouldComponentUpdate() {
 | 
				
			||||||
 | 
					    return false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  changeParams(queryParams) {
 | 
				
			||||||
 | 
					    var router = this.context.router;
 | 
				
			||||||
 | 
					    var routeName = router.getCurrentPathname();
 | 
				
			||||||
 | 
					    var params = router.getCurrentParams();
 | 
				
			||||||
 | 
					    queryParams = _.mapValues(queryParams, encodeURIComponent);
 | 
				
			||||||
 | 
					    router.replaceWith(routeName, params, queryParams);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  render() {
 | 
				
			||||||
 | 
					    return (<GraphenePlayground
 | 
				
			||||||
 | 
					      initialSchema={this.state.initialSchema}
 | 
				
			||||||
 | 
					      initialQuery={this.state.initialQuery}
 | 
				
			||||||
 | 
					      onEditSchema={(source) => {
 | 
				
			||||||
 | 
					        localStorage.setItem(this.schemaCacheKey, source);
 | 
				
			||||||
 | 
					        if (this.cacheKey === DEFAULT_CACHE_KEY) {
 | 
				
			||||||
 | 
					          this.queryParams.schema = source;
 | 
				
			||||||
 | 
					          if (!this.queryParams.query) {
 | 
				
			||||||
 | 
					            this.queryParams.query = this.state.initialQuery;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.changeParams(this.queryParams);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					      onEditQuery={(source) => {
 | 
				
			||||||
 | 
					        localStorage.setItem(this.queryCacheKey, source);
 | 
				
			||||||
 | 
					        if (this.cacheKey === DEFAULT_CACHE_KEY) {
 | 
				
			||||||
 | 
					          this.queryParams.query = source;
 | 
				
			||||||
 | 
					          if (!this.queryParams.schema) {
 | 
				
			||||||
 | 
					            this.queryParams.schema = this.state.initialSchema;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          this.changeParams(this.queryParams);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }}
 | 
				
			||||||
 | 
					    />);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Playground.contextTypes = {
 | 
				
			||||||
 | 
					  router: React.PropTypes.func
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = Playground;
 | 
				
			||||||
							
								
								
									
										15
									
								
								docs/playground/schema.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								docs/playground/schema.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					  GraphQLObjectType,
 | 
				
			||||||
 | 
					  GraphQLString,
 | 
				
			||||||
 | 
					  GraphQLSchema,
 | 
				
			||||||
 | 
					} from 'graphql';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default new GraphQLSchema({
 | 
				
			||||||
 | 
					  query: new GraphQLObjectType({
 | 
				
			||||||
 | 
					    name: 'Query',
 | 
				
			||||||
 | 
					    fields: () => ({
 | 
				
			||||||
 | 
					      __emptyField: {type: GraphQLString},
 | 
				
			||||||
 | 
					    }),
 | 
				
			||||||
 | 
					  }),
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										21
									
								
								docs/playground/wrapper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								docs/playground/wrapper.js
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class PlaygroundWrapper extends React.Component {
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    super();
 | 
				
			||||||
 | 
					    this.state = { currentComponent: null };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  componentDidMount() {
 | 
				
			||||||
 | 
					    require(["playground-page"], (Playground) =>{
 | 
				
			||||||
 | 
					      this.setState({
 | 
				
			||||||
 | 
					        currentComponent: Playground
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  render() {
 | 
				
			||||||
 | 
					    var Current = this.state.currentComponent;
 | 
				
			||||||
 | 
					    return Current?<Current />:null;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = PlaygroundWrapper;
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								docs/static/favicon.png
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/static/favicon.png
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.3 KiB  | 
							
								
								
									
										7
									
								
								docs/static/graphene.appcache
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										7
									
								
								docs/static/graphene.appcache
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,7 @@
 | 
				
			||||||
 | 
					CACHE MANIFEST
 | 
				
			||||||
 | 
					# 2015-11-27 v1.0.0
 | 
				
			||||||
 | 
					/playground/lib/pypyjs.vm.js
 | 
				
			||||||
 | 
					/playground/lib/pypyjs.vm.js.zmem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					NETWORK:
 | 
				
			||||||
 | 
					*
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,7 @@ class Markdown extends React.Component {
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
      <DocumentTitle title={`${post.title?post.title+' - ':''}${this.props.config.siteTitle}`}>
 | 
					      <DocumentTitle title={`${post.title?post.title+' - ':''}${this.props.config.siteTitle}`}>
 | 
				
			||||||
        <div>
 | 
					        <div>
 | 
				
			||||||
          {showTitle?<div className="title">
 | 
					          {showTitle?<div className="page-title">
 | 
				
			||||||
            <h1>{post.title}</h1>
 | 
					            <h1>{post.title}</h1>
 | 
				
			||||||
          </div>:null}
 | 
					          </div>:null}
 | 
				
			||||||
          <div className="markdown">
 | 
					          <div className="markdown">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										31
									
								
								examples/complex_example.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								examples/complex_example.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,31 @@
 | 
				
			||||||
 | 
					import graphene
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class GeoInput(graphene.InputObjectType):
 | 
				
			||||||
 | 
					    lat = graphene.Float(required=True)
 | 
				
			||||||
 | 
					    lng = graphene.Float(required=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Address(graphene.ObjectType):
 | 
				
			||||||
 | 
					    latlng = graphene.String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Query(graphene.ObjectType):
 | 
				
			||||||
 | 
					    address = graphene.Field(Address, geo=graphene.Argument(GeoInput))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_address(self, args, info):
 | 
				
			||||||
 | 
					        geo = args.get('geo')
 | 
				
			||||||
 | 
					        return Address(latlng="({},{})".format(geo.get('lat'), geo.get('lng')))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					schema = graphene.Schema(query=Query)
 | 
				
			||||||
 | 
					query = '''
 | 
				
			||||||
 | 
					    query something{
 | 
				
			||||||
 | 
					      address(geo: {lat:32.2, lng:12}) {
 | 
				
			||||||
 | 
					        latlng
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					result = schema.execute(query)
 | 
				
			||||||
 | 
					print(result.data['address']['latlng'])
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ query = '''
 | 
				
			||||||
        id
 | 
					        id
 | 
				
			||||||
        name
 | 
					        name
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
}
 | 
					    }
 | 
				
			||||||
'''
 | 
					'''
 | 
				
			||||||
result = schema.execute(query)
 | 
					result = schema.execute(query)
 | 
				
			||||||
print(result.data['patron'])
 | 
					print(result.data['patron'])
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,5 @@
 | 
				
			||||||
from graphene.contrib.django.types import (
 | 
					from graphene.contrib.django.types import (
 | 
				
			||||||
 | 
					    DjangoConnection,
 | 
				
			||||||
    DjangoObjectType,
 | 
					    DjangoObjectType,
 | 
				
			||||||
    DjangoInterface,
 | 
					    DjangoInterface,
 | 
				
			||||||
    DjangoNode
 | 
					    DjangoNode
 | 
				
			||||||
| 
						 | 
					@ -9,4 +10,4 @@ from graphene.contrib.django.fields import (
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = ['DjangoObjectType', 'DjangoInterface', 'DjangoNode',
 | 
					__all__ = ['DjangoObjectType', 'DjangoInterface', 'DjangoNode',
 | 
				
			||||||
           'DjangoConnectionField', 'DjangoModelField']
 | 
					           'DjangoConnection', 'DjangoConnectionField', 'DjangoModelField']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,26 +1,22 @@
 | 
				
			||||||
 | 
					import warnings
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ...core.exceptions import SkipField
 | 
					from ...core.exceptions import SkipField
 | 
				
			||||||
from ...core.fields import Field
 | 
					from ...core.fields import Field
 | 
				
			||||||
from ...core.types.base import FieldType
 | 
					from ...core.types.base import FieldType
 | 
				
			||||||
from ...core.types.definitions import List
 | 
					from ...core.types.definitions import List
 | 
				
			||||||
from ...relay import ConnectionField
 | 
					from ...relay import ConnectionField
 | 
				
			||||||
from ...relay.utils import is_node
 | 
					from ...relay.utils import is_node
 | 
				
			||||||
from .utils import get_type_for_model, lazy_map
 | 
					from .utils import get_type_for_model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoConnectionField(ConnectionField):
 | 
					class DjangoConnectionField(ConnectionField):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def wrap_resolved(self, value, instance, args, info):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        return lazy_map(value, self.type)
 | 
					        cls = self.__class__
 | 
				
			||||||
 | 
					        warnings.warn("Using {} will be not longer supported."
 | 
				
			||||||
 | 
					                      " Use relay.ConnectionField instead".format(cls.__name__),
 | 
				
			||||||
class LazyListField(Field):
 | 
					                      FutureWarning)
 | 
				
			||||||
 | 
					        return super(DjangoConnectionField, self).__init__(*args, **kwargs)
 | 
				
			||||||
    def get_type(self, schema):
 | 
					 | 
				
			||||||
        return List(self.type)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def resolver(self, instance, args, info):
 | 
					 | 
				
			||||||
        resolved = super(LazyListField, self).resolver(instance, args, info)
 | 
					 | 
				
			||||||
        return lazy_map(resolved, self.type)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ConnectionOrListField(Field):
 | 
					class ConnectionOrListField(Field):
 | 
				
			||||||
| 
						 | 
					@ -33,8 +29,8 @@ class ConnectionOrListField(Field):
 | 
				
			||||||
        if is_node(field_object_type):
 | 
					        if is_node(field_object_type):
 | 
				
			||||||
            field = DjangoConnectionField(field_object_type)
 | 
					            field = DjangoConnectionField(field_object_type)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            field = LazyListField(field_object_type)
 | 
					            field = Field(List(field_object_type))
 | 
				
			||||||
        field.contribute_to_class(self.object_type, self.name)
 | 
					        field.contribute_to_class(self.object_type, self.attname)
 | 
				
			||||||
        return schema.T(field)
 | 
					        return schema.T(field)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,7 +69,7 @@ def test_node_replacedfield():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_interface_resolve_type():
 | 
					def test_interface_resolve_type():
 | 
				
			||||||
    resolve_type = Character.resolve_type(schema, Human())
 | 
					    resolve_type = Character._resolve_type(schema, Human())
 | 
				
			||||||
    assert isinstance(resolve_type, GraphQLObjectType)
 | 
					    assert isinstance(resolve_type, GraphQLObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,10 +2,10 @@ import six
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ...core.types import BaseObjectType, ObjectTypeMeta
 | 
					from ...core.types import BaseObjectType, ObjectTypeMeta
 | 
				
			||||||
from ...relay.fields import GlobalIDField
 | 
					from ...relay.fields import GlobalIDField
 | 
				
			||||||
from ...relay.types import BaseNode
 | 
					from ...relay.types import BaseNode, Connection
 | 
				
			||||||
from .converter import convert_django_field
 | 
					from .converter import convert_django_field
 | 
				
			||||||
from .options import DjangoOptions
 | 
					from .options import DjangoOptions
 | 
				
			||||||
from .utils import get_reverse_fields
 | 
					from .utils import get_reverse_fields, maybe_queryset
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoObjectTypeMeta(ObjectTypeMeta):
 | 
					class DjangoObjectTypeMeta(ObjectTypeMeta):
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,7 @@ class DjangoObjectTypeMeta(ObjectTypeMeta):
 | 
				
			||||||
            is_excluded = field.name in cls._meta.exclude_fields or is_already_created
 | 
					            is_excluded = field.name in cls._meta.exclude_fields or is_already_created
 | 
				
			||||||
            if is_not_in_only or is_excluded:
 | 
					            if is_not_in_only or is_excluded:
 | 
				
			||||||
                # We skip this field if we specify only_fields and is not
 | 
					                # We skip this field if we specify only_fields and is not
 | 
				
			||||||
                # in there. Or when we excldue this field in exclude_fields
 | 
					                # in there. Or when we exclude this field in exclude_fields
 | 
				
			||||||
                continue
 | 
					                continue
 | 
				
			||||||
            converted_field = convert_django_field(field)
 | 
					            converted_field = convert_django_field(field)
 | 
				
			||||||
            cls.add_to_class(field.name, converted_field)
 | 
					            cls.add_to_class(field.name, converted_field)
 | 
				
			||||||
| 
						 | 
					@ -71,6 +71,14 @@ class DjangoInterface(six.with_metaclass(
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class DjangoConnection(Connection):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def from_list(cls, iterable, *args, **kwargs):
 | 
				
			||||||
 | 
					        iterable = maybe_queryset(iterable)
 | 
				
			||||||
 | 
					        return super(DjangoConnection, cls).from_list(iterable, *args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class DjangoNode(BaseNode, DjangoInterface):
 | 
					class DjangoNode(BaseNode, DjangoInterface):
 | 
				
			||||||
    id = GlobalIDField()
 | 
					    id = GlobalIDField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -81,3 +89,5 @@ class DjangoNode(BaseNode, DjangoInterface):
 | 
				
			||||||
            return cls(instance)
 | 
					            return cls(instance)
 | 
				
			||||||
        except cls._meta.model.DoesNotExist:
 | 
					        except cls._meta.model.DoesNotExist:
 | 
				
			||||||
            return None
 | 
					            return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    connection_type = DjangoConnection
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,5 @@
 | 
				
			||||||
from django.db import models
 | 
					from django.db import models
 | 
				
			||||||
from django.db.models.manager import Manager
 | 
					from django.db.models.manager import Manager
 | 
				
			||||||
from django.db.models.query import QuerySet
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from ...utils import LazyMap
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_type_for_model(schema, model):
 | 
					def get_type_for_model(schema, model):
 | 
				
			||||||
| 
						 | 
					@ -22,9 +19,7 @@ def get_reverse_fields(model):
 | 
				
			||||||
            yield related
 | 
					            yield related
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def lazy_map(value, func):
 | 
					def maybe_queryset(value):
 | 
				
			||||||
    if isinstance(value, Manager):
 | 
					    if isinstance(value, Manager):
 | 
				
			||||||
        value = value.get_queryset()
 | 
					        value = value.get_queryset()
 | 
				
			||||||
    if isinstance(value, QuerySet):
 | 
					 | 
				
			||||||
        return LazyMap(value, func)
 | 
					 | 
				
			||||||
    return value
 | 
					    return value
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -13,7 +13,10 @@ class Character(Interface):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Pet(ObjectType):
 | 
					class Pet(ObjectType):
 | 
				
			||||||
    type = String(resolver=lambda *_: 'Dog')
 | 
					    type = String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def resolve_type(self, args, info):
 | 
				
			||||||
 | 
					        return 'Dog'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Human(Character):
 | 
					class Human(Character):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ class BaseObjectType(BaseType):
 | 
				
			||||||
        signals.post_init.send(self.__class__, instance=self)
 | 
					        signals.post_init.send(self.__class__, instance=self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
    def resolve_type(cls, schema, instance, *args):
 | 
					    def _resolve_type(cls, schema, instance, *args):
 | 
				
			||||||
        return schema.T(instance.__class__)
 | 
					        return schema.T(instance.__class__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @classmethod
 | 
					    @classmethod
 | 
				
			||||||
| 
						 | 
					@ -191,7 +191,7 @@ class BaseObjectType(BaseType):
 | 
				
			||||||
            return GraphQLInterfaceType(
 | 
					            return GraphQLInterfaceType(
 | 
				
			||||||
                cls._meta.type_name,
 | 
					                cls._meta.type_name,
 | 
				
			||||||
                description=cls._meta.description,
 | 
					                description=cls._meta.description,
 | 
				
			||||||
                resolve_type=partial(cls.resolve_type, schema),
 | 
					                resolve_type=partial(cls._resolve_type, schema),
 | 
				
			||||||
                fields=partial(cls.get_fields, schema)
 | 
					                fields=partial(cls.get_fields, schema)
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        elif cls._meta.is_union:
 | 
					        elif cls._meta.is_union:
 | 
				
			||||||
| 
						 | 
					@ -219,6 +219,10 @@ class BaseObjectType(BaseType):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return OrderedDict(fields)
 | 
					        return OrderedDict(fields)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def wrap(cls, instance, args, info):
 | 
				
			||||||
 | 
					        return cls(_root=instance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Interface(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
					class Interface(six.with_metaclass(ObjectTypeMeta, BaseObjectType)):
 | 
				
			||||||
    pass
 | 
					    pass
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ def test_union_cannot_initialize():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def test_interface_resolve_type():
 | 
					def test_interface_resolve_type():
 | 
				
			||||||
    resolve_type = Character.resolve_type(schema, Human(object()))
 | 
					    resolve_type = Character._resolve_type(schema, Human(object()))
 | 
				
			||||||
    assert isinstance(resolve_type, GraphQLObjectType)
 | 
					    assert isinstance(resolve_type, GraphQLObjectType)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,3 @@
 | 
				
			||||||
from collections import Iterable
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from graphql_relay.connection.arrayconnection import connection_from_list
 | 
					 | 
				
			||||||
from graphql_relay.node.node import from_global_id
 | 
					from graphql_relay.node.node import from_global_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..core.fields import Field
 | 
					from ..core.fields import Field
 | 
				
			||||||
| 
						 | 
					@ -30,24 +27,12 @@ class ConnectionField(Field):
 | 
				
			||||||
        return value
 | 
					        return value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def resolver(self, instance, args, info):
 | 
					    def resolver(self, instance, args, info):
 | 
				
			||||||
        from graphene.relay.types import PageInfo
 | 
					 | 
				
			||||||
        schema = info.schema.graphene_schema
 | 
					        schema = info.schema.graphene_schema
 | 
				
			||||||
 | 
					        connection_type = self.get_type(schema)
 | 
				
			||||||
        resolved = super(ConnectionField, self).resolver(instance, args, info)
 | 
					        resolved = super(ConnectionField, self).resolver(instance, args, info)
 | 
				
			||||||
        if resolved:
 | 
					        if isinstance(resolved, connection_type):
 | 
				
			||||||
            resolved = self.wrap_resolved(resolved, instance, args, info)
 | 
					            return resolved
 | 
				
			||||||
            assert isinstance(
 | 
					        return connection_type.from_list(resolved, args, info)
 | 
				
			||||||
                resolved, Iterable), 'Resolved value from the connection field have to be iterable'
 | 
					 | 
				
			||||||
            type = schema.T(self.type)
 | 
					 | 
				
			||||||
            node = schema.objecttype(type)
 | 
					 | 
				
			||||||
            connection_type = self.get_connection_type(node)
 | 
					 | 
				
			||||||
            edge_type = self.get_edge_type(node)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            connection = connection_from_list(
 | 
					 | 
				
			||||||
                resolved, args, connection_type=connection_type,
 | 
					 | 
				
			||||||
                edge_type=edge_type, pageinfo_type=PageInfo)
 | 
					 | 
				
			||||||
            connection.set_connection_data(resolved)
 | 
					 | 
				
			||||||
            return connection
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_connection_type(self, node):
 | 
					    def get_connection_type(self, node):
 | 
				
			||||||
        connection_type = self.connection_type or node.get_connection_type()
 | 
					        connection_type = self.connection_type or node.get_connection_type()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,9 @@
 | 
				
			||||||
import inspect
 | 
					import inspect
 | 
				
			||||||
import warnings
 | 
					import warnings
 | 
				
			||||||
 | 
					from collections import Iterable
 | 
				
			||||||
from functools import wraps
 | 
					from functools import wraps
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from graphql_relay.connection.arrayconnection import connection_from_list
 | 
				
			||||||
from graphql_relay.node.node import to_global_id
 | 
					from graphql_relay.node.node import to_global_id
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from ..core.types import (Boolean, Field, InputObjectType, Interface, List,
 | 
					from ..core.types import (Boolean, Field, InputObjectType, Interface, List,
 | 
				
			||||||
| 
						 | 
					@ -63,6 +66,16 @@ class Connection(ObjectType):
 | 
				
			||||||
            (cls,),
 | 
					            (cls,),
 | 
				
			||||||
            {'edge_type': edge_type, 'edges': edges})
 | 
					            {'edge_type': edge_type, 'edges': edges})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @classmethod
 | 
				
			||||||
 | 
					    def from_list(cls, iterable, args, info):
 | 
				
			||||||
 | 
					        assert isinstance(
 | 
				
			||||||
 | 
					            iterable, Iterable), 'Resolved value from the connection field have to be iterable'
 | 
				
			||||||
 | 
					        connection = connection_from_list(
 | 
				
			||||||
 | 
					            iterable, args, connection_type=cls,
 | 
				
			||||||
 | 
					            edge_type=cls.edge_type, pageinfo_type=PageInfo)
 | 
				
			||||||
 | 
					        connection.set_connection_data(iterable)
 | 
				
			||||||
 | 
					        return connection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def set_connection_data(self, data):
 | 
					    def set_connection_data(self, data):
 | 
				
			||||||
        self._connection_data = data
 | 
					        self._connection_data = data
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,4 +1,9 @@
 | 
				
			||||||
from blinker import Signal
 | 
					try:
 | 
				
			||||||
 | 
					    from blinker import Signal
 | 
				
			||||||
 | 
					except ImportError:
 | 
				
			||||||
 | 
					    class Signal(object):
 | 
				
			||||||
 | 
					        def send(self, *args, **kwargs):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
init_schema = Signal()
 | 
					init_schema = Signal()
 | 
				
			||||||
class_prepared = Signal()
 | 
					class_prepared = Signal()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,11 +1,10 @@
 | 
				
			||||||
from .str_converters import to_camel_case, to_snake_case
 | 
					from .str_converters import to_camel_case, to_snake_case
 | 
				
			||||||
from .proxy_snake_dict import ProxySnakeDict
 | 
					from .proxy_snake_dict import ProxySnakeDict
 | 
				
			||||||
from .caching import cached_property, memoize
 | 
					from .caching import cached_property, memoize
 | 
				
			||||||
from .lazymap import LazyMap
 | 
					 | 
				
			||||||
from .misc import enum_to_graphql_enum
 | 
					from .misc import enum_to_graphql_enum
 | 
				
			||||||
from .resolve_only_args import resolve_only_args
 | 
					from .resolve_only_args import resolve_only_args
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
__all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict',
 | 
					__all__ = ['to_camel_case', 'to_snake_case', 'ProxySnakeDict',
 | 
				
			||||||
           'cached_property', 'memoize', 'LazyMap', 'enum_to_graphql_enum',
 | 
					           'cached_property', 'memoize', 'enum_to_graphql_enum',
 | 
				
			||||||
           'resolve_only_args']
 | 
					           'resolve_only_args']
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,43 +0,0 @@
 | 
				
			||||||
class LazyMap(object):
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, origin, _map, state=None):
 | 
					 | 
				
			||||||
        self._origin = origin
 | 
					 | 
				
			||||||
        self._origin_iter = origin.__iter__()
 | 
					 | 
				
			||||||
        self._state = state or []
 | 
					 | 
				
			||||||
        self._finished = False
 | 
					 | 
				
			||||||
        self._map = _map
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __iter__(self):
 | 
					 | 
				
			||||||
        return self if not self._finished else iter(self._state)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def iter(self):
 | 
					 | 
				
			||||||
        return self.__iter__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __len__(self):
 | 
					 | 
				
			||||||
        return self._origin.__len__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __next__(self):
 | 
					 | 
				
			||||||
        try:
 | 
					 | 
				
			||||||
            n = next(self._origin_iter)
 | 
					 | 
				
			||||||
            n = self._map(n)
 | 
					 | 
				
			||||||
        except StopIteration as e:
 | 
					 | 
				
			||||||
            self._finished = True
 | 
					 | 
				
			||||||
            raise e
 | 
					 | 
				
			||||||
        else:
 | 
					 | 
				
			||||||
            self._state.append(n)
 | 
					 | 
				
			||||||
            return n
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def next(self):
 | 
					 | 
				
			||||||
        return self.__next__()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __getitem__(self, key):
 | 
					 | 
				
			||||||
        item = self._origin[key]
 | 
					 | 
				
			||||||
        if isinstance(key, slice):
 | 
					 | 
				
			||||||
            return LazyMap(item, self._map)
 | 
					 | 
				
			||||||
        return self._map(item)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __getattr__(self, name):
 | 
					 | 
				
			||||||
        return getattr(self._origin, name)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __repr__(self):
 | 
					 | 
				
			||||||
        return "<LazyMap %s>" % repr(self._origin)
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,23 +0,0 @@
 | 
				
			||||||
from py.test import raises
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from ..lazymap import LazyMap
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_lazymap():
 | 
					 | 
				
			||||||
    data = list(range(10))
 | 
					 | 
				
			||||||
    lm = LazyMap(data, lambda x: 2 * x)
 | 
					 | 
				
			||||||
    assert len(lm) == 10
 | 
					 | 
				
			||||||
    assert lm[1] == 2
 | 
					 | 
				
			||||||
    assert isinstance(lm[1:4], LazyMap)
 | 
					 | 
				
			||||||
    assert lm.append == data.append
 | 
					 | 
				
			||||||
    assert repr(lm) == '<LazyMap [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]>'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
def test_lazymap_iter():
 | 
					 | 
				
			||||||
    data = list(range(2))
 | 
					 | 
				
			||||||
    lm = LazyMap(data, lambda x: 2 * x)
 | 
					 | 
				
			||||||
    iter_lm = iter(lm)
 | 
					 | 
				
			||||||
    assert iter_lm.next() == 0
 | 
					 | 
				
			||||||
    assert iter_lm.next() == 2
 | 
					 | 
				
			||||||
    with raises(StopIteration):
 | 
					 | 
				
			||||||
        iter_lm.next()
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,9 @@
 | 
				
			||||||
[flake8]
 | 
					[flake8]
 | 
				
			||||||
exclude = setup.py
 | 
					exclude = setup.py,docs/*
 | 
				
			||||||
max-line-length = 120
 | 
					max-line-length = 120
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[coverage:run]
 | 
					[coverage:run]
 | 
				
			||||||
omit = core/ntypes/tests/*
 | 
					omit = core/ntypes/tests/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					[isort]
 | 
				
			||||||
 | 
					known_first_party=graphene
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										3
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								setup.py
									
									
									
									
									
								
							| 
						 | 
					@ -24,7 +24,7 @@ class PyTest(TestCommand):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
setup(
 | 
					setup(
 | 
				
			||||||
    name='graphene',
 | 
					    name='graphene',
 | 
				
			||||||
    version='0.4.1.1',
 | 
					    version='0.4.2',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    description='Graphene: Python DSL for GraphQL',
 | 
					    description='Graphene: Python DSL for GraphQL',
 | 
				
			||||||
    long_description=open('README.rst').read(),
 | 
					    long_description=open('README.rst').read(),
 | 
				
			||||||
| 
						 | 
					@ -55,7 +55,6 @@ setup(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    install_requires=[
 | 
					    install_requires=[
 | 
				
			||||||
        'six>=1.10.0',
 | 
					        'six>=1.10.0',
 | 
				
			||||||
        'blinker',
 | 
					 | 
				
			||||||
        'graphql-core==0.4.9',
 | 
					        'graphql-core==0.4.9',
 | 
				
			||||||
        'graphql-relay==0.3.3'
 | 
					        'graphql-relay==0.3.3'
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user