[
  {
    "path": ".coveragerc",
    "content": "[run]\nomit = graphene/pyutils/*,*/tests/*\n"
  },
  {
    "path": ".editorconfig",
    "content": "# http://editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.{py,rst,ini}]\nindent_style = space\nindent_size = 4\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: \"\\U0001F41B bug\"\nassignees: ''\n\n---\n\n**Note: for support questions, please use stackoverflow**. This repository's issues are reserved for feature requests and bug reports.\n\n* **What is the current behavior?**\n\n\n\n* **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem** via\na github repo, https://repl.it or similar.\n\n\n\n* **What is the expected behavior?**\n\n\n\n* **What is the motivation / use case for changing the behavior?**\n\n\n\n* **Please tell us about your environment:**\n\n  - Version:\n  - Platform:\n\n* **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow)\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: \"✨ enhancement\"\nassignees: ''\n\n---\n\n**Is your feature request related to a problem? Please describe.**\nA clear and concise description of what the problem is. Ex. I'm always frustrated when [...]\n\n**Describe the solution you'd like**\nA clear and concise description of what you want to happen.\n\n**Describe alternatives you've considered**\nA clear and concise description of any alternative solutions or features you've considered.\n\n**Additional context**\nAdd any other context or screenshots about the feature request here.\n"
  },
  {
    "path": ".github/stale.yml",
    "content": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: false\n# Number of days of inactivity before a stale issue is closed\ndaysUntilClose: false\n# Issues with these labels will never be considered stale\nexemptLabels:\n  - pinned\n  - security\n  - 🐛 bug\n  - 📖 documentation\n  - 🙋 help wanted\n  - ✨ enhancement\n  - good first issue\n  - work in progress\n# Label to use when marking an issue as stale\nstaleLabel: wontfix\n# Comment to post when marking an issue as stale. Set to `false` to disable\nmarkComment: false\n# markComment: >\n  # This issue has been automatically marked as stale because it has not had\n  # recent activity. It will be closed if no further activity occurs. Thank you\n  # for your contributions.\n# Comment to post when closing a stale issue. Set to `false` to disable\ncloseComment: false\n"
  },
  {
    "path": ".github/workflows/build.yaml",
    "content": "name: 📦 Build\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v4\n    - name: Set up Python 3.10\n      uses: actions/setup-python@v5\n      with:\n        python-version: \"3.10\"\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install build twine\n    - name: Building package\n      run: python3 -m build\n    - name: Check package with Twine\n      run: twine check dist/*\n"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "content": "name: 🚀 Deploy to PyPI\n\non:\n  push:\n    tags:\n      - 'v*'\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Set up Python 3.10\n      uses: actions/setup-python@v5\n      with:\n        python-version: \"3.10\"\n    - name: Build wheel and source tarball\n      run: |\n        pip install wheel\n        python setup.py sdist bdist_wheel\n    - name: Publish a Python distribution to PyPI\n      uses: pypa/gh-action-pypi-publish@v1.1.0\n      with:\n        user: __token__\n        password: ${{ secrets.pypi_password }}\n"
  },
  {
    "path": ".github/workflows/lint.yml",
    "content": "name: 💅 Lint\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v4\n    - name: Set up Python 3.10\n      uses: actions/setup-python@v5\n      with:\n        python-version: \"3.10\"\n    - name: Install dependencies\n      run: |\n        python -m pip install --upgrade pip\n        pip install tox\n    - name: Run lint\n      run: tox\n      env:\n        TOXENV: pre-commit\n    - name: Run mypy\n      run: tox\n      env:\n        TOXENV: mypy\n"
  },
  {
    "path": ".github/workflows/tests.yml",
    "content": "name: 📄 Tests\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n    paths-ignore:\n      - 'docs/**'\n      - '*.md'\n      - '*.rst'\n  pull_request:\n    branches:\n      - master\n      - '*.x'\n    paths-ignore:\n      - 'docs/**'\n      - '*.md'\n      - '*.rst'\njobs:\n  tests:\n    # runs the test suite\n    name: ${{ matrix.name }}\n    runs-on: ${{ matrix.os }}\n    strategy:\n      fail-fast: false\n      matrix:\n        include:\n          - {name: '3.13', python: '3.13', os: ubuntu-latest, tox: py313}\n          - {name: '3.12', python: '3.12', os: ubuntu-latest, tox: py312}\n          - {name: '3.11', python: '3.11', os: ubuntu-latest, tox: py311}\n          - {name: '3.10', python: '3.10', os: ubuntu-latest, tox: py310}\n          - {name: '3.9', python: '3.9', os: ubuntu-latest, tox: py39}\n          - {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38}\n    steps:\n      - uses: actions/checkout@v4\n      - uses: actions/setup-python@v5\n        with:\n          python-version: ${{ matrix.python }}\n\n      - name: update pip\n        run: |\n          python -m pip install --upgrade pip\n          pip install --upgrade setuptools wheel\n\n      - name: get pip cache dir\n        id: pip-cache\n        run: echo \"dir=$(pip cache dir)\" >> $GITHUB_OUTPUT\n      - name: cache pip dependencies\n        uses: actions/cache@v3\n        with:\n          path: ${{ steps.pip-cache.outputs.dir }}\n          key: pip|${{ runner.os }}|${{ matrix.python }}|${{ hashFiles('setup.py') }}\n      - run: pip install tox\n      - run: tox -e ${{ matrix.tox }}\n      - name: Upload coverage.xml\n        if: ${{ matrix.python == '3.10' }}\n        uses: actions/upload-artifact@v4\n        with:\n          name: graphene-coverage\n          path: coverage.xml\n          if-no-files-found: error\n      - name: Upload coverage.xml to codecov\n        if: ${{ matrix.python == '3.10' }}\n        uses: codecov/codecov-action@v4\n"
  },
  {
    "path": ".gitignore",
    "content": "# Created by https://www.gitignore.io\n\n### Python ###\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\n*.egg-info/\n.installed.cfg\n*.egg\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\n.pytest_cache\nnosetests.xml\ncoverage.xml\n*.cover\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\n\n# Sphinx documentation\ndocs/_build/\n\n# PyBuilder\ntarget/\n\n# VirtualEnv\n.env\n.venv\nenv/\nvenv/\n\n# Typing\n.mypy_cache/\n\n/tests/django.sqlite\n\n/graphene/index.json\n/graphene/meta.json\n\n/meta.json\n/index.json\n\n/docs/playground/graphene-js/pypyjs-release-nojit/\n/docs/static/playground/lib\n\n/docs/static/playground\n\n# PyCharm\n.idea\n*.iml\n\n# Databases\n*.sqlite3\n.vscode\n.mypy_cache\n.ruff_cache\n"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "default_language_version:\n  python: python3.10\n\nrepos:\n-   repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: v4.3.0\n    hooks:\n    -   id: check-merge-conflict\n    -   id: check-json\n    -   id: check-yaml\n    -   id: debug-statements\n    -   id: end-of-file-fixer\n        exclude: ^docs/.*$\n    -   id: pretty-format-json\n        args:\n        - --autofix\n    -   id: trailing-whitespace\n        exclude: README.md\n-   repo: https://github.com/asottile/pyupgrade\n    rev: v2.37.3\n    hooks:\n    -   id: pyupgrade\n-   repo: https://github.com/astral-sh/ruff-pre-commit\n    # Ruff version.\n    rev: v0.5.0\n    hooks:\n        - id: ruff\n        - id: ruff-format\n          args: [ --check ]\n"
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015-Present Syrus Akbary\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "MANIFEST.in",
    "content": "global-exclude tests/*\nrecursive-exclude tests *\nrecursive-exclude tests_py35 *\nrecursive-exclude examples *\ninclude LICENSE\n"
  },
  {
    "path": "Makefile",
    "content": ".PHONY: help\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@grep -E '^\\.PHONY: [a-zA-Z_-]+ .*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = \"(: |##)\"}; {printf \"\\033[36m%-30s\\033[0m %s\\n\", $$2, $$3}'\n\n.PHONY: install-dev ## Install development dependencies\ninstall-dev:\n\tpip install -e \".[dev]\"\n\n.PHONY: test ## Run tests\ntest:\n\tpy.test graphene examples\n\n.PHONY: docs ## Generate docs\ndocs: install-dev\n\tcd docs && make install && make html\n\n.PHONY: docs-live ## Generate docs with live reloading\ndocs-live: install-dev\n\tcd docs && make install && make livehtml\n\n.PHONY: format\nformat:\n\tblack graphene examples setup.py\n\n.PHONY: lint\nlint:\n\tflake8 graphene examples setup.py\n"
  },
  {
    "path": "README.md",
    "content": "# ![Graphene Logo](http://graphene-python.org/favicon.png) [Graphene](http://graphene-python.org)  [![PyPI version](https://badge.fury.io/py/graphene.svg)](https://badge.fury.io/py/graphene) [![Coverage Status](https://coveralls.io/repos/graphql-python/graphene/badge.svg?branch=master&service=github)](https://coveralls.io/github/graphql-python/graphene?branch=master) [![](https://dcbadge.vercel.app/api/server/T6Gp6NFYHe?style=flat)](https://discord.gg/T6Gp6NFYHe)\n\n[💬 Join the community on Discord](https://discord.gg/T6Gp6NFYHe)\n\n**We are looking for contributors**! Please check the current issues to see how you can help ❤️\n\n## Introduction\n\n[Graphene](http://graphene-python.org) is an opinionated Python library for building GraphQL schemas/types fast and easily.\n\n- **Easy to use:** Graphene helps you use GraphQL in Python without effort.\n- **Relay:** Graphene has builtin support for Relay.\n- **Data agnostic:** Graphene supports any kind of data source: SQL (Django, SQLAlchemy), Mongo, custom Python objects, etc.\n  We believe that by providing a complete API you could plug Graphene anywhere your data lives and make your data available\n  through GraphQL.\n\n## Integrations\n\nGraphene has multiple integrations with different frameworks:\n\n| integration       | Package                                                                                 |\n| ----------------- | --------------------------------------------------------------------------------------- |\n| SQLAlchemy        | [graphene-sqlalchemy](https://github.com/graphql-python/graphene-sqlalchemy/)           |\n| Mongo             | [graphene-mongo](https://github.com/graphql-python/graphene-mongo/)                     |\n| Apollo Federation | [graphene-federation](https://github.com/graphql-python/graphene-federation/)           |\n| Django            | [graphene-django](https://github.com/graphql-python/graphene-django/)                   |\n\nAlso, Graphene is fully compatible with the GraphQL spec, working seamlessly with all GraphQL clients, such as [Relay](https://github.com/facebook/relay), [Apollo](https://github.com/apollographql/apollo-client) and [gql](https://github.com/graphql-python/gql).\n\n## Installation\n\nTo install `graphene`, just run this command in your shell\n\n```bash\npip install \"graphene>=3.1\"\n```\n\n## Examples\n\nHere is one example for you to get started:\n\n```python\nimport graphene\n\nclass Query(graphene.ObjectType):\n    hello = graphene.String(description='A typical hello world')\n\n    def resolve_hello(self, info):\n        return 'World'\n\nschema = graphene.Schema(query=Query)\n```\n\nThen Querying `graphene.Schema` is as simple as:\n\n```python\nquery = '''\n    query SayHello {\n      hello\n    }\n'''\nresult = schema.execute(query)\n```\n\nIf you want to learn even more, you can also check the following [examples](examples/):\n\n- **Basic Schema**: [Starwars example](examples/starwars)\n- **Relay Schema**: [Starwars Relay example](examples/starwars_relay)\n\n## Documentation\n\nDocumentation and links to additional resources are available at\nhttps://docs.graphene-python.org/en/latest/\n\n## Contributing\n\nAfter cloning this repo, create a [virtualenv](https://virtualenv.pypa.io/en/stable/) and ensure dependencies are installed by running:\n\n```sh\nvirtualenv venv\nsource venv/bin/activate\npip install -e \".[test]\"\n```\n\nWell-written tests and maintaining good test coverage is important to this project. While developing, run new and existing tests with:\n\n```sh\npytest graphene/relay/tests/test_node.py # Single file\npytest graphene/relay # All tests in directory\n```\n\nAdd the `-s` flag if you have introduced breakpoints into the code for debugging.\nAdd the `-v` (\"verbose\") flag to get more detailed test output. For even more detailed output, use `-vv`.\nCheck out the [pytest documentation](https://docs.pytest.org/en/latest/) for more options and test running controls.\n\nRegularly ensure your `pre-commit` hooks are up to date and enabled:\n\n```sh\npre-commit install\n```\n\nYou can also run the benchmarks with:\n\n```sh\npytest graphene --benchmark-only\n```\n\nGraphene supports several versions of Python. To make sure that changes do not break compatibility with any of those versions, we use `tox` to create virtualenvs for each Python version and run tests with that version. To run against all Python versions defined in the `tox.ini` config file, just run:\n\n```sh\ntox\n```\n\nIf you wish to run against a specific version defined in the `tox.ini` file:\n\n```sh\ntox -e py39\n```\n\nTox can only use whatever versions of Python are installed on your system. When you create a pull request, GitHub Actions pipelines will also be running the same tests and report the results, so there is no need for potential contributors to try to install every single version of Python on their own system ahead of time. We appreciate opening issues and pull requests to make graphene even more stable & useful!\n\n### Building Documentation\n\nThe documentation is generated using the excellent [Sphinx](http://www.sphinx-doc.org/) and a custom theme.\n\nAn HTML version of the documentation is produced by running:\n\n```sh\nmake docs\n```\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\n## Supported Versions\n\nSupport for security issues is currently provided for Graphene 3.0 and above. Support on earlier versions cannot be guaranteed by the maintainers of this library, but community PRs may be accepted in critical cases.\nThe preferred mitigation strategy is via an upgrade to Graphene 3.\n\n| Version | Supported          |\n| ------- | ------------------ |\n| 3.x     | :white_check_mark: |\n| <3.x    | :x:                |\n\n## Reporting a Vulnerability\n\nPlease use responsible disclosure by contacting a core maintainer via Discord or E-Mail.\n"
  },
  {
    "path": "UPGRADE-v1.0.md",
    "content": "# v1.0 Upgrade Guide\n\nBig changes from v0.10.x to 1.0. While on the surface a lot of this just looks like shuffling around API, the entire codebase has been rewritten to handle some really great use cases and improved performance.\n\n## Backwards Compatibility and Deprecation Warnings\n\nThis has been a community project from the start, we need your help making the upgrade as smooth as possible for everybody!\nWe have done our best to provide backwards compatibility with deprecated APIs.\n\n## Deprecations\n\n- `with_context` is no longer needed. Resolvers now always take the context argument.\n  Before:\n\n  ```python\n  def resolve_xxx(root, args, info):\n      # ...\n  ```\n\n  With 1.0:\n\n  ```python\n  def resolve_xxx(root, args, context, info):\n      # ...\n  ```\n\n- `ObjectType` and `Interface` no longer accept the `abstract` option in the `Meta`.\n  Inheriting fields should be now achieved using `AbstractType` inheritance.\n\n  Before:\n\n  ```python\n  class MyBaseQuery(graphene.ObjectType):\n      my_field = String()\n      class Meta:\n          abstract = True\n\n  class Query(MyBaseQuery):\n      pass\n\n  ```\n\n  With 1.0:\n\n  ```python\n  class MyBaseQuery(graphene.AbstractType):\n      my_field = String()\n\n  class Query(MyBaseQuery, graphene.ObjectType):\n      pass\n  ```\n\n- The `type_name` option in the Meta in types is now `name`\n\n- Type references no longer work with strings, but with functions.\n\n  Before:\n\n  ```python\n  class Query(graphene.ObjectType):\n      user = graphene.Field('User')\n      users = graphene.List('User')\n  ```\n\n  With 1.0:\n\n  ```python\n  class Query(graphene.ObjectType):\n      user = graphene.Field(lambda: User)\n      users = graphene.List(lambda: User)\n  ```\n\n## Schema\n\nSchemas in graphene `1.0` are `Immutable`, that means that once you create a `graphene.Schema` any\nchange in their attributes will not have any effect.\nThe `name` argument is removed from the Schema.\n\nThe arguments `executor` and `middlewares` are also removed from the `Schema` definition.\nYou can still use them, but by calling explicitly in the `execute` method in `graphql`.\n\n```python\n# Old way\nschema = graphene.Schema(name='My Schema')\nschema.query = Query\nschema.mutation = Mutation\n\n# New way\nschema = graphene.Schema(\n    query=Query,\n    mutation=Mutation\n)\n```\n\n## Interfaces\n\nFor implementing an Interface in an ObjectType, you have to add it onto `Meta.interfaces`.\n\nLike:\n\n```python\nfrom graphene import Interface, ObjectType, String\n\nclass Character(Interface):\n    name = String()\n\nclass Human(Character): # Old way, Human will still be an Interface\n    pass\n\nclass Droid(ObjectType): # New way, you have to specify the ObjectType\n    class Meta:\n        interfaces = (Character, )\n```\n\n## Mutations\n\nMutation fields have changed the way of usage, before if you have the mutation `MyMutation` you\nonly have to reference with `graphene.Field(MyMutation)` now it's simply `MyMutation.Field()`\n\nExample:\n\n```python\nfrom graphene import ObjectType, Mutation, String\n\nclass ReverseString(Mutation):\n    class Input:\n        input = String(required=True)\n\n    reversed = String()\n\n    def mutate(root, args, context, info):\n        reversed = args.get('input')[::-1]\n        return ReverseString(reversed=reversed)\n\nclass Query(ObjectType):\n    reverse_string = graphene.Field(ReverseString) # Old way, will not include the mutation arguments by default\n    reverse_string = ReverseString.Field()\n```\n\n## Nodes\n\nApart from implementing as shown in the previous section, to use the node field you have to\nspecify the node Type.\n\nExample:\n\n```python\nfrom graphene import ObjectType, relay\n\nclass Query(ObjectType):\n    node = relay.NodeField() # Old way, NodeField no longer exists. Use Node.Field\n    node = relay.Node.Field() # New way\n```\n\nAlso, if you wanted to create an `ObjectType` that implements `Node`, you have to do it\nexplicitly.\n\n## Django\n\nThe Django integration with Graphene now has an independent package: `graphene-django`.\nFor installing, you have to replace the old `graphene[django]` with `graphene-django`.\n\n- As the package is now independent, you now have to import from `graphene_django`.\n- **DjangoNode no longer exists**, please use `relay.Node` instead:\n\n  ```python\n  from graphene.relay import Node\n  from graphene_django import DjangoObjectType\n\n  class Droid(DjangoObjectType):\n      class Meta:\n          interfaces = (Node, )\n  ```\n\n## SQLAlchemy\n\nThe SQLAlchemy integration with Graphene now has an independent package: `graphene-sqlalchemy`.\nFor installing, you have to replace the old `graphene[sqlalchemy]` with `graphene-sqlalchemy`.\n\n- As the package is now independent, you have to import now from `graphene_sqlalchemy`.\n- **SQLAlchemyNode no longer exists**, please use `relay.Node` instead:\n\n  ```python\n  from graphene.relay import Node\n  from graphene_sqlalchemy import SQLAlchemyObjectType\n\n  class Droid(SQLAlchemyObjectType):\n      class Meta:\n          interfaces = (Node, )\n  ```\n"
  },
  {
    "path": "UPGRADE-v2.0.md",
    "content": "# v2.0 Upgrade Guide\n\n`ObjectType`, `Interface`, `InputObjectType`, `Scalar` and `Enum` implementations\nhave been quite simplified, without the need to define a explicit Metaclass for each subtype.\n\nIt also improves the field resolvers, [simplifying the code](#simpler-resolvers) the\ndeveloper has to write to use them.\n\n**Deprecations:**\n\n- [`AbstractType`](#abstracttype-deprecated)\n- [`resolve_only_args`](#resolve_only_args)\n- [`Mutation.Input`](#mutationinput)\n\n**Breaking changes:**\n\n- [`Simpler Resolvers`](#simpler-resolvers)\n- [`Node Connections`](#node-connections)\n\n**New Features!**\n\n- [`InputObjectType`](#inputobjecttype)\n- [`Meta as Class arguments`](#meta-as-class-arguments) (_only available for Python 3_)\n\n> The type metaclasses are now deleted as they are no longer necessary. If your code was depending\n> on this strategy for creating custom attrs, see an [example on how to do it in 2.0](https://github.com/graphql-python/graphene/blob/v2.0.0/graphene/tests/issues/test_425.py).\n\n## Deprecations\n\n### AbstractType deprecated\n\nAbstractType is deprecated in graphene 2.0, you can now use normal inheritance instead.\n\nBefore:\n\n```python\nclass CommonFields(AbstractType):\n    name = String()\n\nclass Pet(CommonFields, Interface):\n    pass\n```\n\nWith 2.0:\n\n```python\nclass CommonFields(object):\n    name = String()\n\nclass Pet(CommonFields, Interface):\n    pass\n```\n\n### resolve_only_args\n\n`resolve_only_args` is now deprecated as the resolver API has been simplified.\n\nBefore:\n\n```python\nclass User(ObjectType):\n    name = String()\n\n    @resolve_only_args\n    def resolve_name(root):\n        return root.name\n```\n\nWith 2.0:\n\n```python\nclass User(ObjectType):\n    name = String()\n\n    def resolve_name(root, info):\n        return root.name\n```\n\n### Mutation.Input\n\n`Mutation.Input` is now deprecated in favor of using `Mutation.Arguments` (`ClientIDMutation` still uses `Input`).\n\nBefore:\n\n```python\nclass User(Mutation):\n    class Input:\n        name = String()\n```\n\nWith 2.0:\n\n```python\nclass User(Mutation):\n    class Arguments:\n        name = String()\n```\n\n## Breaking Changes\n\n### Simpler resolvers\n\nAll the resolvers in graphene have been simplified.\nPrior to Graphene `2.0`, all resolvers required four arguments: `(root, args, context, info)`.\nNow, resolver `args` are passed as keyword arguments to the function, and `context` argument dissapeared in favor of `info.context`.\n\nBefore:\n\n```python\nmy_field = graphene.String(my_arg=graphene.String())\n\ndef resolve_my_field(root, args, context, info):\n    my_arg = args.get('my_arg')\n    return ...\n```\n\nWith 2.0:\n\n```python\nmy_field = graphene.String(my_arg=graphene.String())\n\ndef resolve_my_field(root, info, my_arg):\n    return ...\n```\n\n**PS.: Take care with receiving args like `my_arg` as above. This doesn't work for optional (non-required) arguments as standard `Connection`'s arguments (first, last, after, before).**\nYou may need something like this:\n\n```python\ndef resolve_my_field(root, info, known_field1, known_field2, **args): ## get other args with: args.get('arg_key')\n```\n\nAnd, if you need the context in the resolver, you can use `info.context`:\n\n```python\nmy_field = graphene.String(my_arg=graphene.String())\n\ndef resolve_my_field(root, info, my_arg):\n    context = info.context\n    return ...\n```\n\n### Node Connections\n\nNode types no longer have a `Connection` by default.\nIn 2.0 and onwards `Connection`s should be defined explicitly.\n\nBefore:\n\n```python\nclass User(ObjectType):\n    class Meta:\n        interfaces = [relay.Node]\n    name = String()\n\nclass Query(ObjectType):\n    user_connection = relay.ConnectionField(User)\n```\n\nWith 2.0:\n\n```python\nclass User(ObjectType):\n    class Meta:\n        interfaces = [relay.Node]\n    name = String()\n\nclass UserConnection(relay.Connection):\n    class Meta:\n        node = User\n\nclass Query(ObjectType):\n    user_connection = relay.ConnectionField(UserConnection)\n```\n\n## Node.get_node\n\nThe method `get_node` in `ObjectTypes` that have `Node` as interface, changes its API.\nFrom `def get_node(cls, id, context, info)` to `def get_node(cls, info, id)`.\n\n```python\nclass MyObject(ObjectType):\n    class Meta:\n        interfaces = (Node, )\n\n    @classmethod\n    def get_node(cls, id, context, info):\n        return ...\n```\n\nTo:\n\n```python\nclass MyObject(ObjectType):\n    class Meta:\n        interfaces = (Node, )\n\n    @classmethod\n    def get_node(cls, info, id):\n        return ...\n```\n\n## Node.get_node_from_global_id\n\nThe parameters' order of `get_node_from_global_id` method has changed. You may need to adjust your [Node Root Field](http://docs.graphene-python.org/en/latest/relay/nodes/#node-root-field) and maybe other places that uses this method to obtain an object.\n\nBefore:\n\n```python\nclass RootQuery(object):\n    ...\n    node = Field(relay.Node, id=ID(required=True))\n\n    def resolve_node(root, args, context, info):\n        node = relay.Node.get_node_from_global_id(args['id'], context, info)\n        return node\n```\n\nNow:\n\n```python\nclass RootQuery(object):\n    ...\n    node = Field(relay.Node, id=ID(required=True))\n\n    def resolve_node(root, info, id):\n        node = relay.Node.get_node_from_global_id(info, id)\n        return node\n```\n\n## Mutation.mutate\n\nNow only receives (`root`, `info`, `**kwargs`) and is not a @classmethod\n\nBefore:\n\n```python\nclass SomeMutation(Mutation):\n    ...\n\n    @classmethod\n    def mutate(cls, instance, args, context, info):\n        ...\n```\n\nWith 2.0:\n\n```python\nclass SomeMutation(Mutation):\n    ...\n\n    def mutate(root, info, **args):\n        ...\n```\n\nWith 2.0 you can also get your declared (as above) `args` this way:\n\n```python\nclass SomeMutation(Mutation):\n    class Arguments:\n        first_name = String(required=True)\n        last_name = String(required=True)\n    ...\n\n    def mutate(root, info, first_name, last_name):\n        ...\n```\n\n## ClientIDMutation.mutate_and_get_payload\n\nNow only receives (`root`, `info`, `**input`)\n\n### Middlewares\n\nIf you are using Middelwares, you need to some adjustments:\n\nBefore:\n\n```python\nclass MyGrapheneMiddleware(object):\n    def resolve(self, next_mw, root, args, context, info):\n\n        ## Middleware code\n\n        return next_mw(root, args, context, info)\n```\n\nWith 2.0:\n\n```python\nclass MyGrapheneMiddleware(object):\n    def resolve(self, next_mw, root, info, **args):\n        context = info.context\n\n        ## Middleware code\n\n        info.context = context\n        return next_mw(root, info, **args)\n```\n\n## New Features\n\n### InputObjectType\n\nIf you are using `InputObjectType`, you now can access\nits fields via `getattr` (`my_input.myattr`) when resolving, instead of\nthe classic way `my_input['myattr']`.\n\nAnd also use custom defined properties on your input class.\n\nExample. Before:\n\n```python\nclass UserInput(InputObjectType):\n    id = ID(required=True)\n\ndef is_valid_input(input):\n    return input.get('id').startswith('userid_')\n\nclass Query(ObjectType):\n    user = graphene.Field(User, input=UserInput())\n\n    @resolve_only_args\n    def resolve_user(root, input):\n        user_id = input.get('id')\n        if is_valid_input(user_id):\n            return get_user(user_id)\n```\n\nWith 2.0:\n\n```python\nclass UserInput(InputObjectType):\n    id = ID(required=True)\n\n    @property\n    def is_valid(root):\n        return root.id.startswith('userid_')\n\nclass Query(ObjectType):\n    user = graphene.Field(User, input=UserInput())\n\n    def resolve_user(root, info, input):\n        if input.is_valid:\n            return get_user(input.id)\n```\n\n### Meta as Class arguments\n\nNow you can use the meta options as class arguments (**ONLY PYTHON 3**).\n\nBefore:\n\n```python\nclass Dog(ObjectType):\n    class Meta:\n        interfaces = [Pet]\n    name = String()\n```\n\nWith 2.0:\n\n```python\nclass Dog(ObjectType, interfaces=[Pet]):\n    name = String()\n```\n\n### Abstract types\n\nNow you can create abstact types super easily, without the need of subclassing the meta.\n\n```python\nclass Base(ObjectType):\n    class Meta:\n        abstract = True\n\n    id = ID()\n\n    def resolve_id(root, info):\n        return f\"{root.__class__.__name__}_{root.id}\"\n```\n\n### UUID Scalar\n\nIn Graphene 2.0 there is a new dedicated scalar for UUIDs, `UUID`.\n"
  },
  {
    "path": "bin/convert_documentation",
    "content": "#!/bin/bash\n\npandoc README.md --from markdown --to rst -s -o README.rst\n"
  },
  {
    "path": "docs/Makefile",
    "content": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD   = sphinx-build\nPAPER         =\nBUILDDIR      = _build\n\n# Internal variables.\nPAPEROPT_a4     = -D latex_paper_size=a4\nPAPEROPT_letter = -D latex_paper_size=letter\nALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n# the i18n builder cannot share the environment and doctrees with the others\nI18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .\n\n.PHONY: help\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@grep -E '^\\.PHONY: [a-zA-Z_-]+ .*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = \"(: |##)\"}; {printf \"\\033[36m%-30s\\033[0m %s\\n\", $$2, $$3}'\n\n.PHONY: install ## to install all documentation related requirements\ninstall:\n\tpip install -r requirements.txt\n\n.PHONY: clean ## to remove all built documentation\nclean:\n\trm -rf $(BUILDDIR)/*\n\n.PHONY: html ## to make standalone HTML files\nhtml:\n\t$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/html.\"\n\n.PHONY: dirhtml ## to make HTML files named index.html in directories\ndirhtml:\n\t$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml\n\t@echo\n\t@echo \"Build finished. The HTML pages are in $(BUILDDIR)/dirhtml.\"\n\n.PHONY: singlehtml ## to make a single large HTML file\nsinglehtml:\n\t$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml\n\t@echo\n\t@echo \"Build finished. The HTML page is in $(BUILDDIR)/singlehtml.\"\n\n.PHONY: pickle ## to make pickle files\npickle:\n\t$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle\n\t@echo\n\t@echo \"Build finished; now you can process the pickle files.\"\n\n.PHONY: json ## to make JSON files\njson:\n\t$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json\n\t@echo\n\t@echo \"Build finished; now you can process the JSON files.\"\n\n.PHONY: htmlhelp ## to make HTML files and a HTML help project\nhtmlhelp:\n\t$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp\n\t@echo\n\t@echo \"Build finished; now you can run HTML Help Workshop with the\" \\\n\t      \".hhp project file in $(BUILDDIR)/htmlhelp.\"\n\n.PHONY: qthelp ## to make HTML files and a qthelp project\nqthelp:\n\t$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp\n\t@echo\n\t@echo \"Build finished; now you can run \"qcollectiongenerator\" with the\" \\\n\t      \".qhcp project file in $(BUILDDIR)/qthelp, like this:\"\n\t@echo \"# qcollectiongenerator $(BUILDDIR)/qthelp/Graphene.qhcp\"\n\t@echo \"To view the help file:\"\n\t@echo \"# assistant -collectionFile $(BUILDDIR)/qthelp/Graphene.qhc\"\n\n.PHONY: applehelp ## to make an Apple Help Book\napplehelp:\n\t$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp\n\t@echo\n\t@echo \"Build finished. The help book is in $(BUILDDIR)/applehelp.\"\n\t@echo \"N.B. You won't be able to view it unless you put it in\" \\\n\t      \"~/Library/Documentation/Help or install it in your application\" \\\n\t      \"bundle.\"\n\n.PHONY: devhelp ## to make HTML files and a Devhelp project\ndevhelp:\n\t$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp\n\t@echo\n\t@echo \"Build finished.\"\n\t@echo \"To view the help file:\"\n\t@echo \"# mkdir -p $$HOME/.local/share/devhelp/Graphene\"\n\t@echo \"# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Graphene\"\n\t@echo \"# devhelp\"\n\n.PHONY: epub ## to make an epub\nepub:\n\t$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub\n\t@echo\n\t@echo \"Build finished. The epub file is in $(BUILDDIR)/epub.\"\n\n.PHONY: epub3 ## to make an epub3\nepub3:\n\t$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3\n\t@echo\n\t@echo \"Build finished. The epub3 file is in $(BUILDDIR)/epub3.\"\n\n.PHONY: latex ## to make LaTeX files, you can set PAPER=a4 or PAPER=letter\nlatex:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo\n\t@echo \"Build finished; the LaTeX files are in $(BUILDDIR)/latex.\"\n\t@echo \"Run \\`make' in that directory to run these through (pdf)latex\" \\\n\t      \"(use \\`make latexpdf' here to do that automatically).\"\n\n.PHONY: latexpdf ## to make LaTeX files and run them through pdflatex\nlatexpdf:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through pdflatex...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\n.PHONY: latexpdfja ## to make LaTeX files and run them through platex/dvipdfmx\nlatexpdfja:\n\t$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex\n\t@echo \"Running LaTeX files through platex and dvipdfmx...\"\n\t$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja\n\t@echo \"pdflatex finished; the PDF files are in $(BUILDDIR)/latex.\"\n\n.PHONY: text ## to make text files\ntext:\n\t$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text\n\t@echo\n\t@echo \"Build finished. The text files are in $(BUILDDIR)/text.\"\n\n.PHONY: man ## to make manual pages\nman:\n\t$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man\n\t@echo\n\t@echo \"Build finished. The manual pages are in $(BUILDDIR)/man.\"\n\n.PHONY: texinfo ## to make Texinfo files\ntexinfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo\n\t@echo \"Build finished. The Texinfo files are in $(BUILDDIR)/texinfo.\"\n\t@echo \"Run \\`make' in that directory to run these through makeinfo\" \\\n\t      \"(use \\`make info' here to do that automatically).\"\n\n.PHONY: info ## to make Texinfo files and run them through makeinfo\ninfo:\n\t$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo\n\t@echo \"Running Texinfo files through makeinfo...\"\n\tmake -C $(BUILDDIR)/texinfo info\n\t@echo \"makeinfo finished; the Info files are in $(BUILDDIR)/texinfo.\"\n\n.PHONY: gettext ## to make PO message catalogs\ngettext:\n\t$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale\n\t@echo\n\t@echo \"Build finished. The message catalogs are in $(BUILDDIR)/locale.\"\n\n.PHONY: changes ## to make an overview of all changed/added/deprecated items\nchanges:\n\t$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes\n\t@echo\n\t@echo \"The overview file is in $(BUILDDIR)/changes.\"\n\n.PHONY: linkcheck ## to check all external links for integrity\nlinkcheck:\n\t$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck\n\t@echo\n\t@echo \"Link check complete; look for any errors in the above output \" \\\n\t      \"or in $(BUILDDIR)/linkcheck/output.txt.\"\n\n.PHONY: doctest ## to run all doctests embedded in the documentation (if enabled)\ndoctest:\n\t$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest\n\t@echo \"Testing of doctests in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/doctest/output.txt.\"\n\n.PHONY: coverage ## to run coverage check of the documentation (if enabled)\ncoverage:\n\t$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage\n\t@echo \"Testing of coverage in the sources finished, look at the \" \\\n\t      \"results in $(BUILDDIR)/coverage/python.txt.\"\n\n.PHONY: xml ## to make Docutils-native XML files\nxml:\n\t$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml\n\t@echo\n\t@echo \"Build finished. The XML files are in $(BUILDDIR)/xml.\"\n\n.PHONY: pseudoxml ## to make pseudoxml-XML files for display purposes\npseudoxml:\n\t$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml\n\t@echo\n\t@echo \"Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml.\"\n\n.PHONY: dummy ## to check syntax errors of document sources\ndummy:\n\t$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy\n\t@echo\n\t@echo \"Build finished. Dummy builder generates no files.\"\n\n.PHONY: livehtml ## to build and serve live-reloading documentation\nlivehtml:\n\tsphinx-autobuild -b html --watch ../graphene $(ALLSPHINXOPTS) $(BUILDDIR)/html\n"
  },
  {
    "path": "docs/_static/.gitkeep",
    "content": ""
  },
  {
    "path": "docs/api/index.rst",
    "content": "API Reference\n=============\n\nSchema\n------\n\n.. autoclass:: graphene.types.schema.Schema\n    :members:\n\n.. Uncomment sections / types as API documentation is fleshed out\n.. in each class\n\nObject types\n------------\n\n.. autoclass:: graphene.ObjectType\n\n.. autoclass:: graphene.InputObjectType\n\n.. autoclass:: graphene.Mutation\n    :members:\n\n.. _fields-mounted-types:\n\nFields (Mounted Types)\n----------------------\n\n.. autoclass:: graphene.Field\n\n.. autoclass:: graphene.Argument\n\n.. autoclass:: graphene.InputField\n\nFields (Unmounted Types)\n------------------------\n\n.. autoclass:: graphene.types.unmountedtype.UnmountedType\n\nGraphQL Scalars\n---------------\n\n.. autoclass:: graphene.Int()\n\n.. autoclass:: graphene.Float()\n\n.. autoclass:: graphene.String()\n\n.. autoclass:: graphene.Boolean()\n\n.. autoclass:: graphene.ID()\n\nGraphene Scalars\n----------------\n\n.. autoclass:: graphene.Date()\n\n.. autoclass:: graphene.DateTime()\n\n.. autoclass:: graphene.Time()\n\n.. autoclass:: graphene.Decimal()\n\n.. autoclass:: graphene.UUID()\n\n.. autoclass:: graphene.JSONString()\n\n.. autoclass:: graphene.Base64()\n\nEnum\n----\n\n.. autoclass:: graphene.Enum()\n\nStructures\n----------\n\n.. autoclass:: graphene.List\n\n.. autoclass:: graphene.NonNull\n\nType Extension\n--------------\n\n.. autoclass:: graphene.Interface()\n\n.. autoclass:: graphene.Union()\n\nExecution Metadata\n------------------\n\n.. autoclass:: graphene.ResolveInfo\n\n.. autoclass:: graphene.Context\n\n.. autoclass:: graphql.ExecutionResult\n\n.. Relay\n.. -----\n\n.. .. autoclass:: graphene.Node\n\n.. .. autoclass:: graphene.GlobalID\n\n.. .. autoclass:: graphene.ClientIDMutation\n\n.. .. autoclass:: graphene.Connection\n\n.. .. autoclass:: graphene.ConnectionField\n\n.. .. autoclass:: graphene.PageInfo\n"
  },
  {
    "path": "docs/conf.py",
    "content": "import os\nimport sys\n\nimport sphinx_graphene_theme\n\non_rtd = os.environ.get(\"READTHEDOCS\", None) == \"True\"\n\n# -*- coding: utf-8 -*-\n#\n# Graphene documentation build configuration file, created by\n# sphinx-quickstart on Sun Sep 11 18:30:51 2016.\n#\n# This file is execfile()d with the current directory set to its\n# containing dir.\n#\n# Note that not all possible configuration values are present in this\n# autogenerated file.\n#\n# All configuration values have a default; values that are commented out\n# serve to show the default.\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n#\n\nsys.path.insert(0, os.path.abspath(\"..\"))\n\n# -- General configuration ------------------------------------------------\n\n# If your documentation needs a minimal Sphinx version, state it here.\n#\n# needs_sphinx = '1.0'\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    \"sphinx.ext.autodoc\",\n    \"sphinx.ext.intersphinx\",\n    \"sphinx.ext.todo\",\n    \"sphinx.ext.coverage\",\n    \"sphinx.ext.viewcode\",\n    \"sphinx.ext.napoleon\",\n]\nif not on_rtd:\n    extensions += [\"sphinx.ext.githubpages\"]\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = [\"_templates\"]\n\n# The suffix(es) of source filenames.\n# You can specify multiple suffix as a list of string:\n#\n# source_suffix = ['.rst', '.md']\nsource_suffix = \".rst\"\n\n# The encoding of source files.\n#\n# source_encoding = 'utf-8-sig'\n\n# The master toctree document.\nmaster_doc = \"index\"\n\n# General information about the project.\nproject = \"Graphene\"\ncopyright = \"Graphene 2016\"\nauthor = \"Syrus Akbary\"\n\n# The version info for the project you're documenting, acts as replacement for\n# |version| and |release|, also used in various other places throughout the\n# built documents.\n#\n# The short X.Y version.\nversion = \"1.0\"\n# The full version, including alpha/beta/rc tags.\nrelease = \"1.0\"\n\n# The language for content autogenerated by Sphinx. Refer to documentation\n# for a list of supported languages.\n#\n# This is also used if you do content translation via gettext catalogs.\n# Usually you set \"language\" from the command line for these cases.\n# language = None\n\n# There are two options for replacing |today|: either, you set today to some\n# non-false value, then it is used:\n#\n# today = ''\n#\n# Else, today_fmt is used as the format for a strftime call.\n#\n# today_fmt = '%B %d, %Y'\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This patterns also effect to html_static_path and html_extra_path\nexclude_patterns = [\"_build\", \"Thumbs.db\", \".DS_Store\"]\n\n# The reST default role (used for this markup: `text`) to use for all\n# documents.\n#\n# default_role = None\n\n# If true, '()' will be appended to :func: etc. cross-reference text.\n#\n# add_function_parentheses = True\n\n# If true, the current module name will be prepended to all description\n# unit titles (such as .. function::).\n#\n# add_module_names = True\n\n# If true, sectionauthor and moduleauthor directives will be shown in the\n# output. They are ignored by default.\n#\n# show_authors = False\n\n# The name of the Pygments (syntax highlighting) style to use.\npygments_style = \"sphinx\"\n\n# A list of ignored prefixes for module index sorting.\n# modindex_common_prefix = []\n\n# If true, keep warnings as \"system message\" paragraphs in the built documents.\n# keep_warnings = False\n\n# If true, `todo` and `todoList` produce output, else they produce nothing.\ntodo_include_todos = True\n\n\n# -- Options for HTML output ----------------------------------------------\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\n# html_theme = 'alabaster'\n# if on_rtd:\n#     html_theme = 'sphinx_rtd_theme'\n\nhtml_theme = \"sphinx_graphene_theme\"\n\nhtml_theme_path = [sphinx_graphene_theme.get_html_theme_path()]\n\n# Theme options are theme-specific and customize the look and feel of a theme\n# further.  For a list of options available for each theme, see the\n# documentation.\n#\n# html_theme_options = {}\n\n# Add any paths that contain custom themes here, relative to this directory.\n# html_theme_path = []\n\n# The name for this set of Sphinx documents.\n# \"<project> v<release> documentation\" by default.\n#\n# html_title = u'Graphene v1.0'\n\n# A shorter title for the navigation bar.  Default is the same as html_title.\n#\n# html_short_title = None\n\n# The name of an image file (relative to this directory) to place at the top\n# of the sidebar.\n#\n# html_logo = None\n\n# The name of an image file (relative to this directory) to use as a favicon of\n# the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32\n# pixels large.\n#\n# html_favicon = None\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\nhtml_static_path = [\"_static\"]\n\n# Add any extra paths that contain custom files (such as robots.txt or\n# .htaccess) here, relative to this directory. These files are copied\n# directly to the root of the documentation.\n#\n# html_extra_path = []\n\n# If not None, a 'Last updated on:' timestamp is inserted at every page\n# bottom, using the given strftime format.\n# The empty string is equivalent to '%b %d, %Y'.\n#\n# html_last_updated_fmt = None\n\n# If true, SmartyPants will be used to convert quotes and dashes to\n# typographically correct entities.\n#\n# html_use_smartypants = True\n\n# Custom sidebar templates, maps document names to template names.\n#\n# html_sidebars = {}\n\n# Additional templates that should be rendered to pages, maps page names to\n# template names.\n#\n# html_additional_pages = {}\n\n# If false, no module index is generated.\n#\n# html_domain_indices = True\n\n# If false, no index is generated.\n#\n# html_use_index = True\n\n# If true, the index is split into individual pages for each letter.\n#\n# html_split_index = False\n\n# If true, links to the reST sources are added to the pages.\n#\n# html_show_sourcelink = True\n\n# If true, \"Created using Sphinx\" is shown in the HTML footer. Default is True.\n#\n# html_show_sphinx = True\n\n# If true, \"(C) Copyright ...\" is shown in the HTML footer. Default is True.\n#\n# html_show_copyright = True\n\n# If true, an OpenSearch description file will be output, and all pages will\n# contain a <link> tag referring to it.  The value of this option must be the\n# base URL from which the finished HTML is served.\n#\n# html_use_opensearch = ''\n\n# This is the file name suffix for HTML files (e.g. \".xhtml\").\n# html_file_suffix = None\n\n# Language to be used for generating the HTML full-text search index.\n# Sphinx supports the following languages:\n#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'\n#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'\n#\n# html_search_language = 'en'\n\n# A dictionary with options for the search language support, empty by default.\n# 'ja' uses this config value.\n# 'zh' user can custom change `jieba` dictionary path.\n#\n# html_search_options = {'type': 'default'}\n\n# The name of a javascript file (relative to the configuration directory) that\n# implements a search results scorer. If empty, the default will be used.\n#\n# html_search_scorer = 'scorer.js'\n\n# Output file base name for HTML help builder.\nhtmlhelp_basename = \"Graphenedoc\"\n\n# -- Options for LaTeX output ---------------------------------------------\n\nlatex_elements = {\n    # The paper size ('letterpaper' or 'a4paper').\n    #\n    # 'papersize': 'letterpaper',\n    # The font size ('10pt', '11pt' or '12pt').\n    #\n    # 'pointsize': '10pt',\n    # Additional stuff for the LaTeX preamble.\n    #\n    # 'preamble': '',\n    # Latex figure (float) alignment\n    #\n    # 'figure_align': 'htbp',\n}\n\n# Grouping the document tree into LaTeX files. List of tuples\n# (source start file, target name, title,\n#  author, documentclass [howto, manual, or own class]).\nlatex_documents = [\n    (master_doc, \"Graphene.tex\", \"Graphene Documentation\", \"Syrus Akbary\", \"manual\")\n]\n\n# The name of an image file (relative to this directory) to place at the top of\n# the title page.\n#\n# latex_logo = None\n\n# For \"manual\" documents, if this is true, then toplevel headings are parts,\n# not chapters.\n#\n# latex_use_parts = False\n\n# If true, show page references after internal links.\n#\n# latex_show_pagerefs = False\n\n# If true, show URL addresses after external links.\n#\n# latex_show_urls = False\n\n# Documents to append as an appendix to all manuals.\n#\n# latex_appendices = []\n\n# It false, will not define \\strong, \\code, \titleref, \\crossref ... but only\n# \\sphinxstrong, ..., \\sphinxtitleref, ... To help avoid clash with user added\n# packages.\n#\n# latex_keep_old_macro_names = True\n\n# If false, no module index is generated.\n#\n# latex_domain_indices = True\n\n\n# -- Options for manual page output ---------------------------------------\n\n# One entry per manual page. List of tuples\n# (source start file, name, description, authors, manual section).\nman_pages = [(master_doc, \"graphene\", \"Graphene Documentation\", [author], 1)]\n\n# If true, show URL addresses after external links.\n#\n# man_show_urls = False\n\n\n# -- Options for Texinfo output -------------------------------------------\n\n# Grouping the document tree into Texinfo files. List of tuples\n# (source start file, target name, title, author,\n#  dir menu entry, description, category)\ntexinfo_documents = [\n    (\n        master_doc,\n        \"Graphene\",\n        \"Graphene Documentation\",\n        author,\n        \"Graphene\",\n        \"One line description of project.\",\n        \"Miscellaneous\",\n    )\n]\n\n# Documents to append as an appendix to all manuals.\n#\n# texinfo_appendices = []\n\n# If false, no module index is generated.\n#\n# texinfo_domain_indices = True\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#\n# texinfo_show_urls = 'footnote'\n\n# If true, do not generate a @detailmenu in the \"Top\" node's menu.\n#\n# texinfo_no_detailmenu = False\n\n\n# -- Options for Epub output ----------------------------------------------\n\n# Bibliographic Dublin Core info.\nepub_title = project\nepub_author = author\nepub_publisher = author\nepub_copyright = copyright\n\n# The basename for the epub file. It defaults to the project name.\n# epub_basename = project\n\n# The HTML theme for the epub output. Since the default themes are not\n# optimized for small screen space, using the same theme for HTML and epub\n# output is usually not wise. This defaults to 'epub', a theme designed to save\n# visual space.\n#\n# epub_theme = 'epub'\n\n# The language of the text. It defaults to the language option\n# or 'en' if the language is not set.\n#\n# epub_language = ''\n\n# The scheme of the identifier. Typical schemes are ISBN or URL.\n# epub_scheme = ''\n\n# The unique identifier of the text. This can be a ISBN number\n# or the project homepage.\n#\n# epub_identifier = ''\n\n# A unique identification for the text.\n#\n# epub_uid = ''\n\n# A tuple containing the cover image and cover page html template filenames.\n#\n# epub_cover = ()\n\n# A sequence of (type, uri, title) tuples for the guide element of content.opf.\n#\n# epub_guide = ()\n\n# HTML files that should be inserted before the pages created by sphinx.\n# The format is a list of tuples containing the path and title.\n#\n# epub_pre_files = []\n\n# HTML files that should be inserted after the pages created by sphinx.\n# The format is a list of tuples containing the path and title.\n#\n# epub_post_files = []\n\n# A list of files that should not be packed into the epub file.\nepub_exclude_files = [\"search.html\"]\n\n# The depth of the table of contents in toc.ncx.\n#\n# epub_tocdepth = 3\n\n# Allow duplicate toc entries.\n#\n# epub_tocdup = True\n\n# Choose between 'default' and 'includehidden'.\n#\n# epub_tocscope = 'default'\n\n# Fix unsupported image types using the Pillow.\n#\n# epub_fix_images = False\n\n# Scale large images.\n#\n# epub_max_image_width = 0\n\n# How to display URL addresses: 'footnote', 'no', or 'inline'.\n#\n# epub_show_urls = 'inline'\n\n# If false, no index is generated.\n#\n# epub_use_index = True\n\n\n# Example configuration for intersphinx: refer to the Python standard library.\nintersphinx_mapping = {\n    \"https://docs.python.org/\": None,\n    \"python\": (\"https://docs.python.org/\", None),\n    \"graphene_django\": (\n        \"http://docs.graphene-python.org/projects/django/en/latest/\",\n        None,\n    ),\n    \"graphene_sqlalchemy\": (\n        \"http://docs.graphene-python.org/projects/sqlalchemy/en/latest/\",\n        None,\n    ),\n}\n"
  },
  {
    "path": "docs/execution/dataloader.rst",
    "content": "Dataloader\n==========\n\nDataLoader is a generic utility to be used as part of your application's\ndata fetching layer to provide a simplified and consistent API over\nvarious remote data sources such as databases or web services via batching\nand caching. It is provided by a separate package `aiodataloader <https://pypi.org/project/aiodataloader/>`.\n\n\nBatching\n--------\n\nBatching is not an advanced feature, it's DataLoader's primary feature.\nCreate loaders by providing a batch loading function.\n\n.. code:: python\n\n    from aiodataloader import DataLoader\n\n    class UserLoader(DataLoader):\n        async def batch_load_fn(self, keys):\n            # Here we call a function to return a user for each key in keys\n            return [get_user(id=key) for key in keys]\n\n\nA batch loading async function accepts a list of keys, and returns a list of ``values``.\n\n\n``DataLoader`` will coalesce all individual loads which occur within a\nsingle frame of execution (executed once the wrapping event loop is resolved)\nand then call your batch function with all requested keys.\n\n\n.. code:: python\n\n    user_loader = UserLoader()\n\n    user1 = await user_loader.load(1)\n    user1_best_friend = await user_loader.load(user1.best_friend_id)\n\n    user2 = await user_loader.load(2)\n    user2_best_friend = await user_loader.load(user2.best_friend_id)\n\n\nA naive application may have issued *four* round-trips to a backend for the\nrequired information, but with ``DataLoader`` this application will make at most *two*.\n\nNote that loaded values are one-to-one with the keys and must have the same\norder. This means that if you load all values from a single query, you must\nmake sure that you then order the query result for the results to match the keys:\n\n\n.. code:: python\n\n   class UserLoader(DataLoader):\n       async def batch_load_fn(self, keys):\n           users = {user.id: user for user in User.objects.filter(id__in=keys)}\n           return [users.get(user_id) for user_id in keys]\n\n\n``DataLoader`` allows you to decouple unrelated parts of your application without\nsacrificing the performance of batch data-loading. While the loader presents\nan API that loads individual values, all concurrent requests will be coalesced\nand presented to your batch loading function. This allows your application to\nsafely distribute data fetching requirements throughout your application and\nmaintain minimal outgoing data requests.\n\n\n\nUsing with Graphene\n-------------------\n\nDataLoader pairs nicely well with Graphene/GraphQL. GraphQL fields are designed\nto be stand-alone functions. Without a caching or batching mechanism, it's easy\nfor a naive GraphQL server to issue new database requests each time a field is resolved.\n\nConsider the following GraphQL request:\n\n\n.. code::\n\n    {\n      me {\n        name\n        bestFriend {\n          name\n        }\n        friends(first: 5) {\n          name\n          bestFriend {\n            name\n          }\n        }\n      }\n    }\n\n\nIf ``me``, ``bestFriend`` and ``friends`` each need to send a request to the backend,\nthere could be at most 13 database requests!\n\n\nWhen using DataLoader, we could define the User type using our previous example with\nleaner code and at most 4 database requests, and possibly fewer if there are cache hits.\n\n\n.. code:: python\n\n    class User(graphene.ObjectType):\n        name = graphene.String()\n        best_friend = graphene.Field(lambda: User)\n        friends = graphene.List(lambda: User)\n\n        async def resolve_best_friend(root, info):\n            return await user_loader.load(root.best_friend_id)\n\n        async def resolve_friends(root, info):\n            return await user_loader.load_many(root.friend_ids)\n"
  },
  {
    "path": "docs/execution/execute.rst",
    "content": ".. _SchemaExecute:\n\nExecuting a query\n=================\n\nFor executing a query against a schema, you can directly call the ``execute`` method on it.\n\n\n.. code:: python\n\n    from graphene import Schema\n\n    schema = Schema(...)\n    result = schema.execute('{ name }')\n\n``result`` represents the result of execution. ``result.data`` is the result of executing the query, ``result.errors`` is ``None`` if no errors occurred, and is a non-empty list if an error occurred.\n\n\n.. _SchemaExecuteContext:\n\nContext\n_______\n\nYou can pass context to a query via ``context``.\n\n\n.. code:: python\n\n    from graphene import ObjectType, String, Schema\n\n    class Query(ObjectType):\n        name = String()\n\n        def resolve_name(root, info):\n            return info.context.get('name')\n\n    schema = Schema(Query)\n    result = schema.execute('{ name }', context={'name': 'Syrus'})\n    assert result.data['name'] == 'Syrus'\n\n\nVariables\n_________\n\nYou can pass variables to a query via ``variables``.\n\n\n.. code:: python\n\n    from graphene import ObjectType, Field, ID, Schema\n\n    class Query(ObjectType):\n        user = Field(User, id=ID(required=True))\n\n        def resolve_user(root, info, id):\n            return get_user_by_id(id)\n\n    schema = Schema(Query)\n    result = schema.execute(\n        '''\n          query getUser($id: ID) {\n            user(id: $id) {\n              id\n              firstName\n              lastName\n            }\n          }\n        ''',\n        variables={'id': 12},\n    )\n\nRoot Value\n__________\n\nValue used for :ref:`ResolverParamParent` in root queries and mutations can be overridden using ``root`` parameter.\n\n.. code:: python\n\n    from graphene import ObjectType, Field, Schema\n\n    class Query(ObjectType):\n        me = Field(User)\n\n        def resolve_user(root, info):\n            return {'id': root.id, 'firstName': root.name}\n\n    schema = Schema(Query)\n    user_root = User(id=12, name='bob')\n    result = schema.execute(\n        '''\n        query getUser {\n            user {\n                id\n                firstName\n                lastName\n            }\n        }\n        ''',\n        root=user_root\n    )\n    assert result.data['user']['id'] == user_root.id\n\nOperation Name\n______________\n\nIf there are multiple operations defined in a query string, ``operation_name`` should be used to indicate which should be executed.\n\n.. code:: python\n\n    from graphene import ObjectType, Field, Schema\n\n    class Query(ObjectType):\n        user = Field(User)\n\n        def resolve_user(root, info):\n            return get_user_by_id(12)\n\n    schema = Schema(Query)\n    query_string = '''\n        query getUserWithFirstName {\n            user {\n                id\n                firstName\n                lastName\n            }\n        }\n        query getUserWithFullName {\n            user {\n                id\n                fullName\n            }\n        }\n    '''\n    result = schema.execute(\n        query_string,\n        operation_name='getUserWithFullName'\n    )\n    assert result.data['user']['fullName']\n"
  },
  {
    "path": "docs/execution/fileuploading.rst",
    "content": "File uploading\n==============\n\nFile uploading is not part of the official GraphQL spec yet and is not natively\nimplemented in Graphene.\n\nIf your server needs to support file uploading then you can use the library: `graphene-file-upload <https://github.com/lmcgartland/graphene-file-upload>`_ which enhances Graphene to add file\nuploads and conforms to the unoffical GraphQL `multipart request spec <https://github.com/jaydenseric/graphql-multipart-request-spec>`_.\n"
  },
  {
    "path": "docs/execution/index.rst",
    "content": "=========\nExecution\n=========\n\n.. toctree::\n   :maxdepth: 2\n\n   execute\n   middleware\n   dataloader\n   fileuploading\n   subscriptions\n   queryvalidation\n"
  },
  {
    "path": "docs/execution/middleware.rst",
    "content": "Middleware\n==========\n\nYou can use ``middleware`` to affect the evaluation of fields in your schema.\n\nA middleware is any object or function that responds to ``resolve(next_middleware, *args)``.\n\nInside that method, it should either:\n\n- Send ``resolve`` to the next middleware to continue the evaluation; or\n- Return a value to end the evaluation early.\n\n\nResolve arguments\n-----------------\n\nMiddlewares ``resolve`` is invoked with several arguments:\n\n- ``next`` represents the execution chain. Call ``next`` to continue evaluation.\n- ``root`` is the root value object passed throughout the query.\n- ``info`` is the resolver info.\n- ``args`` is the dict of arguments passed to the field.\n\nExample\n-------\n\nThis middleware only continues evaluation if the ``field_name`` is not ``'user'``\n\n.. code:: python\n\n    class AuthorizationMiddleware(object):\n        def resolve(self, next, root, info, **args):\n            if info.field_name == 'user':\n                return None\n            return next(root, info, **args)\n\n\nAnd then execute it with:\n\n.. code:: python\n\n    result = schema.execute('THE QUERY', middleware=[AuthorizationMiddleware()])\n\nIf the ``middleware`` argument includes multiple middlewares,\nthese middlewares will be executed bottom-up, i.e. from last to first.\n\nFunctional example\n------------------\n\nMiddleware can also be defined as a function. Here we define a middleware that\nlogs the time it takes to resolve each field:\n\n.. code:: python\n\n    from time import time as timer\n\n    def timing_middleware(next, root, info, **args):\n        start = timer()\n        return_value = next(root, info, **args)\n        duration = round((timer() - start) * 1000, 2)\n        parent_type_name = root._meta.name if root and hasattr(root, '_meta') else ''\n        logger.debug(f\"{parent_type_name}.{info.field_name}: {duration} ms\")\n        return return_value\n\n\nAnd then execute it with:\n\n.. code:: python\n\n    result = schema.execute('THE QUERY', middleware=[timing_middleware])\n"
  },
  {
    "path": "docs/execution/queryvalidation.rst",
    "content": "Query Validation\n================\nGraphQL uses query validators to check if Query AST is valid and can be executed. Every GraphQL server implements\nstandard query validators. For example, there is an validator that tests if queried field exists on queried type, that\nmakes query fail with \"Cannot query field on type\" error if it doesn't.\n\nTo help with common use cases, graphene provides a few validation rules out of the box.\n\n\nDepth limit Validator\n---------------------\nThe depth limit validator helps to prevent execution of malicious\nqueries. It takes in the following arguments.\n\n- ``max_depth`` is the maximum allowed depth for any operation in a GraphQL document.\n- ``ignore`` Stops recursive depth checking based on a field name. Either a string or regexp to match the name, or a function that returns a boolean\n- ``callback`` Called each time validation runs. Receives an Object which is a map of the depths for each operation.\n\nUsage\n-----\n\nHere is how you would implement depth-limiting on your schema.\n\n.. code:: python\n\n    from graphql import validate, parse\n    from graphene import ObjectType, Schema, String\n    from graphene.validation import depth_limit_validator\n\n\n    class MyQuery(ObjectType):\n        name = String(required=True)\n\n\n    schema = Schema(query=MyQuery)\n\n    # queries which have a depth more than 20\n    # will not be executed.\n\n    validation_errors = validate(\n        schema=schema.graphql_schema,\n        document_ast=parse('THE QUERY'),\n        rules=(\n            depth_limit_validator(\n                max_depth=20\n            ),\n        )\n    )\n\n\nDisable Introspection\n---------------------\nthe disable introspection validation rule ensures that your schema cannot be introspected.\nThis is a useful security measure in production environments.\n\nUsage\n-----\n\nHere is how you would disable introspection for your schema.\n\n.. code:: python\n\n    from graphql import validate, parse\n    from graphene import ObjectType, Schema, String\n    from graphene.validation import DisableIntrospection\n\n\n    class MyQuery(ObjectType):\n        name = String(required=True)\n\n\n    schema = Schema(query=MyQuery)\n\n    # introspection queries will not be executed.\n\n    validation_errors = validate(\n        schema=schema.graphql_schema,\n        document_ast=parse('THE QUERY'),\n        rules=(\n            DisableIntrospection,\n        )\n    )\n\n\nImplementing custom validators\n------------------------------\nAll custom query validators should extend the `ValidationRule <https://github.com/graphql-python/graphql-core/blob/v3.0.5/src/graphql/validation/rules/__init__.py#L37>`_\nbase class importable from the graphql.validation.rules module. Query validators are visitor classes. They are\ninstantiated at the time of query validation with one required argument (context: ASTValidationContext). In order to\nperform validation, your validator class should define one or more of enter_* and leave_* methods. For possible\nenter/leave items as well as details on function documentation, please see contents of the visitor module. To make\nvalidation fail, you should call validator's report_error method with the instance of GraphQLError describing failure\nreason. Here is an example query validator that visits field definitions in GraphQL query and fails query validation\nif any of those fields are blacklisted:\n\n.. code:: python\n\n    from graphql import GraphQLError\n    from graphql.language import FieldNode\n    from graphql.validation import ValidationRule\n\n\n    my_blacklist = (\n        \"disallowed_field\",\n    )\n\n\n    def is_blacklisted_field(field_name: str):\n        return field_name.lower() in my_blacklist\n\n\n    class BlackListRule(ValidationRule):\n        def enter_field(self, node: FieldNode, *_args):\n            field_name = node.name.value\n            if not is_blacklisted_field(field_name):\n                return\n\n            self.report_error(\n                GraphQLError(\n                    f\"Cannot query '{field_name}': field is blacklisted.\", node,\n                )\n            )\n\n"
  },
  {
    "path": "docs/execution/subscriptions.rst",
    "content": ".. _SchemaSubscription:\n\nSubscriptions\n=============\n\nTo create a subscription, you can directly call the ``subscribe`` method on the\nschema. This method is async and must be awaited.\n\n.. code:: python\n\n    import asyncio\n    from datetime import datetime\n    from graphene import ObjectType, String, Schema, Field\n\n    # Every schema requires a query.\n    class Query(ObjectType):\n        hello = String()\n\n        def resolve_hello(root, info):\n            return \"Hello, world!\"\n\n    class Subscription(ObjectType):\n        time_of_day = String()\n\n        async def subscribe_time_of_day(root, info):\n            while True:\n                yield datetime.now().isoformat()\n                await asyncio.sleep(1)\n\n    schema = Schema(query=Query, subscription=Subscription)\n\n    async def main(schema):\n        subscription = 'subscription { timeOfDay }'\n        result = await schema.subscribe(subscription)\n        async for item in result:\n            print(item.data['timeOfDay'])\n\n    asyncio.run(main(schema))\n\nThe ``result`` is an async iterator which yields items in the same manner as a query.\n"
  },
  {
    "path": "docs/index.rst",
    "content": "Graphene\n========\n\nContents:\n\n.. toctree::\n   :maxdepth: 2\n\n   quickstart\n   types/index\n   execution/index\n   relay/index\n   testing/index\n   api/index\n\n.. _Integrations:\n\nIntegrations\n------------\n\n* `Graphene-Django <http://docs.graphene-python.org/projects/django/en/latest/>`_ (`source <https://github.com/graphql-python/graphene-django/>`_)\n* Flask-Graphql (`source <https://github.com/graphql-python/flask-graphql>`_)\n* `Graphene-SQLAlchemy <http://docs.graphene-python.org/projects/sqlalchemy/en/latest/>`_ (`source <https://github.com/graphql-python/graphene-sqlalchemy/>`_)\n* `Graphene-Mongo <http://graphene-mongo.readthedocs.io/en/latest/>`_ (`source <https://github.com/graphql-python/graphene-mongo>`_)\n* `Starlette <https://www.starlette.io/graphql/>`_ (`source <https://github.com/encode/starlette>`_)\n* `FastAPI <https://fastapi.tiangolo.com/advanced/graphql/>`_ (`source <https://github.com/tiangolo/fastapi>`_)\n"
  },
  {
    "path": "docs/quickstart.rst",
    "content": "Getting started\n===============\n\nIntroduction\n------------\n\nWhat is GraphQL?\n~~~~~~~~~~~~~~~~\n\nGraphQL is a query language for your API.\n\nIt provides a standard way to:\n\n* *describe data provided by a server* in a statically typed **Schema**\n* *request data* in a **Query** which exactly describes your data requirements and\n* *receive data* in a **Response** containing only the data you requested.\n\nFor an introduction to GraphQL and an overview of its concepts, please refer to `the official GraphQL documentation`_.\n\n.. _the official GraphQL documentation: http://graphql.org/learn/\n\nWhat is Graphene?\n~~~~~~~~~~~~~~~~~\n\nGraphene is a library that provides tools to implement a GraphQL API in Python using a *code-first* approach.\n\nCompare Graphene's *code-first* approach to building a GraphQL API with *schema-first* approaches like `Apollo Server`_ (JavaScript) or Ariadne_ (Python). Instead of writing GraphQL **Schema Definition Language (SDL)**, we write Python code to describe the data provided by your server.\n\n.. _Apollo Server: https://www.apollographql.com/docs/apollo-server/\n\n.. _Ariadne: https://ariadnegraphql.org/\n\nGraphene is fully featured with integrations for the most popular web frameworks and ORMs. Graphene produces schemas that are fully compliant with the GraphQL spec and provides tools and patterns for building a Relay-Compliant API as well.\n\nAn example in Graphene\n----------------------\n\nLet’s build a basic GraphQL schema to say \"hello\" and \"goodbye\" in Graphene.\n\nWhen we send a **Query** requesting only one **Field**, ``hello``, and specify a value for the ``firstName`` **Argument**...\n\n.. code::\n\n    {\n      hello(firstName: \"friend\")\n    }\n\n...we would expect the following Response containing only the data requested (the ``goodbye`` field is not resolved).\n\n.. code::\n\n   {\n     \"data\": {\n       \"hello\": \"Hello friend!\"\n     }\n   }\n\n\nRequirements\n~~~~~~~~~~~~\n\n-  Python (3.8, 3.9, 3.10, 3.11, 3.12, pypy)\n-  Graphene (3.0)\n\nProject setup\n~~~~~~~~~~~~~\n\n.. code:: bash\n\n    pip install \"graphene>=3.0\"\n\nCreating a basic Schema\n~~~~~~~~~~~~~~~~~~~~~~~\n\nIn Graphene, we can define a simple schema using the following code:\n\n.. code:: python\n\n    from graphene import ObjectType, String, Schema\n\n    class Query(ObjectType):\n        # this defines a Field `hello` in our Schema with a single Argument `first_name`\n        # By default, the argument name will automatically be camel-based into firstName in the generated schema\n        hello = String(first_name=String(default_value=\"stranger\"))\n        goodbye = String()\n\n        # our Resolver method takes the GraphQL context (root, info) as well as\n        # Argument (first_name) for the Field and returns data for the query Response\n        def resolve_hello(root, info, first_name):\n            return f'Hello {first_name}!'\n\n        def resolve_goodbye(root, info):\n            return 'See ya!'\n\n    schema = Schema(query=Query)\n\n\nA GraphQL **Schema** describes each **Field** in the data model provided by the server using scalar types like *String*, *Int* and *Enum* and compound types like *List* and *Object*. For more details refer to the Graphene :ref:`TypesReference`.\n\nOur schema can also define any number of **Arguments** for our **Fields**. This is a powerful way for a **Query** to describe the exact data requirements for each **Field**.\n\nFor each **Field** in our **Schema**, we write a **Resolver** method to fetch data requested by a client's **Query** using the current context and **Arguments**. For more details, refer to this section on :ref:`Resolvers`.\n\nSchema Definition Language (SDL)\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nIn the `GraphQL Schema Definition Language`_, we could describe the fields defined by our example code as shown below.\n\n.. _GraphQL Schema Definition Language: https://graphql.org/learn/schema/\n\n.. code::\n\n    type Query {\n      hello(firstName: String = \"stranger\"): String\n      goodbye: String\n    }\n\nFurther examples in this documentation will use SDL to describe schema created by ObjectTypes and other fields.\n\nQuerying\n~~~~~~~~\n\nThen we can start querying our **Schema** by passing a GraphQL query string to ``execute``:\n\n.. code:: python\n\n    # we can query for our field (with the default argument)\n    query_string = '{ hello }'\n    result = schema.execute(query_string)\n    print(result.data['hello'])\n    # \"Hello stranger!\"\n\n    # or passing the argument in the query\n    query_with_argument = '{ hello(firstName: \"GraphQL\") }'\n    result = schema.execute(query_with_argument)\n    print(result.data['hello'])\n    # \"Hello GraphQL!\"\n\nNext steps\n~~~~~~~~~~\n\nCongrats! You got your first Graphene schema working!\n\nNormally, we don't need to directly execute a query string against our schema as Graphene provides many useful Integrations with popular web frameworks like Flask and Django. Check out :ref:`Integrations` for more information on how to get started serving your GraphQL API.\n"
  },
  {
    "path": "docs/relay/connection.rst",
    "content": "Connection\n==========\n\nA connection is a vitaminized version of a List that provides ways of\nslicing and paginating through it. The way you create Connection types\nin ``graphene`` is using ``relay.Connection`` and ``relay.ConnectionField``.\n\nQuick example\n-------------\n\nIf we want to create a custom Connection on a given node, we have to subclass the\n``Connection`` class.\n\nIn the following example, ``extra`` will be an extra field in the connection,\nand ``other`` an extra field in the Connection Edge.\n\n.. code:: python\n\n    class ShipConnection(Connection):\n        extra = String()\n\n        class Meta:\n            node = Ship\n\n        class Edge:\n            other = String()\n\nThe ``ShipConnection`` connection class, will have automatically a ``pageInfo`` field,\nand a ``edges`` field (which is a list of ``ShipConnection.Edge``).\nThis ``Edge`` will have a ``node`` field linking to the specified node\n(in ``ShipConnection.Meta``) and the field ``other`` that we defined in the class.\n\nConnection Field\n----------------\nYou can create connection fields in any Connection, in case any ObjectType\nthat implements ``Node`` will have a default Connection.\n\n.. code:: python\n\n    class Faction(graphene.ObjectType):\n        name = graphene.String()\n        ships = relay.ConnectionField(ShipConnection)\n\n        def resolve_ships(root, info):\n            return []\n"
  },
  {
    "path": "docs/relay/index.rst",
    "content": "Relay\n=====\n\nGraphene has complete support for `Relay`_ and offers some utils to make\nintegration from Python easy.\n\n\n.. toctree::\n   :maxdepth: 2\n\n   nodes\n   connection\n   mutations\n\n\nUseful links\n------------\n\n-  `Getting started with Relay`_\n-  `Relay Global Identification Specification`_\n-  `Relay Cursor Connection Specification`_\n\n.. _Relay: https://relay.dev/docs/guides/graphql-server-specification/\n.. _Getting started with Relay: https://relay.dev/docs/getting-started/step-by-step-guide/\n.. _Relay Global Identification Specification: https://relay.dev/graphql/objectidentification.htm\n.. _Relay Cursor Connection Specification: https://relay.dev/graphql/connections.htm\n"
  },
  {
    "path": "docs/relay/mutations.rst",
    "content": "Mutations\n=========\n\nMost APIs don’t just allow you to read data, they also allow you to\nwrite.\n\nIn GraphQL, this is done using mutations. Just like queries,\nRelay puts some additional requirements on mutations, but Graphene\nnicely manages that for you. All you need to do is make your mutation a\nsubclass of ``relay.ClientIDMutation``.\n\n.. code:: python\n\n    class IntroduceShip(relay.ClientIDMutation):\n\n        class Input:\n            ship_name = graphene.String(required=True)\n            faction_id = graphene.String(required=True)\n\n        ship = graphene.Field(Ship)\n        faction = graphene.Field(Faction)\n\n        @classmethod\n        def mutate_and_get_payload(cls, root, info, **input):\n            ship_name = input.ship_name\n            faction_id = input.faction_id\n            ship = create_ship(ship_name, faction_id)\n            faction = get_faction(faction_id)\n            return IntroduceShip(ship=ship, faction=faction)\n\n\n\nAccepting Files\n---------------\n\nMutations can also accept files, that's how it will work with different integrations:\n\n.. code:: python\n\n    class UploadFile(graphene.ClientIDMutation):\n         class Input:\n             pass\n             # nothing needed for uploading file\n\n         # your return fields\n         success = graphene.String()\n\n        @classmethod\n        def mutate_and_get_payload(cls, root, info, **input):\n            # When using it in Django, context will be the request\n            files = info.context.FILES\n            # Or, if used in Flask, context will be the flask global request\n            # files = context.files\n\n            # do something with files\n\n            return UploadFile(success=True)\n"
  },
  {
    "path": "docs/relay/nodes.rst",
    "content": "Nodes\n=====\n\nA ``Node`` is an Interface provided by ``graphene.relay`` that contains\na single field ``id`` (which is a ``ID!``). Any object that inherits\nfrom it has to implement a ``get_node`` method for retrieving a\n``Node`` by an *id*.\n\n\nQuick example\n-------------\n\nExample usage (taken from the `Starwars Relay example`_):\n\n.. code:: python\n\n    class Ship(graphene.ObjectType):\n        '''A ship in the Star Wars saga'''\n        class Meta:\n            interfaces = (relay.Node, )\n\n        name = graphene.String(description='The name of the ship.')\n\n        @classmethod\n        def get_node(cls, info, id):\n            return get_ship(id)\n\nThe ``id`` returned by the ``Ship`` type when you query it will be a\nscalar which contains enough info for the server to know its type and\nits id.\n\nFor example, the instance ``Ship(id=1)`` will return ``U2hpcDox`` as the\nid when you query it (which is the base64 encoding of ``Ship:1``), and\nwhich could be useful later if we want to query a node by its id.\n\n\nCustom Nodes\n------------\n\nYou can use the predefined ``relay.Node`` or you can subclass it, defining\ncustom ways of how a node id is encoded (using the ``to_global_id`` method in the class)\nor how we can retrieve a Node given a encoded id (with the ``get_node_from_global_id`` method).\n\nExample of a custom node:\n\n.. code:: python\n\n    class CustomNode(Node):\n\n        class Meta:\n            name = 'Node'\n\n        @staticmethod\n        def to_global_id(type_, id):\n            return f\"{type_}:{id}\"\n\n        @staticmethod\n        def get_node_from_global_id(info, global_id, only_type=None):\n            type_, id = global_id.split(':')\n            if only_type:\n                # We assure that the node type that we want to retrieve\n                # is the same that was indicated in the field type\n                assert type_ == only_type._meta.name, 'Received not compatible node.'\n\n            if type_ == 'User':\n                return get_user(id)\n            elif type_ == 'Photo':\n                return get_photo(id)\n\n\nThe ``get_node_from_global_id`` method will be called when ``CustomNode.Field`` is resolved.\n\n\nAccessing node types\n--------------------\n\nIf we want to retrieve node instances from a ``global_id`` (scalar that identifies an instance by it's type name and id),\nwe can simply do ``Node.get_node_from_global_id(info, global_id)``.\n\nIn the case we want to restrict the instance retrieval to a specific type, we can do:\n``Node.get_node_from_global_id(info, global_id, only_type=Ship)``. This will raise an error\nif the ``global_id`` doesn't correspond to a Ship type.\n\n\nNode Root field\n---------------\n\nAs is required in the `Relay specification`_, the server must implement\na root field called ``node`` that returns a ``Node`` Interface.\n\nFor this reason, ``graphene`` provides the field ``relay.Node.Field``,\nwhich links to any type in the Schema which implements ``Node``.\nExample usage:\n\n.. code:: python\n\n    class Query(graphene.ObjectType):\n        # Should be CustomNode.Field() if we want to use our custom Node\n        node = relay.Node.Field()\n\n.. _Relay specification: https://facebook.github.io/relay/docs/graphql-relay-specification.html\n.. _Starwars Relay example: https://github.com/graphql-python/graphene/blob/master/examples/starwars_relay/schema.py\n"
  },
  {
    "path": "docs/requirements.txt",
    "content": "# Required library\nSphinx==6.1.3\nsphinx-autobuild==2021.3.14\n# Docs template\nhttp://graphene-python.org/sphinx_graphene_theme.zip\n"
  },
  {
    "path": "docs/testing/index.rst",
    "content": "===================\nTesting in Graphene\n===================\n\n\nAutomated testing is an extremely useful bug-killing tool for the modern developer. You can use a collection of tests – a test suite – to solve, or avoid, a number of problems:\n\n- When you’re writing new code, you can use tests to validate your code works as expected.\n- When you’re refactoring or modifying old code, you can use tests to ensure your changes haven’t affected your application’s behavior unexpectedly.\n\nTesting a GraphQL application is a complex task, because a GraphQL application is made of several layers of logic – schema definition, schema validation, permissions and field resolution.\n\nWith Graphene test-execution framework and assorted utilities, you can simulate GraphQL requests, execute mutations, inspect your application’s output and generally verify your code is doing what it should be doing.\n\n\nTesting tools\n-------------\n\nGraphene provides a small set of tools that come in handy when writing tests.\n\n\nTest Client\n~~~~~~~~~~~\n\nThe test client is a Python class that acts as a dummy GraphQL client, allowing you to test your views and interact with your Graphene-powered application programmatically.\n\nSome of the things you can do with the test client are:\n\n- Simulate Queries and Mutations and observe the response.\n- Test that a given query request is rendered by a given Django template, with a template context that contains certain values.\n\n\nOverview and a quick example\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nTo use the test client, instantiate ``graphene.test.Client`` and retrieve GraphQL responses:\n\n\n.. code:: python\n\n    from graphene.test import Client\n\n    def test_hey():\n        client = Client(my_schema)\n        executed = client.execute('''{ hey }''')\n        assert executed == {\n            'data': {\n                'hey': 'hello!'\n            }\n        }\n\n\nExecute parameters\n~~~~~~~~~~~~~~~~~~\n\nYou can also add extra keyword arguments to the ``execute`` method, such as\n``context``, ``root``, ``variables``, ...:\n\n\n.. code:: python\n\n    from graphene.test import Client\n\n    def test_hey():\n        client = Client(my_schema)\n        executed = client.execute('''{ hey }''', context={'user': 'Peter'})\n        assert executed == {\n            'data': {\n                'hey': 'hello Peter!'\n            }\n        }\n"
  },
  {
    "path": "docs/types/enums.rst",
    "content": "Enums\n=====\n\nAn ``Enum`` is a special ``GraphQL`` type that represents a set of\nsymbolic names (members) bound to unique, constant values.\n\nDefinition\n----------\n\nYou can create an ``Enum`` using classes:\n\n.. code:: python\n\n    import graphene\n\n    class Episode(graphene.Enum):\n        NEWHOPE = 4\n        EMPIRE = 5\n        JEDI = 6\n\nBut also using instances of Enum:\n\n.. code:: python\n\n    Episode = graphene.Enum('Episode', [('NEWHOPE', 4), ('EMPIRE', 5), ('JEDI', 6)])\n\nValue descriptions\n------------------\n\nIt's possible to add a description to an enum value, for that the enum value\nneeds to have the ``description`` property on it.\n\n.. code:: python\n\n    class Episode(graphene.Enum):\n        NEWHOPE = 4\n        EMPIRE = 5\n        JEDI = 6\n\n        @property\n        def description(self):\n            if self == Episode.NEWHOPE:\n                return 'New Hope Episode'\n            return 'Other episode'\n\n\nUsage with Python Enums\n-----------------------\n\nIn case the Enums are already defined it's possible to reuse them using\nthe ``Enum.from_enum`` function.\n\n.. code:: python\n\n    graphene.Enum.from_enum(AlreadyExistingPyEnum)\n\n``Enum.from_enum`` supports a ``description`` and ``deprecation_reason`` lambdas as input so\nyou can add description etc. to your enum without changing the original:\n\n.. code:: python\n\n    graphene.Enum.from_enum(\n        AlreadyExistingPyEnum,\n        description=lambda v: return 'foo' if v == AlreadyExistingPyEnum.Foo else 'bar'\n    )\n\n\nNotes\n-----\n\n``graphene.Enum`` uses |enum.Enum|_ internally (or a backport if\nthat's not available) and can be used in a similar way, with the exception of\nmember getters.\n\nIn the Python ``Enum`` implementation you can access a member by initing the Enum.\n\n.. code:: python\n\n    from enum import Enum\n\n    class Color(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert Color(1) == Color.RED\n\n\nHowever, in Graphene ``Enum`` you need to call `.get` to have the same effect:\n\n.. code:: python\n\n    from graphene import Enum\n\n    class Color(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert Color.get(1) == Color.RED\n\n.. |enum.Enum| replace:: ``enum.Enum``\n.. _enum.Enum: https://docs.python.org/3/library/enum.html\n"
  },
  {
    "path": "docs/types/index.rst",
    "content": ".. _TypesReference:\n\n===============\nTypes Reference\n===============\n\n.. toctree::\n   :maxdepth: 1\n\n   schema\n   scalars\n   list-and-nonnull\n   objecttypes\n   enums\n   interfaces\n   unions\n   mutations\n"
  },
  {
    "path": "docs/types/interfaces.rst",
    "content": ".. _Interfaces:\n\nInterfaces\n==========\n\nAn *Interface* is an abstract type that defines a certain set of fields that a\ntype must include to implement the interface.\n\nFor example, you can define an Interface ``Character`` that represents any\ncharacter in the Star Wars trilogy:\n\n.. code:: python\n\n    import graphene\n\n    class Character(graphene.Interface):\n        id = graphene.ID(required=True)\n        name = graphene.String(required=True)\n        friends = graphene.List(lambda: Character)\n\n\nAny ObjectType that implements ``Character`` will have these exact fields, with\nthese arguments and return types.\n\nFor example, here are some types that might implement ``Character``:\n\n.. code:: python\n\n    class Human(graphene.ObjectType):\n        class Meta:\n            interfaces = (Character, )\n\n        starships = graphene.List(Starship)\n        home_planet = graphene.String()\n\n    class Droid(graphene.ObjectType):\n        class Meta:\n            interfaces = (Character, )\n\n        primary_function = graphene.String()\n\n\nBoth of these types have all of the fields from the ``Character`` interface,\nbut also bring in extra fields, ``home_planet``, ``starships`` and\n``primary_function``, that are specific to that particular type of character.\n\nThe full GraphQL schema definition will look like this:\n\n.. code::\n\n    interface Character {\n        id: ID!\n        name: String!\n        friends: [Character]\n    }\n\n    type Human implements Character {\n        id: ID!\n        name: String!\n        friends: [Character]\n        starships: [Starship]\n        homePlanet: String\n    }\n\n    type Droid implements Character {\n        id: ID!\n        name: String!\n        friends: [Character]\n        primaryFunction: String\n    }\n\nInterfaces are useful when you want to return an object or set of objects,\nwhich might be of several different types.\n\nFor example, you can define a field ``hero`` that resolves to any\n``Character``, depending on the episode, like this:\n\n.. code:: python\n\n    class Query(graphene.ObjectType):\n        hero = graphene.Field(\n            Character,\n            required=True,\n            episode=graphene.Int(required=True)\n        )\n\n        def resolve_hero(root, info, episode):\n            # Luke is the hero of Episode V\n            if episode == 5:\n                return get_human(name='Luke Skywalker')\n            return get_droid(name='R2-D2')\n\n    schema = graphene.Schema(query=Query, types=[Human, Droid])\n\nThis allows you to directly query for fields that exist on the Character interface\nas well as selecting specific fields on any type that implements the interface\nusing `inline fragments <https://graphql.org/learn/queries/#inline-fragments>`_.\n\nFor example, the following query:\n\n.. code::\n\n    query HeroForEpisode($episode: Int!) {\n        hero(episode: $episode) {\n            __typename\n            name\n            ... on Droid {\n                primaryFunction\n            }\n            ... on Human {\n                homePlanet\n            }\n        }\n    }\n\nWill return the following data with variables ``{ \"episode\": 4 }``:\n\n.. code:: json\n\n    {\n        \"data\": {\n            \"hero\": {\n                \"__typename\": \"Droid\",\n                \"name\": \"R2-D2\",\n                \"primaryFunction\": \"Astromech\"\n            }\n        }\n    }\n\nAnd different data with the variables ``{ \"episode\": 5 }``:\n\n.. code:: json\n\n    {\n        \"data\": {\n            \"hero\": {\n                \"__typename\": \"Human\",\n                \"name\": \"Luke Skywalker\",\n                \"homePlanet\": \"Tatooine\"\n            }\n        }\n    }\n\nResolving data objects to types\n-------------------------------\n\nAs you build out your schema in Graphene it's common for your resolvers to\nreturn objects that represent the data backing your GraphQL types rather than\ninstances of the Graphene types (e.g. Django or SQLAlchemy models). This works\nwell with ``ObjectType`` and ``Scalar`` fields, however when you start using\nInterfaces you might come across this error:\n\n.. code::\n\n    \"Abstract type Character must resolve to an Object type at runtime for field Query.hero ...\"\n\nThis happens because Graphene doesn't have enough information to convert the\ndata object into a Graphene type needed to resolve the ``Interface``. To solve\nthis you can define a ``resolve_type`` class method on the ``Interface`` which\nmaps a data object to a Graphene type:\n\n.. code:: python\n\n    class Character(graphene.Interface):\n        id = graphene.ID(required=True)\n        name = graphene.String(required=True)\n\n        @classmethod\n        def resolve_type(cls, instance, info):\n            if instance.type == 'DROID':\n                return Droid\n            return Human\n"
  },
  {
    "path": "docs/types/list-and-nonnull.rst",
    "content": "Lists and Non-Null\n==================\n\nObject types, scalars, and enums are the only kinds of types you can\ndefine in Graphene. But when you use the types in other parts of the\nschema, or in your query variable declarations, you can apply additional\ntype modifiers that affect validation of those values.\n\nNonNull\n-------\n\n.. code:: python\n\n    import graphene\n\n    class Character(graphene.ObjectType):\n        name = graphene.NonNull(graphene.String)\n\n\nHere, we're using a ``String`` type and marking it as Non-Null by wrapping\nit using the ``NonNull`` class. This means that our server always expects\nto return a non-null value for this field, and if it ends up getting a\nnull value that will actually trigger a GraphQL execution error,\nletting the client know that something has gone wrong.\n\n\nThe previous ``NonNull`` code snippet is also equivalent to:\n\n.. code:: python\n\n    import graphene\n\n    class Character(graphene.ObjectType):\n        name = graphene.String(required=True)\n\n\nList\n----\n\n.. code:: python\n\n    import graphene\n\n    class Character(graphene.ObjectType):\n        appears_in = graphene.List(graphene.String)\n\nLists work in a similar way: We can use a type modifier to mark a type as a\n``List``, which indicates that this field will return a list of that type.\nIt works the same for arguments, where the validation step will expect a list\nfor that value.\n\nNonNull Lists\n-------------\n\nBy default items in a list will be considered nullable. To define a list without\nany nullable items the type needs to be marked as ``NonNull``. For example:\n\n.. code:: python\n\n    import graphene\n\n    class Character(graphene.ObjectType):\n        appears_in = graphene.List(graphene.NonNull(graphene.String))\n\nThe above results in the type definition:\n\n.. code::\n\n    type Character {\n        appearsIn: [String!]\n    }\n"
  },
  {
    "path": "docs/types/mutations.rst",
    "content": "Mutations\n=========\n\nA Mutation is a special ObjectType that also defines an Input.\n\nQuick example\n-------------\n\nThis example defines a Mutation:\n\n.. code:: python\n\n    import graphene\n\n    class CreatePerson(graphene.Mutation):\n        class Arguments:\n            name = graphene.String()\n\n        ok = graphene.Boolean()\n        person = graphene.Field(lambda: Person)\n\n        def mutate(root, info, name):\n            person = Person(name=name)\n            ok = True\n            return CreatePerson(person=person, ok=ok)\n\n**person** and **ok** are the output fields of the Mutation when it is\nresolved.\n\n**Arguments** attributes are the arguments that the Mutation\n``CreatePerson`` needs for resolving, in this case **name** will be the\nonly argument for the mutation.\n\n**mutate** is the function that will be applied once the mutation is\ncalled. This method is just a special resolver that we can change\ndata within. It takes the same arguments as the standard query :ref:`ResolverArguments`.\n\nSo, we can finish our schema like this:\n\n.. code:: python\n\n    # ... the Mutation Class\n\n    class Person(graphene.ObjectType):\n        name = graphene.String()\n        age = graphene.Int()\n\n    class MyMutations(graphene.ObjectType):\n        create_person = CreatePerson.Field()\n\n    # We must define a query for our schema\n    class Query(graphene.ObjectType):\n        person = graphene.Field(Person)\n\n    schema = graphene.Schema(query=Query, mutation=MyMutations)\n\nExecuting the Mutation\n----------------------\n\nThen, if we query (``schema.execute(query_str)``) the following:\n\n.. code::\n\n    mutation myFirstMutation {\n        createPerson(name:\"Peter\") {\n            person {\n                name\n            }\n            ok\n        }\n    }\n\nWe should receive:\n\n.. code:: json\n\n    {\n        \"createPerson\": {\n            \"person\" : {\n                \"name\": \"Peter\"\n            },\n            \"ok\": true\n        }\n    }\n\nInputFields and InputObjectTypes\n----------------------------------\nInputFields are used in mutations to allow nested input data for mutations.\n\nTo use an InputField you define an InputObjectType that specifies the structure of your input data:\n\n\n.. code:: python\n\n    import graphene\n\n    class PersonInput(graphene.InputObjectType):\n        name = graphene.String(required=True)\n        age = graphene.Int(required=True)\n\n    class CreatePerson(graphene.Mutation):\n        class Arguments:\n            person_data = PersonInput(required=True)\n\n        person = graphene.Field(Person)\n\n        def mutate(root, info, person_data=None):\n            person = Person(\n                name=person_data.name,\n                age=person_data.age\n            )\n            return CreatePerson(person=person)\n\n\nNote that  **name** and **age** are part of **person_data** now.\n\nUsing the above mutation your new query would look like this:\n\n.. code::\n\n    mutation myFirstMutation {\n        createPerson(personData: {name:\"Peter\", age: 24}) {\n            person {\n                name,\n                age\n            }\n        }\n    }\n\nInputObjectTypes can also be fields of InputObjectTypes allowing you to have\nas complex of input data as you need:\n\n.. code:: python\n\n    import graphene\n\n    class LatLngInput(graphene.InputObjectType):\n        lat = graphene.Float()\n        lng = graphene.Float()\n\n    #A location has a latlng associated to it\n    class LocationInput(graphene.InputObjectType):\n        name = graphene.String()\n        latlng = graphene.InputField(LatLngInput)\n\nOutput type example\n-------------------\nTo return an existing ObjectType instead of a mutation-specific type, set the **Output** attribute to the desired ObjectType:\n\n.. code:: python\n\n    import graphene\n\n    class CreatePerson(graphene.Mutation):\n        class Arguments:\n            name = graphene.String()\n\n        Output = Person\n\n        def mutate(root, info, name):\n            return Person(name=name)\n\nThen, if we query (``schema.execute(query_str)``) with the following:\n\n.. code::\n\n    mutation myFirstMutation {\n        createPerson(name:\"Peter\") {\n            name\n            __typename\n        }\n    }\n\nWe should receive:\n\n.. code:: json\n\n    {\n        \"createPerson\": {\n            \"name\": \"Peter\",\n            \"__typename\": \"Person\"\n        }\n    }\n"
  },
  {
    "path": "docs/types/objecttypes.rst",
    "content": ".. _ObjectType:\n\nObjectType\n==========\n\nA Graphene *ObjectType* is the building block used to define the relationship between **Fields** in your **Schema** and how their data is retrieved.\n\nThe basics:\n\n- Each ObjectType is a Python class that inherits from ``graphene.ObjectType``.\n- Each attribute of the ObjectType represents a ``Field``.\n- Each ``Field`` has a :ref:`resolver method<Resolvers>` to fetch data (or :ref:`DefaultResolver`).\n\nQuick example\n-------------\n\nThis example model defines a Person, with a first and a last name:\n\n.. code:: python\n\n    from graphene import ObjectType, String\n\n    class Person(ObjectType):\n        first_name = String()\n        last_name = String()\n        full_name = String()\n\n        def resolve_full_name(parent, info):\n            return f\"{parent.first_name} {parent.last_name}\"\n\nThis *ObjectType* defines the field **first\\_name**, **last\\_name**, and **full\\_name**. Each field is specified as a class attribute, and each attribute maps to a Field. Data is fetched by our ``resolve_full_name`` :ref:`resolver method<Resolvers>` for ``full_name`` field and the :ref:`DefaultResolver` for other fields.\n\nThe above ``Person`` ObjectType has the following schema representation:\n\n.. code::\n\n    type Person {\n      firstName: String\n      lastName: String\n      fullName: String\n    }\n\n.. _Resolvers:\n\nResolvers\n---------\n\nA **Resolver** is a method that helps us answer **Queries** by fetching data for a **Field** in our **Schema**.\n\nResolvers are lazily executed, so if a field is not included in a query, its resolver will not be executed.\n\nEach field on an *ObjectType* in Graphene should have a corresponding resolver method to fetch data. This resolver method should match the field name. For example, in the ``Person`` type above, the ``full_name`` field is resolved by the method ``resolve_full_name``.\n\nEach resolver method takes the parameters:\n\n* :ref:`ResolverParamParent` for the value object use to resolve most fields\n* :ref:`ResolverParamInfo` for query and schema meta information and per-request context\n* :ref:`ResolverParamGraphQLArguments` as defined on the **Field**.\n\n.. _ResolverArguments:\n\nResolver Parameters\n~~~~~~~~~~~~~~~~~~~\n\n.. _ResolverParamParent:\n\nParent Value Object (*parent*)\n******************************\n\nThis parameter is typically used to derive the values for most fields on an *ObjectType*.\n\nThe first parameter of a resolver method (*parent*) is the value object returned from the resolver of the parent field. If there is no parent field, such as a root Query field, then the value for *parent* is set to the ``root_value`` configured while executing the query (default ``None``). See :ref:`SchemaExecute` for more details on executing queries.\n\nResolver example\n^^^^^^^^^^^^^^^^\n\nIf we have a schema with Person type and one field on the root query.\n\n.. code:: python\n\n    from graphene import ObjectType, String, Field\n\n    def get_human(name):\n        first_name, last_name = name.split()\n        return Person(first_name, last_name)\n\n    class Person(ObjectType):\n        full_name = String()\n\n        def resolve_full_name(parent, info):\n            return f\"{parent.first_name} {parent.last_name}\"\n\n    class Query(ObjectType):\n        me = Field(Person)\n\n        def resolve_me(parent, info):\n            # returns an object that represents a Person\n            return get_human(name=\"Luke Skywalker\")\n\nWhen we execute a query against that schema.\n\n.. code:: python\n\n    schema = Schema(query=Query)\n\n    query_string = \"{ me { fullName } }\"\n    result = schema.execute(query_string)\n\n    assert result.data[\"me\"] == {\"fullName\": \"Luke Skywalker\"}\n\nThen we go through the following steps to resolve this query:\n\n* ``parent`` is set with the root_value from query execution (None).\n* ``Query.resolve_me`` called with ``parent`` None which returns a value object ``Person(\"Luke\", \"Skywalker\")``.\n* This value object is then used as ``parent`` while calling ``Person.resolve_full_name`` to resolve the scalar String value \"Luke Skywalker\".\n* The scalar value is serialized and sent back in the query response.\n\nEach resolver returns the next :ref:`ResolverParamParent` to be used in executing the following resolver in the chain. If the Field is a Scalar type, that value will be serialized and sent in the **Response**. Otherwise, while resolving Compound types like *ObjectType*, the value be passed forward as the next :ref:`ResolverParamParent`.\n\nNaming convention\n^^^^^^^^^^^^^^^^^\n\nThis :ref:`ResolverParamParent` is sometimes named ``obj``, ``parent``, or ``source`` in other GraphQL documentation. It can also be named after the value object being resolved (ex. ``root`` for a root Query or Mutation, and ``person`` for a Person value object). Sometimes this argument will be named ``self`` in Graphene code, but this can be misleading due to :ref:`ResolverImplicitStaticMethod` while executing queries in Graphene.\n\n.. _ResolverParamInfo:\n\nGraphQL Execution Info (*info*)\n*******************************\n\nThe second parameter provides two things:\n\n* reference to meta information about the execution of the current GraphQL Query (fields, schema, parsed query, etc.)\n* access to per-request ``context`` which can be used to store user authentication, data loader instances or anything else useful for resolving the query.\n\nOnly context will be required for most applications. See :ref:`SchemaExecuteContext` for more information about setting context.\n\n.. _ResolverParamGraphQLArguments:\n\nGraphQL Arguments (*\\*\\*kwargs*)\n********************************\n\nAny arguments that a field defines gets passed to the resolver function as\nkeyword arguments. For example:\n\n.. code:: python\n\n    from graphene import ObjectType, Field, String\n\n    class Query(ObjectType):\n        human_by_name = Field(Human, name=String(required=True))\n\n        def resolve_human_by_name(parent, info, name):\n            return get_human(name=name)\n\nYou can then execute the following query:\n\n.. code::\n\n    query {\n        humanByName(name: \"Luke Skywalker\") {\n            firstName\n            lastName\n        }\n    }\n\n*Note:* There are several arguments to a field that are \"reserved\" by Graphene\n(see :ref:`fields-mounted-types`).\nYou can still define an argument that clashes with one of these fields by using\nthe ``args`` parameter like so:\n\n.. code:: python\n\n    from graphene import ObjectType, Field, String\n\n    class Query(ObjectType):\n        answer = String(args={'description': String()})\n\n        def resolve_answer(parent, info, description):\n            return description\n\n\nConvenience Features of Graphene Resolvers\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\n.. _ResolverImplicitStaticMethod:\n\nImplicit staticmethod\n*********************\n\nOne surprising feature of Graphene is that all resolver methods are treated implicitly as staticmethods. This means that, unlike other methods in Python, the first argument of a resolver is *never* ``self`` while it is being executed by Graphene. Instead, the first argument is always :ref:`ResolverParamParent`.  In practice, this is very convenient as, in GraphQL, we are almost always more concerned with the using the parent value object to resolve queries than attributes on the Python object itself.\n\nThe two resolvers in this example are effectively the same.\n\n.. code:: python\n\n    from graphene import ObjectType, String\n\n    class Person(ObjectType):\n        first_name = String()\n        last_name = String()\n\n        @staticmethod\n        def resolve_first_name(parent, info):\n            '''\n            Decorating a Python method with `staticmethod` ensures that `self` will not be provided as an\n            argument. However, Graphene does not need this decorator for this behavior.\n            '''\n            return parent.first_name\n\n        def resolve_last_name(parent, info):\n            '''\n            Normally the first argument for this method would be `self`, but Graphene executes this as\n            a staticmethod implicitly.\n            '''\n            return parent.last_name\n\n        # ...\n\nIf you prefer your code to be more explicit, feel free to use ``@staticmethod`` decorators. Otherwise, your code may be cleaner without them!\n\n.. _DefaultResolver:\n\nDefault Resolver\n****************\n\nIf a resolver method is not defined for a **Field** attribute on our *ObjectType*, Graphene supplies a default resolver.\n\nIf the :ref:`ResolverParamParent` is a dictionary, the resolver will look for a dictionary key matching the field name. Otherwise, the resolver will get the attribute from the parent value object matching the field name.\n\n.. code:: python\n\n    from collections import namedtuple\n\n    from graphene import ObjectType, String, Field, Schema\n\n    PersonValueObject = namedtuple(\"Person\", [\"first_name\", \"last_name\"])\n\n    class Person(ObjectType):\n        first_name = String()\n        last_name = String()\n\n    class Query(ObjectType):\n        me = Field(Person)\n        my_best_friend = Field(Person)\n\n        def resolve_me(parent, info):\n            # always pass an object for `me` field\n            return PersonValueObject(first_name=\"Luke\", last_name=\"Skywalker\")\n\n        def resolve_my_best_friend(parent, info):\n            # always pass a dictionary for `my_best_fiend_field`\n            return {\"first_name\": \"R2\", \"last_name\": \"D2\"}\n\n    schema = Schema(query=Query)\n    result = schema.execute('''\n        {\n            me { firstName lastName }\n            myBestFriend { firstName lastName }\n        }\n    ''')\n    # With default resolvers we can resolve attributes from an object..\n    assert result.data[\"me\"] == {\"firstName\": \"Luke\", \"lastName\": \"Skywalker\"}\n\n    # With default resolvers, we can also resolve keys from a dictionary..\n    assert result.data[\"myBestFriend\"] == {\"firstName\": \"R2\", \"lastName\": \"D2\"}\n\nAdvanced\n~~~~~~~~\n\nGraphQL Argument defaults\n*************************\n\nIf you define an argument for a field that is not required (and in a query\nexecution it is not provided as an argument) it will not be passed to the\nresolver function at all. This is so that the developer can differentiate\nbetween a ``undefined`` value for an argument and an explicit ``null`` value.\n\nFor example, given this schema:\n\n.. code:: python\n\n    from graphene import ObjectType, String\n\n    class Query(ObjectType):\n        hello = String(required=True, name=String())\n\n        def resolve_hello(parent, info, name):\n            return name if name else 'World'\n\nAnd this query:\n\n.. code::\n\n    query {\n        hello\n    }\n\nAn error will be thrown:\n\n.. code::\n\n    TypeError: resolve_hello() missing 1 required positional argument: 'name'\n\nYou can fix this error in several ways. Either by combining all keyword arguments\ninto a dict:\n\n.. code:: python\n\n    from graphene import ObjectType, String\n\n    class Query(ObjectType):\n        hello = String(required=True, name=String())\n\n        def resolve_hello(parent, info, **kwargs):\n            name = kwargs.get('name', 'World')\n            return f'Hello, {name}!'\n\nOr by setting a default value for the keyword argument:\n\n.. code:: python\n\n    from graphene import ObjectType, String\n\n    class Query(ObjectType):\n        hello = String(required=True, name=String())\n\n        def resolve_hello(parent, info, name='World'):\n            return f'Hello, {name}!'\n\nOne can also set a default value for an Argument in the GraphQL schema itself using Graphene!\n\n.. code:: python\n\n    from graphene import ObjectType, String\n\n    class Query(ObjectType):\n        hello = String(\n            required=True,\n            name=String(default_value='World')\n        )\n\n        def resolve_hello(parent, info, name):\n            return f'Hello, {name}!'\n\nResolvers outside the class\n***************************\n\nA field can use a custom resolver from outside the class:\n\n.. code:: python\n\n    from graphene import ObjectType, String\n\n    def resolve_full_name(person, info):\n        return f\"{person.first_name} {person.last_name}\"\n\n    class Person(ObjectType):\n        first_name = String()\n        last_name = String()\n        full_name = String(resolver=resolve_full_name)\n\n\nInstances as value objects\n**************************\n\nGraphene ``ObjectType``\\ s can act as value objects too. So with the\nprevious example you could use ``Person`` to capture data for each of the *ObjectType*'s fields.\n\n.. code:: python\n\n    peter = Person(first_name='Peter', last_name='Griffin')\n\n    peter.first_name  # prints \"Peter\"\n    peter.last_name  # prints \"Griffin\"\n\nField camelcasing\n*****************\n\nGraphene automatically camelcases fields on *ObjectType* from ``field_name`` to ``fieldName`` to conform with GraphQL standards. See :ref:`SchemaAutoCamelCase` for more information.\n\n*ObjectType* Configuration - Meta class\n---------------------------------------\n\nGraphene uses a Meta inner class on *ObjectType* to set different options.\n\nGraphQL type name\n~~~~~~~~~~~~~~~~~\n\nBy default the type name in the GraphQL schema will be the same as the class name\nthat defines the ``ObjectType``. This can be changed by setting the ``name``\nproperty on the ``Meta`` class:\n\n.. code:: python\n\n    from graphene import ObjectType\n\n    class MyGraphQlSong(ObjectType):\n        class Meta:\n            name = 'Song'\n\nGraphQL Description\n~~~~~~~~~~~~~~~~~~~\n\nThe schema description of an *ObjectType* can be set as a docstring on the Python object or on the Meta inner class.\n\n.. code:: python\n\n    from graphene import ObjectType\n\n    class MyGraphQlSong(ObjectType):\n        ''' We can set the schema description for an Object Type here on a docstring '''\n        class Meta:\n            description = 'But if we set the description in Meta, this value is used instead'\n\nInterfaces & Possible Types\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nSetting ``interfaces`` in Meta inner class specifies the GraphQL Interfaces that this Object implements.\n\nProviding ``possible_types`` helps Graphene resolve ambiguous types such as interfaces or Unions.\n\nSee :ref:`Interfaces` for more information.\n\n.. code:: python\n\n    from graphene import ObjectType, Node\n\n    Song = namedtuple('Song', ('title', 'artist'))\n\n    class MyGraphQlSong(ObjectType):\n        class Meta:\n            interfaces = (Node, )\n            possible_types = (Song, )\n\n.. _Interface: /docs/interfaces/\n"
  },
  {
    "path": "docs/types/scalars.rst",
    "content": ".. _Scalars:\n\nScalars\n=======\n\nScalar types represent concrete values at the leaves of a query. There are\nseveral built in types that Graphene provides out of the box which represent common\nvalues in Python. You can also create your own Scalar types to better express\nvalues that you might have in your data model.\n\nAll Scalar types accept the following arguments. All are optional:\n\n``name``: *string*\n\n    Override the name of the Field.\n\n``description``: *string*\n\n    A description of the type to show in the GraphiQL browser.\n\n``required``: *boolean*\n\n    If ``True``, the server will enforce a value for this field. See `NonNull <../list-and-nonnull.html#nonnull>`_. Default is ``False``.\n\n``deprecation_reason``: *string*\n\n    Provide a deprecation reason for the Field.\n\n``default_value``: *any*\n\n    Provide a default value for the Field.\n\n\n\nBuilt in scalars\n----------------\n\nGraphene defines the following base Scalar Types that match the default `GraphQL types <https://graphql.org/learn/schema/#scalar-types>`_:\n\n``graphene.String``\n^^^^^^^^^^^^^^^^^^^\n\n    Represents textual data, represented as UTF-8\n    character sequences. The String type is most often used by GraphQL to\n    represent free-form human-readable text.\n\n``graphene.Int``\n^^^^^^^^^^^^^^^^\n\n    Represents non-fractional signed whole numeric\n    values. Int is a signed 32‐bit integer per the\n    `GraphQL spec <https://facebook.github.io/graphql/June2018/#sec-Int>`_\n\n``graphene.Float``\n^^^^^^^^^^^^^^^^^^\n\n    Represents signed double-precision fractional\n    values as specified by\n    `IEEE 754 <http://en.wikipedia.org/wiki/IEEE_floating_point>`_.\n\n``graphene.Boolean``\n^^^^^^^^^^^^^^^^^^^^\n\n    Represents `true` or `false`.\n\n``graphene.ID``\n^^^^^^^^^^^^^^^\n\n    Represents a unique identifier, often used to\n    refetch an object or as key for a cache. The ID type appears in a JSON\n    response as a String; however, it is not intended to be human-readable.\n    When expected as an input type, any string (such as `\"4\"`) or integer\n    (such as `4`) input value will be accepted as an ID.\n\n----\n\nGraphene also provides custom scalars for common values:\n\n``graphene.Date``\n^^^^^^^^^^^^^^^^^\n\n    Represents a Date value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.\n\n.. code:: python\n\n    import datetime\n    from graphene import Schema, ObjectType, Date\n\n    class Query(ObjectType):\n        one_week_from = Date(required=True, date_input=Date(required=True))\n\n        def resolve_one_week_from(root, info, date_input):\n            assert date_input == datetime.date(2006, 1, 2)\n            return date_input + datetime.timedelta(weeks=1)\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"\"\"\n        query {\n            oneWeekFrom(dateInput: \"2006-01-02\")\n        }\n    \"\"\")\n\n    assert results.data == {\"oneWeekFrom\": \"2006-01-09\"}\n\n\n``graphene.DateTime``\n^^^^^^^^^^^^^^^^^^^^^\n\n    Represents a DateTime value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.\n\n.. code:: python\n\n    import datetime\n    from graphene import Schema, ObjectType, DateTime\n\n    class Query(ObjectType):\n        one_hour_from = DateTime(required=True, datetime_input=DateTime(required=True))\n\n        def resolve_one_hour_from(root, info, datetime_input):\n            assert datetime_input == datetime.datetime(2006, 1, 2, 15, 4, 5)\n            return datetime_input + datetime.timedelta(hours=1)\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"\"\"\n        query {\n            oneHourFrom(datetimeInput: \"2006-01-02T15:04:05\")\n        }\n    \"\"\")\n\n    assert results.data == {\"oneHourFrom\": \"2006-01-02T16:04:05\"}\n\n``graphene.Time``\n^^^^^^^^^^^^^^^^^\n\n    Represents a Time value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.\n\n.. code:: python\n\n    import datetime\n    from graphene import Schema, ObjectType, Time\n\n    class Query(ObjectType):\n        one_hour_from = Time(required=True, time_input=Time(required=True))\n\n        def resolve_one_hour_from(root, info, time_input):\n            assert time_input == datetime.time(15, 4, 5)\n            tmp_time_input = datetime.datetime.combine(datetime.date(1, 1, 1), time_input)\n            return (tmp_time_input + datetime.timedelta(hours=1)).time()\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"\"\"\n        query {\n            oneHourFrom(timeInput: \"15:04:05\")\n        }\n    \"\"\")\n\n    assert results.data == {\"oneHourFrom\": \"16:04:05\"}\n\n``graphene.Decimal``\n^^^^^^^^^^^^^^^^^^^^\n\n    Represents a Python Decimal value.\n\n.. code:: python\n\n    import decimal\n    from graphene import Schema, ObjectType, Decimal\n\n    class Query(ObjectType):\n        add_one_to = Decimal(required=True, decimal_input=Decimal(required=True))\n\n        def resolve_add_one_to(root, info, decimal_input):\n            assert decimal_input == decimal.Decimal(\"10.50\")\n            return decimal_input + decimal.Decimal(\"1\")\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"\"\"\n        query {\n            addOneTo(decimalInput: \"10.50\")\n        }\n    \"\"\")\n\n    assert results.data == {\"addOneTo\": \"11.50\"}\n\n``graphene.JSONString``\n^^^^^^^^^^^^^^^^^^^^^^^\n\n    Represents a JSON string.\n\n.. code:: python\n\n    from graphene import Schema, ObjectType, JSONString, String\n\n    class Query(ObjectType):\n        update_json_key = JSONString(\n            required=True,\n            json_input=JSONString(required=True),\n            key=String(required=True),\n            value=String(required=True)\n        )\n\n        def resolve_update_json_key(root, info, json_input, key, value):\n            assert json_input == {\"name\": \"Jane\"}\n            json_input[key] = value\n            return json_input\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"\"\"\n        query {\n            updateJsonKey(jsonInput: \"{\\\\\"name\\\\\": \\\\\"Jane\\\\\"}\", key: \"name\", value: \"Beth\")\n        }\n    \"\"\")\n\n    assert results.data == {\"updateJsonKey\": \"{\\\"name\\\": \\\"Beth\\\"}\"}\n\n\n``graphene.Base64``\n^^^^^^^^^^^^^^^^^^^\n\n    Represents a Base64 encoded string.\n\n.. code:: python\n\n    from graphene import Schema, ObjectType, Base64\n\n    class Query(ObjectType):\n        increment_encoded_id = Base64(\n            required=True,\n            base64_input=Base64(required=True),\n        )\n\n        def resolve_increment_encoded_id(root, info, base64_input):\n            assert base64_input == \"4\"\n            return int(base64_input) + 1\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"\"\"\n        query {\n            incrementEncodedId(base64Input: \"NA==\")\n        }\n    \"\"\")\n\n    assert results.data == {\"incrementEncodedId\": \"NQ==\"}\n\n\n\nCustom scalars\n--------------\n\nYou can create custom scalars for your schema.\nThe following is an example for creating a DateTime scalar:\n\n.. code:: python\n\n    import datetime\n    from graphene.types import Scalar\n    from graphql.language import ast\n\n    class DateTime(Scalar):\n        '''DateTime Scalar Description'''\n\n        @staticmethod\n        def serialize(dt):\n            return dt.isoformat()\n\n        @staticmethod\n        def parse_literal(node, _variables=None):\n            if isinstance(node, ast.StringValueNode):\n                return datetime.datetime.strptime(\n                    node.value, \"%Y-%m-%dT%H:%M:%S.%f\")\n\n        @staticmethod\n        def parse_value(value):\n            return datetime.datetime.strptime(value, \"%Y-%m-%dT%H:%M:%S.%f\")\n\nMounting Scalars\n----------------\n\nScalars mounted in a ``ObjectType``, ``Interface`` or ``Mutation`` act as\n``Field``\\ s.\n\n.. code:: python\n\n    class Person(graphene.ObjectType):\n        name = graphene.String()\n\n    # Is equivalent to:\n    class Person(graphene.ObjectType):\n        name = graphene.Field(graphene.String)\n\n\n**Note:** when using the ``Field`` constructor directly, pass the type and\nnot an instance.\n\nTypes mounted in a ``Field`` act as ``Argument``\\ s.\n\n\n.. code:: python\n\n    graphene.Field(graphene.String, to=graphene.String())\n\n    # Is equivalent to:\n    graphene.Field(graphene.String, to=graphene.Argument(graphene.String))\n"
  },
  {
    "path": "docs/types/schema.rst",
    "content": "Schema\n======\n\nA GraphQL **Schema** defines the types and relationships between **Fields** in your API.\n\nA Schema is created by supplying the root :ref:`ObjectType` of each operation, query (mandatory), mutation and subscription.\n\nSchema will collect all type definitions related to the root operations and then supply them to the validator and executor.\n\n.. code:: python\n\n    my_schema = Schema(\n        query=MyRootQuery,\n        mutation=MyRootMutation,\n        subscription=MyRootSubscription\n    )\n\nA Root Query is just a special :ref:`ObjectType` that defines the fields that are the entrypoint for your API. Root Mutation and Root Subscription are similar to Root Query, but for different operation types:\n\n* Query fetches data\n* Mutation changes data and retrieves the changes\n* Subscription sends changes to clients in real-time\n\nReview the `GraphQL documentation on Schema`_ for a brief overview of fields, schema and operations.\n\n.. _GraphQL documentation on Schema: https://graphql.org/learn/schema/\n\n\nQuerying\n--------\n\nTo query a schema, call the ``execute`` method on it. See :ref:`SchemaExecute` for more details.\n\n\n.. code:: python\n\n    query_string = 'query whoIsMyBestFriend { myBestFriend { lastName } }'\n    my_schema.execute(query_string)\n\nTypes\n-----\n\nThere are some cases where the schema cannot access all of the types that we plan to have.\nFor example, when a field returns an ``Interface``, the schema doesn't know about any of the\nimplementations.\n\nIn this case, we need to use the ``types`` argument when creating the Schema:\n\n\n.. code:: python\n\n    my_schema = Schema(\n        query=MyRootQuery,\n        types=[SomeExtraObjectType, ]\n    )\n\n.. _SchemaAutoCamelCase:\n\nAuto camelCase field names\n--------------------------\n\nBy default all field and argument names (that are not\nexplicitly set with the ``name`` arg) will be converted from\n``snake_case`` to ``camelCase`` (as the API is usually being consumed by a js/mobile client)\n\nFor example with the ObjectType the ``last_name`` field name is converted to ``lastName``:\n\n.. code:: python\n\n    class Person(graphene.ObjectType):\n        last_name = graphene.String()\n        other_name = graphene.String(name='_other_Name')\n\nIn case you don't want to apply this transformation, provide a ``name`` argument to the field constructor.\n``other_name`` converts to ``_other_Name`` (without further transformations).\n\nYour query should look like:\n\n.. code::\n\n    {\n        lastName\n        _other_Name\n    }\n\n\nTo disable this behavior, set the ``auto_camelcase`` to ``False`` upon schema instantiation:\n\n.. code:: python\n\n    my_schema = Schema(\n        query=MyRootQuery,\n        auto_camelcase=False,\n    )\n"
  },
  {
    "path": "docs/types/unions.rst",
    "content": "Unions\n======\n\nUnion types are very similar to interfaces, but they don't get\nto specify any common fields between the types.\n\nThe basics:\n\n- Each Union is a Python class that inherits from ``graphene.Union``.\n- Unions don't have any fields on it, just links to the possible ObjectTypes.\n\nQuick example\n-------------\n\nThis example model defines several ObjectTypes with their own fields.\n``SearchResult`` is the implementation of ``Union`` of this object types.\n\n.. code:: python\n\n    import graphene\n\n    class Human(graphene.ObjectType):\n        name = graphene.String()\n        born_in = graphene.String()\n\n    class Droid(graphene.ObjectType):\n        name = graphene.String()\n        primary_function = graphene.String()\n\n    class Starship(graphene.ObjectType):\n        name = graphene.String()\n        length = graphene.Int()\n\n    class SearchResult(graphene.Union):\n        class Meta:\n            types = (Human, Droid, Starship)\n\n\nWherever we return a SearchResult type in our schema, we might get a Human, a Droid, or a Starship.\nNote that members of a union type need to be concrete object types;\nyou can't create a union type out of interfaces or other unions.\n\nThe above types have the following representation in a schema:\n\n.. code::\n\n    type Droid {\n      name: String\n      primaryFunction: String\n    }\n\n    type Human {\n      name: String\n      bornIn: String\n    }\n\n    type Ship {\n      name: String\n      length: Int\n    }\n\n    union SearchResult = Human | Droid | Starship\n\n"
  },
  {
    "path": "examples/__init__.py",
    "content": ""
  },
  {
    "path": "examples/complex_example.py",
    "content": "import graphene\n\n\nclass GeoInput(graphene.InputObjectType):\n    lat = graphene.Float(required=True)\n    lng = graphene.Float(required=True)\n\n    @property\n    def latlng(self):\n        return f\"({self.lat},{self.lng})\"\n\n\nclass Address(graphene.ObjectType):\n    latlng = graphene.String()\n\n\nclass Query(graphene.ObjectType):\n    address = graphene.Field(Address, geo=GeoInput(required=True))\n\n    def resolve_address(root, info, geo):\n        return Address(latlng=geo.latlng)\n\n\nclass CreateAddress(graphene.Mutation):\n    class Arguments:\n        geo = GeoInput(required=True)\n\n    Output = Address\n\n    def mutate(root, info, geo):\n        return Address(latlng=geo.latlng)\n\n\nclass Mutation(graphene.ObjectType):\n    create_address = CreateAddress.Field()\n\n\nschema = graphene.Schema(query=Query, mutation=Mutation)\nquery = \"\"\"\n    query something{\n      address(geo: {lat:32.2, lng:12}) {\n        latlng\n      }\n    }\n\"\"\"\nmutation = \"\"\"\n    mutation addAddress{\n      createAddress(geo: {lat:32.2, lng:12}) {\n        latlng\n      }\n    }\n\"\"\"\n\n\ndef test_query():\n    result = schema.execute(query)\n    assert not result.errors\n    assert result.data == {\"address\": {\"latlng\": \"(32.2,12.0)\"}}\n\n\ndef test_mutation():\n    result = schema.execute(mutation)\n    assert not result.errors\n    assert result.data == {\"createAddress\": {\"latlng\": \"(32.2,12.0)\"}}\n\n\nif __name__ == \"__main__\":\n    result = schema.execute(query)\n    print(result.data[\"address\"][\"latlng\"])\n"
  },
  {
    "path": "examples/context_example.py",
    "content": "import graphene\n\n\nclass User(graphene.ObjectType):\n    id = graphene.ID()\n    name = graphene.String()\n\n\nclass Query(graphene.ObjectType):\n    me = graphene.Field(User)\n\n    def resolve_me(root, info):\n        return info.context[\"user\"]\n\n\nschema = graphene.Schema(query=Query)\nquery = \"\"\"\n    query something{\n      me {\n        id\n        name\n      }\n    }\n\"\"\"\n\n\ndef test_query():\n    result = schema.execute(query, context={\"user\": User(id=\"1\", name=\"Syrus\")})\n    assert not result.errors\n    assert result.data == {\"me\": {\"id\": \"1\", \"name\": \"Syrus\"}}\n\n\nif __name__ == \"__main__\":\n    result = schema.execute(query, context={\"user\": User(id=\"X\", name=\"Console\")})\n    print(result.data[\"me\"])\n"
  },
  {
    "path": "examples/simple_example.py",
    "content": "import graphene\n\n\nclass Patron(graphene.ObjectType):\n    id = graphene.ID()\n    name = graphene.String()\n    age = graphene.Int()\n\n\nclass Query(graphene.ObjectType):\n    patron = graphene.Field(Patron)\n\n    def resolve_patron(root, info):\n        return Patron(id=1, name=\"Syrus\", age=27)\n\n\nschema = graphene.Schema(query=Query)\nquery = \"\"\"\n    query something{\n      patron {\n        id\n        name\n        age\n      }\n    }\n\"\"\"\n\n\ndef test_query():\n    result = schema.execute(query)\n    assert not result.errors\n    assert result.data == {\"patron\": {\"id\": \"1\", \"name\": \"Syrus\", \"age\": 27}}\n\n\nif __name__ == \"__main__\":\n    result = schema.execute(query)\n    print(result.data[\"patron\"])\n"
  },
  {
    "path": "examples/starwars/__init__.py",
    "content": ""
  },
  {
    "path": "examples/starwars/data.py",
    "content": "human_data = {}\ndroid_data = {}\n\n\ndef setup():\n    from .schema import Human, Droid\n\n    global human_data, droid_data\n    luke = Human(\n        id=\"1000\",\n        name=\"Luke Skywalker\",\n        friends=[\"1002\", \"1003\", \"2000\", \"2001\"],\n        appears_in=[4, 5, 6],\n        home_planet=\"Tatooine\",\n    )\n\n    vader = Human(\n        id=\"1001\",\n        name=\"Darth Vader\",\n        friends=[\"1004\"],\n        appears_in=[4, 5, 6],\n        home_planet=\"Tatooine\",\n    )\n\n    han = Human(\n        id=\"1002\",\n        name=\"Han Solo\",\n        friends=[\"1000\", \"1003\", \"2001\"],\n        appears_in=[4, 5, 6],\n        home_planet=None,\n    )\n\n    leia = Human(\n        id=\"1003\",\n        name=\"Leia Organa\",\n        friends=[\"1000\", \"1002\", \"2000\", \"2001\"],\n        appears_in=[4, 5, 6],\n        home_planet=\"Alderaan\",\n    )\n\n    tarkin = Human(\n        id=\"1004\",\n        name=\"Wilhuff Tarkin\",\n        friends=[\"1001\"],\n        appears_in=[4],\n        home_planet=None,\n    )\n\n    human_data = {\n        \"1000\": luke,\n        \"1001\": vader,\n        \"1002\": han,\n        \"1003\": leia,\n        \"1004\": tarkin,\n    }\n\n    c3po = Droid(\n        id=\"2000\",\n        name=\"C-3PO\",\n        friends=[\"1000\", \"1002\", \"1003\", \"2001\"],\n        appears_in=[4, 5, 6],\n        primary_function=\"Protocol\",\n    )\n\n    r2d2 = Droid(\n        id=\"2001\",\n        name=\"R2-D2\",\n        friends=[\"1000\", \"1002\", \"1003\"],\n        appears_in=[4, 5, 6],\n        primary_function=\"Astromech\",\n    )\n\n    droid_data = {\"2000\": c3po, \"2001\": r2d2}\n\n\ndef get_character(id):\n    return human_data.get(id) or droid_data.get(id)\n\n\ndef get_friends(character):\n    return map(get_character, character.friends)\n\n\ndef get_hero(episode):\n    if episode == 5:\n        return human_data[\"1000\"]\n    return droid_data[\"2001\"]\n\n\ndef get_human(id):\n    return human_data.get(id)\n\n\ndef get_droid(id):\n    return droid_data.get(id)\n"
  },
  {
    "path": "examples/starwars/schema.py",
    "content": "import graphene\n\nfrom .data import get_character, get_droid, get_hero, get_human\n\n\nclass Episode(graphene.Enum):\n    NEWHOPE = 4\n    EMPIRE = 5\n    JEDI = 6\n\n\nclass Character(graphene.Interface):\n    id = graphene.ID()\n    name = graphene.String()\n    friends = graphene.List(lambda: Character)\n    appears_in = graphene.List(Episode)\n\n    def resolve_friends(self, info):\n        # The character friends is a list of strings\n        return [get_character(f) for f in self.friends]\n\n\nclass Human(graphene.ObjectType):\n    class Meta:\n        interfaces = (Character,)\n\n    home_planet = graphene.String()\n\n\nclass Droid(graphene.ObjectType):\n    class Meta:\n        interfaces = (Character,)\n\n    primary_function = graphene.String()\n\n\nclass Query(graphene.ObjectType):\n    hero = graphene.Field(Character, episode=Episode())\n    human = graphene.Field(Human, id=graphene.String())\n    droid = graphene.Field(Droid, id=graphene.String())\n\n    def resolve_hero(root, info, episode=None):\n        return get_hero(episode)\n\n    def resolve_human(root, info, id):\n        return get_human(id)\n\n    def resolve_droid(root, info, id):\n        return get_droid(id)\n\n\nschema = graphene.Schema(query=Query)\n"
  },
  {
    "path": "examples/starwars/tests/__init__.py",
    "content": ""
  },
  {
    "path": "examples/starwars/tests/test_query.py",
    "content": "from graphene.test import Client\n\nfrom ..data import setup\nfrom ..schema import schema\n\nsetup()\n\nclient = Client(schema)\n\n\ndef test_hero_name_query():\n    result = client.execute(\"\"\"\n        query HeroNameQuery {\n          hero {\n            name\n          }\n        }\n    \"\"\")\n    assert result == {\"data\": {\"hero\": {\"name\": \"R2-D2\"}}}\n\n\ndef test_hero_name_and_friends_query():\n    result = client.execute(\"\"\"\n        query HeroNameAndFriendsQuery {\n          hero {\n            id\n            name\n            friends {\n              name\n            }\n          }\n        }\n    \"\"\")\n    assert result == {\n        \"data\": {\n            \"hero\": {\n                \"id\": \"2001\",\n                \"name\": \"R2-D2\",\n                \"friends\": [\n                    {\"name\": \"Luke Skywalker\"},\n                    {\"name\": \"Han Solo\"},\n                    {\"name\": \"Leia Organa\"},\n                ],\n            }\n        }\n    }\n\n\ndef test_nested_query():\n    result = client.execute(\"\"\"\n        query NestedQuery {\n          hero {\n            name\n            friends {\n              name\n              appearsIn\n              friends {\n                name\n              }\n            }\n          }\n        }\n    \"\"\")\n    assert result == {\n        \"data\": {\n            \"hero\": {\n                \"name\": \"R2-D2\",\n                \"friends\": [\n                    {\n                        \"name\": \"Luke Skywalker\",\n                        \"appearsIn\": [\"NEWHOPE\", \"EMPIRE\", \"JEDI\"],\n                        \"friends\": [\n                            {\"name\": \"Han Solo\"},\n                            {\"name\": \"Leia Organa\"},\n                            {\"name\": \"C-3PO\"},\n                            {\"name\": \"R2-D2\"},\n                        ],\n                    },\n                    {\n                        \"name\": \"Han Solo\",\n                        \"appearsIn\": [\"NEWHOPE\", \"EMPIRE\", \"JEDI\"],\n                        \"friends\": [\n                            {\"name\": \"Luke Skywalker\"},\n                            {\"name\": \"Leia Organa\"},\n                            {\"name\": \"R2-D2\"},\n                        ],\n                    },\n                    {\n                        \"name\": \"Leia Organa\",\n                        \"appearsIn\": [\"NEWHOPE\", \"EMPIRE\", \"JEDI\"],\n                        \"friends\": [\n                            {\"name\": \"Luke Skywalker\"},\n                            {\"name\": \"Han Solo\"},\n                            {\"name\": \"C-3PO\"},\n                            {\"name\": \"R2-D2\"},\n                        ],\n                    },\n                ],\n            }\n        }\n    }\n\n\ndef test_fetch_luke_query():\n    result = client.execute(\"\"\"\n        query FetchLukeQuery {\n          human(id: \"1000\") {\n            name\n          }\n        }\n    \"\"\")\n    assert result == {\"data\": {\"human\": {\"name\": \"Luke Skywalker\"}}}\n\n\ndef test_fetch_some_id_query():\n    result = client.execute(\n        \"\"\"\n        query FetchSomeIDQuery($someId: String!) {\n          human(id: $someId) {\n            name\n          }\n        }\n    \"\"\",\n        variables={\"someId\": \"1000\"},\n    )\n    assert result == {\"data\": {\"human\": {\"name\": \"Luke Skywalker\"}}}\n\n\ndef test_fetch_some_id_query2():\n    result = client.execute(\n        \"\"\"\n        query FetchSomeIDQuery($someId: String!) {\n          human(id: $someId) {\n            name\n          }\n        }\n    \"\"\",\n        variables={\"someId\": \"1002\"},\n    )\n    assert result == {\"data\": {\"human\": {\"name\": \"Han Solo\"}}}\n\n\ndef test_invalid_id_query():\n    result = client.execute(\n        \"\"\"\n        query humanQuery($id: String!) {\n          human(id: $id) {\n            name\n          }\n        }\n    \"\"\",\n        variables={\"id\": \"not a valid id\"},\n    )\n    assert result == {\"data\": {\"human\": None}}\n\n\ndef test_fetch_luke_aliased():\n    result = client.execute(\"\"\"\n        query FetchLukeAliased {\n          luke: human(id: \"1000\") {\n            name\n          }\n        }\n    \"\"\")\n    assert result == {\"data\": {\"luke\": {\"name\": \"Luke Skywalker\"}}}\n\n\ndef test_fetch_luke_and_leia_aliased():\n    result = client.execute(\"\"\"\n        query FetchLukeAndLeiaAliased {\n          luke: human(id: \"1000\") {\n            name\n          }\n          leia: human(id: \"1003\") {\n            name\n          }\n        }\n    \"\"\")\n    assert result == {\n        \"data\": {\"luke\": {\"name\": \"Luke Skywalker\"}, \"leia\": {\"name\": \"Leia Organa\"}}\n    }\n\n\ndef test_duplicate_fields():\n    result = client.execute(\"\"\"\n        query DuplicateFields {\n          luke: human(id: \"1000\") {\n            name\n            homePlanet\n          }\n          leia: human(id: \"1003\") {\n            name\n            homePlanet\n          }\n        }\n    \"\"\")\n    assert result == {\n        \"data\": {\n            \"luke\": {\"name\": \"Luke Skywalker\", \"homePlanet\": \"Tatooine\"},\n            \"leia\": {\"name\": \"Leia Organa\", \"homePlanet\": \"Alderaan\"},\n        }\n    }\n\n\ndef test_use_fragment():\n    result = client.execute(\"\"\"\n        query UseFragment {\n          luke: human(id: \"1000\") {\n            ...HumanFragment\n          }\n          leia: human(id: \"1003\") {\n            ...HumanFragment\n          }\n        }\n        fragment HumanFragment on Human {\n          name\n          homePlanet\n        }\n    \"\"\")\n    assert result == {\n        \"data\": {\n            \"luke\": {\"name\": \"Luke Skywalker\", \"homePlanet\": \"Tatooine\"},\n            \"leia\": {\"name\": \"Leia Organa\", \"homePlanet\": \"Alderaan\"},\n        }\n    }\n\n\ndef test_check_type_of_r2():\n    result = client.execute(\"\"\"\n        query CheckTypeOfR2 {\n          hero {\n            __typename\n            name\n          }\n        }\n    \"\"\")\n    assert result == {\"data\": {\"hero\": {\"__typename\": \"Droid\", \"name\": \"R2-D2\"}}}\n\n\ndef test_check_type_of_luke():\n    result = client.execute(\"\"\"\n        query CheckTypeOfLuke {\n          hero(episode: EMPIRE) {\n            __typename\n            name\n          }\n        }\n    \"\"\")\n    assert result == {\n        \"data\": {\"hero\": {\"__typename\": \"Human\", \"name\": \"Luke Skywalker\"}}\n    }\n"
  },
  {
    "path": "examples/starwars/tests/test_schema.py",
    "content": ""
  },
  {
    "path": "examples/starwars_relay/__init__.py",
    "content": ""
  },
  {
    "path": "examples/starwars_relay/data.py",
    "content": "data = {}\n\n\ndef setup():\n    global data\n\n    from .schema import Ship, Faction\n\n    xwing = Ship(id=\"1\", name=\"X-Wing\")\n\n    ywing = Ship(id=\"2\", name=\"Y-Wing\")\n\n    awing = Ship(id=\"3\", name=\"A-Wing\")\n\n    # Yeah, technically it's Corellian. But it flew in the service of the rebels,\n    # so for the purposes of this demo it's a rebel ship.\n    falcon = Ship(id=\"4\", name=\"Millennium Falcon\")\n\n    homeOne = Ship(id=\"5\", name=\"Home One\")\n\n    tieFighter = Ship(id=\"6\", name=\"TIE Fighter\")\n\n    tieInterceptor = Ship(id=\"7\", name=\"TIE Interceptor\")\n\n    executor = Ship(id=\"8\", name=\"Executor\")\n\n    rebels = Faction(\n        id=\"1\", name=\"Alliance to Restore the Republic\", ships=[\"1\", \"2\", \"3\", \"4\", \"5\"]\n    )\n\n    empire = Faction(id=\"2\", name=\"Galactic Empire\", ships=[\"6\", \"7\", \"8\"])\n\n    data = {\n        \"Faction\": {\"1\": rebels, \"2\": empire},\n        \"Ship\": {\n            \"1\": xwing,\n            \"2\": ywing,\n            \"3\": awing,\n            \"4\": falcon,\n            \"5\": homeOne,\n            \"6\": tieFighter,\n            \"7\": tieInterceptor,\n            \"8\": executor,\n        },\n    }\n\n\ndef create_ship(ship_name, faction_id):\n    from .schema import Ship\n\n    next_ship = len(data[\"Ship\"].keys()) + 1\n    new_ship = Ship(id=str(next_ship), name=ship_name)\n    data[\"Ship\"][new_ship.id] = new_ship\n    data[\"Faction\"][faction_id].ships.append(new_ship.id)\n    return new_ship\n\n\ndef get_ship(_id):\n    return data[\"Ship\"][_id]\n\n\ndef get_faction(_id):\n    return data[\"Faction\"][_id]\n\n\ndef get_rebels():\n    return get_faction(\"1\")\n\n\ndef get_empire():\n    return get_faction(\"2\")\n"
  },
  {
    "path": "examples/starwars_relay/schema.py",
    "content": "import graphene\nfrom graphene import relay\n\nfrom .data import create_ship, get_empire, get_faction, get_rebels, get_ship\n\n\nclass Ship(graphene.ObjectType):\n    \"\"\"A ship in the Star Wars saga\"\"\"\n\n    class Meta:\n        interfaces = (relay.Node,)\n\n    name = graphene.String(description=\"The name of the ship.\")\n\n    @classmethod\n    def get_node(cls, info, id):\n        return get_ship(id)\n\n\nclass ShipConnection(relay.Connection):\n    class Meta:\n        node = Ship\n\n\nclass Faction(graphene.ObjectType):\n    \"\"\"A faction in the Star Wars saga\"\"\"\n\n    class Meta:\n        interfaces = (relay.Node,)\n\n    name = graphene.String(description=\"The name of the faction.\")\n    ships = relay.ConnectionField(\n        ShipConnection, description=\"The ships used by the faction.\"\n    )\n\n    def resolve_ships(self, info, **args):\n        # Transform the instance ship_ids into real instances\n        return [get_ship(ship_id) for ship_id in self.ships]\n\n    @classmethod\n    def get_node(cls, info, id):\n        return get_faction(id)\n\n\nclass IntroduceShip(relay.ClientIDMutation):\n    class Input:\n        ship_name = graphene.String(required=True)\n        faction_id = graphene.String(required=True)\n\n    ship = graphene.Field(Ship)\n    faction = graphene.Field(Faction)\n\n    @classmethod\n    def mutate_and_get_payload(\n        cls, root, info, ship_name, faction_id, client_mutation_id=None\n    ):\n        ship = create_ship(ship_name, faction_id)\n        faction = get_faction(faction_id)\n        return IntroduceShip(ship=ship, faction=faction)\n\n\nclass Query(graphene.ObjectType):\n    rebels = graphene.Field(Faction)\n    empire = graphene.Field(Faction)\n    node = relay.Node.Field()\n\n    def resolve_rebels(root, info):\n        return get_rebels()\n\n    def resolve_empire(root, info):\n        return get_empire()\n\n\nclass Mutation(graphene.ObjectType):\n    introduce_ship = IntroduceShip.Field()\n\n\nschema = graphene.Schema(query=Query, mutation=Mutation)\n"
  },
  {
    "path": "examples/starwars_relay/tests/__init__.py",
    "content": ""
  },
  {
    "path": "examples/starwars_relay/tests/test_connections.py",
    "content": "from graphene.test import Client\n\nfrom ..data import setup\nfrom ..schema import schema\n\nsetup()\n\nclient = Client(schema)\n\n\ndef test_correct_fetch_first_ship_rebels():\n    result = client.execute(\"\"\"\n        query RebelsShipsQuery {\n          rebels {\n            name,\n            ships(first: 1) {\n              pageInfo {\n                startCursor\n                endCursor\n                hasNextPage\n                hasPreviousPage\n              }\n              edges {\n                cursor\n                node {\n                  name\n                }\n              }\n            }\n          }\n        }\n    \"\"\")\n    assert result == {\n        \"data\": {\n            \"rebels\": {\n                \"name\": \"Alliance to Restore the Republic\",\n                \"ships\": {\n                    \"pageInfo\": {\n                        \"startCursor\": \"YXJyYXljb25uZWN0aW9uOjA=\",\n                        \"endCursor\": \"YXJyYXljb25uZWN0aW9uOjA=\",\n                        \"hasNextPage\": True,\n                        \"hasPreviousPage\": False,\n                    },\n                    \"edges\": [\n                        {\n                            \"cursor\": \"YXJyYXljb25uZWN0aW9uOjA=\",\n                            \"node\": {\"name\": \"X-Wing\"},\n                        }\n                    ],\n                },\n            }\n        }\n    }\n"
  },
  {
    "path": "examples/starwars_relay/tests/test_mutation.py",
    "content": "from graphene.test import Client\n\nfrom ..data import setup\nfrom ..schema import schema\n\nsetup()\n\nclient = Client(schema)\n\n\ndef test_mutations():\n    result = client.execute(\"\"\"\n        mutation MyMutation {\n          introduceShip(input:{clientMutationId:\"abc\", shipName: \"Peter\", factionId: \"1\"}) {\n            ship {\n              id\n              name\n            }\n            faction {\n              name\n              ships {\n                edges {\n                  node {\n                    id\n                    name\n                  }\n                }\n              }\n            }\n          }\n        }\n    \"\"\")\n    assert result == {\n        \"data\": {\n            \"introduceShip\": {\n                \"ship\": {\"id\": \"U2hpcDo5\", \"name\": \"Peter\"},\n                \"faction\": {\n                    \"name\": \"Alliance to Restore the Republic\",\n                    \"ships\": {\n                        \"edges\": [\n                            {\"node\": {\"id\": \"U2hpcDox\", \"name\": \"X-Wing\"}},\n                            {\"node\": {\"id\": \"U2hpcDoy\", \"name\": \"Y-Wing\"}},\n                            {\"node\": {\"id\": \"U2hpcDoz\", \"name\": \"A-Wing\"}},\n                            {\"node\": {\"id\": \"U2hpcDo0\", \"name\": \"Millennium Falcon\"}},\n                            {\"node\": {\"id\": \"U2hpcDo1\", \"name\": \"Home One\"}},\n                            {\"node\": {\"id\": \"U2hpcDo5\", \"name\": \"Peter\"}},\n                        ]\n                    },\n                },\n            }\n        }\n    }\n"
  },
  {
    "path": "examples/starwars_relay/tests/test_objectidentification.py",
    "content": "import textwrap\n\nfrom graphene.test import Client\n\nfrom ..data import setup\nfrom ..schema import schema\n\nsetup()\n\nclient = Client(schema)\n\n\ndef test_str_schema():\n    assert str(schema).strip() == textwrap.dedent(\n        '''\\\n        type Query {\n          rebels: Faction\n          empire: Faction\n          node(\n            \"\"\"The ID of the object\"\"\"\n            id: ID!\n          ): Node\n        }\n\n        \"\"\"A faction in the Star Wars saga\"\"\"\n        type Faction implements Node {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n\n          \"\"\"The name of the faction.\"\"\"\n          name: String\n\n          \"\"\"The ships used by the faction.\"\"\"\n          ships(before: String, after: String, first: Int, last: Int): ShipConnection\n        }\n\n        \"\"\"An object with an ID\"\"\"\n        interface Node {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n        }\n\n        type ShipConnection {\n          \"\"\"Pagination data for this connection.\"\"\"\n          pageInfo: PageInfo!\n\n          \"\"\"Contains the nodes in this connection.\"\"\"\n          edges: [ShipEdge]!\n        }\n\n        \"\"\"\n        The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.\n        \"\"\"\n        type PageInfo {\n          \"\"\"When paginating forwards, are there more items?\"\"\"\n          hasNextPage: Boolean!\n\n          \"\"\"When paginating backwards, are there more items?\"\"\"\n          hasPreviousPage: Boolean!\n\n          \"\"\"When paginating backwards, the cursor to continue.\"\"\"\n          startCursor: String\n\n          \"\"\"When paginating forwards, the cursor to continue.\"\"\"\n          endCursor: String\n        }\n\n        \"\"\"A Relay edge containing a `Ship` and its cursor.\"\"\"\n        type ShipEdge {\n          \"\"\"The item at the end of the edge\"\"\"\n          node: Ship\n\n          \"\"\"A cursor for use in pagination\"\"\"\n          cursor: String!\n        }\n\n        \"\"\"A ship in the Star Wars saga\"\"\"\n        type Ship implements Node {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n\n          \"\"\"The name of the ship.\"\"\"\n          name: String\n        }\n\n        type Mutation {\n          introduceShip(input: IntroduceShipInput!): IntroduceShipPayload\n        }\n\n        type IntroduceShipPayload {\n          ship: Ship\n          faction: Faction\n          clientMutationId: String\n        }\n\n        input IntroduceShipInput {\n          shipName: String!\n          factionId: String!\n          clientMutationId: String\n        }'''\n    )\n\n\ndef test_correctly_fetches_id_name_rebels():\n    result = client.execute(\"\"\"\n      query RebelsQuery {\n        rebels {\n          id\n          name\n        }\n      }\n    \"\"\")\n    assert result == {\n        \"data\": {\n            \"rebels\": {\"id\": \"RmFjdGlvbjox\", \"name\": \"Alliance to Restore the Republic\"}\n        }\n    }\n\n\ndef test_correctly_refetches_rebels():\n    result = client.execute(\"\"\"\n      query RebelsRefetchQuery {\n        node(id: \"RmFjdGlvbjox\") {\n          id\n          ... on Faction {\n            name\n          }\n        }\n      }\n    \"\"\")\n    assert result == {\n        \"data\": {\n            \"node\": {\"id\": \"RmFjdGlvbjox\", \"name\": \"Alliance to Restore the Republic\"}\n        }\n    }\n\n\ndef test_correctly_fetches_id_name_empire():\n    result = client.execute(\"\"\"\n      query EmpireQuery {\n        empire {\n          id\n          name\n        }\n      }\n    \"\"\")\n    assert result == {\n        \"data\": {\"empire\": {\"id\": \"RmFjdGlvbjoy\", \"name\": \"Galactic Empire\"}}\n    }\n\n\ndef test_correctly_refetches_empire():\n    result = client.execute(\"\"\"\n      query EmpireRefetchQuery {\n        node(id: \"RmFjdGlvbjoy\") {\n          id\n          ... on Faction {\n            name\n          }\n        }\n      }\n    \"\"\")\n    assert result == {\n        \"data\": {\"node\": {\"id\": \"RmFjdGlvbjoy\", \"name\": \"Galactic Empire\"}}\n    }\n\n\ndef test_correctly_refetches_xwing():\n    result = client.execute(\"\"\"\n      query XWingRefetchQuery {\n        node(id: \"U2hpcDox\") {\n          id\n          ... on Ship {\n            name\n          }\n        }\n      }\n    \"\"\")\n    assert result == {\"data\": {\"node\": {\"id\": \"U2hpcDox\", \"name\": \"X-Wing\"}}}\n"
  },
  {
    "path": "graphene/__init__.py",
    "content": "from .pyutils.version import get_version\nfrom .relay import (\n    BaseGlobalIDType,\n    ClientIDMutation,\n    Connection,\n    ConnectionField,\n    DefaultGlobalIDType,\n    GlobalID,\n    Node,\n    PageInfo,\n    SimpleGlobalIDType,\n    UUIDGlobalIDType,\n    is_node,\n)\nfrom .types import (\n    ID,\n    UUID,\n    Argument,\n    Base64,\n    BigInt,\n    Boolean,\n    Context,\n    Date,\n    DateTime,\n    Decimal,\n    Dynamic,\n    Enum,\n    Field,\n    Float,\n    InputField,\n    InputObjectType,\n    Int,\n    Interface,\n    JSONString,\n    List,\n    Mutation,\n    NonNull,\n    ObjectType,\n    ResolveInfo,\n    Scalar,\n    Schema,\n    String,\n    Time,\n    Union,\n)\nfrom .utils.module_loading import lazy_import\nfrom .utils.resolve_only_args import resolve_only_args\n\nVERSION = (3, 4, 3, \"final\", 0)\n\n\n__version__ = get_version(VERSION)\n\n__all__ = [\n    \"__version__\",\n    \"Argument\",\n    \"Base64\",\n    \"BigInt\",\n    \"BaseGlobalIDType\",\n    \"Boolean\",\n    \"ClientIDMutation\",\n    \"Connection\",\n    \"ConnectionField\",\n    \"Context\",\n    \"Date\",\n    \"DateTime\",\n    \"Decimal\",\n    \"DefaultGlobalIDType\",\n    \"Dynamic\",\n    \"Enum\",\n    \"Field\",\n    \"Float\",\n    \"GlobalID\",\n    \"ID\",\n    \"InputField\",\n    \"InputObjectType\",\n    \"Int\",\n    \"Interface\",\n    \"JSONString\",\n    \"List\",\n    \"Mutation\",\n    \"Node\",\n    \"NonNull\",\n    \"ObjectType\",\n    \"PageInfo\",\n    \"ResolveInfo\",\n    \"Scalar\",\n    \"Schema\",\n    \"SimpleGlobalIDType\",\n    \"String\",\n    \"Time\",\n    \"Union\",\n    \"UUID\",\n    \"UUIDGlobalIDType\",\n    \"is_node\",\n    \"lazy_import\",\n    \"resolve_only_args\",\n]\n"
  },
  {
    "path": "graphene/pyutils/__init__.py",
    "content": ""
  },
  {
    "path": "graphene/pyutils/version.py",
    "content": "import datetime\nimport os\nimport subprocess\n\n\ndef get_version(version=None):\n    \"Returns a PEP 440-compliant version number from VERSION.\"\n    version = get_complete_version(version)\n\n    # Now build the two parts of the version number:\n    # main = X.Y[.Z]\n    # sub = .devN - for pre-alpha releases\n    #     | {a|b|rc}N - for alpha, beta, and rc releases\n\n    main = get_main_version(version)\n\n    sub = \"\"\n    if version[3] == \"alpha\" and version[4] == 0:\n        git_changeset = get_git_changeset()\n        sub = \".dev%s\" % git_changeset if git_changeset else \".dev\"\n    elif version[3] != \"final\":\n        mapping = {\"alpha\": \"a\", \"beta\": \"b\", \"rc\": \"rc\"}\n        sub = mapping[version[3]] + str(version[4])\n\n    return str(main + sub)\n\n\ndef get_main_version(version=None):\n    \"Returns main version (X.Y[.Z]) from VERSION.\"\n    version = get_complete_version(version)\n    parts = 2 if version[2] == 0 else 3\n    return \".\".join(str(x) for x in version[:parts])\n\n\ndef get_complete_version(version=None):\n    \"\"\"Returns a tuple of the graphene version. If version argument is non-empty,\n    then checks for correctness of the tuple provided.\n    \"\"\"\n    if version is None:\n        from graphene import VERSION as version\n    else:\n        assert len(version) == 5\n        assert version[3] in (\"alpha\", \"beta\", \"rc\", \"final\")\n\n    return version\n\n\ndef get_docs_version(version=None):\n    version = get_complete_version(version)\n    if version[3] != \"final\":\n        return \"dev\"\n    else:\n        return \"%d.%d\" % version[:2]\n\n\ndef get_git_changeset():\n    \"\"\"Returns a numeric identifier of the latest git changeset.\n    The result is the UTC timestamp of the changeset in YYYYMMDDHHMMSS format.\n    This value isn't guaranteed to be unique, but collisions are very unlikely,\n    so it's sufficient for generating the development version numbers.\n    \"\"\"\n    repo_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n    try:\n        git_log = subprocess.Popen(\n            \"git log --pretty=format:%ct --quiet -1 HEAD\",\n            stdout=subprocess.PIPE,\n            stderr=subprocess.PIPE,\n            shell=True,\n            cwd=repo_dir,\n            universal_newlines=True,\n        )\n        timestamp = git_log.communicate()[0]\n        timestamp = datetime.datetime.utcfromtimestamp(int(timestamp))\n    except Exception:\n        return None\n    return timestamp.strftime(\"%Y%m%d%H%M%S\")\n"
  },
  {
    "path": "graphene/relay/__init__.py",
    "content": "from .node import Node, is_node, GlobalID\nfrom .mutation import ClientIDMutation\nfrom .connection import Connection, ConnectionField, PageInfo\nfrom .id_type import (\n    BaseGlobalIDType,\n    DefaultGlobalIDType,\n    SimpleGlobalIDType,\n    UUIDGlobalIDType,\n)\n\n__all__ = [\n    \"BaseGlobalIDType\",\n    \"ClientIDMutation\",\n    \"Connection\",\n    \"ConnectionField\",\n    \"DefaultGlobalIDType\",\n    \"GlobalID\",\n    \"Node\",\n    \"PageInfo\",\n    \"SimpleGlobalIDType\",\n    \"UUIDGlobalIDType\",\n    \"is_node\",\n]\n"
  },
  {
    "path": "graphene/relay/connection.py",
    "content": "import re\nfrom collections.abc import Iterable\nfrom functools import partial\nfrom typing import Type\n\nfrom graphql_relay import connection_from_array\n\nfrom ..types import Boolean, Enum, Int, Interface, List, NonNull, Scalar, String, Union\nfrom ..types.field import Field\nfrom ..types.objecttype import ObjectType, ObjectTypeOptions\nfrom ..utils.thenables import maybe_thenable\nfrom .node import is_node, AbstractNode\n\n\ndef get_edge_class(\n    connection_class: Type[\"Connection\"],\n    _node: Type[AbstractNode],\n    base_name: str,\n    strict_types: bool = False,\n):\n    edge_class = getattr(connection_class, \"Edge\", None)\n\n    class EdgeBase:\n        node = Field(\n            NonNull(_node) if strict_types else _node,\n            description=\"The item at the end of the edge\",\n        )\n        cursor = String(required=True, description=\"A cursor for use in pagination\")\n\n    class EdgeMeta:\n        description = f\"A Relay edge containing a `{base_name}` and its cursor.\"\n\n    edge_name = f\"{base_name}Edge\"\n\n    edge_bases = [edge_class, EdgeBase] if edge_class else [EdgeBase]\n    if not isinstance(edge_class, ObjectType):\n        edge_bases = [*edge_bases, ObjectType]\n\n    return type(edge_name, tuple(edge_bases), {\"Meta\": EdgeMeta})\n\n\nclass PageInfo(ObjectType):\n    class Meta:\n        description = (\n            \"The Relay compliant `PageInfo` type, containing data necessary to\"\n            \" paginate this connection.\"\n        )\n\n    has_next_page = Boolean(\n        required=True,\n        name=\"hasNextPage\",\n        description=\"When paginating forwards, are there more items?\",\n    )\n\n    has_previous_page = Boolean(\n        required=True,\n        name=\"hasPreviousPage\",\n        description=\"When paginating backwards, are there more items?\",\n    )\n\n    start_cursor = String(\n        name=\"startCursor\",\n        description=\"When paginating backwards, the cursor to continue.\",\n    )\n\n    end_cursor = String(\n        name=\"endCursor\",\n        description=\"When paginating forwards, the cursor to continue.\",\n    )\n\n\n# noinspection PyPep8Naming\ndef page_info_adapter(startCursor, endCursor, hasPreviousPage, hasNextPage):\n    \"\"\"Adapter for creating PageInfo instances\"\"\"\n    return PageInfo(\n        start_cursor=startCursor,\n        end_cursor=endCursor,\n        has_previous_page=hasPreviousPage,\n        has_next_page=hasNextPage,\n    )\n\n\nclass ConnectionOptions(ObjectTypeOptions):\n    node = None\n\n\nclass Connection(ObjectType):\n    class Meta:\n        abstract = True\n\n    @classmethod\n    def __init_subclass_with_meta__(\n        cls, node=None, name=None, strict_types=False, _meta=None, **options\n    ):\n        if not _meta:\n            _meta = ConnectionOptions(cls)\n        assert node, f\"You have to provide a node in {cls.__name__}.Meta\"\n        assert isinstance(node, NonNull) or issubclass(\n            node, (Scalar, Enum, ObjectType, Interface, Union, NonNull)\n        ), f'Received incompatible node \"{node}\" for Connection {cls.__name__}.'\n\n        base_name = re.sub(\"Connection$\", \"\", name or cls.__name__) or node._meta.name\n        if not name:\n            name = f\"{base_name}Connection\"\n\n        options[\"name\"] = name\n\n        _meta.node = node\n\n        if not _meta.fields:\n            _meta.fields = {}\n\n        if \"page_info\" not in _meta.fields:\n            _meta.fields[\"page_info\"] = Field(\n                PageInfo,\n                name=\"pageInfo\",\n                required=True,\n                description=\"Pagination data for this connection.\",\n            )\n\n        if \"edges\" not in _meta.fields:\n            edge_class = get_edge_class(cls, node, base_name, strict_types)  # type: ignore\n            cls.Edge = edge_class\n            _meta.fields[\"edges\"] = Field(\n                NonNull(List(NonNull(edge_class) if strict_types else edge_class)),\n                description=\"Contains the nodes in this connection.\",\n            )\n\n        return super(Connection, cls).__init_subclass_with_meta__(\n            _meta=_meta, **options\n        )\n\n\n# noinspection PyPep8Naming\ndef connection_adapter(cls, edges, pageInfo):\n    \"\"\"Adapter for creating Connection instances\"\"\"\n    return cls(edges=edges, page_info=pageInfo)\n\n\nclass IterableConnectionField(Field):\n    def __init__(self, type_, *args, **kwargs):\n        kwargs.setdefault(\"before\", String())\n        kwargs.setdefault(\"after\", String())\n        kwargs.setdefault(\"first\", Int())\n        kwargs.setdefault(\"last\", Int())\n        super(IterableConnectionField, self).__init__(type_, *args, **kwargs)\n\n    @property\n    def type(self):\n        type_ = super(IterableConnectionField, self).type\n        connection_type = type_\n        if isinstance(type_, NonNull):\n            connection_type = type_.of_type\n\n        if is_node(connection_type):\n            raise Exception(\n                \"ConnectionFields now need a explicit ConnectionType for Nodes.\\n\"\n                \"Read more: https://github.com/graphql-python/graphene/blob/v2.0.0/UPGRADE-v2.0.md#node-connections\"\n            )\n\n        assert issubclass(\n            connection_type, Connection\n        ), f'{self.__class__.__name__} type has to be a subclass of Connection. Received \"{connection_type}\".'\n        return type_\n\n    @classmethod\n    def resolve_connection(cls, connection_type, args, resolved):\n        if isinstance(resolved, connection_type):\n            return resolved\n\n        assert isinstance(resolved, Iterable), (\n            f\"Resolved value from the connection field has to be an iterable or instance of {connection_type}. \"\n            f'Received \"{resolved}\"'\n        )\n        connection = connection_from_array(\n            resolved,\n            args,\n            connection_type=partial(connection_adapter, connection_type),\n            edge_type=connection_type.Edge,\n            page_info_type=page_info_adapter,\n        )\n        connection.iterable = resolved\n        return connection\n\n    @classmethod\n    def connection_resolver(cls, resolver, connection_type, root, info, **args):\n        resolved = resolver(root, info, **args)\n\n        if isinstance(connection_type, NonNull):\n            connection_type = connection_type.of_type\n\n        on_resolve = partial(cls.resolve_connection, connection_type, args)\n        return maybe_thenable(resolved, on_resolve)\n\n    def wrap_resolve(self, parent_resolver):\n        resolver = super(IterableConnectionField, self).wrap_resolve(parent_resolver)\n        return partial(self.connection_resolver, resolver, self.type)\n\n\nConnectionField = IterableConnectionField\n"
  },
  {
    "path": "graphene/relay/id_type.py",
    "content": "from graphql_relay import from_global_id, to_global_id\n\nfrom ..types import ID, UUID\nfrom ..types.base import BaseType\n\nfrom typing import Type\n\n\nclass BaseGlobalIDType:\n    \"\"\"\n    Base class that define the required attributes/method for a type.\n    \"\"\"\n\n    graphene_type: Type[BaseType] = ID\n\n    @classmethod\n    def resolve_global_id(cls, info, global_id):\n        # return _type, _id\n        raise NotImplementedError\n\n    @classmethod\n    def to_global_id(cls, _type, _id):\n        # return _id\n        raise NotImplementedError\n\n\nclass DefaultGlobalIDType(BaseGlobalIDType):\n    \"\"\"\n    Default global ID type: base64 encoded version of \"<node type name>: <node id>\".\n    \"\"\"\n\n    graphene_type = ID\n\n    @classmethod\n    def resolve_global_id(cls, info, global_id):\n        try:\n            _type, _id = from_global_id(global_id)\n            if not _type:\n                raise ValueError(\"Invalid Global ID\")\n            return _type, _id\n        except Exception as e:\n            raise Exception(\n                f'Unable to parse global ID \"{global_id}\". '\n                'Make sure it is a base64 encoded string in the format: \"TypeName:id\". '\n                f\"Exception message: {e}\"\n            )\n\n    @classmethod\n    def to_global_id(cls, _type, _id):\n        return to_global_id(_type, _id)\n\n\nclass SimpleGlobalIDType(BaseGlobalIDType):\n    \"\"\"\n    Simple global ID type: simply the id of the object.\n    To be used carefully as the user is responsible for ensuring that the IDs are indeed global\n    (otherwise it could cause request caching issues).\n    \"\"\"\n\n    graphene_type = ID\n\n    @classmethod\n    def resolve_global_id(cls, info, global_id):\n        _type = info.return_type.graphene_type._meta.name\n        return _type, global_id\n\n    @classmethod\n    def to_global_id(cls, _type, _id):\n        return _id\n\n\nclass UUIDGlobalIDType(BaseGlobalIDType):\n    \"\"\"\n    UUID global ID type.\n    By definition UUID are global so they are used as they are.\n    \"\"\"\n\n    graphene_type = UUID\n\n    @classmethod\n    def resolve_global_id(cls, info, global_id):\n        _type = info.return_type.graphene_type._meta.name\n        return _type, global_id\n\n    @classmethod\n    def to_global_id(cls, _type, _id):\n        return _id\n"
  },
  {
    "path": "graphene/relay/mutation.py",
    "content": "import re\n\nfrom ..types import Field, InputObjectType, String\nfrom ..types.mutation import Mutation\nfrom ..utils.thenables import maybe_thenable\n\n\nclass ClientIDMutation(Mutation):\n    class Meta:\n        abstract = True\n\n    @classmethod\n    def __init_subclass_with_meta__(\n        cls, output=None, input_fields=None, arguments=None, name=None, **options\n    ):\n        input_class = getattr(cls, \"Input\", None)\n        base_name = re.sub(\"Payload$\", \"\", name or cls.__name__)\n\n        assert not output, \"Can't specify any output\"\n        assert not arguments, \"Can't specify any arguments\"\n\n        bases = (InputObjectType,)\n        if input_class:\n            bases += (input_class,)\n\n        if not input_fields:\n            input_fields = {}\n\n        cls.Input = type(\n            f\"{base_name}Input\",\n            bases,\n            dict(input_fields, client_mutation_id=String(name=\"clientMutationId\")),\n        )\n\n        arguments = dict(\n            input=cls.Input(required=True)\n            # 'client_mutation_id': String(name='clientMutationId')\n        )\n        mutate_and_get_payload = getattr(cls, \"mutate_and_get_payload\", None)\n        if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__:\n            assert mutate_and_get_payload, (\n                f\"{name or cls.__name__}.mutate_and_get_payload method is required\"\n                \" in a ClientIDMutation.\"\n            )\n\n        if not name:\n            name = f\"{base_name}Payload\"\n\n        super(ClientIDMutation, cls).__init_subclass_with_meta__(\n            output=None, arguments=arguments, name=name, **options\n        )\n        cls._meta.fields[\"client_mutation_id\"] = Field(String, name=\"clientMutationId\")\n\n    @classmethod\n    def mutate(cls, root, info, input):\n        def on_resolve(payload):\n            try:\n                payload.client_mutation_id = input.get(\"client_mutation_id\")\n            except Exception:\n                raise Exception(\n                    f\"Cannot set client_mutation_id in the payload object {repr(payload)}\"\n                )\n            return payload\n\n        result = cls.mutate_and_get_payload(root, info, **input)\n        return maybe_thenable(result, on_resolve)\n"
  },
  {
    "path": "graphene/relay/node.py",
    "content": "from functools import partial\nfrom inspect import isclass\n\nfrom ..types import Field, Interface, ObjectType\nfrom ..types.interface import InterfaceOptions\nfrom ..types.utils import get_type\nfrom .id_type import BaseGlobalIDType, DefaultGlobalIDType\n\n\ndef is_node(objecttype):\n    \"\"\"\n    Check if the given objecttype has Node as an interface\n    \"\"\"\n    if not isclass(objecttype):\n        return False\n\n    if not issubclass(objecttype, ObjectType):\n        return False\n\n    return any(issubclass(i, Node) for i in objecttype._meta.interfaces)\n\n\nclass GlobalID(Field):\n    def __init__(\n        self,\n        node=None,\n        parent_type=None,\n        required=True,\n        global_id_type=DefaultGlobalIDType,\n        *args,\n        **kwargs,\n    ):\n        super(GlobalID, self).__init__(\n            global_id_type.graphene_type, required=required, *args, **kwargs\n        )\n        self.node = node or Node\n        self.parent_type_name = parent_type._meta.name if parent_type else None\n\n    @staticmethod\n    def id_resolver(parent_resolver, node, root, info, parent_type_name=None, **args):\n        type_id = parent_resolver(root, info, **args)\n        parent_type_name = parent_type_name or info.parent_type.name\n        return node.to_global_id(parent_type_name, type_id)  # root._meta.name\n\n    def wrap_resolve(self, parent_resolver):\n        return partial(\n            self.id_resolver,\n            parent_resolver,\n            self.node,\n            parent_type_name=self.parent_type_name,\n        )\n\n\nclass NodeField(Field):\n    def __init__(self, node, type_=False, **kwargs):\n        assert issubclass(node, Node), \"NodeField can only operate in Nodes\"\n        self.node_type = node\n        self.field_type = type_\n        global_id_type = node._meta.global_id_type\n\n        super(NodeField, self).__init__(\n            # If we don't specify a type, the field type will be the node interface\n            type_ or node,\n            id=global_id_type.graphene_type(\n                required=True, description=\"The ID of the object\"\n            ),\n            **kwargs,\n        )\n\n    def wrap_resolve(self, parent_resolver):\n        return partial(self.node_type.node_resolver, get_type(self.field_type))\n\n\nclass AbstractNode(Interface):\n    class Meta:\n        abstract = True\n\n    @classmethod\n    def __init_subclass_with_meta__(cls, global_id_type=DefaultGlobalIDType, **options):\n        assert issubclass(\n            global_id_type, BaseGlobalIDType\n        ), \"Custom ID type need to be implemented as a subclass of BaseGlobalIDType.\"\n        _meta = InterfaceOptions(cls)\n        _meta.global_id_type = global_id_type\n        _meta.fields = {\n            \"id\": GlobalID(\n                cls, global_id_type=global_id_type, description=\"The ID of the object\"\n            )\n        }\n        super(AbstractNode, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n    @classmethod\n    def resolve_global_id(cls, info, global_id):\n        return cls._meta.global_id_type.resolve_global_id(info, global_id)\n\n\nclass Node(AbstractNode):\n    \"\"\"An object with an ID\"\"\"\n\n    @classmethod\n    def Field(cls, *args, **kwargs):  # noqa: N802\n        return NodeField(cls, *args, **kwargs)\n\n    @classmethod\n    def node_resolver(cls, only_type, root, info, id):\n        return cls.get_node_from_global_id(info, id, only_type=only_type)\n\n    @classmethod\n    def get_node_from_global_id(cls, info, global_id, only_type=None):\n        _type, _id = cls.resolve_global_id(info, global_id)\n\n        graphene_type = info.schema.get_type(_type)\n        if graphene_type is None:\n            raise Exception(f'Relay Node \"{_type}\" not found in schema')\n\n        graphene_type = graphene_type.graphene_type\n\n        if only_type:\n            assert (\n                graphene_type == only_type\n            ), f\"Must receive a {only_type._meta.name} id.\"\n\n        # We make sure the ObjectType implements the \"Node\" interface\n        if cls not in graphene_type._meta.interfaces:\n            raise Exception(\n                f'ObjectType \"{_type}\" does not implement the \"{cls}\" interface.'\n            )\n\n        get_node = getattr(graphene_type, \"get_node\", None)\n        if get_node:\n            return get_node(info, _id)\n\n    @classmethod\n    def to_global_id(cls, type_, id):\n        return cls._meta.global_id_type.to_global_id(type_, id)\n"
  },
  {
    "path": "graphene/relay/tests/__init__.py",
    "content": ""
  },
  {
    "path": "graphene/relay/tests/test_connection.py",
    "content": "import re\n\nfrom pytest import raises\n\nfrom ...types import Argument, Field, Int, List, NonNull, ObjectType, Schema, String\nfrom ..connection import (\n    Connection,\n    ConnectionField,\n    PageInfo,\n    ConnectionOptions,\n    get_edge_class,\n)\nfrom ..node import Node\n\n\nclass MyObject(ObjectType):\n    class Meta:\n        interfaces = [Node]\n\n    field = String()\n\n\ndef test_connection():\n    class MyObjectConnection(Connection):\n        extra = String()\n\n        class Meta:\n            node = MyObject\n\n        class Edge:\n            other = String()\n\n    assert MyObjectConnection._meta.name == \"MyObjectConnection\"\n    fields = MyObjectConnection._meta.fields\n    assert list(fields) == [\"page_info\", \"edges\", \"extra\"]\n    edge_field = fields[\"edges\"]\n    pageinfo_field = fields[\"page_info\"]\n\n    assert isinstance(edge_field, Field)\n    assert isinstance(edge_field.type, NonNull)\n    assert isinstance(edge_field.type.of_type, List)\n    assert edge_field.type.of_type.of_type == MyObjectConnection.Edge\n\n    assert isinstance(pageinfo_field, Field)\n    assert isinstance(pageinfo_field.type, NonNull)\n    assert pageinfo_field.type.of_type == PageInfo\n\n\ndef test_connection_inherit_abstracttype():\n    class BaseConnection:\n        extra = String()\n\n    class MyObjectConnection(BaseConnection, Connection):\n        class Meta:\n            node = MyObject\n\n    assert MyObjectConnection._meta.name == \"MyObjectConnection\"\n    fields = MyObjectConnection._meta.fields\n    assert list(fields) == [\"page_info\", \"edges\", \"extra\"]\n\n\ndef test_connection_extra_abstract_fields():\n    class ConnectionWithNodes(Connection):\n        class Meta:\n            abstract = True\n\n        @classmethod\n        def __init_subclass_with_meta__(cls, node=None, name=None, **options):\n            _meta = ConnectionOptions(cls)\n\n            _meta.fields = {\n                \"nodes\": Field(\n                    NonNull(List(node)),\n                    description=\"Contains all the nodes in this connection.\",\n                ),\n            }\n\n            return super(ConnectionWithNodes, cls).__init_subclass_with_meta__(\n                node=node, name=name, _meta=_meta, **options\n            )\n\n    class MyObjectConnection(ConnectionWithNodes):\n        class Meta:\n            node = MyObject\n\n        class Edge:\n            other = String()\n\n    assert MyObjectConnection._meta.name == \"MyObjectConnection\"\n    fields = MyObjectConnection._meta.fields\n    assert list(fields) == [\"nodes\", \"page_info\", \"edges\"]\n    edge_field = fields[\"edges\"]\n    pageinfo_field = fields[\"page_info\"]\n    nodes_field = fields[\"nodes\"]\n\n    assert isinstance(edge_field, Field)\n    assert isinstance(edge_field.type, NonNull)\n    assert isinstance(edge_field.type.of_type, List)\n    assert edge_field.type.of_type.of_type == MyObjectConnection.Edge\n\n    assert isinstance(pageinfo_field, Field)\n    assert isinstance(pageinfo_field.type, NonNull)\n    assert pageinfo_field.type.of_type == PageInfo\n\n    assert isinstance(nodes_field, Field)\n    assert isinstance(nodes_field.type, NonNull)\n    assert isinstance(nodes_field.type.of_type, List)\n    assert nodes_field.type.of_type.of_type == MyObject\n\n\ndef test_connection_override_fields():\n    class ConnectionWithNodes(Connection):\n        class Meta:\n            abstract = True\n\n        @classmethod\n        def __init_subclass_with_meta__(cls, node=None, name=None, **options):\n            _meta = ConnectionOptions(cls)\n            base_name = (\n                re.sub(\"Connection$\", \"\", name or cls.__name__) or node._meta.name\n            )\n\n            edge_class = get_edge_class(cls, node, base_name)\n\n            _meta.fields = {\n                \"page_info\": Field(\n                    NonNull(\n                        PageInfo,\n                        name=\"pageInfo\",\n                        required=True,\n                        description=\"Pagination data for this connection.\",\n                    )\n                ),\n                \"edges\": Field(\n                    NonNull(List(NonNull(edge_class))),\n                    description=\"Contains the nodes in this connection.\",\n                ),\n            }\n\n            return super(ConnectionWithNodes, cls).__init_subclass_with_meta__(\n                node=node, name=name, _meta=_meta, **options\n            )\n\n    class MyObjectConnection(ConnectionWithNodes):\n        class Meta:\n            node = MyObject\n\n    assert MyObjectConnection._meta.name == \"MyObjectConnection\"\n    fields = MyObjectConnection._meta.fields\n    assert list(fields) == [\"page_info\", \"edges\"]\n    edge_field = fields[\"edges\"]\n    pageinfo_field = fields[\"page_info\"]\n\n    assert isinstance(edge_field, Field)\n    assert isinstance(edge_field.type, NonNull)\n    assert isinstance(edge_field.type.of_type, List)\n    assert isinstance(edge_field.type.of_type.of_type, NonNull)\n\n    assert edge_field.type.of_type.of_type.of_type.__name__ == \"MyObjectEdge\"\n\n    # This page info is NonNull\n    assert isinstance(pageinfo_field, Field)\n    assert isinstance(edge_field.type, NonNull)\n    assert pageinfo_field.type.of_type == PageInfo\n\n\ndef test_connection_name():\n    custom_name = \"MyObjectCustomNameConnection\"\n\n    class BaseConnection:\n        extra = String()\n\n    class MyObjectConnection(BaseConnection, Connection):\n        class Meta:\n            node = MyObject\n            name = custom_name\n\n    assert MyObjectConnection._meta.name == custom_name\n\n\ndef test_edge():\n    class MyObjectConnection(Connection):\n        class Meta:\n            node = MyObject\n\n        class Edge:\n            other = String()\n\n    Edge = MyObjectConnection.Edge\n    assert Edge._meta.name == \"MyObjectEdge\"\n    edge_fields = Edge._meta.fields\n    assert list(edge_fields) == [\"node\", \"cursor\", \"other\"]\n\n    assert isinstance(edge_fields[\"node\"], Field)\n    assert edge_fields[\"node\"].type == MyObject\n\n    assert isinstance(edge_fields[\"other\"], Field)\n    assert edge_fields[\"other\"].type == String\n\n\ndef test_edge_with_bases():\n    class BaseEdge:\n        extra = String()\n\n    class MyObjectConnection(Connection):\n        class Meta:\n            node = MyObject\n\n        class Edge(BaseEdge):\n            other = String()\n\n    Edge = MyObjectConnection.Edge\n    assert Edge._meta.name == \"MyObjectEdge\"\n    edge_fields = Edge._meta.fields\n    assert list(edge_fields) == [\"node\", \"cursor\", \"extra\", \"other\"]\n\n    assert isinstance(edge_fields[\"node\"], Field)\n    assert edge_fields[\"node\"].type == MyObject\n\n    assert isinstance(edge_fields[\"other\"], Field)\n    assert edge_fields[\"other\"].type == String\n\n\ndef test_edge_with_nonnull_node():\n    class MyObjectConnection(Connection):\n        class Meta:\n            node = NonNull(MyObject)\n\n    edge_fields = MyObjectConnection.Edge._meta.fields\n    assert isinstance(edge_fields[\"node\"], Field)\n    assert isinstance(edge_fields[\"node\"].type, NonNull)\n    assert edge_fields[\"node\"].type.of_type == MyObject\n\n\ndef test_pageinfo():\n    assert PageInfo._meta.name == \"PageInfo\"\n    fields = PageInfo._meta.fields\n    assert list(fields) == [\n        \"has_next_page\",\n        \"has_previous_page\",\n        \"start_cursor\",\n        \"end_cursor\",\n    ]\n\n\ndef test_connectionfield():\n    class MyObjectConnection(Connection):\n        class Meta:\n            node = MyObject\n\n    field = ConnectionField(MyObjectConnection)\n    assert field.args == {\n        \"before\": Argument(String),\n        \"after\": Argument(String),\n        \"first\": Argument(Int),\n        \"last\": Argument(Int),\n    }\n\n\ndef test_connectionfield_node_deprecated():\n    field = ConnectionField(MyObject)\n    with raises(Exception) as exc_info:\n        field.type\n\n    assert \"ConnectionFields now need a explicit ConnectionType for Nodes.\" in str(\n        exc_info.value\n    )\n\n\ndef test_connectionfield_custom_args():\n    class MyObjectConnection(Connection):\n        class Meta:\n            node = MyObject\n\n    field = ConnectionField(\n        MyObjectConnection, before=String(required=True), extra=String()\n    )\n    assert field.args == {\n        \"before\": Argument(NonNull(String)),\n        \"after\": Argument(String),\n        \"first\": Argument(Int),\n        \"last\": Argument(Int),\n        \"extra\": Argument(String),\n    }\n\n\ndef test_connectionfield_required():\n    class MyObjectConnection(Connection):\n        class Meta:\n            node = MyObject\n\n    class Query(ObjectType):\n        test_connection = ConnectionField(MyObjectConnection, required=True)\n\n        def resolve_test_connection(root, info, **args):\n            return []\n\n    schema = Schema(query=Query)\n    executed = schema.execute(\"{ testConnection { edges { cursor } } }\")\n    assert not executed.errors\n    assert executed.data == {\"testConnection\": {\"edges\": []}}\n\n\ndef test_connectionfield_strict_types():\n    class MyObjectConnection(Connection):\n        class Meta:\n            node = MyObject\n            strict_types = True\n\n    connection_field = ConnectionField(MyObjectConnection)\n    edges_field_type = connection_field.type._meta.fields[\"edges\"].type\n    assert isinstance(edges_field_type, NonNull)\n\n    edges_list_element_type = edges_field_type.of_type.of_type\n    assert isinstance(edges_list_element_type, NonNull)\n\n    node_field = edges_list_element_type.of_type._meta.fields[\"node\"]\n    assert isinstance(node_field.type, NonNull)\n"
  },
  {
    "path": "graphene/relay/tests/test_connection_async.py",
    "content": "from pytest import mark\n\nfrom graphql_relay.utils import base64\n\nfrom graphene.types import ObjectType, Schema, String\nfrom graphene.relay.connection import Connection, ConnectionField, PageInfo\nfrom graphene.relay.node import Node\n\nletter_chars = [\"A\", \"B\", \"C\", \"D\", \"E\"]\n\n\nclass Letter(ObjectType):\n    class Meta:\n        interfaces = (Node,)\n\n    letter = String()\n\n\nclass LetterConnection(Connection):\n    class Meta:\n        node = Letter\n\n\nclass Query(ObjectType):\n    letters = ConnectionField(LetterConnection)\n    connection_letters = ConnectionField(LetterConnection)\n    async_letters = ConnectionField(LetterConnection)\n\n    node = Node.Field()\n\n    def resolve_letters(self, info, **args):\n        return list(letters.values())\n\n    async def resolve_async_letters(self, info, **args):\n        return list(letters.values())\n\n    def resolve_connection_letters(self, info, **args):\n        return LetterConnection(\n            page_info=PageInfo(has_next_page=True, has_previous_page=False),\n            edges=[\n                LetterConnection.Edge(node=Letter(id=0, letter=\"A\"), cursor=\"a-cursor\")\n            ],\n        )\n\n\nschema = Schema(Query)\n\nletters = {letter: Letter(id=i, letter=letter) for i, letter in enumerate(letter_chars)}\n\n\ndef edges(selected_letters):\n    return [\n        {\n            \"node\": {\"id\": base64(\"Letter:%s\" % letter.id), \"letter\": letter.letter},\n            \"cursor\": base64(\"arrayconnection:%s\" % letter.id),\n        }\n        for letter in [letters[i] for i in selected_letters]\n    ]\n\n\ndef cursor_for(ltr):\n    letter = letters[ltr]\n    return base64(\"arrayconnection:%s\" % letter.id)\n\n\ndef execute(args=\"\"):\n    if args:\n        args = \"(\" + args + \")\"\n\n    return schema.execute(\n        \"\"\"\n    {\n        letters%s {\n            edges {\n                node {\n                    id\n                    letter\n                }\n                cursor\n            }\n            pageInfo {\n                hasPreviousPage\n                hasNextPage\n                startCursor\n                endCursor\n            }\n        }\n    }\n    \"\"\"\n        % args\n    )\n\n\n@mark.asyncio\nasync def test_connection_async():\n    result = await schema.execute_async(\n        \"\"\"\n    {\n        asyncLetters(first:1) {\n            edges {\n                node {\n                    id\n                    letter\n                }\n            }\n            pageInfo {\n                hasPreviousPage\n                hasNextPage\n            }\n        }\n    }\n    \"\"\"\n    )\n\n    assert not result.errors\n    assert result.data == {\n        \"asyncLetters\": {\n            \"edges\": [{\"node\": {\"id\": \"TGV0dGVyOjA=\", \"letter\": \"A\"}}],\n            \"pageInfo\": {\"hasPreviousPage\": False, \"hasNextPage\": True},\n        }\n    }\n"
  },
  {
    "path": "graphene/relay/tests/test_connection_query.py",
    "content": "from pytest import mark\n\nfrom graphql_relay.utils import base64\n\nfrom ...types import ObjectType, Schema, String\nfrom ..connection import Connection, ConnectionField, PageInfo\nfrom ..node import Node\n\nletter_chars = [\"A\", \"B\", \"C\", \"D\", \"E\"]\n\n\nclass Letter(ObjectType):\n    class Meta:\n        interfaces = (Node,)\n\n    letter = String()\n\n\nclass LetterConnection(Connection):\n    class Meta:\n        node = Letter\n\n\nclass Query(ObjectType):\n    letters = ConnectionField(LetterConnection)\n    connection_letters = ConnectionField(LetterConnection)\n    async_letters = ConnectionField(LetterConnection)\n\n    node = Node.Field()\n\n    def resolve_letters(self, info, **args):\n        return list(letters.values())\n\n    async def resolve_async_letters(self, info, **args):\n        return list(letters.values())\n\n    def resolve_connection_letters(self, info, **args):\n        return LetterConnection(\n            page_info=PageInfo(has_next_page=True, has_previous_page=False),\n            edges=[\n                LetterConnection.Edge(node=Letter(id=0, letter=\"A\"), cursor=\"a-cursor\")\n            ],\n        )\n\n\nschema = Schema(Query)\n\nletters = {letter: Letter(id=i, letter=letter) for i, letter in enumerate(letter_chars)}\n\n\ndef edges(selected_letters):\n    return [\n        {\n            \"node\": {\"id\": base64(\"Letter:%s\" % letter.id), \"letter\": letter.letter},\n            \"cursor\": base64(\"arrayconnection:%s\" % letter.id),\n        }\n        for letter in [letters[i] for i in selected_letters]\n    ]\n\n\ndef cursor_for(ltr):\n    letter = letters[ltr]\n    return base64(\"arrayconnection:%s\" % letter.id)\n\n\nasync def execute(args=\"\"):\n    if args:\n        args = \"(\" + args + \")\"\n    return await schema.execute_async(\n        \"\"\"\n    {\n        letters%s {\n            edges {\n                node {\n                    id\n                    letter\n                }\n                cursor\n            }\n            pageInfo {\n                hasPreviousPage\n                hasNextPage\n                startCursor\n                endCursor\n            }\n        }\n    }\n    \"\"\"\n        % args\n    )\n\n\nasync def check(args, letters, has_previous_page=False, has_next_page=False):\n    result = await execute(args)\n    expected_edges = edges(letters)\n    expected_page_info = {\n        \"hasPreviousPage\": has_previous_page,\n        \"hasNextPage\": has_next_page,\n        \"endCursor\": expected_edges[-1][\"cursor\"] if expected_edges else None,\n        \"startCursor\": expected_edges[0][\"cursor\"] if expected_edges else None,\n    }\n\n    assert not result.errors\n    assert result.data == {\n        \"letters\": {\"edges\": expected_edges, \"pageInfo\": expected_page_info}\n    }\n\n\n@mark.asyncio\nasync def test_returns_all_elements_without_filters():\n    await check(\"\", \"ABCDE\")\n\n\n@mark.asyncio\nasync def test_respects_a_smaller_first():\n    await check(\"first: 2\", \"AB\", has_next_page=True)\n\n\n@mark.asyncio\nasync def test_respects_an_overly_large_first():\n    await check(\"first: 10\", \"ABCDE\")\n\n\n@mark.asyncio\nasync def test_respects_a_smaller_last():\n    await check(\"last: 2\", \"DE\", has_previous_page=True)\n\n\n@mark.asyncio\nasync def test_respects_an_overly_large_last():\n    await check(\"last: 10\", \"ABCDE\")\n\n\n@mark.asyncio\nasync def test_respects_first_and_after():\n    await check(f'first: 2, after: \"{cursor_for(\"B\")}\"', \"CD\", has_next_page=True)\n\n\n@mark.asyncio\nasync def test_respects_first_and_after_with_long_first():\n    await check(f'first: 10, after: \"{cursor_for(\"B\")}\"', \"CDE\")\n\n\n@mark.asyncio\nasync def test_respects_last_and_before():\n    await check(f'last: 2, before: \"{cursor_for(\"D\")}\"', \"BC\", has_previous_page=True)\n\n\n@mark.asyncio\nasync def test_respects_last_and_before_with_long_last():\n    await check(f'last: 10, before: \"{cursor_for(\"D\")}\"', \"ABC\")\n\n\n@mark.asyncio\nasync def test_respects_first_and_after_and_before_too_few():\n    await check(\n        f'first: 2, after: \"{cursor_for(\"A\")}\", before: \"{cursor_for(\"E\")}\"',\n        \"BC\",\n        has_next_page=True,\n    )\n\n\n@mark.asyncio\nasync def test_respects_first_and_after_and_before_too_many():\n    await check(\n        f'first: 4, after: \"{cursor_for(\"A\")}\", before: \"{cursor_for(\"E\")}\"', \"BCD\"\n    )\n\n\n@mark.asyncio\nasync def test_respects_first_and_after_and_before_exactly_right():\n    await check(\n        f'first: 3, after: \"{cursor_for(\"A\")}\", before: \"{cursor_for(\"E\")}\"', \"BCD\"\n    )\n\n\n@mark.asyncio\nasync def test_respects_last_and_after_and_before_too_few():\n    await check(\n        f'last: 2, after: \"{cursor_for(\"A\")}\", before: \"{cursor_for(\"E\")}\"',\n        \"CD\",\n        has_previous_page=True,\n    )\n\n\n@mark.asyncio\nasync def test_respects_last_and_after_and_before_too_many():\n    await check(\n        f'last: 4, after: \"{cursor_for(\"A\")}\", before: \"{cursor_for(\"E\")}\"', \"BCD\"\n    )\n\n\n@mark.asyncio\nasync def test_respects_last_and_after_and_before_exactly_right():\n    await check(\n        f'last: 3, after: \"{cursor_for(\"A\")}\", before: \"{cursor_for(\"E\")}\"', \"BCD\"\n    )\n\n\n@mark.asyncio\nasync def test_returns_no_elements_if_first_is_0():\n    await check(\"first: 0\", \"\", has_next_page=True)\n\n\n@mark.asyncio\nasync def test_returns_all_elements_if_cursors_are_invalid():\n    await check('before: \"invalid\" after: \"invalid\"', \"ABCDE\")\n\n\n@mark.asyncio\nasync def test_returns_all_elements_if_cursors_are_on_the_outside():\n    await check(\n        f'before: \"{base64(\"arrayconnection:%s\" % 6)}\" after: \"{base64(\"arrayconnection:%s\" % -1)}\"',\n        \"ABCDE\",\n    )\n\n\n@mark.asyncio\nasync def test_returns_no_elements_if_cursors_cross():\n    await check(\n        f'before: \"{base64(\"arrayconnection:%s\" % 2)}\" after: \"{base64(\"arrayconnection:%s\" % 4)}\"',\n        \"\",\n    )\n\n\n@mark.asyncio\nasync def test_connection_type_nodes():\n    result = await schema.execute_async(\n        \"\"\"\n    {\n        connectionLetters {\n            edges {\n                node {\n                    id\n                    letter\n                }\n                cursor\n            }\n            pageInfo {\n                hasPreviousPage\n                hasNextPage\n            }\n        }\n    }\n    \"\"\"\n    )\n\n    assert not result.errors\n    assert result.data == {\n        \"connectionLetters\": {\n            \"edges\": [\n                {\"node\": {\"id\": \"TGV0dGVyOjA=\", \"letter\": \"A\"}, \"cursor\": \"a-cursor\"}\n            ],\n            \"pageInfo\": {\"hasPreviousPage\": False, \"hasNextPage\": True},\n        }\n    }\n\n\n@mark.asyncio\nasync def test_connection_async():\n    result = await schema.execute_async(\n        \"\"\"\n    {\n        asyncLetters(first:1) {\n            edges {\n                node {\n                    id\n                    letter\n                }\n            }\n            pageInfo {\n                hasPreviousPage\n                hasNextPage\n            }\n        }\n    }\n    \"\"\"\n    )\n\n    assert not result.errors\n    assert result.data == {\n        \"asyncLetters\": {\n            \"edges\": [{\"node\": {\"id\": \"TGV0dGVyOjA=\", \"letter\": \"A\"}}],\n            \"pageInfo\": {\"hasPreviousPage\": False, \"hasNextPage\": True},\n        }\n    }\n"
  },
  {
    "path": "graphene/relay/tests/test_custom_global_id.py",
    "content": "import re\nfrom uuid import uuid4\n\nfrom graphql import graphql_sync\n\nfrom ..id_type import BaseGlobalIDType, SimpleGlobalIDType, UUIDGlobalIDType\nfrom ..node import Node\nfrom ...types import Int, ObjectType, Schema, String\n\n\nclass TestUUIDGlobalID:\n    def setup_method(self):\n        self.user_list = [\n            {\"id\": uuid4(), \"name\": \"First\"},\n            {\"id\": uuid4(), \"name\": \"Second\"},\n            {\"id\": uuid4(), \"name\": \"Third\"},\n            {\"id\": uuid4(), \"name\": \"Fourth\"},\n        ]\n        self.users = {user[\"id\"]: user for user in self.user_list}\n\n        class CustomNode(Node):\n            class Meta:\n                global_id_type = UUIDGlobalIDType\n\n        class User(ObjectType):\n            class Meta:\n                interfaces = [CustomNode]\n\n            name = String()\n\n            @classmethod\n            def get_node(cls, _type, _id):\n                return self.users[_id]\n\n        class RootQuery(ObjectType):\n            user = CustomNode.Field(User)\n\n        self.schema = Schema(query=RootQuery, types=[User])\n        self.graphql_schema = self.schema.graphql_schema\n\n    def test_str_schema_correct(self):\n        \"\"\"\n        Check that the schema has the expected and custom node interface and user type and that they both use UUIDs\n        \"\"\"\n        parsed = re.findall(r\"(.+) \\{\\n\\s*([\\w\\W]*?)\\n\\}\", str(self.schema))\n        types = [t for t, f in parsed]\n        fields = [f for t, f in parsed]\n        custom_node_interface = \"interface CustomNode\"\n        assert custom_node_interface in types\n        assert (\n            '\"\"\"The ID of the object\"\"\"\\n  id: UUID!'\n            == fields[types.index(custom_node_interface)]\n        )\n        user_type = \"type User implements CustomNode\"\n        assert user_type in types\n        assert (\n            '\"\"\"The ID of the object\"\"\"\\n  id: UUID!\\n  name: String'\n            == fields[types.index(user_type)]\n        )\n\n    def test_get_by_id(self):\n        query = \"\"\"query userById($id: UUID!) {\n            user(id: $id) {\n                id\n                name\n            }\n        }\"\"\"\n        # UUID need to be converted to string for serialization\n        result = graphql_sync(\n            self.graphql_schema,\n            query,\n            variable_values={\"id\": str(self.user_list[0][\"id\"])},\n        )\n        assert not result.errors\n        assert result.data[\"user\"][\"id\"] == str(self.user_list[0][\"id\"])\n        assert result.data[\"user\"][\"name\"] == self.user_list[0][\"name\"]\n\n\nclass TestSimpleGlobalID:\n    def setup_method(self):\n        self.user_list = [\n            {\"id\": \"my global primary key in clear 1\", \"name\": \"First\"},\n            {\"id\": \"my global primary key in clear 2\", \"name\": \"Second\"},\n            {\"id\": \"my global primary key in clear 3\", \"name\": \"Third\"},\n            {\"id\": \"my global primary key in clear 4\", \"name\": \"Fourth\"},\n        ]\n        self.users = {user[\"id\"]: user for user in self.user_list}\n\n        class CustomNode(Node):\n            class Meta:\n                global_id_type = SimpleGlobalIDType\n\n        class User(ObjectType):\n            class Meta:\n                interfaces = [CustomNode]\n\n            name = String()\n\n            @classmethod\n            def get_node(cls, _type, _id):\n                return self.users[_id]\n\n        class RootQuery(ObjectType):\n            user = CustomNode.Field(User)\n\n        self.schema = Schema(query=RootQuery, types=[User])\n        self.graphql_schema = self.schema.graphql_schema\n\n    def test_str_schema_correct(self):\n        \"\"\"\n        Check that the schema has the expected and custom node interface and user type and that they both use UUIDs\n        \"\"\"\n        parsed = re.findall(r\"(.+) \\{\\n\\s*([\\w\\W]*?)\\n\\}\", str(self.schema))\n        types = [t for t, f in parsed]\n        fields = [f for t, f in parsed]\n        custom_node_interface = \"interface CustomNode\"\n        assert custom_node_interface in types\n        assert (\n            '\"\"\"The ID of the object\"\"\"\\n  id: ID!'\n            == fields[types.index(custom_node_interface)]\n        )\n        user_type = \"type User implements CustomNode\"\n        assert user_type in types\n        assert (\n            '\"\"\"The ID of the object\"\"\"\\n  id: ID!\\n  name: String'\n            == fields[types.index(user_type)]\n        )\n\n    def test_get_by_id(self):\n        query = \"\"\"query {\n            user(id: \"my global primary key in clear 3\") {\n                id\n                name\n            }\n        }\"\"\"\n        result = graphql_sync(self.graphql_schema, query)\n        assert not result.errors\n        assert result.data[\"user\"][\"id\"] == self.user_list[2][\"id\"]\n        assert result.data[\"user\"][\"name\"] == self.user_list[2][\"name\"]\n\n\nclass TestCustomGlobalID:\n    def setup_method(self):\n        self.user_list = [\n            {\"id\": 1, \"name\": \"First\"},\n            {\"id\": 2, \"name\": \"Second\"},\n            {\"id\": 3, \"name\": \"Third\"},\n            {\"id\": 4, \"name\": \"Fourth\"},\n        ]\n        self.users = {user[\"id\"]: user for user in self.user_list}\n\n        class CustomGlobalIDType(BaseGlobalIDType):\n            \"\"\"\n            Global id that is simply and integer in clear.\n            \"\"\"\n\n            graphene_type = Int\n\n            @classmethod\n            def resolve_global_id(cls, info, global_id):\n                _type = info.return_type.graphene_type._meta.name\n                return _type, global_id\n\n            @classmethod\n            def to_global_id(cls, _type, _id):\n                return _id\n\n        class CustomNode(Node):\n            class Meta:\n                global_id_type = CustomGlobalIDType\n\n        class User(ObjectType):\n            class Meta:\n                interfaces = [CustomNode]\n\n            name = String()\n\n            @classmethod\n            def get_node(cls, _type, _id):\n                return self.users[_id]\n\n        class RootQuery(ObjectType):\n            user = CustomNode.Field(User)\n\n        self.schema = Schema(query=RootQuery, types=[User])\n        self.graphql_schema = self.schema.graphql_schema\n\n    def test_str_schema_correct(self):\n        \"\"\"\n        Check that the schema has the expected and custom node interface and user type and that they both use UUIDs\n        \"\"\"\n        parsed = re.findall(r\"(.+) \\{\\n\\s*([\\w\\W]*?)\\n\\}\", str(self.schema))\n        types = [t for t, f in parsed]\n        fields = [f for t, f in parsed]\n        custom_node_interface = \"interface CustomNode\"\n        assert custom_node_interface in types\n        assert (\n            '\"\"\"The ID of the object\"\"\"\\n  id: Int!'\n            == fields[types.index(custom_node_interface)]\n        )\n        user_type = \"type User implements CustomNode\"\n        assert user_type in types\n        assert (\n            '\"\"\"The ID of the object\"\"\"\\n  id: Int!\\n  name: String'\n            == fields[types.index(user_type)]\n        )\n\n    def test_get_by_id(self):\n        query = \"\"\"query {\n            user(id: 2) {\n                id\n                name\n            }\n        }\"\"\"\n        result = graphql_sync(self.graphql_schema, query)\n        assert not result.errors\n        assert result.data[\"user\"][\"id\"] == self.user_list[1][\"id\"]\n        assert result.data[\"user\"][\"name\"] == self.user_list[1][\"name\"]\n\n\nclass TestIncompleteCustomGlobalID:\n    def setup_method(self):\n        self.user_list = [\n            {\"id\": 1, \"name\": \"First\"},\n            {\"id\": 2, \"name\": \"Second\"},\n            {\"id\": 3, \"name\": \"Third\"},\n            {\"id\": 4, \"name\": \"Fourth\"},\n        ]\n        self.users = {user[\"id\"]: user for user in self.user_list}\n\n    def test_must_define_to_global_id(self):\n        \"\"\"\n        Test that if the `to_global_id` method is not defined, we can query the object, but we can't request its ID.\n        \"\"\"\n\n        class CustomGlobalIDType(BaseGlobalIDType):\n            graphene_type = Int\n\n            @classmethod\n            def resolve_global_id(cls, info, global_id):\n                _type = info.return_type.graphene_type._meta.name\n                return _type, global_id\n\n        class CustomNode(Node):\n            class Meta:\n                global_id_type = CustomGlobalIDType\n\n        class User(ObjectType):\n            class Meta:\n                interfaces = [CustomNode]\n\n            name = String()\n\n            @classmethod\n            def get_node(cls, _type, _id):\n                return self.users[_id]\n\n        class RootQuery(ObjectType):\n            user = CustomNode.Field(User)\n\n        self.schema = Schema(query=RootQuery, types=[User])\n        self.graphql_schema = self.schema.graphql_schema\n\n        query = \"\"\"query {\n            user(id: 2) {\n                name\n            }\n        }\"\"\"\n        result = graphql_sync(self.graphql_schema, query)\n        assert not result.errors\n        assert result.data[\"user\"][\"name\"] == self.user_list[1][\"name\"]\n\n        query = \"\"\"query {\n            user(id: 2) {\n                id\n                name\n            }\n        }\"\"\"\n        result = graphql_sync(self.graphql_schema, query)\n        assert result.errors is not None\n        assert len(result.errors) == 1\n        assert result.errors[0].path == [\"user\", \"id\"]\n\n    def test_must_define_resolve_global_id(self):\n        \"\"\"\n        Test that if the `resolve_global_id` method is not defined, we can't query the object by ID.\n        \"\"\"\n\n        class CustomGlobalIDType(BaseGlobalIDType):\n            graphene_type = Int\n\n            @classmethod\n            def to_global_id(cls, _type, _id):\n                return _id\n\n        class CustomNode(Node):\n            class Meta:\n                global_id_type = CustomGlobalIDType\n\n        class User(ObjectType):\n            class Meta:\n                interfaces = [CustomNode]\n\n            name = String()\n\n            @classmethod\n            def get_node(cls, _type, _id):\n                return self.users[_id]\n\n        class RootQuery(ObjectType):\n            user = CustomNode.Field(User)\n\n        self.schema = Schema(query=RootQuery, types=[User])\n        self.graphql_schema = self.schema.graphql_schema\n\n        query = \"\"\"query {\n            user(id: 2) {\n                id\n                name\n            }\n        }\"\"\"\n        result = graphql_sync(self.graphql_schema, query)\n        assert result.errors is not None\n        assert len(result.errors) == 1\n        assert result.errors[0].path == [\"user\"]\n"
  },
  {
    "path": "graphene/relay/tests/test_global_id.py",
    "content": "from graphql_relay import to_global_id\n\nfrom ...types import ID, NonNull, ObjectType, String\nfrom ...types.definitions import GrapheneObjectType\nfrom ..node import GlobalID, Node\n\n\nclass CustomNode(Node):\n    class Meta:\n        name = \"Node\"\n\n\nclass User(ObjectType):\n    class Meta:\n        interfaces = [CustomNode]\n\n    name = String()\n\n\nclass Info:\n    def __init__(self, parent_type):\n        self.parent_type = GrapheneObjectType(\n            graphene_type=parent_type,\n            name=parent_type._meta.name,\n            description=parent_type._meta.description,\n            fields=None,\n            is_type_of=parent_type.is_type_of,\n            interfaces=None,\n        )\n\n\ndef test_global_id_defaults_to_required_and_node():\n    gid = GlobalID()\n    assert isinstance(gid.type, NonNull)\n    assert gid.type.of_type == ID\n    assert gid.node == Node\n\n\ndef test_global_id_allows_overriding_of_node_and_required():\n    gid = GlobalID(node=CustomNode, required=False)\n    assert gid.type == ID\n    assert gid.node == CustomNode\n\n\ndef test_global_id_defaults_to_info_parent_type():\n    my_id = \"1\"\n    gid = GlobalID()\n    id_resolver = gid.wrap_resolve(lambda *_: my_id)\n    my_global_id = id_resolver(None, Info(User))\n    assert my_global_id == to_global_id(User._meta.name, my_id)\n\n\ndef test_global_id_allows_setting_customer_parent_type():\n    my_id = \"1\"\n    gid = GlobalID(parent_type=User)\n    id_resolver = gid.wrap_resolve(lambda *_: my_id)\n    my_global_id = id_resolver(None, None)\n    assert my_global_id == to_global_id(User._meta.name, my_id)\n"
  },
  {
    "path": "graphene/relay/tests/test_mutation.py",
    "content": "from pytest import mark, raises\n\nfrom ...types import (\n    ID,\n    Argument,\n    Field,\n    InputField,\n    InputObjectType,\n    NonNull,\n    ObjectType,\n    Schema,\n)\nfrom ...types.scalars import String\nfrom ..mutation import ClientIDMutation\n\n\nclass SharedFields:\n    shared = String()\n\n\nclass MyNode(ObjectType):\n    # class Meta:\n    #     interfaces = (Node, )\n    id = ID()\n    name = String()\n\n\nclass SaySomething(ClientIDMutation):\n    class Input:\n        what = String()\n\n    phrase = String()\n\n    @staticmethod\n    def mutate_and_get_payload(self, info, what, client_mutation_id=None):\n        return SaySomething(phrase=str(what))\n\n\nclass FixedSaySomething:\n    __slots__ = (\"phrase\",)\n\n    def __init__(self, phrase):\n        self.phrase = phrase\n\n\nclass SaySomethingFixed(ClientIDMutation):\n    class Input:\n        what = String()\n\n    phrase = String()\n\n    @staticmethod\n    def mutate_and_get_payload(self, info, what, client_mutation_id=None):\n        return FixedSaySomething(phrase=str(what))\n\n\nclass SaySomethingAsync(ClientIDMutation):\n    class Input:\n        what = String()\n\n    phrase = String()\n\n    @staticmethod\n    async def mutate_and_get_payload(self, info, what, client_mutation_id=None):\n        return SaySomething(phrase=str(what))\n\n\n# MyEdge = MyNode.Connection.Edge\nclass MyEdge(ObjectType):\n    node = Field(MyNode)\n    cursor = String()\n\n\nclass OtherMutation(ClientIDMutation):\n    class Input(SharedFields):\n        additional_field = String()\n\n    name = String()\n    my_node_edge = Field(MyEdge)\n\n    @staticmethod\n    def mutate_and_get_payload(\n        self, info, shared=\"\", additional_field=\"\", client_mutation_id=None\n    ):\n        edge_type = MyEdge\n        return OtherMutation(\n            name=shared + additional_field,\n            my_node_edge=edge_type(cursor=\"1\", node=MyNode(name=\"name\")),\n        )\n\n\nclass RootQuery(ObjectType):\n    something = String()\n\n\nclass Mutation(ObjectType):\n    say = SaySomething.Field()\n    say_fixed = SaySomethingFixed.Field()\n    say_async = SaySomethingAsync.Field()\n    other = OtherMutation.Field()\n\n\nschema = Schema(query=RootQuery, mutation=Mutation)\n\n\ndef test_no_mutate_and_get_payload():\n    with raises(AssertionError) as excinfo:\n\n        class MyMutation(ClientIDMutation):\n            pass\n\n    assert (\n        \"MyMutation.mutate_and_get_payload method is required in a ClientIDMutation.\"\n        == str(excinfo.value)\n    )\n\n\ndef test_mutation():\n    fields = SaySomething._meta.fields\n    assert list(fields) == [\"phrase\", \"client_mutation_id\"]\n    assert SaySomething._meta.name == \"SaySomethingPayload\"\n    assert isinstance(fields[\"phrase\"], Field)\n    field = SaySomething.Field()\n    assert field.type == SaySomething\n    assert list(field.args) == [\"input\"]\n    assert isinstance(field.args[\"input\"], Argument)\n    assert isinstance(field.args[\"input\"].type, NonNull)\n    assert field.args[\"input\"].type.of_type == SaySomething.Input\n    assert isinstance(fields[\"client_mutation_id\"], Field)\n    assert fields[\"client_mutation_id\"].name == \"clientMutationId\"\n    assert fields[\"client_mutation_id\"].type == String\n\n\ndef test_mutation_input():\n    Input = SaySomething.Input\n    assert issubclass(Input, InputObjectType)\n    fields = Input._meta.fields\n    assert list(fields) == [\"what\", \"client_mutation_id\"]\n    assert isinstance(fields[\"what\"], InputField)\n    assert fields[\"what\"].type == String\n    assert isinstance(fields[\"client_mutation_id\"], InputField)\n    assert fields[\"client_mutation_id\"].type == String\n\n\ndef test_subclassed_mutation():\n    fields = OtherMutation._meta.fields\n    assert list(fields) == [\"name\", \"my_node_edge\", \"client_mutation_id\"]\n    assert isinstance(fields[\"name\"], Field)\n    field = OtherMutation.Field()\n    assert field.type == OtherMutation\n    assert list(field.args) == [\"input\"]\n    assert isinstance(field.args[\"input\"], Argument)\n    assert isinstance(field.args[\"input\"].type, NonNull)\n    assert field.args[\"input\"].type.of_type == OtherMutation.Input\n\n\ndef test_subclassed_mutation_input():\n    Input = OtherMutation.Input\n    assert issubclass(Input, InputObjectType)\n    fields = Input._meta.fields\n    assert list(fields) == [\"shared\", \"additional_field\", \"client_mutation_id\"]\n    assert isinstance(fields[\"shared\"], InputField)\n    assert fields[\"shared\"].type == String\n    assert isinstance(fields[\"additional_field\"], InputField)\n    assert fields[\"additional_field\"].type == String\n    assert isinstance(fields[\"client_mutation_id\"], InputField)\n    assert fields[\"client_mutation_id\"].type == String\n\n\ndef test_node_query():\n    executed = schema.execute(\n        'mutation a { say(input: {what:\"hello\", clientMutationId:\"1\"}) { phrase } }'\n    )\n    assert not executed.errors\n    assert executed.data == {\"say\": {\"phrase\": \"hello\"}}\n\n\ndef test_node_query_fixed():\n    executed = schema.execute(\n        'mutation a { sayFixed(input: {what:\"hello\", clientMutationId:\"1\"}) { phrase } }'\n    )\n    assert \"Cannot set client_mutation_id in the payload object\" in str(\n        executed.errors[0]\n    )\n\n\n@mark.asyncio\nasync def test_node_query_async():\n    executed = await schema.execute_async(\n        'mutation a { sayAsync(input: {what:\"hello\", clientMutationId:\"1\"}) { phrase } }'\n    )\n    assert not executed.errors\n    assert executed.data == {\"sayAsync\": {\"phrase\": \"hello\"}}\n\n\ndef test_edge_query():\n    executed = schema.execute(\n        'mutation a { other(input: {clientMutationId:\"1\"}) { clientMutationId, myNodeEdge { cursor node { name }} } }'\n    )\n    assert not executed.errors\n    assert dict(executed.data) == {\n        \"other\": {\n            \"clientMutationId\": \"1\",\n            \"myNodeEdge\": {\"cursor\": \"1\", \"node\": {\"name\": \"name\"}},\n        }\n    }\n"
  },
  {
    "path": "graphene/relay/tests/test_mutation_async.py",
    "content": "from pytest import mark\n\nfrom graphene.types import ID, Field, ObjectType, Schema\nfrom graphene.types.scalars import String\nfrom graphene.relay.mutation import ClientIDMutation\nfrom graphene.test import Client\n\n\nclass SharedFields(object):\n    shared = String()\n\n\nclass MyNode(ObjectType):\n    # class Meta:\n    #     interfaces = (Node, )\n    id = ID()\n    name = String()\n\n\nclass SaySomethingAsync(ClientIDMutation):\n    class Input:\n        what = String()\n\n    phrase = String()\n\n    @staticmethod\n    async def mutate_and_get_payload(self, info, what, client_mutation_id=None):\n        return SaySomethingAsync(phrase=str(what))\n\n\n# MyEdge = MyNode.Connection.Edge\nclass MyEdge(ObjectType):\n    node = Field(MyNode)\n    cursor = String()\n\n\nclass OtherMutation(ClientIDMutation):\n    class Input(SharedFields):\n        additional_field = String()\n\n    name = String()\n    my_node_edge = Field(MyEdge)\n\n    @staticmethod\n    def mutate_and_get_payload(\n        self, info, shared=\"\", additional_field=\"\", client_mutation_id=None\n    ):\n        edge_type = MyEdge\n        return OtherMutation(\n            name=shared + additional_field,\n            my_node_edge=edge_type(cursor=\"1\", node=MyNode(name=\"name\")),\n        )\n\n\nclass RootQuery(ObjectType):\n    something = String()\n\n\nclass Mutation(ObjectType):\n    say_promise = SaySomethingAsync.Field()\n    other = OtherMutation.Field()\n\n\nschema = Schema(query=RootQuery, mutation=Mutation)\nclient = Client(schema)\n\n\n@mark.asyncio\nasync def test_node_query_promise():\n    executed = await client.execute_async(\n        'mutation a { sayPromise(input: {what:\"hello\", clientMutationId:\"1\"}) { phrase } }'\n    )\n    assert isinstance(executed, dict)\n    assert \"errors\" not in executed\n    assert executed[\"data\"] == {\"sayPromise\": {\"phrase\": \"hello\"}}\n\n\n@mark.asyncio\nasync def test_edge_query():\n    executed = await client.execute_async(\n        'mutation a { other(input: {clientMutationId:\"1\"}) { clientMutationId, myNodeEdge { cursor node { name }} } }'\n    )\n    assert isinstance(executed, dict)\n    assert \"errors\" not in executed\n    assert executed[\"data\"] == {\n        \"other\": {\n            \"clientMutationId\": \"1\",\n            \"myNodeEdge\": {\"cursor\": \"1\", \"node\": {\"name\": \"name\"}},\n        }\n    }\n"
  },
  {
    "path": "graphene/relay/tests/test_node.py",
    "content": "import re\nfrom textwrap import dedent\n\nfrom graphql_relay import to_global_id\n\nfrom ...types import ObjectType, Schema, String\nfrom ..node import Node, is_node\n\n\nclass SharedNodeFields:\n    shared = String()\n    something_else = String()\n\n    def resolve_something_else(*_):\n        return \"----\"\n\n\nclass MyNode(ObjectType):\n    class Meta:\n        interfaces = (Node,)\n\n    name = String()\n\n    @staticmethod\n    def get_node(info, id):\n        return MyNode(name=str(id))\n\n\nclass MyOtherNode(SharedNodeFields, ObjectType):\n    extra_field = String()\n\n    class Meta:\n        interfaces = (Node,)\n\n    def resolve_extra_field(self, *_):\n        return \"extra field info.\"\n\n    @staticmethod\n    def get_node(info, id):\n        return MyOtherNode(shared=str(id))\n\n\nclass RootQuery(ObjectType):\n    first = String()\n    node = Node.Field()\n    only_node = Node.Field(MyNode)\n    only_node_lazy = Node.Field(lambda: MyNode)\n\n\nschema = Schema(query=RootQuery, types=[MyNode, MyOtherNode])\n\n\ndef test_node_good():\n    assert \"id\" in MyNode._meta.fields\n    assert is_node(MyNode)\n    assert not is_node(object)\n    assert not is_node(\"node\")\n\n\ndef test_node_query():\n    executed = schema.execute(\n        '{ node(id:\"%s\") { ... on MyNode { name } } }' % Node.to_global_id(\"MyNode\", 1)\n    )\n    assert not executed.errors\n    assert executed.data == {\"node\": {\"name\": \"1\"}}\n\n\ndef test_subclassed_node_query():\n    executed = schema.execute(\n        '{ node(id:\"%s\") { ... on MyOtherNode { shared, extraField, somethingElse } } }'\n        % to_global_id(\"MyOtherNode\", 1)\n    )\n    assert not executed.errors\n    assert executed.data == {\n        \"node\": {\n            \"shared\": \"1\",\n            \"extraField\": \"extra field info.\",\n            \"somethingElse\": \"----\",\n        }\n    }\n\n\ndef test_node_requesting_non_node():\n    executed = schema.execute(\n        '{ node(id:\"%s\") { __typename } } ' % Node.to_global_id(\"RootQuery\", 1)\n    )\n    assert executed.errors\n    assert re.match(\n        r\"ObjectType .* does not implement the .* interface.\",\n        executed.errors[0].message,\n    )\n    assert executed.data == {\"node\": None}\n\n\ndef test_node_requesting_unknown_type():\n    executed = schema.execute(\n        '{ node(id:\"%s\") { __typename } } ' % Node.to_global_id(\"UnknownType\", 1)\n    )\n    assert executed.errors\n    assert re.match(r\"Relay Node .* not found in schema\", executed.errors[0].message)\n    assert executed.data == {\"node\": None}\n\n\ndef test_node_query_incorrect_id():\n    executed = schema.execute(\n        '{ node(id:\"%s\") { ... on MyNode { name } } }' % \"something:2\"\n    )\n    assert executed.errors\n    assert re.match(r\"Unable to parse global ID .*\", executed.errors[0].message)\n    assert executed.data == {\"node\": None}\n\n\ndef test_node_field():\n    node_field = Node.Field()\n    assert node_field.type == Node\n    assert node_field.node_type == Node\n\n\ndef test_node_field_custom():\n    node_field = Node.Field(MyNode)\n    assert node_field.type == MyNode\n    assert node_field.node_type == Node\n\n\ndef test_node_field_args():\n    field_args = {\n        \"name\": \"my_custom_name\",\n        \"description\": \"my_custom_description\",\n        \"deprecation_reason\": \"my_custom_deprecation_reason\",\n    }\n    node_field = Node.Field(**field_args)\n    for field_arg, value in field_args.items():\n        assert getattr(node_field, field_arg) == value\n\n\ndef test_node_field_only_type():\n    executed = schema.execute(\n        '{ onlyNode(id:\"%s\") { __typename, name } } ' % Node.to_global_id(\"MyNode\", 1)\n    )\n    assert not executed.errors\n    assert executed.data == {\"onlyNode\": {\"__typename\": \"MyNode\", \"name\": \"1\"}}\n\n\ndef test_node_field_only_type_wrong():\n    executed = schema.execute(\n        '{ onlyNode(id:\"%s\") { __typename, name } } '\n        % Node.to_global_id(\"MyOtherNode\", 1)\n    )\n    assert len(executed.errors) == 1\n    assert str(executed.errors[0]).startswith(\"Must receive a MyNode id.\")\n    assert executed.data == {\"onlyNode\": None}\n\n\ndef test_node_field_only_lazy_type():\n    executed = schema.execute(\n        '{ onlyNodeLazy(id:\"%s\") { __typename, name } } '\n        % Node.to_global_id(\"MyNode\", 1)\n    )\n    assert not executed.errors\n    assert executed.data == {\"onlyNodeLazy\": {\"__typename\": \"MyNode\", \"name\": \"1\"}}\n\n\ndef test_node_field_only_lazy_type_wrong():\n    executed = schema.execute(\n        '{ onlyNodeLazy(id:\"%s\") { __typename, name } } '\n        % Node.to_global_id(\"MyOtherNode\", 1)\n    )\n    assert len(executed.errors) == 1\n    assert str(executed.errors[0]).startswith(\"Must receive a MyNode id.\")\n    assert executed.data == {\"onlyNodeLazy\": None}\n\n\ndef test_str_schema():\n    assert (\n        str(schema).strip()\n        == dedent(\n            '''\n        schema {\n          query: RootQuery\n        }\n\n        type MyNode implements Node {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n          name: String\n        }\n\n        \"\"\"An object with an ID\"\"\"\n        interface Node {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n        }\n\n        type MyOtherNode implements Node {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n          shared: String\n          somethingElse: String\n          extraField: String\n        }\n\n        type RootQuery {\n          first: String\n          node(\n            \"\"\"The ID of the object\"\"\"\n            id: ID!\n          ): Node\n          onlyNode(\n            \"\"\"The ID of the object\"\"\"\n            id: ID!\n          ): MyNode\n          onlyNodeLazy(\n            \"\"\"The ID of the object\"\"\"\n            id: ID!\n          ): MyNode\n        }\n        '''\n        ).strip()\n    )\n"
  },
  {
    "path": "graphene/relay/tests/test_node_custom.py",
    "content": "from textwrap import dedent\n\nfrom graphql import graphql_sync\n\nfrom ...types import Interface, ObjectType, Schema\nfrom ...types.scalars import Int, String\nfrom ..node import Node\n\n\nclass CustomNode(Node):\n    class Meta:\n        name = \"Node\"\n\n    @staticmethod\n    def to_global_id(type_, id):\n        return id\n\n    @staticmethod\n    def get_node_from_global_id(info, id, only_type=None):\n        assert info.schema is graphql_schema\n        if id in user_data:\n            return user_data.get(id)\n        else:\n            return photo_data.get(id)\n\n\nclass BasePhoto(Interface):\n    width = Int(description=\"The width of the photo in pixels\")\n\n\nclass User(ObjectType):\n    class Meta:\n        interfaces = [CustomNode]\n\n    name = String(description=\"The full name of the user\")\n\n\nclass Photo(ObjectType):\n    class Meta:\n        interfaces = [CustomNode, BasePhoto]\n\n\nuser_data = {\"1\": User(id=\"1\", name=\"John Doe\"), \"2\": User(id=\"2\", name=\"Jane Smith\")}\n\nphoto_data = {\"3\": Photo(id=\"3\", width=300), \"4\": Photo(id=\"4\", width=400)}\n\n\nclass RootQuery(ObjectType):\n    node = CustomNode.Field()\n\n\nschema = Schema(query=RootQuery, types=[User, Photo])\ngraphql_schema = schema.graphql_schema\n\n\ndef test_str_schema_correct():\n    assert (\n        str(schema).strip()\n        == dedent(\n            '''\n        schema {\n          query: RootQuery\n        }\n\n        type User implements Node {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n\n          \"\"\"The full name of the user\"\"\"\n          name: String\n        }\n\n        interface Node {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n        }\n\n        type Photo implements Node & BasePhoto {\n          \"\"\"The ID of the object\"\"\"\n          id: ID!\n\n          \"\"\"The width of the photo in pixels\"\"\"\n          width: Int\n        }\n\n        interface BasePhoto {\n          \"\"\"The width of the photo in pixels\"\"\"\n          width: Int\n        }\n\n        type RootQuery {\n          node(\n            \"\"\"The ID of the object\"\"\"\n            id: ID!\n          ): Node\n        }\n        '''\n        ).strip()\n    )\n\n\ndef test_gets_the_correct_id_for_users():\n    query = \"\"\"\n      {\n        node(id: \"1\") {\n          id\n        }\n      }\n    \"\"\"\n    expected = {\"node\": {\"id\": \"1\"}}\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_gets_the_correct_id_for_photos():\n    query = \"\"\"\n      {\n        node(id: \"4\") {\n          id\n        }\n      }\n    \"\"\"\n    expected = {\"node\": {\"id\": \"4\"}}\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_gets_the_correct_name_for_users():\n    query = \"\"\"\n      {\n        node(id: \"1\") {\n          id\n          ... on User {\n            name\n          }\n        }\n      }\n    \"\"\"\n    expected = {\"node\": {\"id\": \"1\", \"name\": \"John Doe\"}}\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_gets_the_correct_width_for_photos():\n    query = \"\"\"\n      {\n        node(id: \"4\") {\n          id\n          ... on Photo {\n            width\n          }\n        }\n      }\n    \"\"\"\n    expected = {\"node\": {\"id\": \"4\", \"width\": 400}}\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_gets_the_correct_typename_for_users():\n    query = \"\"\"\n      {\n        node(id: \"1\") {\n          id\n          __typename\n        }\n      }\n    \"\"\"\n    expected = {\"node\": {\"id\": \"1\", \"__typename\": \"User\"}}\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_gets_the_correct_typename_for_photos():\n    query = \"\"\"\n      {\n        node(id: \"4\") {\n          id\n          __typename\n        }\n      }\n    \"\"\"\n    expected = {\"node\": {\"id\": \"4\", \"__typename\": \"Photo\"}}\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_ignores_photo_fragments_on_user():\n    query = \"\"\"\n      {\n        node(id: \"1\") {\n          id\n          ... on Photo {\n            width\n          }\n        }\n      }\n    \"\"\"\n    expected = {\"node\": {\"id\": \"1\"}}\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_returns_null_for_bad_ids():\n    query = \"\"\"\n      {\n        node(id: \"5\") {\n          id\n        }\n      }\n    \"\"\"\n    expected = {\"node\": None}\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_have_correct_node_interface():\n    query = \"\"\"\n      {\n        __type(name: \"Node\") {\n          name\n          kind\n          fields {\n            name\n            type {\n              kind\n              ofType {\n                name\n                kind\n              }\n            }\n          }\n        }\n      }\n    \"\"\"\n    expected = {\n        \"__type\": {\n            \"name\": \"Node\",\n            \"kind\": \"INTERFACE\",\n            \"fields\": [\n                {\n                    \"name\": \"id\",\n                    \"type\": {\n                        \"kind\": \"NON_NULL\",\n                        \"ofType\": {\"name\": \"ID\", \"kind\": \"SCALAR\"},\n                    },\n                }\n            ],\n        }\n    }\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n\n\ndef test_has_correct_node_root_field():\n    query = \"\"\"\n      {\n        __schema {\n          queryType {\n            fields {\n              name\n              type {\n                name\n                kind\n              }\n              args {\n                name\n                type {\n                  kind\n                  ofType {\n                    name\n                    kind\n                  }\n                }\n              }\n            }\n          }\n        }\n      }\n    \"\"\"\n    expected = {\n        \"__schema\": {\n            \"queryType\": {\n                \"fields\": [\n                    {\n                        \"name\": \"node\",\n                        \"type\": {\"name\": \"Node\", \"kind\": \"INTERFACE\"},\n                        \"args\": [\n                            {\n                                \"name\": \"id\",\n                                \"type\": {\n                                    \"kind\": \"NON_NULL\",\n                                    \"ofType\": {\"name\": \"ID\", \"kind\": \"SCALAR\"},\n                                },\n                            }\n                        ],\n                    }\n                ]\n            }\n        }\n    }\n    result = graphql_sync(graphql_schema, query)\n    assert not result.errors\n    assert result.data == expected\n"
  },
  {
    "path": "graphene/test/__init__.py",
    "content": "from graphql.error import GraphQLError\n\nfrom graphene.types.schema import Schema\n\n\ndef default_format_error(error):\n    if isinstance(error, GraphQLError):\n        return error.formatted\n    return {\"message\": str(error)}\n\n\ndef format_execution_result(execution_result, format_error):\n    if execution_result:\n        response = {}\n        if execution_result.errors:\n            response[\"errors\"] = [format_error(e) for e in execution_result.errors]\n        response[\"data\"] = execution_result.data\n        return response\n\n\nclass Client:\n    def __init__(self, schema, format_error=None, **execute_options):\n        assert isinstance(schema, Schema)\n        self.schema = schema\n        self.execute_options = execute_options\n        self.format_error = format_error or default_format_error\n\n    def format_result(self, result):\n        return format_execution_result(result, self.format_error)\n\n    def execute(self, *args, **kwargs):\n        executed = self.schema.execute(*args, **dict(self.execute_options, **kwargs))\n        return self.format_result(executed)\n\n    async def execute_async(self, *args, **kwargs):\n        executed = await self.schema.execute_async(\n            *args, **dict(self.execute_options, **kwargs)\n        )\n        return self.format_result(executed)\n"
  },
  {
    "path": "graphene/tests/__init__.py",
    "content": ""
  },
  {
    "path": "graphene/tests/issues/__init__.py",
    "content": ""
  },
  {
    "path": "graphene/tests/issues/test_1293.py",
    "content": "# https://github.com/graphql-python/graphene/issues/1293\n\nfrom datetime import datetime, timezone\n\nimport graphene\nfrom graphql.utilities import print_schema\n\n\nclass Filters(graphene.InputObjectType):\n    datetime_after = graphene.DateTime(\n        required=False,\n        default_value=datetime.fromtimestamp(1434549820.776, timezone.utc),\n    )\n    datetime_before = graphene.DateTime(\n        required=False,\n        default_value=datetime.fromtimestamp(1444549820.776, timezone.utc),\n    )\n\n\nclass SetDatetime(graphene.Mutation):\n    class Arguments:\n        filters = Filters(required=True)\n\n    ok = graphene.Boolean()\n\n    def mutate(root, info, filters):\n        return SetDatetime(ok=True)\n\n\nclass Query(graphene.ObjectType):\n    goodbye = graphene.String()\n\n\nclass Mutations(graphene.ObjectType):\n    set_datetime = SetDatetime.Field()\n\n\ndef test_schema_printable_with_default_datetime_value():\n    schema = graphene.Schema(query=Query, mutation=Mutations)\n    schema_str = print_schema(schema.graphql_schema)\n    assert schema_str, \"empty schema printed\"\n"
  },
  {
    "path": "graphene/tests/issues/test_1394.py",
    "content": "from ...types import ObjectType, Schema, String, NonNull\n\n\nclass Query(ObjectType):\n    hello = String(input=NonNull(String))\n\n    def resolve_hello(self, info, input):\n        if input == \"nothing\":\n            return None\n        return f\"Hello {input}!\"\n\n\nschema = Schema(query=Query)\n\n\ndef test_required_input_provided():\n    \"\"\"\n    Test that a required argument works when provided.\n    \"\"\"\n    input_value = \"Potato\"\n    result = schema.execute('{ hello(input: \"%s\") }' % input_value)\n    assert not result.errors\n    assert result.data == {\"hello\": \"Hello Potato!\"}\n\n\ndef test_required_input_missing():\n    \"\"\"\n    Test that a required argument raised an error if not provided.\n    \"\"\"\n    result = schema.execute(\"{ hello }\")\n    assert result.errors\n    assert len(result.errors) == 1\n    assert (\n        result.errors[0].message\n        == \"Field 'hello' argument 'input' of type 'String!' is required, but it was not provided.\"\n    )\n"
  },
  {
    "path": "graphene/tests/issues/test_1419.py",
    "content": "import pytest\n\nfrom ...types.base64 import Base64\nfrom ...types.datetime import Date, DateTime\nfrom ...types.decimal import Decimal\nfrom ...types.generic import GenericScalar\nfrom ...types.json import JSONString\nfrom ...types.objecttype import ObjectType\nfrom ...types.scalars import ID, BigInt, Boolean, Float, Int, String\nfrom ...types.schema import Schema\nfrom ...types.uuid import UUID\n\n\n@pytest.mark.parametrize(\n    \"input_type,input_value\",\n    [\n        (Date, '\"2022-02-02\"'),\n        (GenericScalar, '\"foo\"'),\n        (Int, \"1\"),\n        (BigInt, \"12345678901234567890\"),\n        (Float, \"1.1\"),\n        (String, '\"foo\"'),\n        (Boolean, \"true\"),\n        (ID, \"1\"),\n        (DateTime, '\"2022-02-02T11:11:11\"'),\n        (UUID, '\"cbebbc62-758e-4f75-a890-bc73b5017d81\"'),\n        (Decimal, '\"1.1\"'),\n        (JSONString, '\"{\\\\\"key\\\\\":\\\\\"foo\\\\\",\\\\\"value\\\\\":\\\\\"bar\\\\\"}\"'),\n        (Base64, '\"Q2hlbG8gd29ycmxkCg==\"'),\n    ],\n)\ndef test_parse_literal_with_variables(input_type, input_value):\n    # input_b needs to be evaluated as literal while the variable dict for\n    # input_a is passed along.\n\n    class Query(ObjectType):\n        generic = GenericScalar(input_a=GenericScalar(), input_b=input_type())\n\n        def resolve_generic(self, info, input_a=None, input_b=None):\n            return input\n\n    schema = Schema(query=Query)\n\n    query = f\"\"\"\n        query Test($a: GenericScalar){{\n            generic(inputA: $a, inputB: {input_value})\n        }}\n    \"\"\"\n    result = schema.execute(\n        query,\n        variables={\"a\": \"bar\"},\n    )\n    assert not result.errors\n"
  },
  {
    "path": "graphene/tests/issues/test_313.py",
    "content": "# https://github.com/graphql-python/graphene/issues/313\n\nimport graphene\n\n\nclass Query(graphene.ObjectType):\n    rand = graphene.String()\n\n\nclass Success(graphene.ObjectType):\n    yeah = graphene.String()\n\n\nclass Error(graphene.ObjectType):\n    message = graphene.String()\n\n\nclass CreatePostResult(graphene.Union):\n    class Meta:\n        types = [Success, Error]\n\n\nclass CreatePost(graphene.Mutation):\n    class Arguments:\n        text = graphene.String(required=True)\n\n    result = graphene.Field(CreatePostResult)\n\n    def mutate(self, info, text):\n        result = Success(yeah=\"yeah\")\n\n        return CreatePost(result=result)\n\n\nclass Mutations(graphene.ObjectType):\n    create_post = CreatePost.Field()\n\n\n# tests.py\n\n\ndef test_create_post():\n    query_string = \"\"\"\n    mutation {\n      createPost(text: \"Try this out\") {\n        result {\n          __typename\n        }\n      }\n    }\n    \"\"\"\n\n    schema = graphene.Schema(query=Query, mutation=Mutations)\n    result = schema.execute(query_string)\n\n    assert not result.errors\n    assert result.data[\"createPost\"][\"result\"][\"__typename\"] == \"Success\"\n"
  },
  {
    "path": "graphene/tests/issues/test_356.py",
    "content": "# https://github.com/graphql-python/graphene/issues/356\n\nfrom pytest import raises\n\nimport graphene\nfrom graphene import relay\n\n\nclass SomeTypeOne(graphene.ObjectType):\n    pass\n\n\nclass SomeTypeTwo(graphene.ObjectType):\n    pass\n\n\nclass MyUnion(graphene.Union):\n    class Meta:\n        types = (SomeTypeOne, SomeTypeTwo)\n\n\ndef test_issue():\n    class Query(graphene.ObjectType):\n        things = relay.ConnectionField(MyUnion)\n\n    with raises(Exception) as exc_info:\n        graphene.Schema(query=Query)\n\n    assert str(exc_info.value) == (\n        \"Query fields cannot be resolved.\"\n        \" IterableConnectionField type has to be a subclass of Connection.\"\n        ' Received \"MyUnion\".'\n    )\n"
  },
  {
    "path": "graphene/tests/issues/test_425.py",
    "content": "# https://github.com/graphql-python/graphene/issues/425\n# Adapted for Graphene 2.0\n\nfrom graphene.types.enum import Enum, EnumOptions\nfrom graphene.types.inputobjecttype import InputObjectType\nfrom graphene.types.objecttype import ObjectType, ObjectTypeOptions\n\n\n# ObjectType\nclass SpecialOptions(ObjectTypeOptions):\n    other_attr = None\n\n\nclass SpecialObjectType(ObjectType):\n    @classmethod\n    def __init_subclass_with_meta__(cls, other_attr=\"default\", **options):\n        _meta = SpecialOptions(cls)\n        _meta.other_attr = other_attr\n        super(SpecialObjectType, cls).__init_subclass_with_meta__(\n            _meta=_meta, **options\n        )\n\n\ndef test_special_objecttype_could_be_subclassed():\n    class MyType(SpecialObjectType):\n        class Meta:\n            other_attr = \"yeah!\"\n\n    assert MyType._meta.other_attr == \"yeah!\"\n\n\ndef test_special_objecttype_could_be_subclassed_default():\n    class MyType(SpecialObjectType):\n        pass\n\n    assert MyType._meta.other_attr == \"default\"\n\n\ndef test_special_objecttype_inherit_meta_options():\n    class MyType(SpecialObjectType):\n        pass\n\n    assert MyType._meta.name == \"MyType\"\n    assert MyType._meta.default_resolver is None\n    assert MyType._meta.interfaces == ()\n\n\n# InputObjectType\nclass SpecialInputObjectTypeOptions(ObjectTypeOptions):\n    other_attr = None\n\n\nclass SpecialInputObjectType(InputObjectType):\n    @classmethod\n    def __init_subclass_with_meta__(cls, other_attr=\"default\", **options):\n        _meta = SpecialInputObjectTypeOptions(cls)\n        _meta.other_attr = other_attr\n        super(SpecialInputObjectType, cls).__init_subclass_with_meta__(\n            _meta=_meta, **options\n        )\n\n\ndef test_special_inputobjecttype_could_be_subclassed():\n    class MyInputObjectType(SpecialInputObjectType):\n        class Meta:\n            other_attr = \"yeah!\"\n\n    assert MyInputObjectType._meta.other_attr == \"yeah!\"\n\n\ndef test_special_inputobjecttype_could_be_subclassed_default():\n    class MyInputObjectType(SpecialInputObjectType):\n        pass\n\n    assert MyInputObjectType._meta.other_attr == \"default\"\n\n\ndef test_special_inputobjecttype_inherit_meta_options():\n    class MyInputObjectType(SpecialInputObjectType):\n        pass\n\n    assert MyInputObjectType._meta.name == \"MyInputObjectType\"\n\n\n# Enum\nclass SpecialEnumOptions(EnumOptions):\n    other_attr = None\n\n\nclass SpecialEnum(Enum):\n    @classmethod\n    def __init_subclass_with_meta__(cls, other_attr=\"default\", **options):\n        _meta = SpecialEnumOptions(cls)\n        _meta.other_attr = other_attr\n        super(SpecialEnum, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n\ndef test_special_enum_could_be_subclassed():\n    class MyEnum(SpecialEnum):\n        class Meta:\n            other_attr = \"yeah!\"\n\n    assert MyEnum._meta.other_attr == \"yeah!\"\n\n\ndef test_special_enum_could_be_subclassed_default():\n    class MyEnum(SpecialEnum):\n        pass\n\n    assert MyEnum._meta.other_attr == \"default\"\n\n\ndef test_special_enum_inherit_meta_options():\n    class MyEnum(SpecialEnum):\n        pass\n\n    assert MyEnum._meta.name == \"MyEnum\"\n"
  },
  {
    "path": "graphene/tests/issues/test_490.py",
    "content": "# https://github.com/graphql-python/graphene/issues/313\n\nimport graphene\n\n\nclass Query(graphene.ObjectType):\n    some_field = graphene.String(from_=graphene.String(name=\"from\"))\n\n    def resolve_some_field(self, info, from_=None):\n        return from_\n\n\ndef test_issue():\n    query_string = \"\"\"\n    query myQuery {\n      someField(from: \"Oh\")\n    }\n    \"\"\"\n\n    schema = graphene.Schema(query=Query)\n    result = schema.execute(query_string)\n\n    assert not result.errors\n    assert result.data[\"someField\"] == \"Oh\"\n"
  },
  {
    "path": "graphene/tests/issues/test_720.py",
    "content": "# https://github.com/graphql-python/graphene/issues/720\n# InputObjectTypes overwrite the \"fields\" attribute of the provided\n# _meta object, so even if dynamic fields are provided with a standard\n# InputObjectTypeOptions, they are ignored.\n\nimport graphene\n\n\nclass MyInputClass(graphene.InputObjectType):\n    @classmethod\n    def __init_subclass_with_meta__(\n        cls, container=None, _meta=None, fields=None, **options\n    ):\n        if _meta is None:\n            _meta = graphene.types.inputobjecttype.InputObjectTypeOptions(cls)\n        _meta.fields = fields\n        super(MyInputClass, cls).__init_subclass_with_meta__(\n            container=container, _meta=_meta, **options\n        )\n\n\nclass MyInput(MyInputClass):\n    class Meta:\n        fields = dict(x=graphene.Field(graphene.Int))\n\n\nclass Query(graphene.ObjectType):\n    myField = graphene.Field(graphene.String, input=graphene.Argument(MyInput))\n\n    def resolve_myField(parent, info, input):\n        return \"ok\"\n\n\ndef test_issue():\n    query_string = \"\"\"\n    query myQuery {\n      myField(input: {x: 1})\n    }\n    \"\"\"\n\n    schema = graphene.Schema(query=Query)\n    result = schema.execute(query_string)\n\n    assert not result.errors\n"
  },
  {
    "path": "graphene/tests/issues/test_881.py",
    "content": "import pickle\n\nfrom ...types.enum import Enum\n\n\nclass PickleEnum(Enum):\n    # is defined outside of test because pickle unable to dump class inside ot pytest function\n    A = \"a\"\n    B = 1\n\n\ndef test_enums_pickling():\n    a = PickleEnum.A\n    pickled = pickle.dumps(a)\n    restored = pickle.loads(pickled)\n    assert type(a) is type(restored)\n    assert a == restored\n    assert a.value == restored.value\n    assert a.name == restored.name\n\n    b = PickleEnum.B\n    pickled = pickle.dumps(b)\n    restored = pickle.loads(pickled)\n    assert type(a) is type(restored)\n    assert b == restored\n    assert b.value == restored.value\n    assert b.name == restored.name\n"
  },
  {
    "path": "graphene/tests/issues/test_956.py",
    "content": "import graphene\n\n\ndef test_issue():\n    options = {\"description\": \"This my enum\", \"deprecation_reason\": \"For the funs\"}\n    new_enum = graphene.Enum(\"MyEnum\", [(\"some\", \"data\")], **options)\n    assert new_enum._meta.description == options[\"description\"]\n    assert new_enum._meta.deprecation_reason == options[\"deprecation_reason\"]\n"
  },
  {
    "path": "graphene/types/__init__.py",
    "content": "from graphql import GraphQLResolveInfo as ResolveInfo\n\nfrom .argument import Argument\nfrom .base64 import Base64\nfrom .context import Context\nfrom .datetime import Date, DateTime, Time\nfrom .decimal import Decimal\nfrom .dynamic import Dynamic\nfrom .enum import Enum\nfrom .field import Field\nfrom .inputfield import InputField\nfrom .inputobjecttype import InputObjectType\nfrom .interface import Interface\nfrom .json import JSONString\nfrom .mutation import Mutation\nfrom .objecttype import ObjectType\nfrom .scalars import ID, BigInt, Boolean, Float, Int, Scalar, String\nfrom .schema import Schema\nfrom .structures import List, NonNull\nfrom .union import Union\nfrom .uuid import UUID\n\n__all__ = [\n    \"Argument\",\n    \"Base64\",\n    \"BigInt\",\n    \"Boolean\",\n    \"Context\",\n    \"Date\",\n    \"DateTime\",\n    \"Decimal\",\n    \"Dynamic\",\n    \"Enum\",\n    \"Field\",\n    \"Float\",\n    \"ID\",\n    \"InputField\",\n    \"InputObjectType\",\n    \"Int\",\n    \"Interface\",\n    \"JSONString\",\n    \"List\",\n    \"Mutation\",\n    \"NonNull\",\n    \"ObjectType\",\n    \"ResolveInfo\",\n    \"Scalar\",\n    \"Schema\",\n    \"String\",\n    \"Time\",\n    \"UUID\",\n    \"Union\",\n]\n"
  },
  {
    "path": "graphene/types/argument.py",
    "content": "from itertools import chain\nfrom graphql import Undefined\n\nfrom .dynamic import Dynamic\nfrom .mountedtype import MountedType\nfrom .structures import NonNull\nfrom .utils import get_type\n\n\nclass Argument(MountedType):\n    \"\"\"\n    Makes an Argument available on a Field in the GraphQL schema.\n\n    Arguments will be parsed and provided to resolver methods for fields as keyword arguments.\n\n    All ``arg`` and ``**extra_args`` for a ``graphene.Field`` are implicitly mounted as Argument\n    using the below parameters.\n\n    .. code:: python\n\n        from graphene import String, Boolean, Argument\n\n        age = String(\n            # Boolean implicitly mounted as Argument\n            dog_years=Boolean(description=\"convert to dog years\"),\n            # Boolean explicitly mounted as Argument\n            decades=Argument(Boolean, default_value=False),\n        )\n\n    args:\n        type (class for a graphene.UnmountedType): must be a class (not an instance) of an\n            unmounted graphene type (ex. scalar or object) which is used for the type of this\n            argument in the GraphQL schema.\n        required (optional, bool): indicates this argument as not null in the graphql schema. Same behavior\n            as graphene.NonNull. Default False.\n        name (optional, str): the name of the GraphQL argument. Defaults to parameter name.\n        description (optional, str): the description of the GraphQL argument in the schema.\n        default_value (optional, Any): The value to be provided if the user does not set this argument in\n            the operation.\n        deprecation_reason (optional, str): Setting this value indicates that the argument is\n            depreciated and may provide instruction or reason on how for clients to proceed. Cannot be\n            set if the argument is required (see spec).\n    \"\"\"\n\n    def __init__(\n        self,\n        type_,\n        default_value=Undefined,\n        deprecation_reason=None,\n        description=None,\n        name=None,\n        required=False,\n        _creation_counter=None,\n    ):\n        super(Argument, self).__init__(_creation_counter=_creation_counter)\n\n        if required:\n            assert (\n                deprecation_reason is None\n            ), f\"Argument {name} is required, cannot deprecate it.\"\n            type_ = NonNull(type_)\n\n        self.name = name\n        self._type = type_\n        self.default_value = default_value\n        self.description = description\n        self.deprecation_reason = deprecation_reason\n\n    @property\n    def type(self):\n        return get_type(self._type)\n\n    def __eq__(self, other):\n        return isinstance(other, Argument) and (\n            self.name == other.name\n            and self.type == other.type\n            and self.default_value == other.default_value\n            and self.description == other.description\n            and self.deprecation_reason == other.deprecation_reason\n        )\n\n\ndef to_arguments(args, extra_args=None):\n    from .unmountedtype import UnmountedType\n    from .field import Field\n    from .inputfield import InputField\n\n    if extra_args:\n        extra_args = sorted(extra_args.items(), key=lambda f: f[1])\n    else:\n        extra_args = []\n    iter_arguments = chain(args.items(), extra_args)\n    arguments = {}\n    for default_name, arg in iter_arguments:\n        if isinstance(arg, Dynamic):\n            arg = arg.get_type()\n            if arg is None:\n                # If the Dynamic type returned None\n                # then we skip the Argument\n                continue\n\n        if isinstance(arg, UnmountedType):\n            arg = Argument.mounted(arg)\n\n        if isinstance(arg, (InputField, Field)):\n            raise ValueError(\n                f\"Expected {default_name} to be Argument, \"\n                f\"but received {type(arg).__name__}. Try using Argument({arg.type}).\"\n            )\n\n        if not isinstance(arg, Argument):\n            raise ValueError(f'Unknown argument \"{default_name}\".')\n\n        arg_name = default_name or arg.name\n        assert (\n            arg_name not in arguments\n        ), f'More than one Argument have same name \"{arg_name}\".'\n        arguments[arg_name] = arg\n\n    return arguments\n"
  },
  {
    "path": "graphene/types/base.py",
    "content": "from typing import Type, Optional\n\nfrom ..utils.subclass_with_meta import SubclassWithMeta, SubclassWithMeta_Meta\nfrom ..utils.trim_docstring import trim_docstring\n\n\nclass BaseOptions:\n    name: Optional[str] = None\n    description: Optional[str] = None\n\n    _frozen: bool = False\n\n    def __init__(self, class_type: Type):\n        self.class_type: Type = class_type\n\n    def freeze(self):\n        self._frozen = True\n\n    def __setattr__(self, name, value):\n        if not self._frozen:\n            super(BaseOptions, self).__setattr__(name, value)\n        else:\n            raise Exception(f\"Can't modify frozen Options {self}\")\n\n    def __repr__(self):\n        return f\"<{self.__class__.__name__} name={repr(self.name)}>\"\n\n\nBaseTypeMeta = SubclassWithMeta_Meta\n\n\nclass BaseType(SubclassWithMeta):\n    @classmethod\n    def create_type(cls, class_name, **options):\n        return type(class_name, (cls,), {\"Meta\": options})\n\n    @classmethod\n    def __init_subclass_with_meta__(\n        cls, name=None, description=None, _meta=None, **_kwargs\n    ):\n        assert \"_meta\" not in cls.__dict__, \"Can't assign meta directly\"\n        if not _meta:\n            return\n        _meta.name = name or cls.__name__\n        _meta.description = description or trim_docstring(cls.__doc__)\n        _meta.freeze()\n        cls._meta = _meta\n        super(BaseType, cls).__init_subclass_with_meta__()\n"
  },
  {
    "path": "graphene/types/base64.py",
    "content": "from binascii import Error as _Error\nfrom base64 import b64decode, b64encode\n\nfrom graphql.error import GraphQLError\nfrom graphql.language import StringValueNode, print_ast\n\nfrom .scalars import Scalar\n\n\nclass Base64(Scalar):\n    \"\"\"\n    The `Base64` scalar type represents a base64-encoded String.\n    \"\"\"\n\n    @staticmethod\n    def serialize(value):\n        if not isinstance(value, bytes):\n            if isinstance(value, str):\n                value = value.encode(\"utf-8\")\n            else:\n                value = str(value).encode(\"utf-8\")\n        return b64encode(value).decode(\"utf-8\")\n\n    @classmethod\n    def parse_literal(cls, node, _variables=None):\n        if not isinstance(node, StringValueNode):\n            raise GraphQLError(\n                f\"Base64 cannot represent non-string value: {print_ast(node)}\"\n            )\n        return cls.parse_value(node.value)\n\n    @staticmethod\n    def parse_value(value):\n        if not isinstance(value, bytes):\n            if not isinstance(value, str):\n                raise GraphQLError(\n                    f\"Base64 cannot represent non-string value: {repr(value)}\"\n                )\n            value = value.encode(\"utf-8\")\n        try:\n            return b64decode(value, validate=True).decode(\"utf-8\")\n        except _Error:\n            raise GraphQLError(f\"Base64 cannot decode value: {repr(value)}\")\n"
  },
  {
    "path": "graphene/types/context.py",
    "content": "class Context:\n    \"\"\"\n    Context can be used to make a convenient container for attributes to provide\n    for execution for resolvers of a GraphQL operation like a query.\n\n    .. code:: python\n\n        from graphene import Context\n\n        context = Context(loaders=build_dataloaders(), request=my_web_request)\n        schema.execute('{ hello(name: \"world\") }', context=context)\n\n        def resolve_hello(parent, info, name):\n            info.context.request  # value set in Context\n            info.context.loaders  # value set in Context\n            # ...\n\n    args:\n        **params (Dict[str, Any]): values to make available on Context instance as attributes.\n\n    \"\"\"\n\n    def __init__(self, **params):\n        for key, value in params.items():\n            setattr(self, key, value)\n"
  },
  {
    "path": "graphene/types/datetime.py",
    "content": "import datetime\n\nfrom dateutil.parser import isoparse\n\nfrom graphql.error import GraphQLError\nfrom graphql.language import StringValueNode, print_ast\n\nfrom .scalars import Scalar\n\n\nclass Date(Scalar):\n    \"\"\"\n    The `Date` scalar type represents a Date\n    value as specified by\n    [iso8601](https://en.wikipedia.org/wiki/ISO_8601).\n    \"\"\"\n\n    @staticmethod\n    def serialize(date):\n        if isinstance(date, datetime.datetime):\n            date = date.date()\n        if not isinstance(date, datetime.date):\n            raise GraphQLError(f\"Date cannot represent value: {repr(date)}\")\n        return date.isoformat()\n\n    @classmethod\n    def parse_literal(cls, node, _variables=None):\n        if not isinstance(node, StringValueNode):\n            raise GraphQLError(\n                f\"Date cannot represent non-string value: {print_ast(node)}\"\n            )\n        return cls.parse_value(node.value)\n\n    @staticmethod\n    def parse_value(value):\n        if isinstance(value, datetime.date):\n            return value\n        if not isinstance(value, str):\n            raise GraphQLError(f\"Date cannot represent non-string value: {repr(value)}\")\n        try:\n            return datetime.date.fromisoformat(value)\n        except ValueError:\n            raise GraphQLError(f\"Date cannot represent value: {repr(value)}\")\n\n\nclass DateTime(Scalar):\n    \"\"\"\n    The `DateTime` scalar type represents a DateTime\n    value as specified by\n    [iso8601](https://en.wikipedia.org/wiki/ISO_8601).\n    \"\"\"\n\n    @staticmethod\n    def serialize(dt):\n        if not isinstance(dt, (datetime.datetime, datetime.date)):\n            raise GraphQLError(f\"DateTime cannot represent value: {repr(dt)}\")\n        return dt.isoformat()\n\n    @classmethod\n    def parse_literal(cls, node, _variables=None):\n        if not isinstance(node, StringValueNode):\n            raise GraphQLError(\n                f\"DateTime cannot represent non-string value: {print_ast(node)}\"\n            )\n        return cls.parse_value(node.value)\n\n    @staticmethod\n    def parse_value(value):\n        if isinstance(value, datetime.datetime):\n            return value\n        if not isinstance(value, str):\n            raise GraphQLError(\n                f\"DateTime cannot represent non-string value: {repr(value)}\"\n            )\n        try:\n            return isoparse(value)\n        except ValueError:\n            raise GraphQLError(f\"DateTime cannot represent value: {repr(value)}\")\n\n\nclass Time(Scalar):\n    \"\"\"\n    The `Time` scalar type represents a Time value as\n    specified by\n    [iso8601](https://en.wikipedia.org/wiki/ISO_8601).\n    \"\"\"\n\n    @staticmethod\n    def serialize(time):\n        if not isinstance(time, datetime.time):\n            raise GraphQLError(f\"Time cannot represent value: {repr(time)}\")\n        return time.isoformat()\n\n    @classmethod\n    def parse_literal(cls, node, _variables=None):\n        if not isinstance(node, StringValueNode):\n            raise GraphQLError(\n                f\"Time cannot represent non-string value: {print_ast(node)}\"\n            )\n        return cls.parse_value(node.value)\n\n    @classmethod\n    def parse_value(cls, value):\n        if isinstance(value, datetime.time):\n            return value\n        if not isinstance(value, str):\n            raise GraphQLError(f\"Time cannot represent non-string value: {repr(value)}\")\n        try:\n            return datetime.time.fromisoformat(value)\n        except ValueError:\n            raise GraphQLError(f\"Time cannot represent value: {repr(value)}\")\n"
  },
  {
    "path": "graphene/types/decimal.py",
    "content": "from decimal import Decimal as _Decimal\n\nfrom graphql import Undefined\nfrom graphql.language.ast import StringValueNode, IntValueNode\n\nfrom .scalars import Scalar\n\n\nclass Decimal(Scalar):\n    \"\"\"\n    The `Decimal` scalar type represents a python Decimal.\n    \"\"\"\n\n    @staticmethod\n    def serialize(dec):\n        if isinstance(dec, str):\n            dec = _Decimal(dec)\n        assert isinstance(\n            dec, _Decimal\n        ), f'Received not compatible Decimal \"{repr(dec)}\"'\n        return str(dec)\n\n    @classmethod\n    def parse_literal(cls, node, _variables=None):\n        if isinstance(node, (StringValueNode, IntValueNode)):\n            return cls.parse_value(node.value)\n        return Undefined\n\n    @staticmethod\n    def parse_value(value):\n        try:\n            return _Decimal(value)\n        except Exception:\n            return Undefined\n"
  },
  {
    "path": "graphene/types/definitions.py",
    "content": "from enum import Enum as PyEnum\n\nfrom graphql import (\n    GraphQLEnumType,\n    GraphQLInputObjectType,\n    GraphQLInterfaceType,\n    GraphQLObjectType,\n    GraphQLScalarType,\n    GraphQLUnionType,\n)\n\n\nclass GrapheneGraphQLType:\n    \"\"\"\n    A class for extending the base GraphQLType with the related\n    graphene_type\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self.graphene_type = kwargs.pop(\"graphene_type\")\n        super(GrapheneGraphQLType, self).__init__(*args, **kwargs)\n\n    def __copy__(self):\n        result = GrapheneGraphQLType(graphene_type=self.graphene_type)\n        result.__dict__.update(self.__dict__)\n        return result\n\n\nclass GrapheneInterfaceType(GrapheneGraphQLType, GraphQLInterfaceType):\n    pass\n\n\nclass GrapheneUnionType(GrapheneGraphQLType, GraphQLUnionType):\n    pass\n\n\nclass GrapheneObjectType(GrapheneGraphQLType, GraphQLObjectType):\n    pass\n\n\nclass GrapheneScalarType(GrapheneGraphQLType, GraphQLScalarType):\n    pass\n\n\nclass GrapheneEnumType(GrapheneGraphQLType, GraphQLEnumType):\n    def serialize(self, value):\n        if not isinstance(value, PyEnum):\n            enum = self.graphene_type._meta.enum\n            try:\n                # Try and get enum by value\n                value = enum(value)\n            except ValueError:\n                # Try and get enum by name\n                try:\n                    value = enum[value]\n                except KeyError:\n                    pass\n        return super(GrapheneEnumType, self).serialize(value)\n\n\nclass GrapheneInputObjectType(GrapheneGraphQLType, GraphQLInputObjectType):\n    pass\n"
  },
  {
    "path": "graphene/types/dynamic.py",
    "content": "import inspect\nfrom functools import partial\n\nfrom .mountedtype import MountedType\n\n\nclass Dynamic(MountedType):\n    \"\"\"\n    A Dynamic Type let us get the type in runtime when we generate\n    the schema. So we can have lazy fields.\n    \"\"\"\n\n    def __init__(self, type_, with_schema=False, _creation_counter=None):\n        super(Dynamic, self).__init__(_creation_counter=_creation_counter)\n        assert inspect.isfunction(type_) or isinstance(type_, partial)\n        self.type = type_\n        self.with_schema = with_schema\n\n    def get_type(self, schema=None):\n        if schema and self.with_schema:\n            return self.type(schema=schema)\n        return self.type()\n"
  },
  {
    "path": "graphene/types/enum.py",
    "content": "from enum import Enum as PyEnum\n\nfrom graphene.utils.subclass_with_meta import SubclassWithMeta_Meta\n\nfrom .base import BaseOptions, BaseType\nfrom .unmountedtype import UnmountedType\n\n\ndef eq_enum(self, other):\n    if isinstance(other, self.__class__):\n        return self is other\n    return self.value is other\n\n\ndef hash_enum(self):\n    return hash(self.name)\n\n\nEnumType = type(PyEnum)\n\n\nclass EnumOptions(BaseOptions):\n    enum = None  # type: Enum\n    deprecation_reason = None\n\n\nclass EnumMeta(SubclassWithMeta_Meta):\n    def __new__(cls, name_, bases, classdict, **options):\n        enum_members = dict(classdict, __eq__=eq_enum, __hash__=hash_enum)\n        # We remove the Meta attribute from the class to not collide\n        # with the enum values.\n        enum_members.pop(\"Meta\", None)\n        enum = PyEnum(cls.__name__, enum_members)\n        obj = SubclassWithMeta_Meta.__new__(\n            cls, name_, bases, dict(classdict, __enum__=enum), **options\n        )\n        globals()[name_] = obj.__enum__\n        return obj\n\n    def get(cls, value):\n        return cls._meta.enum(value)\n\n    def __getitem__(cls, value):\n        return cls._meta.enum[value]\n\n    def __prepare__(name, bases, **kwargs):  # noqa: N805\n        return {}\n\n    def __call__(cls, *args, **kwargs):  # noqa: N805\n        if cls is Enum:\n            description = kwargs.pop(\"description\", None)\n            deprecation_reason = kwargs.pop(\"deprecation_reason\", None)\n            return cls.from_enum(\n                PyEnum(*args, **kwargs),\n                description=description,\n                deprecation_reason=deprecation_reason,\n            )\n        return super(EnumMeta, cls).__call__(*args, **kwargs)\n        # return cls._meta.enum(*args, **kwargs)\n\n    def __iter__(cls):\n        return cls._meta.enum.__iter__()\n\n    def from_enum(cls, enum, name=None, description=None, deprecation_reason=None):  # noqa: N805\n        name = name or enum.__name__\n        description = description or enum.__doc__ or \"An enumeration.\"\n        meta_dict = {\n            \"enum\": enum,\n            \"description\": description,\n            \"deprecation_reason\": deprecation_reason,\n        }\n        meta_class = type(\"Meta\", (object,), meta_dict)\n        return type(name, (Enum,), {\"Meta\": meta_class})\n\n\nclass Enum(UnmountedType, BaseType, metaclass=EnumMeta):\n    \"\"\"\n    Enum type definition\n\n    Defines a static set of values that can be provided as a Field, Argument or InputField.\n\n    .. code:: python\n\n        from graphene import Enum\n\n        class NameFormat(Enum):\n            FIRST_LAST = \"first_last\"\n            LAST_FIRST = \"last_first\"\n\n    Meta:\n        enum (optional, Enum): Python enum to use as a base for GraphQL Enum.\n\n        name (optional, str): Name of the GraphQL type (must be unique in schema). Defaults to class\n            name.\n        description (optional, str): Description of the GraphQL type in the schema. Defaults to class\n            docstring.\n        deprecation_reason (optional, str): Setting this value indicates that the enum is\n            depreciated and may provide instruction or reason on how for clients to proceed.\n    \"\"\"\n\n    @classmethod\n    def __init_subclass_with_meta__(cls, enum=None, _meta=None, **options):\n        if not _meta:\n            _meta = EnumOptions(cls)\n        _meta.enum = enum or cls.__enum__\n        _meta.deprecation_reason = options.pop(\"deprecation_reason\", None)\n        for key, value in _meta.enum.__members__.items():\n            setattr(cls, key, value)\n\n        super(Enum, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n    @classmethod\n    def get_type(cls):\n        \"\"\"\n        This function is called when the unmounted type (Enum instance)\n        is mounted (as a Field, InputField or Argument)\n        \"\"\"\n        return cls\n"
  },
  {
    "path": "graphene/types/field.py",
    "content": "import inspect\nfrom collections.abc import Mapping\nfrom functools import partial\n\nfrom .argument import Argument, to_arguments\nfrom .mountedtype import MountedType\nfrom .resolver import default_resolver\nfrom .structures import NonNull\nfrom .unmountedtype import UnmountedType\nfrom .utils import get_type\nfrom ..utils.deprecated import warn_deprecation\n\nbase_type = type\n\n\ndef source_resolver(source, root, info, **args):\n    resolved = default_resolver(source, None, root, info, **args)\n    if inspect.isfunction(resolved) or inspect.ismethod(resolved):\n        return resolved()\n    return resolved\n\n\nclass Field(MountedType):\n    \"\"\"\n    Makes a field available on an ObjectType in the GraphQL schema. Any type can be mounted as a\n    Field:\n\n    - Object Type\n    - Scalar Type\n    - Enum\n    - Interface\n    - Union\n\n    All class attributes of ``graphene.ObjectType`` are implicitly mounted as Field using the below\n    arguments.\n\n    .. code:: python\n\n        class Person(ObjectType):\n            first_name = graphene.String(required=True)                # implicitly mounted as Field\n            last_name = graphene.Field(String, description='Surname')  # explicitly mounted as Field\n\n    args:\n        type (class for a graphene.UnmountedType): Must be a class (not an instance) of an\n            unmounted graphene type (ex. scalar or object) which is used for the type of this\n            field in the GraphQL schema. You can provide a dotted module import path (string)\n            to the class instead of the class itself (e.g. to avoid circular import issues).\n        args (optional, Dict[str, graphene.Argument]): Arguments that can be input to the field.\n            Prefer to use ``**extra_args``, unless you use an argument name that clashes with one\n            of the Field arguments presented here (see :ref:`example<ResolverParamGraphQLArguments>`).\n        resolver (optional, Callable): A function to get the value for a Field from the parent\n            value object. If not set, the default resolver method for the schema is used.\n        source (optional, str): attribute name to resolve for this field from the parent value\n            object. Alternative to resolver (cannot set both source and resolver).\n        deprecation_reason (optional, str): Setting this value indicates that the field is\n            depreciated and may provide instruction or reason on how for clients to proceed.\n        required (optional, bool): indicates this field as not null in the graphql schema. Same behavior as\n            graphene.NonNull. Default False.\n        name (optional, str): the name of the GraphQL field (must be unique in a type). Defaults to attribute\n            name.\n        description (optional, str): the description of the GraphQL field in the schema.\n        default_value (optional, Any): Default value to resolve if none set from schema.\n        **extra_args (optional, Dict[str, Union[graphene.Argument, graphene.UnmountedType]): any\n            additional arguments to mount on the field.\n    \"\"\"\n\n    def __init__(\n        self,\n        type_,\n        args=None,\n        resolver=None,\n        source=None,\n        deprecation_reason=None,\n        name=None,\n        description=None,\n        required=False,\n        _creation_counter=None,\n        default_value=None,\n        **extra_args,\n    ):\n        super(Field, self).__init__(_creation_counter=_creation_counter)\n        assert not args or isinstance(\n            args, Mapping\n        ), f'Arguments in a field have to be a mapping, received \"{args}\".'\n        assert not (\n            source and resolver\n        ), \"A Field cannot have a source and a resolver in at the same time.\"\n        assert not callable(\n            default_value\n        ), f'The default value can not be a function but received \"{base_type(default_value)}\".'\n\n        if required:\n            type_ = NonNull(type_)\n\n        # Check if name is actually an argument of the field\n        if isinstance(name, (Argument, UnmountedType)):\n            extra_args[\"name\"] = name\n            name = None\n\n        # Check if source is actually an argument of the field\n        if isinstance(source, (Argument, UnmountedType)):\n            extra_args[\"source\"] = source\n            source = None\n\n        self.name = name\n        self._type = type_\n        self.args = to_arguments(args or {}, extra_args)\n        if source:\n            resolver = partial(source_resolver, source)\n        self.resolver = resolver\n        self.deprecation_reason = deprecation_reason\n        self.description = description\n        self.default_value = default_value\n\n    @property\n    def type(self):\n        return get_type(self._type)\n\n    get_resolver = None\n\n    def wrap_resolve(self, parent_resolver):\n        \"\"\"\n        Wraps a function resolver, using the ObjectType resolve_{FIELD_NAME}\n        (parent_resolver) if the Field definition has no resolver.\n        \"\"\"\n        if self.get_resolver is not None:\n            warn_deprecation(\n                \"The get_resolver method is being deprecated, please rename it to wrap_resolve.\"\n            )\n            return self.get_resolver(parent_resolver)\n\n        return self.resolver or parent_resolver\n\n    def wrap_subscribe(self, parent_subscribe):\n        \"\"\"\n        Wraps a function subscribe, using the ObjectType subscribe_{FIELD_NAME}\n        (parent_subscribe) if the Field definition has no subscribe.\n        \"\"\"\n        return parent_subscribe\n"
  },
  {
    "path": "graphene/types/generic.py",
    "content": "from graphql.language.ast import (\n    BooleanValueNode,\n    FloatValueNode,\n    IntValueNode,\n    ListValueNode,\n    ObjectValueNode,\n    StringValueNode,\n)\n\nfrom graphene.types.scalars import MAX_INT, MIN_INT\n\nfrom .scalars import Scalar\n\n\nclass GenericScalar(Scalar):\n    \"\"\"\n    The `GenericScalar` scalar type represents a generic\n    GraphQL scalar value that could be:\n    String, Boolean, Int, Float, List or Object.\n    \"\"\"\n\n    @staticmethod\n    def identity(value):\n        return value\n\n    serialize = identity\n    parse_value = identity\n\n    @staticmethod\n    def parse_literal(ast, _variables=None):\n        if isinstance(ast, (StringValueNode, BooleanValueNode)):\n            return ast.value\n        elif isinstance(ast, IntValueNode):\n            num = int(ast.value)\n            if MIN_INT <= num <= MAX_INT:\n                return num\n        elif isinstance(ast, FloatValueNode):\n            return float(ast.value)\n        elif isinstance(ast, ListValueNode):\n            return [GenericScalar.parse_literal(value) for value in ast.values]\n        elif isinstance(ast, ObjectValueNode):\n            return {\n                field.name.value: GenericScalar.parse_literal(field.value)\n                for field in ast.fields\n            }\n        else:\n            return None\n"
  },
  {
    "path": "graphene/types/inputfield.py",
    "content": "from graphql import Undefined\n\nfrom .mountedtype import MountedType\nfrom .structures import NonNull\nfrom .utils import get_type\n\n\nclass InputField(MountedType):\n    \"\"\"\n    Makes a field available on an ObjectType in the GraphQL schema. Any type can be mounted as a\n    Input Field except Interface and Union:\n\n    - Object Type\n    - Scalar Type\n    - Enum\n\n    Input object types also can't have arguments on their input fields, unlike regular ``graphene.Field``.\n\n    All class attributes of ``graphene.InputObjectType`` are implicitly mounted as InputField\n    using the below arguments.\n\n    .. code:: python\n\n        from graphene import InputObjectType, String, InputField\n\n        class Person(InputObjectType):\n            # implicitly mounted as Input Field\n            first_name = String(required=True)\n            # explicitly mounted as Input Field\n            last_name = InputField(String, description=\"Surname\")\n\n    args:\n        type (class for a graphene.UnmountedType): Must be a class (not an instance) of an\n            unmounted graphene type (ex. scalar or object) which is used for the type of this\n            field in the GraphQL schema.\n        name (optional, str): Name of the GraphQL input field (must be unique in a type).\n            Defaults to attribute name.\n        default_value (optional, Any): Default value to use as input if none set in user operation (\n            query, mutation, etc.).\n        deprecation_reason (optional, str): Setting this value indicates that the field is\n            depreciated and may provide instruction or reason on how for clients to proceed.\n        description (optional, str): Description of the GraphQL field in the schema.\n        required (optional, bool): Indicates this input field as not null in the graphql schema.\n            Raises a validation error if argument not provided. Same behavior as graphene.NonNull.\n            Default False.\n        **extra_args (optional, Dict): Not used.\n    \"\"\"\n\n    def __init__(\n        self,\n        type_,\n        name=None,\n        default_value=Undefined,\n        deprecation_reason=None,\n        description=None,\n        required=False,\n        _creation_counter=None,\n        **extra_args,\n    ):\n        super(InputField, self).__init__(_creation_counter=_creation_counter)\n        self.name = name\n        if required:\n            assert (\n                deprecation_reason is None\n            ), f\"InputField {name} is required, cannot deprecate it.\"\n            type_ = NonNull(type_)\n        self._type = type_\n        self.deprecation_reason = deprecation_reason\n        self.default_value = default_value\n        self.description = description\n\n    @property\n    def type(self):\n        return get_type(self._type)\n"
  },
  {
    "path": "graphene/types/inputobjecttype.py",
    "content": "from typing import TYPE_CHECKING\n\nfrom .base import BaseOptions, BaseType\nfrom .inputfield import InputField\nfrom .unmountedtype import UnmountedType\nfrom .utils import yank_fields_from_attrs\n\n# For static type checking with type checker\nif TYPE_CHECKING:\n    from typing import Dict, Callable  # NOQA\n\n\nclass InputObjectTypeOptions(BaseOptions):\n    fields = None  # type: Dict[str, InputField]\n    container = None  # type: InputObjectTypeContainer\n\n\n# Currently in Graphene, we get a `None` whenever we access an (optional) field that was not set in an InputObjectType\n# using the InputObjectType.<attribute> dot access syntax. This is ambiguous, because in this current (Graphene\n# historical) arrangement, we cannot distinguish between a field not being set and a field being set to None.\n# At the same time, we shouldn't break existing code that expects a `None` when accessing a field that was not set.\n_INPUT_OBJECT_TYPE_DEFAULT_VALUE = None\n\n# To mitigate this, we provide the function `set_input_object_type_default_value` to allow users to change the default\n# value returned in non-specified fields in InputObjectType to another meaningful sentinel value (e.g. Undefined)\n# if they want to. This way, we can keep code that expects a `None` working while we figure out a better solution (or\n# a well-documented breaking change) for this issue.\n\n\ndef set_input_object_type_default_value(default_value):\n    \"\"\"\n    Change the sentinel value returned by non-specified fields in an InputObjectType\n    Useful to differentiate between a field not being set and a field being set to None by using a sentinel value\n    (e.g. Undefined is a good sentinel value for this purpose)\n\n    This function should be called at the beginning of the app or in some other place where it is guaranteed to\n    be called before any InputObjectType is defined.\n    \"\"\"\n    global _INPUT_OBJECT_TYPE_DEFAULT_VALUE\n    _INPUT_OBJECT_TYPE_DEFAULT_VALUE = default_value\n\n\nclass InputObjectTypeContainer(dict, BaseType):  # type: ignore\n    class Meta:\n        abstract = True\n\n    def __init__(self, *args, **kwargs):\n        dict.__init__(self, *args, **kwargs)\n        for key in self._meta.fields:\n            setattr(self, key, self.get(key, _INPUT_OBJECT_TYPE_DEFAULT_VALUE))\n\n    def __init_subclass__(cls, *args, **kwargs):\n        pass\n\n\nclass InputObjectType(UnmountedType, BaseType):\n    \"\"\"\n    Input Object Type Definition\n\n    An input object defines a structured collection of fields which may be\n    supplied to a field argument.\n\n    Using ``graphene.NonNull`` will ensure that a input value must be provided by the query.\n\n    All class attributes of ``graphene.InputObjectType`` are implicitly mounted as InputField\n    using the below Meta class options.\n\n    .. code:: python\n\n        from graphene import InputObjectType, String, InputField\n\n        class Person(InputObjectType):\n            # implicitly mounted as Input Field\n            first_name = String(required=True)\n            # explicitly mounted as Input Field\n            last_name = InputField(String, description=\"Surname\")\n\n    The fields on an input object type can themselves refer to input object types, but you can't\n    mix input and output types in your schema.\n\n    Meta class options (optional):\n        name (str): the name of the GraphQL type (must be unique in schema). Defaults to class\n            name.\n        description (str): the description of the GraphQL type in the schema. Defaults to class\n            docstring.\n        container (class): A class reference for a value object that allows for\n            attribute initialization and access. Default InputObjectTypeContainer.\n        fields (Dict[str, graphene.InputField]): Dictionary of field name to InputField. Not\n            recommended to use (prefer class attributes).\n    \"\"\"\n\n    @classmethod\n    def __init_subclass_with_meta__(cls, container=None, _meta=None, **options):\n        if not _meta:\n            _meta = InputObjectTypeOptions(cls)\n\n        fields = {}\n        for base in reversed(cls.__mro__):\n            fields.update(yank_fields_from_attrs(base.__dict__, _as=InputField))\n\n        if _meta.fields:\n            _meta.fields.update(fields)\n        else:\n            _meta.fields = fields\n        if container is None:\n            container = type(cls.__name__, (InputObjectTypeContainer, cls), {})\n        _meta.container = container\n        super(InputObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n    @classmethod\n    def get_type(cls):\n        \"\"\"\n        This function is called when the unmounted type (InputObjectType instance)\n        is mounted (as a Field, InputField or Argument)\n        \"\"\"\n        return cls\n"
  },
  {
    "path": "graphene/types/interface.py",
    "content": "from typing import TYPE_CHECKING\n\nfrom .base import BaseOptions, BaseType\nfrom .field import Field\nfrom .utils import yank_fields_from_attrs\n\n# For static type checking with type checker\nif TYPE_CHECKING:\n    from typing import Dict, Iterable, Type  # NOQA\n\n\nclass InterfaceOptions(BaseOptions):\n    fields = None  # type: Dict[str, Field]\n    interfaces = ()  # type: Iterable[Type[Interface]]\n\n\nclass Interface(BaseType):\n    \"\"\"\n    Interface Type Definition\n\n    When a field can return one of a heterogeneous set of types, a Interface type\n    is used to describe what types are possible, what fields are in common across\n    all types, as well as a function to determine which type is actually used\n    when the field is resolved.\n\n    .. code:: python\n\n        from graphene import Interface, String\n\n        class HasAddress(Interface):\n            class Meta:\n                description = \"Address fields\"\n\n            address1 = String()\n            address2 = String()\n\n    If a field returns an Interface Type, the ambiguous type of the object can be determined using\n    ``resolve_type`` on Interface and an ObjectType with ``Meta.possible_types`` or ``is_type_of``.\n\n    Meta:\n        name (str): Name of the GraphQL type (must be unique in schema). Defaults to class\n            name.\n        description (str): Description of the GraphQL type in the schema. Defaults to class\n            docstring.\n        fields (Dict[str, graphene.Field]): Dictionary of field name to Field. Not recommended to\n            use (prefer class attributes).\n    \"\"\"\n\n    @classmethod\n    def __init_subclass_with_meta__(cls, _meta=None, interfaces=(), **options):\n        if not _meta:\n            _meta = InterfaceOptions(cls)\n\n        fields = {}\n        for base in reversed(cls.__mro__):\n            fields.update(yank_fields_from_attrs(base.__dict__, _as=Field))\n\n        if _meta.fields:\n            _meta.fields.update(fields)\n        else:\n            _meta.fields = fields\n\n        if not _meta.interfaces:\n            _meta.interfaces = interfaces\n\n        super(Interface, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n    @classmethod\n    def resolve_type(cls, instance, info):\n        from .objecttype import ObjectType\n\n        if isinstance(instance, ObjectType):\n            return type(instance)\n\n    def __init__(self, *args, **kwargs):\n        raise Exception(\"An Interface cannot be initialized\")\n"
  },
  {
    "path": "graphene/types/json.py",
    "content": "import json\n\nfrom graphql import Undefined\nfrom graphql.language.ast import StringValueNode\n\nfrom .scalars import Scalar\n\n\nclass JSONString(Scalar):\n    \"\"\"\n    Allows use of a JSON String for input / output from the GraphQL schema.\n\n    Use of this type is *not recommended* as you lose the benefits of having a defined, static\n    schema (one of the key benefits of GraphQL).\n    \"\"\"\n\n    @staticmethod\n    def serialize(dt):\n        return json.dumps(dt)\n\n    @staticmethod\n    def parse_literal(node, _variables=None):\n        if isinstance(node, StringValueNode):\n            try:\n                return json.loads(node.value)\n            except Exception as error:\n                raise ValueError(f\"Badly formed JSONString: {str(error)}\")\n        return Undefined\n\n    @staticmethod\n    def parse_value(value):\n        return json.loads(value)\n"
  },
  {
    "path": "graphene/types/mountedtype.py",
    "content": "from ..utils.orderedtype import OrderedType\nfrom .unmountedtype import UnmountedType\n\n\nclass MountedType(OrderedType):\n    @classmethod\n    def mounted(cls, unmounted):  # noqa: N802\n        \"\"\"\n        Mount the UnmountedType instance\n        \"\"\"\n        assert isinstance(\n            unmounted, UnmountedType\n        ), f\"{cls.__name__} can't mount {repr(unmounted)}\"\n\n        return cls(\n            unmounted.get_type(),\n            *unmounted.args,\n            _creation_counter=unmounted.creation_counter,\n            **unmounted.kwargs,\n        )\n"
  },
  {
    "path": "graphene/types/mutation.py",
    "content": "from typing import TYPE_CHECKING\n\nfrom ..utils.deprecated import warn_deprecation\nfrom ..utils.get_unbound_function import get_unbound_function\nfrom ..utils.props import props\nfrom .field import Field\nfrom .objecttype import ObjectType, ObjectTypeOptions\nfrom .utils import yank_fields_from_attrs\nfrom .interface import Interface\n\n# For static type checking with type checker\nif TYPE_CHECKING:\n    from .argument import Argument  # NOQA\n    from typing import Dict, Type, Callable, Iterable  # NOQA\n\n\nclass MutationOptions(ObjectTypeOptions):\n    arguments = None  # type: Dict[str, Argument]\n    output = None  # type: Type[ObjectType]\n    resolver = None  # type: Callable\n    interfaces = ()  # type: Iterable[Type[Interface]]\n\n\nclass Mutation(ObjectType):\n    \"\"\"\n    Object Type Definition (mutation field)\n\n    Mutation is a convenience type that helps us build a Field which takes Arguments and returns a\n    mutation Output ObjectType.\n\n    .. code:: python\n\n        import graphene\n\n        class CreatePerson(graphene.Mutation):\n            class Arguments:\n                name = graphene.String()\n\n            ok = graphene.Boolean()\n            person = graphene.Field(Person)\n\n            def mutate(parent, info, name):\n                person = Person(name=name)\n                ok = True\n                return CreatePerson(person=person, ok=ok)\n\n        class Mutation(graphene.ObjectType):\n            create_person = CreatePerson.Field()\n\n    Meta class options (optional):\n        output (graphene.ObjectType): Or ``Output`` inner class with attributes on Mutation class.\n            Or attributes from Mutation class. Fields which can be returned from this mutation\n            field.\n        resolver (Callable resolver method): Or ``mutate`` method on Mutation class. Perform data\n            change and return output.\n        arguments (Dict[str, graphene.Argument]): Or ``Arguments`` inner class with attributes on\n            Mutation class. Arguments to use for the mutation Field.\n        name (str): Name of the GraphQL type (must be unique in schema). Defaults to class\n            name.\n        description (str): Description of the GraphQL type in the schema. Defaults to class\n            docstring.\n        interfaces (Iterable[graphene.Interface]): GraphQL interfaces to extend with the payload\n            object. All fields from interface will be included in this object's schema.\n        fields (Dict[str, graphene.Field]): Dictionary of field name to Field. Not recommended to\n            use (prefer class attributes or ``Meta.output``).\n    \"\"\"\n\n    @classmethod\n    def __init_subclass_with_meta__(\n        cls,\n        interfaces=(),\n        resolver=None,\n        output=None,\n        arguments=None,\n        _meta=None,\n        **options,\n    ):\n        if not _meta:\n            _meta = MutationOptions(cls)\n        output = output or getattr(cls, \"Output\", None)\n        fields = {}\n\n        for interface in interfaces:\n            assert issubclass(\n                interface, Interface\n            ), f'All interfaces of {cls.__name__} must be a subclass of Interface. Received \"{interface}\".'\n            fields.update(interface._meta.fields)\n        if not output:\n            # If output is defined, we don't need to get the fields\n            fields = {}\n            for base in reversed(cls.__mro__):\n                fields.update(yank_fields_from_attrs(base.__dict__, _as=Field))\n            output = cls\n        if not arguments:\n            input_class = getattr(cls, \"Arguments\", None)\n            if not input_class:\n                input_class = getattr(cls, \"Input\", None)\n                if input_class:\n                    warn_deprecation(\n                        f\"Please use {cls.__name__}.Arguments instead of {cls.__name__}.Input.\"\n                        \" Input is now only used in ClientMutationID.\\n\"\n                        \"Read more:\"\n                        \" https://github.com/graphql-python/graphene/blob/v2.0.0/UPGRADE-v2.0.md#mutation-input\"\n                    )\n            arguments = props(input_class) if input_class else {}\n        if not resolver:\n            mutate = getattr(cls, \"mutate\", None)\n            assert mutate, \"All mutations must define a mutate method in it\"\n            resolver = get_unbound_function(mutate)\n        if _meta.fields:\n            _meta.fields.update(fields)\n        else:\n            _meta.fields = fields\n        _meta.interfaces = interfaces\n        _meta.output = output\n        _meta.resolver = resolver\n        _meta.arguments = arguments\n\n        super(Mutation, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n    @classmethod\n    def Field(\n        cls, name=None, description=None, deprecation_reason=None, required=False\n    ):\n        \"\"\"Mount instance of mutation Field.\"\"\"\n        return Field(\n            cls._meta.output,\n            args=cls._meta.arguments,\n            resolver=cls._meta.resolver,\n            name=name,\n            description=description or cls._meta.description,\n            deprecation_reason=deprecation_reason,\n            required=required,\n        )\n"
  },
  {
    "path": "graphene/types/objecttype.py",
    "content": "from typing import TYPE_CHECKING\n\nfrom .base import BaseOptions, BaseType, BaseTypeMeta\nfrom .field import Field\nfrom .interface import Interface\nfrom .utils import yank_fields_from_attrs\n\nfrom dataclasses import make_dataclass, field\n\n# For static type checking with type checker\nif TYPE_CHECKING:\n    from typing import Dict, Iterable, Type  # NOQA\n\n\nclass ObjectTypeOptions(BaseOptions):\n    fields = None  # type: Dict[str, Field]\n    interfaces = ()  # type: Iterable[Type[Interface]]\n\n\nclass ObjectTypeMeta(BaseTypeMeta):\n    def __new__(cls, name_, bases, namespace, **options):\n        # Note: it's safe to pass options as keyword arguments as they are still type-checked by ObjectTypeOptions.\n\n        # We create this type, to then overload it with the dataclass attrs\n        class InterObjectType:\n            pass\n\n        base_cls = super().__new__(\n            cls, name_, (InterObjectType,) + bases, namespace, **options\n        )\n        if base_cls._meta:\n            fields = [\n                (\n                    key,\n                    \"typing.Any\",\n                    field(\n                        default=field_value.default_value\n                        if isinstance(field_value, Field)\n                        else None\n                    ),\n                )\n                for key, field_value in base_cls._meta.fields.items()\n            ]\n            dataclass = make_dataclass(name_, fields, bases=())\n            InterObjectType.__init__ = dataclass.__init__\n            InterObjectType.__eq__ = dataclass.__eq__\n            InterObjectType.__repr__ = dataclass.__repr__\n        return base_cls\n\n\nclass ObjectType(BaseType, metaclass=ObjectTypeMeta):\n    \"\"\"\n    Object Type Definition\n\n    Almost all of the GraphQL types you define will be object types. Object types\n    have a name, but most importantly describe their fields.\n\n    The name of the type defined by an _ObjectType_ defaults to the class name. The type\n    description defaults to the class docstring. This can be overridden by adding attributes\n    to a Meta inner class.\n\n    The class attributes of an _ObjectType_ are mounted as instances of ``graphene.Field``.\n\n    Methods starting with ``resolve_<field_name>`` are bound as resolvers of the matching Field\n    name. If no resolver is provided, the default resolver is used.\n\n    Ambiguous types with Interface and Union can be determined through ``is_type_of`` method and\n    ``Meta.possible_types`` attribute.\n\n    .. code:: python\n\n        from graphene import ObjectType, String, Field\n\n        class Person(ObjectType):\n            class Meta:\n                description = 'A human'\n\n            # implicitly mounted as Field\n            first_name = String()\n            # explicitly mounted as Field\n            last_name = Field(String)\n\n            def resolve_last_name(parent, info):\n                return last_name\n\n    ObjectType must be mounted using ``graphene.Field``.\n\n    .. code:: python\n\n        from graphene import ObjectType, Field\n\n        class Query(ObjectType):\n\n            person = Field(Person, description=\"My favorite person\")\n\n    Meta class options (optional):\n        name (str): Name of the GraphQL type (must be unique in schema). Defaults to class\n            name.\n        description (str): Description of the GraphQL type in the schema. Defaults to class\n            docstring.\n        interfaces (Iterable[graphene.Interface]): GraphQL interfaces to extend with this object.\n            all fields from interface will be included in this object's schema.\n        possible_types (Iterable[class]): Used to test parent value object via isinstance to see if\n            this type can be used to resolve an ambiguous type (interface, union).\n        default_resolver (any Callable resolver): Override the default resolver for this\n            type. Defaults to graphene default resolver which returns an attribute or dictionary\n            key with the same name as the field.\n        fields (Dict[str, graphene.Field]): Dictionary of field name to Field. Not recommended to\n            use (prefer class attributes).\n\n    An _ObjectType_ can be used as a simple value object by creating an instance of the class.\n\n    .. code:: python\n\n        p = Person(first_name='Bob', last_name='Roberts')\n        assert p.first_name == 'Bob'\n\n    Args:\n        *args (List[Any]): Positional values to use for Field values of value object\n        **kwargs (Dict[str: Any]): Keyword arguments to use for Field values of value object\n    \"\"\"\n\n    @classmethod\n    def __init_subclass_with_meta__(\n        cls,\n        interfaces=(),\n        possible_types=(),\n        default_resolver=None,\n        _meta=None,\n        **options,\n    ):\n        if not _meta:\n            _meta = ObjectTypeOptions(cls)\n        fields = {}\n\n        for interface in interfaces:\n            assert issubclass(\n                interface, Interface\n            ), f'All interfaces of {cls.__name__} must be a subclass of Interface. Received \"{interface}\".'\n            fields.update(interface._meta.fields)\n        for base in reversed(cls.__mro__):\n            fields.update(yank_fields_from_attrs(base.__dict__, _as=Field))\n        assert not (possible_types and cls.is_type_of), (\n            f\"{cls.__name__}.Meta.possible_types will cause type collision with {cls.__name__}.is_type_of. \"\n            \"Please use one or other.\"\n        )\n\n        if _meta.fields:\n            _meta.fields.update(fields)\n        else:\n            _meta.fields = fields\n        if not _meta.interfaces:\n            _meta.interfaces = interfaces\n        _meta.possible_types = possible_types\n        _meta.default_resolver = default_resolver\n\n        super(ObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n    is_type_of = None\n"
  },
  {
    "path": "graphene/types/resolver.py",
    "content": "def attr_resolver(attname, default_value, root, info, **args):\n    return getattr(root, attname, default_value)\n\n\ndef dict_resolver(attname, default_value, root, info, **args):\n    return root.get(attname, default_value)\n\n\ndef dict_or_attr_resolver(attname, default_value, root, info, **args):\n    resolver = dict_resolver if isinstance(root, dict) else attr_resolver\n    return resolver(attname, default_value, root, info, **args)\n\n\ndefault_resolver = dict_or_attr_resolver\n\n\ndef set_default_resolver(resolver):\n    global default_resolver\n    assert callable(resolver), \"Received non-callable resolver.\"\n    default_resolver = resolver\n\n\ndef get_default_resolver():\n    return default_resolver\n"
  },
  {
    "path": "graphene/types/scalars.py",
    "content": "from typing import Any\n\nfrom graphql import Undefined\nfrom graphql.language.ast import (\n    BooleanValueNode,\n    FloatValueNode,\n    IntValueNode,\n    StringValueNode,\n)\n\nfrom .base import BaseOptions, BaseType\nfrom .unmountedtype import UnmountedType\n\n\nclass ScalarOptions(BaseOptions):\n    pass\n\n\nclass Scalar(UnmountedType, BaseType):\n    \"\"\"\n    Scalar Type Definition\n\n    The leaf values of any request and input values to arguments are\n    Scalars (or Enums) and are defined with a name and a series of functions\n    used to parse input from ast or variables and to ensure validity.\n    \"\"\"\n\n    @classmethod\n    def __init_subclass_with_meta__(cls, **options):\n        _meta = ScalarOptions(cls)\n        super(Scalar, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n    serialize = None\n    parse_value = None\n    parse_literal = None\n\n    @classmethod\n    def get_type(cls):\n        \"\"\"\n        This function is called when the unmounted type (Scalar instance)\n        is mounted (as a Field, InputField or Argument)\n        \"\"\"\n        return cls\n\n\n# As per the GraphQL Spec, Integers are only treated as valid when a valid\n# 32-bit signed integer, providing the broadest support across platforms.\n#\n# n.b. JavaScript's integers are safe between -(2^53 - 1) and 2^53 - 1 because\n# they are internally represented as IEEE 754 doubles.\nMAX_INT = 2147483647\nMIN_INT = -2147483648\n\n\nclass Int(Scalar):\n    \"\"\"\n    The `Int` scalar type represents non-fractional signed whole numeric\n    values. Int can represent values between -(2^53 - 1) and 2^53 - 1 since\n    represented in JSON as double-precision floating point numbers specified\n    by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).\n    \"\"\"\n\n    @staticmethod\n    def coerce_int(value):\n        try:\n            num = int(value)\n        except ValueError:\n            try:\n                num = int(float(value))\n            except ValueError:\n                return Undefined\n        if MIN_INT <= num <= MAX_INT:\n            return num\n        return Undefined\n\n    serialize = coerce_int\n    parse_value = coerce_int\n\n    @staticmethod\n    def parse_literal(ast, _variables=None):\n        if isinstance(ast, IntValueNode):\n            num = int(ast.value)\n            if MIN_INT <= num <= MAX_INT:\n                return num\n        return Undefined\n\n\nclass BigInt(Scalar):\n    \"\"\"\n    The `BigInt` scalar type represents non-fractional whole numeric values.\n    `BigInt` is not constrained to 32-bit like the `Int` type and thus is a less\n    compatible type.\n    \"\"\"\n\n    @staticmethod\n    def coerce_int(value):\n        try:\n            num = int(value)\n        except ValueError:\n            try:\n                num = int(float(value))\n            except ValueError:\n                return Undefined\n        return num\n\n    serialize = coerce_int\n    parse_value = coerce_int\n\n    @staticmethod\n    def parse_literal(ast, _variables=None):\n        if isinstance(ast, IntValueNode):\n            return int(ast.value)\n        return Undefined\n\n\nclass Float(Scalar):\n    \"\"\"\n    The `Float` scalar type represents signed double-precision fractional\n    values as specified by\n    [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point).\n    \"\"\"\n\n    @staticmethod\n    def coerce_float(value: Any) -> float:\n        try:\n            return float(value)\n        except ValueError:\n            return Undefined\n\n    serialize = coerce_float\n    parse_value = coerce_float\n\n    @staticmethod\n    def parse_literal(ast, _variables=None):\n        if isinstance(ast, (FloatValueNode, IntValueNode)):\n            return float(ast.value)\n        return Undefined\n\n\nclass String(Scalar):\n    \"\"\"\n    The `String` scalar type represents textual data, represented as UTF-8\n    character sequences. The String type is most often used by GraphQL to\n    represent free-form human-readable text.\n    \"\"\"\n\n    @staticmethod\n    def coerce_string(value):\n        if isinstance(value, bool):\n            return \"true\" if value else \"false\"\n        return str(value)\n\n    serialize = coerce_string\n    parse_value = coerce_string\n\n    @staticmethod\n    def parse_literal(ast, _variables=None):\n        if isinstance(ast, StringValueNode):\n            return ast.value\n        return Undefined\n\n\nclass Boolean(Scalar):\n    \"\"\"\n    The `Boolean` scalar type represents `true` or `false`.\n    \"\"\"\n\n    serialize = bool\n    parse_value = bool\n\n    @staticmethod\n    def parse_literal(ast, _variables=None):\n        if isinstance(ast, BooleanValueNode):\n            return ast.value\n        return Undefined\n\n\nclass ID(Scalar):\n    \"\"\"\n    The `ID` scalar type represents a unique identifier, often used to\n    refetch an object or as key for a cache. The ID type appears in a JSON\n    response as a String; however, it is not intended to be human-readable.\n    When expected as an input type, any string (such as `\"4\"`) or integer\n    (such as `4`) input value will be accepted as an ID.\n    \"\"\"\n\n    serialize = str\n    parse_value = str\n\n    @staticmethod\n    def parse_literal(ast, _variables=None):\n        if isinstance(ast, (StringValueNode, IntValueNode)):\n            return ast.value\n        return Undefined\n"
  },
  {
    "path": "graphene/types/schema.py",
    "content": "from enum import Enum as PyEnum\nimport inspect\nfrom functools import partial\n\nfrom graphql import (\n    default_type_resolver,\n    get_introspection_query,\n    graphql,\n    graphql_sync,\n    introspection_types,\n    parse,\n    print_schema,\n    subscribe,\n    validate,\n    ExecutionResult,\n    GraphQLArgument,\n    GraphQLBoolean,\n    GraphQLError,\n    GraphQLEnumValue,\n    GraphQLField,\n    GraphQLFloat,\n    GraphQLID,\n    GraphQLInputField,\n    GraphQLInt,\n    GraphQLList,\n    GraphQLNonNull,\n    GraphQLObjectType,\n    GraphQLSchema,\n    GraphQLString,\n)\n\nfrom ..utils.str_converters import to_camel_case\nfrom ..utils.get_unbound_function import get_unbound_function\nfrom .definitions import (\n    GrapheneEnumType,\n    GrapheneGraphQLType,\n    GrapheneInputObjectType,\n    GrapheneInterfaceType,\n    GrapheneObjectType,\n    GrapheneScalarType,\n    GrapheneUnionType,\n)\nfrom .dynamic import Dynamic\nfrom .enum import Enum\nfrom .field import Field\nfrom .inputobjecttype import InputObjectType\nfrom .interface import Interface\nfrom .objecttype import ObjectType\nfrom .resolver import get_default_resolver\nfrom .scalars import ID, Boolean, Float, Int, Scalar, String\nfrom .structures import List, NonNull\nfrom .union import Union\nfrom .utils import get_field_as\n\nintrospection_query = get_introspection_query()\nIntrospectionSchema = introspection_types[\"__Schema\"]\n\n\ndef assert_valid_root_type(type_):\n    if type_ is None:\n        return\n    is_graphene_objecttype = inspect.isclass(type_) and issubclass(type_, ObjectType)\n    is_graphql_objecttype = isinstance(type_, GraphQLObjectType)\n    assert (\n        is_graphene_objecttype or is_graphql_objecttype\n    ), f\"Type {type_} is not a valid ObjectType.\"\n\n\ndef is_graphene_type(type_):\n    if isinstance(type_, (List, NonNull)):\n        return True\n    if inspect.isclass(type_) and issubclass(\n        type_, (ObjectType, InputObjectType, Scalar, Interface, Union, Enum)\n    ):\n        return True\n\n\ndef is_type_of_from_possible_types(possible_types, root, _info):\n    return isinstance(root, possible_types)\n\n\n# We use this resolver for subscriptions\ndef identity_resolve(root, info, **arguments):\n    return root\n\n\nclass TypeMap(dict):\n    def __init__(\n        self,\n        query=None,\n        mutation=None,\n        subscription=None,\n        types=None,\n        auto_camelcase=True,\n    ):\n        assert_valid_root_type(query)\n        assert_valid_root_type(mutation)\n        assert_valid_root_type(subscription)\n        if types is None:\n            types = []\n        for type_ in types:\n            assert is_graphene_type(type_)\n\n        self.auto_camelcase = auto_camelcase\n\n        create_graphql_type = self.add_type\n\n        self.query = create_graphql_type(query) if query else None\n        self.mutation = create_graphql_type(mutation) if mutation else None\n        self.subscription = create_graphql_type(subscription) if subscription else None\n\n        self.types = [create_graphql_type(graphene_type) for graphene_type in types]\n\n    def add_type(self, graphene_type):\n        if inspect.isfunction(graphene_type):\n            graphene_type = graphene_type()\n        if isinstance(graphene_type, List):\n            return GraphQLList(self.add_type(graphene_type.of_type))\n        if isinstance(graphene_type, NonNull):\n            return GraphQLNonNull(self.add_type(graphene_type.of_type))\n        try:\n            name = graphene_type._meta.name\n        except AttributeError:\n            raise TypeError(f\"Expected Graphene type, but received: {graphene_type}.\")\n        graphql_type = self.get(name)\n        if graphql_type:\n            return graphql_type\n        if issubclass(graphene_type, ObjectType):\n            graphql_type = self.create_objecttype(graphene_type)\n        elif issubclass(graphene_type, InputObjectType):\n            graphql_type = self.create_inputobjecttype(graphene_type)\n        elif issubclass(graphene_type, Interface):\n            graphql_type = self.create_interface(graphene_type)\n        elif issubclass(graphene_type, Scalar):\n            graphql_type = self.create_scalar(graphene_type)\n        elif issubclass(graphene_type, Enum):\n            graphql_type = self.create_enum(graphene_type)\n        elif issubclass(graphene_type, Union):\n            graphql_type = self.construct_union(graphene_type)\n        else:\n            raise TypeError(f\"Expected Graphene type, but received: {graphene_type}.\")\n        self[name] = graphql_type\n        return graphql_type\n\n    @staticmethod\n    def create_scalar(graphene_type):\n        # We have a mapping to the original GraphQL types\n        # so there are no collisions.\n        _scalars = {\n            String: GraphQLString,\n            Int: GraphQLInt,\n            Float: GraphQLFloat,\n            Boolean: GraphQLBoolean,\n            ID: GraphQLID,\n        }\n        if graphene_type in _scalars:\n            return _scalars[graphene_type]\n\n        return GrapheneScalarType(\n            graphene_type=graphene_type,\n            name=graphene_type._meta.name,\n            description=graphene_type._meta.description,\n            serialize=getattr(graphene_type, \"serialize\", None),\n            parse_value=getattr(graphene_type, \"parse_value\", None),\n            parse_literal=getattr(graphene_type, \"parse_literal\", None),\n        )\n\n    @staticmethod\n    def create_enum(graphene_type):\n        values = {}\n        for name, value in graphene_type._meta.enum.__members__.items():\n            description = getattr(value, \"description\", None)\n            # if the \"description\" attribute is an Enum, it is likely an enum member\n            # called description, not a description property\n            if isinstance(description, PyEnum):\n                description = None\n            if not description and callable(graphene_type._meta.description):\n                description = graphene_type._meta.description(value)\n\n            deprecation_reason = getattr(value, \"deprecation_reason\", None)\n            if isinstance(deprecation_reason, PyEnum):\n                deprecation_reason = None\n            if not deprecation_reason and callable(\n                graphene_type._meta.deprecation_reason\n            ):\n                deprecation_reason = graphene_type._meta.deprecation_reason(value)\n\n            values[name] = GraphQLEnumValue(\n                value=value,\n                description=description,\n                deprecation_reason=deprecation_reason,\n            )\n\n        type_description = (\n            graphene_type._meta.description(None)\n            if callable(graphene_type._meta.description)\n            else graphene_type._meta.description\n        )\n\n        return GrapheneEnumType(\n            graphene_type=graphene_type,\n            values=values,\n            name=graphene_type._meta.name,\n            description=type_description,\n        )\n\n    def create_objecttype(self, graphene_type):\n        create_graphql_type = self.add_type\n\n        def interfaces():\n            interfaces = []\n            for graphene_interface in graphene_type._meta.interfaces:\n                interface = create_graphql_type(graphene_interface)\n                assert interface.graphene_type == graphene_interface\n                interfaces.append(interface)\n            return interfaces\n\n        if graphene_type._meta.possible_types:\n            is_type_of = partial(\n                is_type_of_from_possible_types, graphene_type._meta.possible_types\n            )\n        else:\n            is_type_of = graphene_type.is_type_of\n\n        return GrapheneObjectType(\n            graphene_type=graphene_type,\n            name=graphene_type._meta.name,\n            description=graphene_type._meta.description,\n            fields=partial(self.create_fields_for_type, graphene_type),\n            is_type_of=is_type_of,\n            interfaces=interfaces,\n        )\n\n    def create_interface(self, graphene_type):\n        resolve_type = (\n            partial(\n                self.resolve_type, graphene_type.resolve_type, graphene_type._meta.name\n            )\n            if graphene_type.resolve_type\n            else None\n        )\n\n        def interfaces():\n            interfaces = []\n            for graphene_interface in graphene_type._meta.interfaces:\n                interface = self.add_type(graphene_interface)\n                assert interface.graphene_type == graphene_interface\n                interfaces.append(interface)\n            return interfaces\n\n        return GrapheneInterfaceType(\n            graphene_type=graphene_type,\n            name=graphene_type._meta.name,\n            description=graphene_type._meta.description,\n            fields=partial(self.create_fields_for_type, graphene_type),\n            interfaces=interfaces,\n            resolve_type=resolve_type,\n        )\n\n    def create_inputobjecttype(self, graphene_type):\n        return GrapheneInputObjectType(\n            graphene_type=graphene_type,\n            name=graphene_type._meta.name,\n            description=graphene_type._meta.description,\n            out_type=graphene_type._meta.container,\n            fields=partial(\n                self.create_fields_for_type, graphene_type, is_input_type=True\n            ),\n        )\n\n    def construct_union(self, graphene_type):\n        create_graphql_type = self.add_type\n\n        def types():\n            union_types = []\n            for graphene_objecttype in graphene_type._meta.types:\n                object_type = create_graphql_type(graphene_objecttype)\n                assert object_type.graphene_type == graphene_objecttype\n                union_types.append(object_type)\n            return union_types\n\n        resolve_type = (\n            partial(\n                self.resolve_type, graphene_type.resolve_type, graphene_type._meta.name\n            )\n            if graphene_type.resolve_type\n            else None\n        )\n\n        return GrapheneUnionType(\n            graphene_type=graphene_type,\n            name=graphene_type._meta.name,\n            description=graphene_type._meta.description,\n            types=types,\n            resolve_type=resolve_type,\n        )\n\n    def get_name(self, name):\n        if self.auto_camelcase:\n            return to_camel_case(name)\n        return name\n\n    def create_fields_for_type(self, graphene_type, is_input_type=False):\n        create_graphql_type = self.add_type\n\n        fields = {}\n        for name, field in graphene_type._meta.fields.items():\n            if isinstance(field, Dynamic):\n                field = get_field_as(field.get_type(self), _as=Field)\n                if not field:\n                    continue\n            field_type = create_graphql_type(field.type)\n            if is_input_type:\n                _field = GraphQLInputField(\n                    field_type,\n                    default_value=field.default_value,\n                    out_name=name,\n                    description=field.description,\n                    deprecation_reason=field.deprecation_reason,\n                )\n            else:\n                args = {}\n                for arg_name, arg in field.args.items():\n                    arg_type = create_graphql_type(arg.type)\n                    processed_arg_name = arg.name or self.get_name(arg_name)\n                    args[processed_arg_name] = GraphQLArgument(\n                        arg_type,\n                        out_name=arg_name,\n                        description=arg.description,\n                        default_value=arg.default_value,\n                        deprecation_reason=arg.deprecation_reason,\n                    )\n                subscribe = field.wrap_subscribe(\n                    self.get_function_for_type(\n                        graphene_type, f\"subscribe_{name}\", name, field.default_value\n                    )\n                )\n\n                # If we are in a subscription, we use (by default) an\n                # identity-based resolver for the root, rather than the\n                # default resolver for objects/dicts.\n                if subscribe:\n                    field_default_resolver = identity_resolve\n                elif issubclass(graphene_type, ObjectType):\n                    default_resolver = (\n                        graphene_type._meta.default_resolver or get_default_resolver()\n                    )\n                    field_default_resolver = partial(\n                        default_resolver, name, field.default_value\n                    )\n                else:\n                    field_default_resolver = None\n\n                resolve = field.wrap_resolve(\n                    self.get_function_for_type(\n                        graphene_type, f\"resolve_{name}\", name, field.default_value\n                    )\n                    or field_default_resolver\n                )\n\n                _field = GraphQLField(\n                    field_type,\n                    args=args,\n                    resolve=resolve,\n                    subscribe=subscribe,\n                    deprecation_reason=field.deprecation_reason,\n                    description=field.description,\n                )\n            field_name = field.name or self.get_name(name)\n            fields[field_name] = _field\n        return fields\n\n    def get_function_for_type(self, graphene_type, func_name, name, default_value):\n        \"\"\"Gets a resolve or subscribe function for a given ObjectType\"\"\"\n        if not issubclass(graphene_type, ObjectType):\n            return\n        resolver = getattr(graphene_type, func_name, None)\n        if not resolver:\n            # If we don't find the resolver in the ObjectType class, then try to\n            # find it in each of the interfaces\n            interface_resolver = None\n            for interface in graphene_type._meta.interfaces:\n                if name not in interface._meta.fields:\n                    continue\n                interface_resolver = getattr(interface, func_name, None)\n                if interface_resolver:\n                    break\n            resolver = interface_resolver\n\n        # Only if is not decorated with classmethod\n        if resolver:\n            return get_unbound_function(resolver)\n\n    def resolve_type(self, resolve_type_func, type_name, root, info, _type):\n        type_ = resolve_type_func(root, info)\n\n        if inspect.isclass(type_) and issubclass(type_, ObjectType):\n            return type_._meta.name\n\n        return_type = self[type_name]\n        return default_type_resolver(root, info, return_type)\n\n\nclass Schema:\n    \"\"\"Schema Definition.\n    A Graphene Schema can execute operations (query, mutation, subscription) against the defined\n    types. For advanced purposes, the schema can be used to lookup type definitions and answer\n    questions about the types through introspection.\n    Args:\n        query (Type[ObjectType]): Root query *ObjectType*. Describes entry point for fields to *read*\n            data in your Schema.\n        mutation (Optional[Type[ObjectType]]): Root mutation *ObjectType*. Describes entry point for\n            fields to *create, update or delete* data in your API.\n        subscription (Optional[Type[ObjectType]]): Root subscription *ObjectType*. Describes entry point\n            for fields to receive continuous updates.\n        types (Optional[List[Type[ObjectType]]]): List of any types to include in schema that\n            may not be introspected through root types.\n        directives (List[GraphQLDirective], optional): List of custom directives to include in the\n            GraphQL schema. Defaults to only include directives defined by GraphQL spec (@include\n            and @skip) [GraphQLIncludeDirective, GraphQLSkipDirective].\n        auto_camelcase (bool): Fieldnames will be transformed in Schema's TypeMap from snake_case\n            to camelCase (preferred by GraphQL standard). Default True.\n    \"\"\"\n\n    def __init__(\n        self,\n        query=None,\n        mutation=None,\n        subscription=None,\n        types=None,\n        directives=None,\n        auto_camelcase=True,\n    ):\n        self.query = query\n        self.mutation = mutation\n        self.subscription = subscription\n        type_map = TypeMap(\n            query, mutation, subscription, types, auto_camelcase=auto_camelcase\n        )\n        self.graphql_schema = GraphQLSchema(\n            type_map.query,\n            type_map.mutation,\n            type_map.subscription,\n            type_map.types,\n            directives,\n        )\n\n    def __str__(self):\n        return print_schema(self.graphql_schema)\n\n    def __getattr__(self, type_name):\n        \"\"\"\n        This function let the developer select a type in a given schema\n        by accessing its attrs.\n        Example: using schema.Query for accessing the \"Query\" type in the Schema\n        \"\"\"\n        _type = self.graphql_schema.get_type(type_name)\n        if _type is None:\n            raise AttributeError(f'Type \"{type_name}\" not found in the Schema')\n        if isinstance(_type, GrapheneGraphQLType):\n            return _type.graphene_type\n        return _type\n\n    def lazy(self, _type):\n        return lambda: self.get_type(_type)\n\n    def execute(self, *args, **kwargs):\n        \"\"\"Execute a GraphQL query on the schema.\n        Use the `graphql_sync` function from `graphql-core` to provide the result\n        for a query string. Most of the time this method will be called by one of the Graphene\n        :ref:`Integrations` via a web request.\n        Args:\n            request_string (str or Document): GraphQL request (query, mutation or subscription)\n                as string or parsed AST form from `graphql-core`.\n            root_value (Any, optional): Value to use as the parent value object when resolving\n                root types.\n            context_value (Any, optional): Value to be made available to all resolvers via\n                `info.context`. Can be used to share authorization, dataloaders or other\n                information needed to resolve an operation.\n            variable_values (dict, optional): If variables are used in the request string, they can\n                be provided in dictionary form mapping the variable name to the variable value.\n            operation_name (str, optional): If multiple operations are provided in the\n                request_string, an operation name must be provided for the result to be provided.\n            middleware (List[SupportsGraphQLMiddleware]): Supply request level middleware as\n                defined in `graphql-core`.\n            execution_context_class (ExecutionContext, optional): The execution context class\n                to use when resolving queries and mutations.\n        Returns:\n            :obj:`ExecutionResult` containing any data and errors for the operation.\n        \"\"\"\n        kwargs = normalize_execute_kwargs(kwargs)\n        return graphql_sync(self.graphql_schema, *args, **kwargs)\n\n    async def execute_async(self, *args, **kwargs):\n        \"\"\"Execute a GraphQL query on the schema asynchronously.\n        Same as `execute`, but uses `graphql` instead of `graphql_sync`.\n        \"\"\"\n        kwargs = normalize_execute_kwargs(kwargs)\n        return await graphql(self.graphql_schema, *args, **kwargs)\n\n    async def subscribe(self, query, *args, **kwargs):\n        \"\"\"Execute a GraphQL subscription on the schema asynchronously.\"\"\"\n        # Do parsing\n        try:\n            document = parse(query)\n        except GraphQLError as error:\n            return ExecutionResult(data=None, errors=[error])\n\n        # Do validation\n        validation_errors = validate(self.graphql_schema, document)\n        if validation_errors:\n            return ExecutionResult(data=None, errors=validation_errors)\n\n        # Execute the query\n        kwargs = normalize_execute_kwargs(kwargs)\n        return await subscribe(self.graphql_schema, document, *args, **kwargs)\n\n    def introspect(self):\n        introspection = self.execute(introspection_query)\n        if introspection.errors:\n            raise introspection.errors[0]\n        return introspection.data\n\n\ndef normalize_execute_kwargs(kwargs):\n    \"\"\"Replace alias names in keyword arguments for graphql()\"\"\"\n    if \"root\" in kwargs and \"root_value\" not in kwargs:\n        kwargs[\"root_value\"] = kwargs.pop(\"root\")\n    if \"context\" in kwargs and \"context_value\" not in kwargs:\n        kwargs[\"context_value\"] = kwargs.pop(\"context\")\n    if \"variables\" in kwargs and \"variable_values\" not in kwargs:\n        kwargs[\"variable_values\"] = kwargs.pop(\"variables\")\n    if \"operation\" in kwargs and \"operation_name\" not in kwargs:\n        kwargs[\"operation_name\"] = kwargs.pop(\"operation\")\n    return kwargs\n"
  },
  {
    "path": "graphene/types/structures.py",
    "content": "from .unmountedtype import UnmountedType\nfrom .utils import get_type\n\n\nclass Structure(UnmountedType):\n    \"\"\"\n    A structure is a GraphQL type instance that\n    wraps a main type with certain structure.\n    \"\"\"\n\n    def __init__(self, of_type, *args, **kwargs):\n        super(Structure, self).__init__(*args, **kwargs)\n        if not isinstance(of_type, Structure) and isinstance(of_type, UnmountedType):\n            cls_name = type(self).__name__\n            of_type_name = type(of_type).__name__\n            raise Exception(\n                f\"{cls_name} could not have a mounted {of_type_name}()\"\n                f\" as inner type. Try with {cls_name}({of_type_name}).\"\n            )\n        self._of_type = of_type\n\n    @property\n    def of_type(self):\n        return get_type(self._of_type)\n\n    def get_type(self):\n        \"\"\"\n        This function is called when the unmounted type (List or NonNull instance)\n        is mounted (as a Field, InputField or Argument)\n        \"\"\"\n        return self\n\n\nclass List(Structure):\n    \"\"\"\n    List Modifier\n\n    A list is a kind of type marker, a wrapping type which points to another\n    type. Lists are often created within the context of defining the fields of\n    an object type.\n\n    List indicates that many values will be returned (or input) for this field.\n\n    .. code:: python\n\n        from graphene import List, String\n\n        field_name = List(String, description=\"There will be many values\")\n    \"\"\"\n\n    def __str__(self):\n        return f\"[{self.of_type}]\"\n\n    def __eq__(self, other):\n        return isinstance(other, List) and (\n            self.of_type == other.of_type\n            and self.args == other.args\n            and self.kwargs == other.kwargs\n        )\n\n\nclass NonNull(Structure):\n    \"\"\"\n    Non-Null Modifier\n\n    A non-null is a kind of type marker, a wrapping type which points to another\n    type. Non-null types enforce that their values are never null and can ensure\n    an error is raised if this ever occurs during a request. It is useful for\n    fields which you can make a strong guarantee on non-nullability, for example\n    usually the id field of a database row will never be null.\n\n    Note: the enforcement of non-nullability occurs within the executor.\n\n    NonNull can also be indicated on all Mounted types with the keyword argument ``required``.\n\n    .. code:: python\n\n        from graphene import NonNull, String\n\n        field_name = NonNull(String, description='This field will not be null')\n        another_field = String(required=True, description='This is equivalent to the above')\n\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super(NonNull, self).__init__(*args, **kwargs)\n        assert not isinstance(\n            self._of_type, NonNull\n        ), f\"Can only create NonNull of a Nullable GraphQLType but got: {self._of_type}.\"\n\n    def __str__(self):\n        return f\"{self.of_type}!\"\n\n    def __eq__(self, other):\n        return isinstance(other, NonNull) and (\n            self.of_type == other.of_type\n            and self.args == other.args\n            and self.kwargs == other.kwargs\n        )\n"
  },
  {
    "path": "graphene/types/tests/__init__.py",
    "content": ""
  },
  {
    "path": "graphene/types/tests/conftest.py",
    "content": "import pytest\nfrom graphql import Undefined\n\nfrom graphene.types.inputobjecttype import set_input_object_type_default_value\n\n\n@pytest.fixture()\ndef set_default_input_object_type_to_undefined():\n    \"\"\"This fixture is used to change the default value of optional inputs in InputObjectTypes for specific tests\"\"\"\n    set_input_object_type_default_value(Undefined)\n    yield\n    set_input_object_type_default_value(None)\n"
  },
  {
    "path": "graphene/types/tests/test_argument.py",
    "content": "from functools import partial\n\nfrom pytest import raises\n\nfrom ..argument import Argument, to_arguments\nfrom ..field import Field\nfrom ..inputfield import InputField\nfrom ..scalars import String\nfrom ..structures import NonNull\n\n\ndef test_argument():\n    arg = Argument(String, default_value=\"a\", description=\"desc\", name=\"b\")\n    assert arg.type == String\n    assert arg.default_value == \"a\"\n    assert arg.description == \"desc\"\n    assert arg.name == \"b\"\n\n\ndef test_argument_comparasion():\n    arg1 = Argument(\n        String,\n        name=\"Hey\",\n        description=\"Desc\",\n        default_value=\"default\",\n        deprecation_reason=\"deprecated\",\n    )\n    arg2 = Argument(\n        String,\n        name=\"Hey\",\n        description=\"Desc\",\n        default_value=\"default\",\n        deprecation_reason=\"deprecated\",\n    )\n\n    assert arg1 == arg2\n    assert arg1 != String()\n\n\ndef test_argument_required():\n    arg = Argument(String, required=True)\n    assert arg.type == NonNull(String)\n\n\ndef test_to_arguments():\n    args = {\"arg_string\": Argument(String), \"unmounted_arg\": String(required=True)}\n\n    my_args = to_arguments(args)\n    assert my_args == {\n        \"arg_string\": Argument(String),\n        \"unmounted_arg\": Argument(String, required=True),\n    }\n\n\ndef test_to_arguments_deprecated():\n    args = {\"unmounted_arg\": String(required=False, deprecation_reason=\"deprecated\")}\n\n    my_args = to_arguments(args)\n    assert my_args == {\n        \"unmounted_arg\": Argument(\n            String, required=False, deprecation_reason=\"deprecated\"\n        ),\n    }\n\n\ndef test_to_arguments_required_deprecated():\n    args = {\n        \"unmounted_arg\": String(\n            required=True, name=\"arg\", deprecation_reason=\"deprecated\"\n        )\n    }\n\n    with raises(AssertionError) as exc_info:\n        to_arguments(args)\n\n    assert str(exc_info.value) == \"Argument arg is required, cannot deprecate it.\"\n\n\ndef test_to_arguments_raises_if_field():\n    args = {\"arg_string\": Field(String)}\n\n    with raises(ValueError) as exc_info:\n        to_arguments(args)\n\n    assert str(exc_info.value) == (\n        \"Expected arg_string to be Argument, but received Field. Try using \"\n        \"Argument(String).\"\n    )\n\n\ndef test_to_arguments_raises_if_inputfield():\n    args = {\"arg_string\": InputField(String)}\n\n    with raises(ValueError) as exc_info:\n        to_arguments(args)\n\n    assert str(exc_info.value) == (\n        \"Expected arg_string to be Argument, but received InputField. Try \"\n        \"using Argument(String).\"\n    )\n\n\ndef test_argument_with_lazy_type():\n    MyType = object()\n    arg = Argument(lambda: MyType)\n    assert arg.type == MyType\n\n\ndef test_argument_with_lazy_partial_type():\n    MyType = object()\n    arg = Argument(partial(lambda: MyType))\n    assert arg.type == MyType\n"
  },
  {
    "path": "graphene/types/tests/test_base.py",
    "content": "from ..base import BaseOptions, BaseType\n\n\nclass CustomOptions(BaseOptions):\n    pass\n\n\nclass CustomType(BaseType):\n    @classmethod\n    def __init_subclass_with_meta__(cls, **options):\n        _meta = CustomOptions(cls)\n        super(CustomType, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n\ndef test_basetype():\n    class MyBaseType(CustomType):\n        pass\n\n    assert isinstance(MyBaseType._meta, CustomOptions)\n    assert MyBaseType._meta.name == \"MyBaseType\"\n    assert MyBaseType._meta.description is None\n\n\ndef test_basetype_nones():\n    class MyBaseType(CustomType):\n        \"\"\"Documentation\"\"\"\n\n        class Meta:\n            name = None\n            description = None\n\n    assert isinstance(MyBaseType._meta, CustomOptions)\n    assert MyBaseType._meta.name == \"MyBaseType\"\n    assert MyBaseType._meta.description == \"Documentation\"\n\n\ndef test_basetype_custom():\n    class MyBaseType(CustomType):\n        \"\"\"Documentation\"\"\"\n\n        class Meta:\n            name = \"Base\"\n            description = \"Desc\"\n\n    assert isinstance(MyBaseType._meta, CustomOptions)\n    assert MyBaseType._meta.name == \"Base\"\n    assert MyBaseType._meta.description == \"Desc\"\n\n\ndef test_basetype_create():\n    MyBaseType = CustomType.create_type(\"MyBaseType\")\n\n    assert isinstance(MyBaseType._meta, CustomOptions)\n    assert MyBaseType._meta.name == \"MyBaseType\"\n    assert MyBaseType._meta.description is None\n\n\ndef test_basetype_create_extra():\n    MyBaseType = CustomType.create_type(\"MyBaseType\", name=\"Base\", description=\"Desc\")\n\n    assert isinstance(MyBaseType._meta, CustomOptions)\n    assert MyBaseType._meta.name == \"Base\"\n    assert MyBaseType._meta.description == \"Desc\"\n"
  },
  {
    "path": "graphene/types/tests/test_base64.py",
    "content": "import base64\n\nfrom graphql import GraphQLError\n\nfrom ..objecttype import ObjectType\nfrom ..scalars import String\nfrom ..schema import Schema\nfrom ..base64 import Base64\n\n\nclass Query(ObjectType):\n    base64 = Base64(_in=Base64(name=\"input\"), _match=String(name=\"match\"))\n    bytes_as_base64 = Base64()\n    string_as_base64 = Base64()\n    number_as_base64 = Base64()\n\n    def resolve_base64(self, info, _in=None, _match=None):\n        if _match:\n            assert _in == _match\n        return _in\n\n    def resolve_bytes_as_base64(self, info):\n        return b\"Hello world\"\n\n    def resolve_string_as_base64(self, info):\n        return \"Spam and eggs\"\n\n    def resolve_number_as_base64(self, info):\n        return 42\n\n\nschema = Schema(query=Query)\n\n\ndef test_base64_query():\n    base64_value = base64.b64encode(b\"Random string\").decode(\"utf-8\")\n    result = schema.execute(\n        \"\"\"{{ base64(input: \"{}\", match: \"Random string\") }}\"\"\".format(base64_value)\n    )\n    assert not result.errors\n    assert result.data == {\"base64\": base64_value}\n\n\ndef test_base64_query_with_variable():\n    base64_value = base64.b64encode(b\"Another string\").decode(\"utf-8\")\n\n    # test datetime variable in string representation\n    result = schema.execute(\n        \"\"\"\n        query GetBase64($base64: Base64) {\n            base64(input: $base64, match: \"Another string\")\n        }\n        \"\"\",\n        variables={\"base64\": base64_value},\n    )\n    assert not result.errors\n    assert result.data == {\"base64\": base64_value}\n\n\ndef test_base64_query_none():\n    result = schema.execute(\"\"\"{ base64 }\"\"\")\n    assert not result.errors\n    assert result.data == {\"base64\": None}\n\n\ndef test_base64_query_invalid():\n    bad_inputs = [dict(), 123, \"This is not valid base64\"]\n\n    for input_ in bad_inputs:\n        result = schema.execute(\n            \"\"\"{ base64(input: $input) }\"\"\", variables={\"input\": input_}\n        )\n        assert isinstance(result.errors, list)\n        assert len(result.errors) == 1\n        assert isinstance(result.errors[0], GraphQLError)\n        assert result.data is None\n\n\ndef test_base64_from_bytes():\n    base64_value = base64.b64encode(b\"Hello world\").decode(\"utf-8\")\n    result = schema.execute(\"\"\"{ bytesAsBase64 }\"\"\")\n    assert not result.errors\n    assert result.data == {\"bytesAsBase64\": base64_value}\n\n\ndef test_base64_from_string():\n    base64_value = base64.b64encode(b\"Spam and eggs\").decode(\"utf-8\")\n    result = schema.execute(\"\"\"{ stringAsBase64 }\"\"\")\n    assert not result.errors\n    assert result.data == {\"stringAsBase64\": base64_value}\n\n\ndef test_base64_from_number():\n    base64_value = base64.b64encode(b\"42\").decode(\"utf-8\")\n    result = schema.execute(\"\"\"{ numberAsBase64 }\"\"\")\n    assert not result.errors\n    assert result.data == {\"numberAsBase64\": base64_value}\n"
  },
  {
    "path": "graphene/types/tests/test_datetime.py",
    "content": "import datetime\n\nfrom graphql import GraphQLError\n\nfrom pytest import fixture\n\nfrom ..datetime import Date, DateTime, Time\nfrom ..objecttype import ObjectType\nfrom ..schema import Schema\n\n\nclass Query(ObjectType):\n    datetime = DateTime(_in=DateTime(name=\"in\"))\n    date = Date(_in=Date(name=\"in\"))\n    time = Time(_at=Time(name=\"at\"))\n\n    def resolve_datetime(self, info, _in=None):\n        return _in\n\n    def resolve_date(self, info, _in=None):\n        return _in\n\n    def resolve_time(self, info, _at=None):\n        return _at\n\n\nschema = Schema(query=Query)\n\n\n@fixture\ndef sample_datetime():\n    utc_datetime = datetime.datetime(2019, 5, 25, 5, 30, 15, 10, datetime.timezone.utc)\n    return utc_datetime\n\n\n@fixture\ndef sample_time(sample_datetime):\n    time = datetime.time(\n        sample_datetime.hour,\n        sample_datetime.minute,\n        sample_datetime.second,\n        sample_datetime.microsecond,\n        sample_datetime.tzinfo,\n    )\n    return time\n\n\n@fixture\ndef sample_date(sample_datetime):\n    date = sample_datetime.date()\n    return date\n\n\ndef test_datetime_query(sample_datetime):\n    isoformat = sample_datetime.isoformat()\n\n    result = schema.execute(\"\"\"{ datetime(in: \"%s\") }\"\"\" % isoformat)\n    assert not result.errors\n    assert result.data == {\"datetime\": isoformat}\n\n\ndef test_datetime_query_with_variables(sample_datetime):\n    isoformat = sample_datetime.isoformat()\n\n    result = schema.execute(\n        \"\"\"\n        query GetDate($datetime: DateTime) {\n          literal: datetime(in: \"%s\")\n          value: datetime(in: $datetime)\n        }\n        \"\"\"\n        % isoformat,\n        variable_values={\"datetime\": isoformat},\n    )\n    assert not result.errors\n    assert result.data == {\"literal\": isoformat, \"value\": isoformat}\n\n\ndef test_date_query(sample_date):\n    isoformat = sample_date.isoformat()\n\n    result = schema.execute(\"\"\"{ date(in: \"%s\") }\"\"\" % isoformat)\n    assert not result.errors\n    assert result.data == {\"date\": isoformat}\n\n\ndef test_date_query_with_variables(sample_date):\n    isoformat = sample_date.isoformat()\n\n    result = schema.execute(\n        \"\"\"\n        query GetDate($date: Date) {\n          literal: date(in: \"%s\")\n          value: date(in: $date)\n        }\n        \"\"\"\n        % isoformat,\n        variable_values={\"date\": isoformat},\n    )\n    assert not result.errors\n    assert result.data == {\"literal\": isoformat, \"value\": isoformat}\n\n\ndef test_time_query(sample_time):\n    isoformat = sample_time.isoformat()\n\n    result = schema.execute(\"\"\"{ time(at: \"%s\") }\"\"\" % isoformat)\n    assert not result.errors\n    assert result.data == {\"time\": isoformat}\n\n\ndef test_time_query_with_variables(sample_time):\n    isoformat = sample_time.isoformat()\n\n    result = schema.execute(\n        \"\"\"\n        query GetTime($time: Time) {\n          literal: time(at: \"%s\")\n          value: time(at: $time)\n        }\n        \"\"\"\n        % isoformat,\n        variable_values={\"time\": isoformat},\n    )\n    assert not result.errors\n    assert result.data == {\"literal\": isoformat, \"value\": isoformat}\n\n\ndef test_bad_datetime_query():\n    not_a_date = \"Some string that's not a datetime\"\n\n    result = schema.execute(\"\"\"{ datetime(in: \"%s\") }\"\"\" % not_a_date)\n\n    assert result.errors and len(result.errors) == 1\n    error = result.errors[0]\n    assert isinstance(error, GraphQLError)\n    assert (\n        error.message == \"DateTime cannot represent value:\"\n        ' \"Some string that\\'s not a datetime\"'\n    )\n    assert result.data is None\n\n\ndef test_bad_date_query():\n    not_a_date = \"Some string that's not a date\"\n\n    result = schema.execute(\"\"\"{ date(in: \"%s\") }\"\"\" % not_a_date)\n\n    error = result.errors[0]\n    assert isinstance(error, GraphQLError)\n    assert (\n        error.message == \"Date cannot represent value:\"\n        ' \"Some string that\\'s not a date\"'\n    )\n    assert result.data is None\n\n\ndef test_bad_time_query():\n    not_a_date = \"Some string that's not a time\"\n\n    result = schema.execute(\"\"\"{ time(at: \"%s\") }\"\"\" % not_a_date)\n\n    error = result.errors[0]\n    assert isinstance(error, GraphQLError)\n    assert (\n        error.message == \"Time cannot represent value:\"\n        ' \"Some string that\\'s not a time\"'\n    )\n    assert result.data is None\n\n\ndef test_datetime_query_variable(sample_datetime):\n    isoformat = sample_datetime.isoformat()\n\n    # test datetime variable provided as Python datetime\n    result = schema.execute(\n        \"\"\"query Test($date: DateTime){ datetime(in: $date) }\"\"\",\n        variables={\"date\": sample_datetime},\n    )\n    assert not result.errors\n    assert result.data == {\"datetime\": isoformat}\n\n    # test datetime variable in string representation\n    result = schema.execute(\n        \"\"\"query Test($date: DateTime){ datetime(in: $date) }\"\"\",\n        variables={\"date\": isoformat},\n    )\n    assert not result.errors\n    assert result.data == {\"datetime\": isoformat}\n\n\ndef test_date_query_variable(sample_date):\n    isoformat = sample_date.isoformat()\n\n    # test date variable provided as Python date\n    result = schema.execute(\n        \"\"\"query Test($date: Date){ date(in: $date) }\"\"\",\n        variables={\"date\": sample_date},\n    )\n    assert not result.errors\n    assert result.data == {\"date\": isoformat}\n\n    # test date variable in string representation\n    result = schema.execute(\n        \"\"\"query Test($date: Date){ date(in: $date) }\"\"\", variables={\"date\": isoformat}\n    )\n    assert not result.errors\n    assert result.data == {\"date\": isoformat}\n\n\ndef test_time_query_variable(sample_time):\n    isoformat = sample_time.isoformat()\n\n    # test time variable provided as Python time\n    result = schema.execute(\n        \"\"\"query Test($time: Time){ time(at: $time) }\"\"\",\n        variables={\"time\": sample_time},\n    )\n    assert not result.errors\n    assert result.data == {\"time\": isoformat}\n\n    # test time variable in string representation\n    result = schema.execute(\n        \"\"\"query Test($time: Time){ time(at: $time) }\"\"\", variables={\"time\": isoformat}\n    )\n    assert not result.errors\n    assert result.data == {\"time\": isoformat}\n\n\ndef test_support_isoformat():\n    isoformat = \"2011-11-04T00:05:23Z\"\n\n    # test time variable provided as Python time\n    result = schema.execute(\n        \"\"\"query DateTime($time: DateTime){ datetime(in: $time) }\"\"\",\n        variables={\"time\": isoformat},\n    )\n    assert not result.errors\n    assert result.data == {\"datetime\": \"2011-11-04T00:05:23+00:00\"}\n\n\ndef test_bad_variables(sample_date, sample_datetime, sample_time):\n    def _test_bad_variables(type_, input_):\n        result = schema.execute(\n            f\"\"\"query Test($input: {type_}){{ {type_.lower()}(in: $input) }}\"\"\",\n            variables={\"input\": input_},\n        )\n        assert isinstance(result.errors, list)\n        assert len(result.errors) == 1\n        assert isinstance(result.errors[0], GraphQLError)\n        assert result.data is None\n\n    not_a_date = dict()\n    not_a_date_str = \"Some string that's not a date\"\n    today = sample_date\n    now = sample_datetime\n    time = sample_time\n\n    bad_pairs = [\n        (\"DateTime\", not_a_date),\n        (\"DateTime\", not_a_date_str),\n        (\"DateTime\", today),\n        (\"DateTime\", time),\n        (\"Date\", not_a_date),\n        (\"Date\", not_a_date_str),\n        (\"Date\", time),\n        (\"Time\", not_a_date),\n        (\"Time\", not_a_date_str),\n        (\"Time\", now),\n        (\"Time\", today),\n    ]\n\n    for type_, input_ in bad_pairs:\n        _test_bad_variables(type_, input_)\n"
  },
  {
    "path": "graphene/types/tests/test_decimal.py",
    "content": "import decimal\n\nfrom ..decimal import Decimal\nfrom ..objecttype import ObjectType\nfrom ..schema import Schema\n\n\nclass Query(ObjectType):\n    decimal = Decimal(input=Decimal())\n\n    def resolve_decimal(self, info, input):\n        return input\n\n\nschema = Schema(query=Query)\n\n\ndef test_decimal_string_query():\n    decimal_value = decimal.Decimal(\"1969.1974\")\n    result = schema.execute(\"\"\"{ decimal(input: \"%s\") }\"\"\" % decimal_value)\n    assert not result.errors\n    assert result.data == {\"decimal\": str(decimal_value)}\n    assert decimal.Decimal(result.data[\"decimal\"]) == decimal_value\n\n\ndef test_decimal_string_query_variable():\n    decimal_value = decimal.Decimal(\"1969.1974\")\n\n    result = schema.execute(\n        \"\"\"query Test($decimal: Decimal){ decimal(input: $decimal) }\"\"\",\n        variables={\"decimal\": decimal_value},\n    )\n    assert not result.errors\n    assert result.data == {\"decimal\": str(decimal_value)}\n    assert decimal.Decimal(result.data[\"decimal\"]) == decimal_value\n\n\ndef test_bad_decimal_query():\n    not_a_decimal = \"Nobody expects the Spanish Inquisition!\"\n\n    result = schema.execute(\"\"\"{ decimal(input: \"%s\") }\"\"\" % not_a_decimal)\n    assert result.errors\n    assert len(result.errors) == 1\n    assert result.data is None\n    assert (\n        result.errors[0].message\n        == \"Expected value of type 'Decimal', found \\\"Nobody expects the Spanish Inquisition!\\\".\"\n    )\n\n    result = schema.execute(\"{ decimal(input: true) }\")\n    assert result.errors\n    assert len(result.errors) == 1\n    assert result.data is None\n    assert result.errors[0].message == \"Expected value of type 'Decimal', found true.\"\n\n    result = schema.execute(\"{ decimal(input: 1.2) }\")\n    assert result.errors\n    assert len(result.errors) == 1\n    assert result.data is None\n    assert result.errors[0].message == \"Expected value of type 'Decimal', found 1.2.\"\n\n\ndef test_decimal_string_query_integer():\n    decimal_value = 1\n    result = schema.execute(\"\"\"{ decimal(input: %s) }\"\"\" % decimal_value)\n    assert not result.errors\n    assert result.data == {\"decimal\": str(decimal_value)}\n    assert decimal.Decimal(result.data[\"decimal\"]) == decimal_value\n"
  },
  {
    "path": "graphene/types/tests/test_definition.py",
    "content": "import copy\n\nfrom ..argument import Argument\nfrom ..definitions import GrapheneGraphQLType\nfrom ..enum import Enum\nfrom ..field import Field\nfrom ..inputfield import InputField\nfrom ..inputobjecttype import InputObjectType\nfrom ..interface import Interface\nfrom ..objecttype import ObjectType\nfrom ..scalars import Boolean, Int, String\nfrom ..schema import Schema\nfrom ..structures import List, NonNull\nfrom ..union import Union\n\n\nclass Image(ObjectType):\n    url = String()\n    width = Int()\n    height = Int()\n\n\nclass Author(ObjectType):\n    id = String()\n    name = String()\n    pic = Field(Image, width=Int(), height=Int())\n    recent_article = Field(lambda: Article)\n\n\nclass Article(ObjectType):\n    id = String()\n    is_published = Boolean()\n    author = Field(Author)\n    title = String()\n    body = String()\n\n\nclass Query(ObjectType):\n    article = Field(Article, id=String())\n    feed = List(Article)\n\n\nclass Mutation(ObjectType):\n    write_article = Field(Article)\n\n\nclass Subscription(ObjectType):\n    article_subscribe = Field(Article, id=String())\n\n\nclass MyObjectType(ObjectType):\n    pass\n\n\nclass MyInterface(Interface):\n    pass\n\n\nclass MyUnion(Union):\n    class Meta:\n        types = (Article,)\n\n\nclass MyEnum(Enum):\n    foo = \"foo\"\n\n\nclass MyInputObjectType(InputObjectType):\n    pass\n\n\ndef test_defines_a_query_only_schema():\n    blog_schema = Schema(Query)\n\n    assert blog_schema.query == Query\n    assert blog_schema.graphql_schema.query_type.graphene_type == Query\n\n    article_field = Query._meta.fields[\"article\"]\n    assert article_field.type == Article\n    assert article_field.type._meta.name == \"Article\"\n\n    article_field_type = article_field.type\n    assert issubclass(article_field_type, ObjectType)\n\n    title_field = article_field_type._meta.fields[\"title\"]\n    assert title_field.type == String\n\n    author_field = article_field_type._meta.fields[\"author\"]\n    author_field_type = author_field.type\n    assert issubclass(author_field_type, ObjectType)\n    recent_article_field = author_field_type._meta.fields[\"recent_article\"]\n\n    assert recent_article_field.type == Article\n\n    feed_field = Query._meta.fields[\"feed\"]\n    assert feed_field.type.of_type == Article\n\n\ndef test_defines_a_mutation_schema():\n    blog_schema = Schema(Query, mutation=Mutation)\n\n    assert blog_schema.mutation == Mutation\n    assert blog_schema.graphql_schema.mutation_type.graphene_type == Mutation\n\n    write_mutation = Mutation._meta.fields[\"write_article\"]\n    assert write_mutation.type == Article\n    assert write_mutation.type._meta.name == \"Article\"\n\n\ndef test_defines_a_subscription_schema():\n    blog_schema = Schema(Query, subscription=Subscription)\n\n    assert blog_schema.subscription == Subscription\n    assert blog_schema.graphql_schema.subscription_type.graphene_type == Subscription\n\n    subscription = Subscription._meta.fields[\"article_subscribe\"]\n    assert subscription.type == Article\n    assert subscription.type._meta.name == \"Article\"\n\n\ndef test_includes_nested_input_objects_in_the_map():\n    class NestedInputObject(InputObjectType):\n        value = String()\n\n    class SomeInputObject(InputObjectType):\n        nested = InputField(NestedInputObject)\n\n    class SomeMutation(Mutation):\n        mutate_something = Field(Article, input=Argument(SomeInputObject))\n\n    class SomeSubscription(Mutation):\n        subscribe_to_something = Field(Article, input=Argument(SomeInputObject))\n\n    schema = Schema(query=Query, mutation=SomeMutation, subscription=SomeSubscription)\n    type_map = schema.graphql_schema.type_map\n\n    assert type_map[\"NestedInputObject\"].graphene_type is NestedInputObject\n\n\ndef test_includes_interfaces_thunk_subtypes_in_the_type_map():\n    class SomeInterface(Interface):\n        f = Int()\n\n    class SomeSubtype(ObjectType):\n        class Meta:\n            interfaces = (SomeInterface,)\n\n    class Query(ObjectType):\n        iface = Field(lambda: SomeInterface)\n\n    schema = Schema(query=Query, types=[SomeSubtype])\n    type_map = schema.graphql_schema.type_map\n\n    assert type_map[\"SomeSubtype\"].graphene_type is SomeSubtype\n\n\ndef test_includes_types_in_union():\n    class SomeType(ObjectType):\n        a = String()\n\n    class OtherType(ObjectType):\n        b = String()\n\n    class MyUnion(Union):\n        class Meta:\n            types = (SomeType, OtherType)\n\n    class Query(ObjectType):\n        union = Field(MyUnion)\n\n    schema = Schema(query=Query)\n    type_map = schema.graphql_schema.type_map\n\n    assert type_map[\"OtherType\"].graphene_type is OtherType\n    assert type_map[\"SomeType\"].graphene_type is SomeType\n\n\ndef test_maps_enum():\n    class SomeType(ObjectType):\n        a = String()\n\n    class OtherType(ObjectType):\n        b = String()\n\n    class MyUnion(Union):\n        class Meta:\n            types = (SomeType, OtherType)\n\n    class Query(ObjectType):\n        union = Field(MyUnion)\n\n    schema = Schema(query=Query)\n    type_map = schema.graphql_schema.type_map\n\n    assert type_map[\"OtherType\"].graphene_type is OtherType\n    assert type_map[\"SomeType\"].graphene_type is SomeType\n\n\ndef test_includes_interfaces_subtypes_in_the_type_map():\n    class SomeInterface(Interface):\n        f = Int()\n\n    class SomeSubtype(ObjectType):\n        class Meta:\n            interfaces = (SomeInterface,)\n\n    class Query(ObjectType):\n        iface = Field(SomeInterface)\n\n    schema = Schema(query=Query, types=[SomeSubtype])\n    type_map = schema.graphql_schema.type_map\n\n    assert type_map[\"SomeSubtype\"].graphene_type is SomeSubtype\n\n\ndef test_stringifies_simple_types():\n    assert str(Int) == \"Int\"\n    assert str(Article) == \"Article\"\n    assert str(MyInterface) == \"MyInterface\"\n    assert str(MyUnion) == \"MyUnion\"\n    assert str(MyEnum) == \"MyEnum\"\n    assert str(MyInputObjectType) == \"MyInputObjectType\"\n    assert str(NonNull(Int)) == \"Int!\"\n    assert str(List(Int)) == \"[Int]\"\n    assert str(NonNull(List(Int))) == \"[Int]!\"\n    assert str(List(NonNull(Int))) == \"[Int!]\"\n    assert str(List(List(Int))) == \"[[Int]]\"\n\n\n# def test_identifies_input_types():\n#     expected = (\n#         (GraphQLInt, True),\n#         (ObjectType, False),\n#         (InterfaceType, False),\n#         (UnionType, False),\n#         (EnumType, True),\n#         (InputObjectType, True)\n#     )\n\n#     for type_, answer in expected:\n#         assert is_input_type(type_) == answer\n#         assert is_input_type(GraphQLList(type_)) == answer\n#         assert is_input_type(GraphQLNonNull(type_)) == answer\n\n\n# def test_identifies_output_types():\n#     expected = (\n#         (GraphQLInt, True),\n#         (ObjectType, True),\n#         (InterfaceType, True),\n#         (UnionType, True),\n#         (EnumType, True),\n#         (InputObjectType, False)\n#     )\n\n#     for type, answer in expected:\n#         assert is_output_type(type) == answer\n#         assert is_output_type(GraphQLList(type)) == answer\n#         assert is_output_type(GraphQLNonNull(type)) == answer\n\n\n# def test_prohibits_nesting_nonnull_inside_nonnull():\n#     with raises(Exception) as excinfo:\n#         GraphQLNonNull(GraphQLNonNull(GraphQLInt))\n\n#     assert 'Can only create NonNull of a Nullable GraphQLType but got: Int!.' in str(excinfo.value)\n\n\n# def test_prohibits_putting_non_object_types_in_unions():\n#     bad_union_types = [\n#         GraphQLInt,\n#         GraphQLNonNull(GraphQLInt),\n#         GraphQLList(GraphQLInt),\n#         InterfaceType,\n#         UnionType,\n#         EnumType,\n#         InputObjectType\n#     ]\n#     for x in bad_union_types:\n#         with raises(Exception) as excinfo:\n#             GraphQLSchema(\n#                 GraphQLObjectType(\n#                     'Root',\n#                     fields={\n#                         'union': GraphQLField(GraphQLUnionType('BadUnion', [x]))\n#                     }\n#                 )\n#             )\n\n#         assert 'BadUnion may only contain Object types, it cannot contain: ' + str(x) + '.' \\\n#                == str(excinfo.value)\n\n\ndef test_does_not_mutate_passed_field_definitions():\n    class CommonFields:\n        field1 = String()\n        field2 = String(id=String())\n\n    class TestObject1(CommonFields, ObjectType):\n        pass\n\n    class TestObject2(CommonFields, ObjectType):\n        pass\n\n    assert TestObject1._meta.fields == TestObject2._meta.fields\n\n    class CommonFields:\n        field1 = String()\n        field2 = String()\n\n    class TestInputObject1(CommonFields, InputObjectType):\n        pass\n\n    class TestInputObject2(CommonFields, InputObjectType):\n        pass\n\n    assert TestInputObject1._meta.fields == TestInputObject2._meta.fields\n\n\ndef test_graphene_graphql_type_can_be_copied():\n    class Query(ObjectType):\n        field = String()\n\n        def resolve_field(self, info):\n            return \"\"\n\n    schema = Schema(query=Query)\n    query_type_copy = copy.copy(schema.graphql_schema.query_type)\n    assert query_type_copy.__dict__ == schema.graphql_schema.query_type.__dict__\n    assert isinstance(schema.graphql_schema.query_type, GrapheneGraphQLType)\n"
  },
  {
    "path": "graphene/types/tests/test_dynamic.py",
    "content": "from functools import partial\n\nfrom ..dynamic import Dynamic\nfrom ..scalars import String\nfrom ..structures import List, NonNull\n\n\ndef test_dynamic():\n    dynamic = Dynamic(lambda: String)\n    assert dynamic.get_type() == String\n    assert str(dynamic.get_type()) == \"String\"\n\n\ndef test_nonnull():\n    dynamic = Dynamic(lambda: NonNull(String))\n    assert dynamic.get_type().of_type == String\n    assert str(dynamic.get_type()) == \"String!\"\n\n\ndef test_list():\n    dynamic = Dynamic(lambda: List(String))\n    assert dynamic.get_type().of_type == String\n    assert str(dynamic.get_type()) == \"[String]\"\n\n\ndef test_list_non_null():\n    dynamic = Dynamic(lambda: List(NonNull(String)))\n    assert dynamic.get_type().of_type.of_type == String\n    assert str(dynamic.get_type()) == \"[String!]\"\n\n\ndef test_partial():\n    def __type(_type):\n        return _type\n\n    dynamic = Dynamic(partial(__type, String))\n    assert dynamic.get_type() == String\n    assert str(dynamic.get_type()) == \"String\"\n"
  },
  {
    "path": "graphene/types/tests/test_enum.py",
    "content": "from textwrap import dedent\n\nfrom ..argument import Argument\nfrom ..enum import Enum, PyEnum\nfrom ..field import Field\nfrom ..inputfield import InputField\nfrom ..inputobjecttype import InputObjectType\nfrom ..mutation import Mutation\nfrom ..scalars import String\nfrom ..schema import ObjectType, Schema\n\n\ndef test_enum_construction():\n    class RGB(Enum):\n        \"\"\"Description\"\"\"\n\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n        @property\n        def description(self):\n            return f\"Description {self.name}\"\n\n    assert RGB._meta.name == \"RGB\"\n    assert RGB._meta.description == \"Description\"\n\n    values = RGB._meta.enum.__members__.values()\n    assert sorted(v.name for v in values) == [\"BLUE\", \"GREEN\", \"RED\"]\n    assert sorted(v.description for v in values) == [\n        \"Description BLUE\",\n        \"Description GREEN\",\n        \"Description RED\",\n    ]\n\n\ndef test_enum_construction_meta():\n    class RGB(Enum):\n        class Meta:\n            name = \"RGBEnum\"\n            description = \"Description\"\n\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert RGB._meta.name == \"RGBEnum\"\n    assert RGB._meta.description == \"Description\"\n\n\ndef test_enum_instance_construction():\n    RGB = Enum(\"RGB\", \"RED,GREEN,BLUE\")\n\n    values = RGB._meta.enum.__members__.values()\n    assert sorted(v.name for v in values) == [\"BLUE\", \"GREEN\", \"RED\"]\n\n\ndef test_enum_from_builtin_enum():\n    PyRGB = PyEnum(\"RGB\", \"RED,GREEN,BLUE\")\n\n    RGB = Enum.from_enum(PyRGB)\n    assert RGB._meta.enum == PyRGB\n    assert RGB.RED\n    assert RGB.GREEN\n    assert RGB.BLUE\n\n\ndef test_enum_custom_description_in_constructor():\n    description = \"An enumeration, but with a custom description\"\n    RGB = Enum(\n        \"RGB\",\n        \"RED,GREEN,BLUE\",\n        description=description,\n    )\n    assert RGB._meta.description == description\n\n\ndef test_enum_from_python3_enum_uses_default_builtin_doc():\n    RGB = Enum(\"RGB\", \"RED,GREEN,BLUE\")\n    assert RGB._meta.description == \"An enumeration.\"\n\n\ndef test_enum_from_builtin_enum_accepts_lambda_description():\n    def custom_description(value):\n        if not value:\n            return \"StarWars Episodes\"\n\n        return \"New Hope Episode\" if value == Episode.NEWHOPE else \"Other\"\n\n    def custom_deprecation_reason(value):\n        return \"meh\" if value == Episode.NEWHOPE else None\n\n    PyEpisode = PyEnum(\"PyEpisode\", \"NEWHOPE,EMPIRE,JEDI\")\n    Episode = Enum.from_enum(\n        PyEpisode,\n        description=custom_description,\n        deprecation_reason=custom_deprecation_reason,\n    )\n\n    class Query(ObjectType):\n        foo = Episode()\n\n    schema = Schema(query=Query).graphql_schema\n\n    episode = schema.get_type(\"PyEpisode\")\n\n    assert episode.description == \"StarWars Episodes\"\n    assert [\n        (name, value.description, value.deprecation_reason)\n        for name, value in episode.values.items()\n    ] == [\n        (\"NEWHOPE\", \"New Hope Episode\", \"meh\"),\n        (\"EMPIRE\", \"Other\", None),\n        (\"JEDI\", \"Other\", None),\n    ]\n\n\ndef test_enum_from_python3_enum_uses_enum_doc():\n    from enum import Enum as PyEnum\n\n    class Color(PyEnum):\n        \"\"\"This is the description\"\"\"\n\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    RGB = Enum.from_enum(Color)\n    assert RGB._meta.enum == Color\n    assert RGB._meta.description == \"This is the description\"\n    assert RGB\n    assert RGB.RED\n    assert RGB.GREEN\n    assert RGB.BLUE\n\n\ndef test_enum_value_from_class():\n    class RGB(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert RGB.RED.value == 1\n    assert RGB.GREEN.value == 2\n    assert RGB.BLUE.value == 3\n\n\ndef test_enum_value_as_unmounted_field():\n    class RGB(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    unmounted = RGB()\n    unmounted_field = unmounted.Field()\n    assert isinstance(unmounted_field, Field)\n    assert unmounted_field.type == RGB\n\n\ndef test_enum_value_as_unmounted_inputfield():\n    class RGB(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    unmounted = RGB()\n    unmounted_field = unmounted.InputField()\n    assert isinstance(unmounted_field, InputField)\n    assert unmounted_field.type == RGB\n\n\ndef test_enum_value_as_unmounted_argument():\n    class RGB(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    unmounted = RGB()\n    unmounted_field = unmounted.Argument()\n    assert isinstance(unmounted_field, Argument)\n    assert unmounted_field.type == RGB\n\n\ndef test_enum_can_be_compared():\n    class RGB(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert RGB.RED == 1\n    assert RGB.GREEN == 2\n    assert RGB.BLUE == 3\n\n\ndef test_enum_can_be_initialized():\n    class RGB(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert RGB.get(1) == RGB.RED\n    assert RGB.get(2) == RGB.GREEN\n    assert RGB.get(3) == RGB.BLUE\n\n\ndef test_enum_can_retrieve_members():\n    class RGB(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert RGB[\"RED\"] == RGB.RED\n    assert RGB[\"GREEN\"] == RGB.GREEN\n    assert RGB[\"BLUE\"] == RGB.BLUE\n\n\ndef test_enum_to_enum_comparison_should_differ():\n    class RGB1(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    class RGB2(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert RGB1.RED != RGB2.RED\n    assert RGB1.GREEN != RGB2.GREEN\n    assert RGB1.BLUE != RGB2.BLUE\n\n\ndef test_enum_skip_meta_from_members():\n    class RGB1(Enum):\n        class Meta:\n            name = \"RGB\"\n\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    assert dict(RGB1._meta.enum.__members__) == {\n        \"RED\": RGB1.RED,\n        \"GREEN\": RGB1.GREEN,\n        \"BLUE\": RGB1.BLUE,\n    }\n\n\ndef test_enum_types():\n    from enum import Enum as PyEnum\n\n    class Color(PyEnum):\n        \"\"\"Primary colors\"\"\"\n\n        RED = 1\n        YELLOW = 2\n        BLUE = 3\n\n    GColor = Enum.from_enum(Color)\n\n    class Query(ObjectType):\n        color = GColor(required=True)\n\n        def resolve_color(_, info):\n            return Color.RED\n\n    schema = Schema(query=Query)\n\n    assert (\n        str(schema).strip()\n        == dedent(\n            '''\n            type Query {\n              color: Color!\n            }\n\n            \"\"\"Primary colors\"\"\"\n            enum Color {\n              RED\n              YELLOW\n              BLUE\n            }\n            '''\n        ).strip()\n    )\n\n\ndef test_enum_resolver():\n    from enum import Enum as PyEnum\n\n    class Color(PyEnum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    GColor = Enum.from_enum(Color)\n\n    class Query(ObjectType):\n        color = GColor(required=True)\n\n        def resolve_color(_, info):\n            return Color.RED\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"query { color }\")\n    assert not results.errors\n\n    assert results.data[\"color\"] == Color.RED.name\n\n\ndef test_enum_resolver_compat():\n    from enum import Enum as PyEnum\n\n    class Color(PyEnum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    GColor = Enum.from_enum(Color)\n\n    class Query(ObjectType):\n        color = GColor(required=True)\n        color_by_name = GColor(required=True)\n\n        def resolve_color(_, info):\n            return Color.RED.value\n\n        def resolve_color_by_name(_, info):\n            return Color.RED.name\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\n        \"\"\"query {\n            color\n            colorByName\n        }\"\"\"\n    )\n    assert not results.errors\n\n    assert results.data[\"color\"] == Color.RED.name\n    assert results.data[\"colorByName\"] == Color.RED.name\n\n\ndef test_enum_with_name():\n    from enum import Enum as PyEnum\n\n    class Color(PyEnum):\n        RED = 1\n        YELLOW = 2\n        BLUE = 3\n\n    GColor = Enum.from_enum(Color, description=\"original colors\")\n    UniqueGColor = Enum.from_enum(\n        Color, name=\"UniqueColor\", description=\"unique colors\"\n    )\n\n    class Query(ObjectType):\n        color = GColor(required=True)\n        unique_color = UniqueGColor(required=True)\n\n    schema = Schema(query=Query)\n\n    assert (\n        str(schema).strip()\n        == dedent(\n            '''\n            type Query {\n              color: Color!\n              uniqueColor: UniqueColor!\n            }\n\n            \"\"\"original colors\"\"\"\n            enum Color {\n              RED\n              YELLOW\n              BLUE\n            }\n\n            \"\"\"unique colors\"\"\"\n            enum UniqueColor {\n              RED\n              YELLOW\n              BLUE\n            }\n            '''\n        ).strip()\n    )\n\n\ndef test_enum_resolver_invalid():\n    from enum import Enum as PyEnum\n\n    class Color(PyEnum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    GColor = Enum.from_enum(Color)\n\n    class Query(ObjectType):\n        color = GColor(required=True)\n\n        def resolve_color(_, info):\n            return \"BLACK\"\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"query { color }\")\n    assert results.errors\n    assert results.errors[0].message == \"Enum 'Color' cannot represent value: 'BLACK'\"\n\n\ndef test_field_enum_argument():\n    class Color(Enum):\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    class Brick(ObjectType):\n        color = Color(required=True)\n\n    color_filter = None\n\n    class Query(ObjectType):\n        bricks_by_color = Field(Brick, color=Color(required=True))\n\n        def resolve_bricks_by_color(_, info, color):\n            nonlocal color_filter\n            color_filter = color\n            return Brick(color=color)\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\n        \"\"\"\n        query {\n            bricksByColor(color: RED) {\n                color\n            }\n        }\n    \"\"\"\n    )\n    assert not results.errors\n    assert results.data == {\"bricksByColor\": {\"color\": \"RED\"}}\n    assert color_filter == Color.RED\n\n\ndef test_mutation_enum_input():\n    class RGB(Enum):\n        \"\"\"Available colors\"\"\"\n\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    color_input = None\n\n    class CreatePaint(Mutation):\n        class Arguments:\n            color = RGB(required=True)\n\n        color = RGB(required=True)\n\n        def mutate(_, info, color):\n            nonlocal color_input\n            color_input = color\n            return CreatePaint(color=color)\n\n    class MyMutation(ObjectType):\n        create_paint = CreatePaint.Field()\n\n    class Query(ObjectType):\n        a = String()\n\n    schema = Schema(query=Query, mutation=MyMutation)\n    result = schema.execute(\n        \"\"\" mutation MyMutation {\n        createPaint(color: RED) {\n            color\n        }\n    }\n    \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"createPaint\": {\"color\": \"RED\"}}\n\n    assert color_input == RGB.RED\n\n\ndef test_mutation_enum_input_type():\n    class RGB(Enum):\n        \"\"\"Available colors\"\"\"\n\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    class ColorInput(InputObjectType):\n        color = RGB(required=True)\n\n    color_input_value = None\n\n    class CreatePaint(Mutation):\n        class Arguments:\n            color_input = ColorInput(required=True)\n\n        color = RGB(required=True)\n\n        def mutate(_, info, color_input):\n            nonlocal color_input_value\n            color_input_value = color_input.color\n            return CreatePaint(color=color_input.color)\n\n    class MyMutation(ObjectType):\n        create_paint = CreatePaint.Field()\n\n    class Query(ObjectType):\n        a = String()\n\n    schema = Schema(query=Query, mutation=MyMutation)\n    result = schema.execute(\n        \"\"\"\n        mutation MyMutation {\n            createPaint(colorInput: { color: RED }) {\n                color\n            }\n        }\n        \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"createPaint\": {\"color\": \"RED\"}}\n\n    assert color_input_value == RGB.RED\n\n\ndef test_hashable_enum():\n    class RGB(Enum):\n        \"\"\"Available colors\"\"\"\n\n        RED = 1\n        GREEN = 2\n        BLUE = 3\n\n    color_map = {RGB.RED: \"a\", RGB.BLUE: \"b\", 1: \"c\"}\n\n    assert color_map[RGB.RED] == \"a\"\n    assert color_map[RGB.BLUE] == \"b\"\n    assert color_map[1] == \"c\"\n\n\ndef test_hashable_instance_creation_enum():\n    Episode = Enum(\"Episode\", [(\"NEWHOPE\", 4), (\"EMPIRE\", 5), (\"JEDI\", 6)])\n\n    trilogy_map = {Episode.NEWHOPE: \"better\", Episode.EMPIRE: \"best\", 5: \"foo\"}\n\n    assert trilogy_map[Episode.NEWHOPE] == \"better\"\n    assert trilogy_map[Episode.EMPIRE] == \"best\"\n    assert trilogy_map[5] == \"foo\"\n\n\ndef test_enum_iteration():\n    class TestEnum(Enum):\n        FIRST = 1\n        SECOND = 2\n\n    result = []\n    expected_values = [\"FIRST\", \"SECOND\"]\n    for c in TestEnum:\n        result.append(c.name)\n    assert result == expected_values\n\n\ndef test_iterable_instance_creation_enum():\n    TestEnum = Enum(\"TestEnum\", [(\"FIRST\", 1), (\"SECOND\", 2)])\n\n    result = []\n    expected_values = [\"FIRST\", \"SECOND\"]\n    for c in TestEnum:\n        result.append(c.name)\n    assert result == expected_values\n\n\n# https://github.com/graphql-python/graphene/issues/1321\ndef test_enum_description_member_not_interpreted_as_property():\n    class RGB(Enum):\n        \"\"\"Description\"\"\"\n\n        red = \"red\"\n        green = \"green\"\n        blue = \"blue\"\n        description = \"description\"\n        deprecation_reason = \"deprecation_reason\"\n\n    class Query(ObjectType):\n        color = RGB()\n\n        def resolve_color(_, info):\n            return RGB.description\n\n    values = RGB._meta.enum.__members__.values()\n    assert sorted(v.name for v in values) == [\n        \"blue\",\n        \"deprecation_reason\",\n        \"description\",\n        \"green\",\n        \"red\",\n    ]\n\n    schema = Schema(query=Query)\n\n    results = schema.execute(\"query { color }\")\n    assert not results.errors\n    assert results.data[\"color\"] == RGB.description.name\n"
  },
  {
    "path": "graphene/types/tests/test_field.py",
    "content": "from functools import partial\n\nfrom pytest import raises\n\nfrom ..argument import Argument\nfrom ..field import Field\nfrom ..scalars import String\nfrom ..structures import NonNull\nfrom .utils import MyLazyType\n\n\nclass MyInstance:\n    value = \"value\"\n    value_func = staticmethod(lambda: \"value_func\")\n\n    def value_method(self):\n        return \"value_method\"\n\n\ndef test_field_basic():\n    MyType = object()\n    args = {\"my arg\": Argument(True)}\n\n    def resolver():\n        return None\n\n    deprecation_reason = \"Deprecated now\"\n    description = \"My Field\"\n    my_default = \"something\"\n    field = Field(\n        MyType,\n        name=\"name\",\n        args=args,\n        resolver=resolver,\n        description=description,\n        deprecation_reason=deprecation_reason,\n        default_value=my_default,\n    )\n    assert field.name == \"name\"\n    assert field.args == args\n    assert field.resolver == resolver\n    assert field.deprecation_reason == deprecation_reason\n    assert field.description == description\n    assert field.default_value == my_default\n\n\ndef test_field_required():\n    MyType = object()\n    field = Field(MyType, required=True)\n    assert isinstance(field.type, NonNull)\n    assert field.type.of_type == MyType\n\n\ndef test_field_default_value_not_callable():\n    MyType = object()\n    try:\n        Field(MyType, default_value=lambda: True)\n    except AssertionError as e:\n        # substring comparison for py 2/3 compatibility\n        assert \"The default value can not be a function but received\" in str(e)\n\n\ndef test_field_source():\n    MyType = object()\n    field = Field(MyType, source=\"value\")\n    assert field.resolver(MyInstance(), None) == MyInstance.value\n\n\ndef test_field_source_dict_or_attr():\n    MyType = object()\n    field = Field(MyType, source=\"value\")\n    assert field.resolver(MyInstance(), None) == MyInstance.value\n    assert field.resolver({\"value\": MyInstance.value}, None) == MyInstance.value\n\n\ndef test_field_with_lazy_type():\n    MyType = object()\n    field = Field(lambda: MyType)\n    assert field.type == MyType\n\n\ndef test_field_with_lazy_partial_type():\n    MyType = object()\n    field = Field(partial(lambda: MyType))\n    assert field.type == MyType\n\n\ndef test_field_with_string_type():\n    field = Field(\"graphene.types.tests.utils.MyLazyType\")\n    assert field.type == MyLazyType\n\n\ndef test_field_not_source_and_resolver():\n    MyType = object()\n    with raises(Exception) as exc_info:\n        Field(MyType, source=\"value\", resolver=lambda: None)\n    assert (\n        str(exc_info.value)\n        == \"A Field cannot have a source and a resolver in at the same time.\"\n    )\n\n\ndef test_field_source_func():\n    MyType = object()\n    field = Field(MyType, source=\"value_func\")\n    assert field.resolver(MyInstance(), None) == MyInstance.value_func()\n\n\ndef test_field_source_method():\n    MyType = object()\n    field = Field(MyType, source=\"value_method\")\n    assert field.resolver(MyInstance(), None) == MyInstance().value_method()\n\n\ndef test_field_source_as_argument():\n    MyType = object()\n    field = Field(MyType, source=String())\n    assert \"source\" in field.args\n    assert field.args[\"source\"].type == String\n\n\ndef test_field_name_as_argument():\n    MyType = object()\n    field = Field(MyType, name=String())\n    assert \"name\" in field.args\n    assert field.args[\"name\"].type == String\n\n\ndef test_field_source_argument_as_kw():\n    MyType = object()\n    deprecation_reason = \"deprecated\"\n    field = Field(\n        MyType,\n        b=NonNull(True),\n        c=Argument(None, deprecation_reason=deprecation_reason),\n        a=NonNull(False),\n    )\n    assert list(field.args) == [\"b\", \"c\", \"a\"]\n    assert isinstance(field.args[\"b\"], Argument)\n    assert isinstance(field.args[\"b\"].type, NonNull)\n    assert field.args[\"b\"].type.of_type is True\n    assert isinstance(field.args[\"c\"], Argument)\n    assert field.args[\"c\"].type is None\n    assert field.args[\"c\"].deprecation_reason == deprecation_reason\n    assert isinstance(field.args[\"a\"], Argument)\n    assert isinstance(field.args[\"a\"].type, NonNull)\n    assert field.args[\"a\"].type.of_type is False\n"
  },
  {
    "path": "graphene/types/tests/test_generic.py",
    "content": "from ..generic import GenericScalar\nfrom ..objecttype import ObjectType\nfrom ..schema import Schema\n\n\nclass Query(ObjectType):\n    generic = GenericScalar(input=GenericScalar())\n\n    def resolve_generic(self, info, input=None):\n        return input\n\n\nschema = Schema(query=Query)\n\n\ndef test_generic_query_variable():\n    for generic_value in [\n        1,\n        1.1,\n        True,\n        \"str\",\n        [1, 2, 3],\n        [1.1, 2.2, 3.3],\n        [True, False],\n        [\"str1\", \"str2\"],\n        {\"key_a\": \"a\", \"key_b\": \"b\"},\n        {\n            \"int\": 1,\n            \"float\": 1.1,\n            \"boolean\": True,\n            \"string\": \"str\",\n            \"int_list\": [1, 2, 3],\n            \"float_list\": [1.1, 2.2, 3.3],\n            \"boolean_list\": [True, False],\n            \"string_list\": [\"str1\", \"str2\"],\n            \"nested_dict\": {\"key_a\": \"a\", \"key_b\": \"b\"},\n        },\n        None,\n    ]:\n        result = schema.execute(\n            \"\"\"query Test($generic: GenericScalar){ generic(input: $generic) }\"\"\",\n            variables={\"generic\": generic_value},\n        )\n        assert not result.errors\n        assert result.data == {\"generic\": generic_value}\n\n\ndef test_generic_parse_literal_query():\n    result = schema.execute(\n        \"\"\"\n        query {\n            generic(input: {\n                int: 1,\n                float: 1.1\n                boolean: true,\n                string: \"str\",\n                int_list: [1, 2, 3],\n                float_list: [1.1, 2.2, 3.3],\n                boolean_list: [true, false]\n                string_list: [\"str1\", \"str2\"],\n                nested_dict: {\n                    key_a: \"a\",\n                    key_b: \"b\"\n                },\n                empty_key: undefined\n            })\n        }\n        \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\n        \"generic\": {\n            \"int\": 1,\n            \"float\": 1.1,\n            \"boolean\": True,\n            \"string\": \"str\",\n            \"int_list\": [1, 2, 3],\n            \"float_list\": [1.1, 2.2, 3.3],\n            \"boolean_list\": [True, False],\n            \"string_list\": [\"str1\", \"str2\"],\n            \"nested_dict\": {\"key_a\": \"a\", \"key_b\": \"b\"},\n            \"empty_key\": None,\n        }\n    }\n"
  },
  {
    "path": "graphene/types/tests/test_inputfield.py",
    "content": "from functools import partial\n\nfrom pytest import raises\n\nfrom ..inputfield import InputField\nfrom ..structures import NonNull\nfrom .utils import MyLazyType\n\n\ndef test_inputfield_required():\n    MyType = object()\n    field = InputField(MyType, required=True)\n    assert isinstance(field.type, NonNull)\n    assert field.type.of_type == MyType\n\n\ndef test_inputfield_deprecated():\n    MyType = object()\n    deprecation_reason = \"deprecated\"\n    field = InputField(MyType, required=False, deprecation_reason=deprecation_reason)\n    assert isinstance(field.type, type(MyType))\n    assert field.deprecation_reason == deprecation_reason\n\n\ndef test_inputfield_required_deprecated():\n    MyType = object()\n    with raises(AssertionError) as exc_info:\n        InputField(MyType, name=\"input\", required=True, deprecation_reason=\"deprecated\")\n\n    assert str(exc_info.value) == \"InputField input is required, cannot deprecate it.\"\n\n\ndef test_inputfield_with_lazy_type():\n    MyType = object()\n    field = InputField(lambda: MyType)\n    assert field.type == MyType\n\n\ndef test_inputfield_with_lazy_partial_type():\n    MyType = object()\n    field = InputField(partial(lambda: MyType))\n    assert field.type == MyType\n\n\ndef test_inputfield_with_string_type():\n    field = InputField(\"graphene.types.tests.utils.MyLazyType\")\n    assert field.type == MyLazyType\n"
  },
  {
    "path": "graphene/types/tests/test_inputobjecttype.py",
    "content": "from graphql import Undefined\n\nfrom ..argument import Argument\nfrom ..field import Field\nfrom ..inputfield import InputField\nfrom ..inputobjecttype import InputObjectType\nfrom ..objecttype import ObjectType\nfrom ..scalars import Boolean, String\nfrom ..schema import Schema\nfrom ..unmountedtype import UnmountedType\nfrom ... import NonNull\n\n\nclass MyType:\n    pass\n\n\nclass MyScalar(UnmountedType):\n    def get_type(self):\n        return MyType\n\n\ndef test_generate_inputobjecttype():\n    class MyInputObjectType(InputObjectType):\n        \"\"\"Documentation\"\"\"\n\n    assert MyInputObjectType._meta.name == \"MyInputObjectType\"\n    assert MyInputObjectType._meta.description == \"Documentation\"\n    assert MyInputObjectType._meta.fields == {}\n\n\ndef test_generate_inputobjecttype_with_meta():\n    class MyInputObjectType(InputObjectType):\n        class Meta:\n            name = \"MyOtherInputObjectType\"\n            description = \"Documentation\"\n\n    assert MyInputObjectType._meta.name == \"MyOtherInputObjectType\"\n    assert MyInputObjectType._meta.description == \"Documentation\"\n\n\ndef test_generate_inputobjecttype_with_fields():\n    class MyInputObjectType(InputObjectType):\n        field = Field(MyType)\n\n    assert \"field\" in MyInputObjectType._meta.fields\n\n\ndef test_ordered_fields_in_inputobjecttype():\n    class MyInputObjectType(InputObjectType):\n        b = InputField(MyType)\n        a = InputField(MyType)\n        field = MyScalar()\n        asa = InputField(MyType)\n\n    assert list(MyInputObjectType._meta.fields) == [\"b\", \"a\", \"field\", \"asa\"]\n\n\ndef test_generate_inputobjecttype_unmountedtype():\n    class MyInputObjectType(InputObjectType):\n        field = MyScalar(MyType)\n\n    assert \"field\" in MyInputObjectType._meta.fields\n    assert isinstance(MyInputObjectType._meta.fields[\"field\"], InputField)\n\n\ndef test_generate_inputobjecttype_as_argument():\n    class MyInputObjectType(InputObjectType):\n        field = MyScalar()\n\n    class MyObjectType(ObjectType):\n        field = Field(MyType, input=MyInputObjectType())\n\n    assert \"field\" in MyObjectType._meta.fields\n    field = MyObjectType._meta.fields[\"field\"]\n    assert isinstance(field, Field)\n    assert field.type == MyType\n    assert \"input\" in field.args\n    assert isinstance(field.args[\"input\"], Argument)\n    assert field.args[\"input\"].type == MyInputObjectType\n\n\ndef test_generate_inputobjecttype_inherit_abstracttype():\n    class MyAbstractType:\n        field1 = MyScalar(MyType)\n\n    class MyInputObjectType(InputObjectType, MyAbstractType):\n        field2 = MyScalar(MyType)\n\n    assert list(MyInputObjectType._meta.fields) == [\"field1\", \"field2\"]\n    assert [type(x) for x in MyInputObjectType._meta.fields.values()] == [\n        InputField,\n        InputField,\n    ]\n\n\ndef test_generate_inputobjecttype_inherit_abstracttype_reversed():\n    class MyAbstractType:\n        field1 = MyScalar(MyType)\n\n    class MyInputObjectType(MyAbstractType, InputObjectType):\n        field2 = MyScalar(MyType)\n\n    assert list(MyInputObjectType._meta.fields) == [\"field1\", \"field2\"]\n    assert [type(x) for x in MyInputObjectType._meta.fields.values()] == [\n        InputField,\n        InputField,\n    ]\n\n\ndef test_inputobjecttype_of_input():\n    class Child(InputObjectType):\n        first_name = String()\n        last_name = String()\n\n        @property\n        def full_name(self):\n            return f\"{self.first_name} {self.last_name}\"\n\n    class Parent(InputObjectType):\n        child = InputField(Child)\n\n    class Query(ObjectType):\n        is_child = Boolean(parent=Parent())\n\n        def resolve_is_child(self, info, parent):\n            return (\n                isinstance(parent.child, Child)\n                and parent.child.full_name == \"Peter Griffin\"\n            )\n\n    schema = Schema(query=Query)\n    result = schema.execute(\n        \"\"\"query basequery {\n        isChild(parent: {child: {firstName: \"Peter\", lastName: \"Griffin\"}})\n    }\n    \"\"\"\n    )\n\n    assert not result.errors\n    assert result.data == {\"isChild\": True}\n\n\ndef test_inputobjecttype_default_input_as_undefined(\n    set_default_input_object_type_to_undefined,\n):\n    class TestUndefinedInput(InputObjectType):\n        required_field = String(required=True)\n        optional_field = String()\n\n    class Query(ObjectType):\n        undefined_optionals_work = Field(NonNull(Boolean), input=TestUndefinedInput())\n\n        def resolve_undefined_optionals_work(self, info, input: TestUndefinedInput):\n            # Confirm that optional_field comes as Undefined\n            return (\n                input.required_field == \"required\" and input.optional_field is Undefined\n            )\n\n    schema = Schema(query=Query)\n    result = schema.execute(\n        \"\"\"query basequery {\n        undefinedOptionalsWork(input: {requiredField: \"required\"})\n    }\n    \"\"\"\n    )\n\n    assert not result.errors\n    assert result.data == {\"undefinedOptionalsWork\": True}\n"
  },
  {
    "path": "graphene/types/tests/test_interface.py",
    "content": "from ..field import Field\nfrom ..interface import Interface\nfrom ..objecttype import ObjectType\nfrom ..scalars import String\nfrom ..schema import Schema\nfrom ..unmountedtype import UnmountedType\n\n\nclass MyType:\n    pass\n\n\nclass MyScalar(UnmountedType):\n    def get_type(self):\n        return MyType\n\n\ndef test_generate_interface():\n    class MyInterface(Interface):\n        \"\"\"Documentation\"\"\"\n\n    assert MyInterface._meta.name == \"MyInterface\"\n    assert MyInterface._meta.description == \"Documentation\"\n    assert MyInterface._meta.fields == {}\n\n\ndef test_generate_interface_with_meta():\n    class MyFirstInterface(Interface):\n        pass\n\n    class MyInterface(Interface):\n        class Meta:\n            name = \"MyOtherInterface\"\n            description = \"Documentation\"\n            interfaces = [MyFirstInterface]\n\n    assert MyInterface._meta.name == \"MyOtherInterface\"\n    assert MyInterface._meta.description == \"Documentation\"\n    assert MyInterface._meta.interfaces == [MyFirstInterface]\n\n\ndef test_generate_interface_with_fields():\n    class MyInterface(Interface):\n        field = Field(MyType)\n\n    assert \"field\" in MyInterface._meta.fields\n\n\ndef test_ordered_fields_in_interface():\n    class MyInterface(Interface):\n        b = Field(MyType)\n        a = Field(MyType)\n        field = MyScalar()\n        asa = Field(MyType)\n\n    assert list(MyInterface._meta.fields) == [\"b\", \"a\", \"field\", \"asa\"]\n\n\ndef test_generate_interface_unmountedtype():\n    class MyInterface(Interface):\n        field = MyScalar()\n\n    assert \"field\" in MyInterface._meta.fields\n    assert isinstance(MyInterface._meta.fields[\"field\"], Field)\n\n\ndef test_generate_interface_inherit_abstracttype():\n    class MyAbstractType:\n        field1 = MyScalar()\n\n    class MyInterface(Interface, MyAbstractType):\n        field2 = MyScalar()\n\n    assert list(MyInterface._meta.fields) == [\"field1\", \"field2\"]\n    assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]\n\n\ndef test_generate_interface_inherit_interface():\n    class MyBaseInterface(Interface):\n        field1 = MyScalar()\n\n    class MyInterface(MyBaseInterface):\n        field2 = MyScalar()\n\n    assert MyInterface._meta.name == \"MyInterface\"\n    assert list(MyInterface._meta.fields) == [\"field1\", \"field2\"]\n    assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]\n\n\ndef test_generate_interface_inherit_abstracttype_reversed():\n    class MyAbstractType:\n        field1 = MyScalar()\n\n    class MyInterface(MyAbstractType, Interface):\n        field2 = MyScalar()\n\n    assert list(MyInterface._meta.fields) == [\"field1\", \"field2\"]\n    assert [type(x) for x in MyInterface._meta.fields.values()] == [Field, Field]\n\n\ndef test_resolve_type_default():\n    class MyInterface(Interface):\n        field2 = String()\n\n    class MyTestType(ObjectType):\n        class Meta:\n            interfaces = (MyInterface,)\n\n    class Query(ObjectType):\n        test = Field(MyInterface)\n\n        def resolve_test(_, info):\n            return MyTestType()\n\n    schema = Schema(query=Query, types=[MyTestType])\n\n    result = schema.execute(\n        \"\"\"\n        query {\n            test {\n                __typename\n            }\n        }\n    \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"test\": {\"__typename\": \"MyTestType\"}}\n\n\ndef test_resolve_type_custom():\n    class MyInterface(Interface):\n        field2 = String()\n\n        @classmethod\n        def resolve_type(cls, instance, info):\n            if instance[\"type\"] == 1:\n                return MyTestType1\n            return MyTestType2\n\n    class MyTestType1(ObjectType):\n        class Meta:\n            interfaces = (MyInterface,)\n\n    class MyTestType2(ObjectType):\n        class Meta:\n            interfaces = (MyInterface,)\n\n    class Query(ObjectType):\n        test = Field(MyInterface)\n\n        def resolve_test(_, info):\n            return {\"type\": 1}\n\n    schema = Schema(query=Query, types=[MyTestType1, MyTestType2])\n\n    result = schema.execute(\n        \"\"\"\n        query {\n            test {\n                __typename\n            }\n        }\n    \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"test\": {\"__typename\": \"MyTestType1\"}}\n\n\ndef test_resolve_type_custom_interferes():\n    class MyInterface(Interface):\n        field2 = String()\n        type_ = String(name=\"type\")\n\n        def resolve_type_(_, info):\n            return \"foo\"\n\n    class MyTestType1(ObjectType):\n        class Meta:\n            interfaces = (MyInterface,)\n\n    class MyTestType2(ObjectType):\n        class Meta:\n            interfaces = (MyInterface,)\n\n    class Query(ObjectType):\n        test = Field(MyInterface)\n\n        def resolve_test(_, info):\n            return MyTestType1()\n\n    schema = Schema(query=Query, types=[MyTestType1, MyTestType2])\n\n    result = schema.execute(\n        \"\"\"\n        query {\n            test {\n                __typename\n                type\n            }\n        }\n    \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"test\": {\"__typename\": \"MyTestType1\", \"type\": \"foo\"}}\n"
  },
  {
    "path": "graphene/types/tests/test_json.py",
    "content": "from ..json import JSONString\nfrom ..objecttype import ObjectType\nfrom ..schema import Schema\n\n\nclass Query(ObjectType):\n    json = JSONString(input=JSONString())\n\n    def resolve_json(self, info, input):\n        return input\n\n\nschema = Schema(query=Query)\n\n\ndef test_jsonstring_query():\n    json_value = '{\"key\": \"value\"}'\n\n    json_value_quoted = json_value.replace('\"', '\\\\\"')\n    result = schema.execute(\"\"\"{ json(input: \"%s\") }\"\"\" % json_value_quoted)\n    assert not result.errors\n    assert result.data == {\"json\": json_value}\n\n    result = schema.execute(\"\"\"{ json(input: \"{}\") }\"\"\")\n    assert not result.errors\n    assert result.data == {\"json\": \"{}\"}\n\n\ndef test_jsonstring_query_variable():\n    json_value = '{\"key\": \"value\"}'\n\n    result = schema.execute(\n        \"\"\"query Test($json: JSONString){ json(input: $json) }\"\"\",\n        variables={\"json\": json_value},\n    )\n    assert not result.errors\n    assert result.data == {\"json\": json_value}\n\n\ndef test_jsonstring_optional_uuid_input():\n    \"\"\"\n    Test that we can provide a null value to an optional input\n    \"\"\"\n    result = schema.execute(\"{ json(input: null) }\")\n    assert not result.errors\n    assert result.data == {\"json\": None}\n\n\ndef test_jsonstring_invalid_query():\n    \"\"\"\n    Test that if an invalid type is provided we get an error\n    \"\"\"\n    result = schema.execute(\"{ json(input: 1) }\")\n    assert result.errors == [\n        {\"message\": \"Expected value of type 'JSONString', found 1.\"},\n    ]\n\n    result = schema.execute(\"{ json(input: {}) }\")\n    assert result.errors == [\n        {\"message\": \"Expected value of type 'JSONString', found {}.\"},\n    ]\n\n    result = schema.execute('{ json(input: \"a\") }')\n    assert result.errors == [\n        {\n            \"message\": \"Expected value of type 'JSONString', found \\\"a\\\"; \"\n            \"Badly formed JSONString: Expecting value: line 1 column 1 (char 0)\",\n        },\n    ]\n\n    result = schema.execute(\"\"\"{ json(input: \"{\\\\'key\\\\': 0}\") }\"\"\")\n    assert result.errors == [\n        {\"message\": \"Syntax Error: Invalid character escape sequence: '\\\\''.\"},\n    ]\n\n    result = schema.execute(\"\"\"{ json(input: \"{\\\\\"key\\\\\": 0,}\") }\"\"\")\n    assert len(result.errors) == 1\n    assert result.errors[0].message.startswith(\n        'Expected value of type \\'JSONString\\', found \"{\\\\\"key\\\\\": 0,}\"; Badly formed JSONString:'\n    )\n"
  },
  {
    "path": "graphene/types/tests/test_mountedtype.py",
    "content": "from ..field import Field\nfrom ..scalars import String\n\n\nclass CustomField(Field):\n    def __init__(self, *args, **kwargs):\n        self.metadata = kwargs.pop(\"metadata\", None)\n        super(CustomField, self).__init__(*args, **kwargs)\n\n\ndef test_mounted_type():\n    unmounted = String()\n    mounted = Field.mounted(unmounted)\n    assert isinstance(mounted, Field)\n    assert mounted.type == String\n\n\ndef test_mounted_type_custom():\n    unmounted = String(metadata={\"hey\": \"yo!\"})\n    mounted = CustomField.mounted(unmounted)\n    assert isinstance(mounted, CustomField)\n    assert mounted.type == String\n    assert mounted.metadata == {\"hey\": \"yo!\"}\n"
  },
  {
    "path": "graphene/types/tests/test_mutation.py",
    "content": "from pytest import raises\n\nfrom ..argument import Argument\nfrom ..dynamic import Dynamic\nfrom ..mutation import Mutation\nfrom ..objecttype import ObjectType\nfrom ..scalars import String\nfrom ..schema import Schema\nfrom ..structures import NonNull\nfrom ..interface import Interface\n\n\nclass MyType(Interface):\n    pass\n\n\ndef test_generate_mutation_no_args():\n    class MyMutation(Mutation):\n        \"\"\"Documentation\"\"\"\n\n        def mutate(self, info, **args):\n            return args\n\n    assert issubclass(MyMutation, ObjectType)\n    assert MyMutation._meta.name == \"MyMutation\"\n    assert MyMutation._meta.description == \"Documentation\"\n    resolved = MyMutation.Field().resolver(None, None, name=\"Peter\")\n    assert resolved == {\"name\": \"Peter\"}\n\n\ndef test_generate_mutation_with_meta():\n    class MyMutation(Mutation):\n        class Meta:\n            name = \"MyOtherMutation\"\n            description = \"Documentation\"\n            interfaces = (MyType,)\n\n        def mutate(self, info, **args):\n            return args\n\n    assert MyMutation._meta.name == \"MyOtherMutation\"\n    assert MyMutation._meta.description == \"Documentation\"\n    assert MyMutation._meta.interfaces == (MyType,)\n    resolved = MyMutation.Field().resolver(None, None, name=\"Peter\")\n    assert resolved == {\"name\": \"Peter\"}\n\n\ndef test_mutation_raises_exception_if_no_mutate():\n    with raises(AssertionError) as excinfo:\n\n        class MyMutation(Mutation):\n            pass\n\n    assert \"All mutations must define a mutate method in it\" == str(excinfo.value)\n\n\ndef test_mutation_custom_output_type():\n    class User(ObjectType):\n        name = String()\n\n    class CreateUser(Mutation):\n        class Arguments:\n            name = String()\n\n        Output = User\n\n        def mutate(self, info, name):\n            return User(name=name)\n\n    field = CreateUser.Field()\n    assert field.type == User\n    assert field.args == {\"name\": Argument(String)}\n    resolved = field.resolver(None, None, name=\"Peter\")\n    assert isinstance(resolved, User)\n    assert resolved.name == \"Peter\"\n\n\ndef test_mutation_execution():\n    class CreateUser(Mutation):\n        class Arguments:\n            name = String()\n            dynamic = Dynamic(lambda: String())\n            dynamic_none = Dynamic(lambda: None)\n\n        name = String()\n        dynamic = Dynamic(lambda: String())\n\n        def mutate(self, info, name, dynamic):\n            return CreateUser(name=name, dynamic=dynamic)\n\n    class Query(ObjectType):\n        a = String()\n\n    class MyMutation(ObjectType):\n        create_user = CreateUser.Field()\n\n    schema = Schema(query=Query, mutation=MyMutation)\n    result = schema.execute(\n        \"\"\" mutation mymutation {\n        createUser(name:\"Peter\", dynamic: \"dynamic\") {\n            name\n            dynamic\n        }\n    }\n    \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"createUser\": {\"name\": \"Peter\", \"dynamic\": \"dynamic\"}}\n\n\ndef test_mutation_no_fields_output():\n    class CreateUser(Mutation):\n        name = String()\n\n        def mutate(self, info):\n            return CreateUser()\n\n    class Query(ObjectType):\n        a = String()\n\n    class MyMutation(ObjectType):\n        create_user = CreateUser.Field()\n\n    schema = Schema(query=Query, mutation=MyMutation)\n    result = schema.execute(\n        \"\"\" mutation mymutation {\n        createUser {\n            name\n        }\n    }\n    \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"createUser\": {\"name\": None}}\n\n\ndef test_mutation_allow_to_have_custom_args():\n    class CreateUser(Mutation):\n        class Arguments:\n            name = String()\n\n        name = String()\n\n        def mutate(self, info, name):\n            return CreateUser(name=name)\n\n    class MyMutation(ObjectType):\n        create_user = CreateUser.Field(\n            name=\"createUser\",\n            description=\"Create a user\",\n            deprecation_reason=\"Is deprecated\",\n            required=True,\n        )\n\n    field = MyMutation._meta.fields[\"create_user\"]\n    assert field.name == \"createUser\"\n    assert field.description == \"Create a user\"\n    assert field.deprecation_reason == \"Is deprecated\"\n    assert field.type == NonNull(CreateUser)\n\n\ndef test_mutation_default_args_output():\n    class CreateUser(Mutation):\n        \"\"\"Description.\"\"\"\n\n        class Arguments:\n            name = String()\n\n        name = String()\n\n        def mutate(self, info, name):\n            return CreateUser(name=name)\n\n    class MyMutation(ObjectType):\n        create_user = CreateUser.Field()\n\n    field = MyMutation._meta.fields[\"create_user\"]\n    assert field.name is None\n    assert field.description == \"Description.\"\n    assert field.deprecation_reason is None\n    assert field.type == CreateUser\n\n\ndef test_mutation_as_subclass():\n    class BaseCreateUser(Mutation):\n        class Arguments:\n            name = String()\n\n        name = String()\n\n        def mutate(self, info, **args):\n            return args\n\n    class CreateUserWithPlanet(BaseCreateUser):\n        class Arguments(BaseCreateUser.Arguments):\n            planet = String()\n\n        planet = String()\n\n        def mutate(self, info, **args):\n            return CreateUserWithPlanet(**args)\n\n    class MyMutation(ObjectType):\n        create_user_with_planet = CreateUserWithPlanet.Field()\n\n    class Query(ObjectType):\n        a = String()\n\n    schema = Schema(query=Query, mutation=MyMutation)\n    result = schema.execute(\n        \"\"\" mutation mymutation {\n        createUserWithPlanet(name:\"Peter\", planet: \"earth\") {\n            name\n            planet\n        }\n    }\n    \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"createUserWithPlanet\": {\"name\": \"Peter\", \"planet\": \"earth\"}}\n"
  },
  {
    "path": "graphene/types/tests/test_objecttype.py",
    "content": "from pytest import raises\n\nfrom ..field import Field\nfrom ..interface import Interface\nfrom ..objecttype import ObjectType\nfrom ..scalars import String\nfrom ..schema import Schema\nfrom ..structures import NonNull\nfrom ..unmountedtype import UnmountedType\n\n\nclass MyType(Interface):\n    pass\n\n\nclass Container(ObjectType):\n    field1 = Field(MyType)\n    field2 = Field(MyType)\n\n\nclass MyInterface(Interface):\n    ifield = Field(MyType)\n\n\nclass ContainerWithInterface(ObjectType):\n    class Meta:\n        interfaces = (MyInterface,)\n\n    field1 = Field(MyType)\n    field2 = Field(MyType)\n\n\nclass MyScalar(UnmountedType):\n    def get_type(self):\n        return MyType\n\n\ndef test_generate_objecttype():\n    class MyObjectType(ObjectType):\n        \"\"\"Documentation\"\"\"\n\n    assert MyObjectType._meta.name == \"MyObjectType\"\n    assert MyObjectType._meta.description == \"Documentation\"\n    assert MyObjectType._meta.interfaces == tuple()\n    assert MyObjectType._meta.fields == {}\n    assert (\n        repr(MyObjectType)\n        == \"<MyObjectType meta=<ObjectTypeOptions name='MyObjectType'>>\"\n    )\n\n\ndef test_generate_objecttype_with_meta():\n    class MyObjectType(ObjectType):\n        class Meta:\n            name = \"MyOtherObjectType\"\n            description = \"Documentation\"\n            interfaces = (MyType,)\n\n    assert MyObjectType._meta.name == \"MyOtherObjectType\"\n    assert MyObjectType._meta.description == \"Documentation\"\n    assert MyObjectType._meta.interfaces == (MyType,)\n\n\ndef test_generate_lazy_objecttype():\n    class MyObjectType(ObjectType):\n        example = Field(lambda: InnerObjectType, required=True)\n\n    class InnerObjectType(ObjectType):\n        field = Field(MyType)\n\n    assert MyObjectType._meta.name == \"MyObjectType\"\n    example_field = MyObjectType._meta.fields[\"example\"]\n    assert isinstance(example_field.type, NonNull)\n    assert example_field.type.of_type == InnerObjectType\n\n\ndef test_generate_objecttype_with_fields():\n    class MyObjectType(ObjectType):\n        field = Field(MyType)\n\n    assert \"field\" in MyObjectType._meta.fields\n\n\ndef test_generate_objecttype_with_private_attributes():\n    class MyObjectType(ObjectType):\n        def __init__(self, _private_state=None, **kwargs):\n            self._private_state = _private_state\n            super().__init__(**kwargs)\n\n        _private_state = None\n\n    assert \"_private_state\" not in MyObjectType._meta.fields\n    assert hasattr(MyObjectType, \"_private_state\")\n\n    m = MyObjectType(_private_state=\"custom\")\n    assert m._private_state == \"custom\"\n\n    with raises(TypeError):\n        MyObjectType(_other_private_state=\"Wrong\")\n\n\ndef test_ordered_fields_in_objecttype():\n    class MyObjectType(ObjectType):\n        b = Field(MyType)\n        a = Field(MyType)\n        field = MyScalar()\n        asa = Field(MyType)\n\n    assert list(MyObjectType._meta.fields) == [\"b\", \"a\", \"field\", \"asa\"]\n\n\ndef test_generate_objecttype_inherit_abstracttype():\n    class MyAbstractType:\n        field1 = MyScalar()\n\n    class MyObjectType(ObjectType, MyAbstractType):\n        field2 = MyScalar()\n\n    assert MyObjectType._meta.description is None\n    assert MyObjectType._meta.interfaces == ()\n    assert MyObjectType._meta.name == \"MyObjectType\"\n    assert list(MyObjectType._meta.fields) == [\"field1\", \"field2\"]\n    assert list(map(type, MyObjectType._meta.fields.values())) == [Field, Field]\n\n\ndef test_generate_objecttype_inherit_abstracttype_reversed():\n    class MyAbstractType:\n        field1 = MyScalar()\n\n    class MyObjectType(MyAbstractType, ObjectType):\n        field2 = MyScalar()\n\n    assert MyObjectType._meta.description is None\n    assert MyObjectType._meta.interfaces == ()\n    assert MyObjectType._meta.name == \"MyObjectType\"\n    assert list(MyObjectType._meta.fields) == [\"field1\", \"field2\"]\n    assert list(map(type, MyObjectType._meta.fields.values())) == [Field, Field]\n\n\ndef test_generate_objecttype_unmountedtype():\n    class MyObjectType(ObjectType):\n        field = MyScalar()\n\n    assert \"field\" in MyObjectType._meta.fields\n    assert isinstance(MyObjectType._meta.fields[\"field\"], Field)\n\n\ndef test_parent_container_get_fields():\n    assert list(Container._meta.fields) == [\"field1\", \"field2\"]\n\n\ndef test_parent_container_interface_get_fields():\n    assert list(ContainerWithInterface._meta.fields) == [\"ifield\", \"field1\", \"field2\"]\n\n\ndef test_objecttype_as_container_only_args():\n    container = Container(\"1\", \"2\")\n    assert container.field1 == \"1\"\n    assert container.field2 == \"2\"\n\n\ndef test_objecttype_repr():\n    container = Container(\"1\", \"2\")\n    assert repr(container) == \"Container(field1='1', field2='2')\"\n\n\ndef test_objecttype_eq():\n    container1 = Container(\"1\", \"2\")\n    container2 = Container(\"1\", \"2\")\n    container3 = Container(\"2\", \"3\")\n    assert container1 == container1\n    assert container1 == container2\n    assert container2 != container3\n\n\ndef test_objecttype_as_container_args_kwargs():\n    container = Container(\"1\", field2=\"2\")\n    assert container.field1 == \"1\"\n    assert container.field2 == \"2\"\n\n\ndef test_objecttype_as_container_few_kwargs():\n    container = Container(field2=\"2\")\n    assert container.field2 == \"2\"\n\n\ndef test_objecttype_as_container_all_kwargs():\n    container = Container(field1=\"1\", field2=\"2\")\n    assert container.field1 == \"1\"\n    assert container.field2 == \"2\"\n\n\ndef test_objecttype_as_container_extra_args():\n    msg = r\"__init__\\(\\) takes from 1 to 3 positional arguments but 4 were given\"\n    with raises(TypeError, match=msg):\n        Container(\"1\", \"2\", \"3\")  # type: ignore\n\n\ndef test_objecttype_as_container_invalid_kwargs():\n    msg = r\"__init__\\(\\) got an unexpected keyword argument 'unexisting_field'\"\n    with raises(TypeError, match=msg):\n        Container(unexisting_field=\"3\")  # type: ignore\n\n\ndef test_objecttype_container_benchmark(benchmark):\n    @benchmark\n    def create_objecttype():\n        Container(field1=\"field1\", field2=\"field2\")\n\n\ndef test_generate_objecttype_description():\n    class MyObjectType(ObjectType):\n        \"\"\"\n        Documentation\n\n        Documentation line 2\n        \"\"\"\n\n    assert MyObjectType._meta.description == \"Documentation\\n\\nDocumentation line 2\"\n\n\ndef test_objecttype_with_possible_types():\n    class MyObjectType(ObjectType):\n        class Meta:\n            possible_types = (dict,)\n\n    assert MyObjectType._meta.possible_types == (dict,)\n\n\ndef test_objecttype_with_possible_types_and_is_type_of_should_raise():\n    with raises(AssertionError) as excinfo:\n\n        class MyObjectType(ObjectType):\n            class Meta:\n                possible_types = (dict,)\n\n            @classmethod\n            def is_type_of(cls, root, context, info):\n                return False\n\n    assert str(excinfo.value) == (\n        \"MyObjectType.Meta.possible_types will cause type collision with \"\n        \"MyObjectType.is_type_of. Please use one or other.\"\n    )\n\n\ndef test_objecttype_no_fields_output():\n    class User(ObjectType):\n        name = String()\n\n    class Query(ObjectType):\n        user = Field(User)\n\n        def resolve_user(self, info):\n            return User()\n\n    schema = Schema(query=Query)\n    result = schema.execute(\n        \"\"\" query basequery {\n        user {\n            name\n        }\n    }\n    \"\"\"\n    )\n    assert not result.errors\n    assert result.data == {\"user\": {\"name\": None}}\n\n\ndef test_abstract_objecttype_can_str():\n    class MyObjectType(ObjectType):\n        class Meta:\n            abstract = True\n\n        field = MyScalar()\n\n    assert str(MyObjectType) == \"MyObjectType\"\n\n\ndef test_objecttype_meta_with_annotations():\n    class Query(ObjectType):\n        class Meta:\n            name: str = \"oops\"\n\n        hello = String()\n\n        def resolve_hello(self, info):\n            return \"Hello\"\n\n    schema = Schema(query=Query)\n    assert schema is not None\n\n\ndef test_objecttype_meta_arguments():\n    class MyInterface(Interface):\n        foo = String()\n\n    class MyType(ObjectType, interfaces=[MyInterface]):\n        bar = String()\n\n    assert MyType._meta.interfaces == [MyInterface]\n    assert list(MyType._meta.fields.keys()) == [\"foo\", \"bar\"]\n\n\ndef test_objecttype_type_name():\n    class MyObjectType(ObjectType, name=\"FooType\"):\n        pass\n\n    assert MyObjectType._meta.name == \"FooType\"\n"
  },
  {
    "path": "graphene/types/tests/test_query.py",
    "content": "import json\nfrom functools import partial\n\nfrom graphql import (\n    GraphQLError,\n    GraphQLResolveInfo as ResolveInfo,\n    Source,\n    execute,\n    parse,\n)\n\nfrom ..context import Context\nfrom ..dynamic import Dynamic\nfrom ..field import Field\nfrom ..inputfield import InputField\nfrom ..inputobjecttype import InputObjectType\nfrom ..interface import Interface\nfrom ..objecttype import ObjectType\nfrom ..scalars import Boolean, Int, String\nfrom ..schema import Schema\nfrom ..structures import List, NonNull\nfrom ..union import Union\n\n\ndef test_query():\n    class Query(ObjectType):\n        hello = String(resolver=lambda *_: \"World\")\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\"{ hello }\")\n    assert not executed.errors\n    assert executed.data == {\"hello\": \"World\"}\n\n\ndef test_query_source():\n    class Root:\n        _hello = \"World\"\n\n        def hello(self):\n            return self._hello\n\n    class Query(ObjectType):\n        hello = String(source=\"hello\")\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\"{ hello }\", Root())\n    assert not executed.errors\n    assert executed.data == {\"hello\": \"World\"}\n\n\ndef test_query_union():\n    class one_object:\n        pass\n\n    class two_object:\n        pass\n\n    class One(ObjectType):\n        one = String()\n\n        @classmethod\n        def is_type_of(cls, root, info):\n            return isinstance(root, one_object)\n\n    class Two(ObjectType):\n        two = String()\n\n        @classmethod\n        def is_type_of(cls, root, info):\n            return isinstance(root, two_object)\n\n    class MyUnion(Union):\n        class Meta:\n            types = (One, Two)\n\n    class Query(ObjectType):\n        unions = List(MyUnion)\n\n        def resolve_unions(self, info):\n            return [one_object(), two_object()]\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\"{ unions { __typename } }\")\n    assert not executed.errors\n    assert executed.data == {\"unions\": [{\"__typename\": \"One\"}, {\"__typename\": \"Two\"}]}\n\n\ndef test_query_interface():\n    class one_object:\n        pass\n\n    class two_object:\n        pass\n\n    class MyInterface(Interface):\n        base = String()\n\n    class One(ObjectType):\n        class Meta:\n            interfaces = (MyInterface,)\n\n        one = String()\n\n        @classmethod\n        def is_type_of(cls, root, info):\n            return isinstance(root, one_object)\n\n    class Two(ObjectType):\n        class Meta:\n            interfaces = (MyInterface,)\n\n        two = String()\n\n        @classmethod\n        def is_type_of(cls, root, info):\n            return isinstance(root, two_object)\n\n    class Query(ObjectType):\n        interfaces = List(MyInterface)\n\n        def resolve_interfaces(self, info):\n            return [one_object(), two_object()]\n\n    hello_schema = Schema(Query, types=[One, Two])\n\n    executed = hello_schema.execute(\"{ interfaces { __typename } }\")\n    assert not executed.errors\n    assert executed.data == {\n        \"interfaces\": [{\"__typename\": \"One\"}, {\"__typename\": \"Two\"}]\n    }\n\n\ndef test_query_dynamic():\n    class Query(ObjectType):\n        hello = Dynamic(lambda: String(resolver=lambda *_: \"World\"))\n        hellos = Dynamic(lambda: List(String, resolver=lambda *_: [\"Worlds\"]))\n        hello_field = Dynamic(lambda: Field(String, resolver=lambda *_: \"Field World\"))\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\"{ hello hellos helloField }\")\n    assert not executed.errors\n    assert executed.data == {\n        \"hello\": \"World\",\n        \"hellos\": [\"Worlds\"],\n        \"helloField\": \"Field World\",\n    }\n\n\ndef test_query_default_value():\n    class MyType(ObjectType):\n        field = String()\n\n    class Query(ObjectType):\n        hello = Field(MyType, default_value=MyType(field=\"something else!\"))\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\"{ hello { field } }\")\n    assert not executed.errors\n    assert executed.data == {\"hello\": {\"field\": \"something else!\"}}\n\n\ndef test_query_wrong_default_value():\n    class MyType(ObjectType):\n        field = String()\n\n        @classmethod\n        def is_type_of(cls, root, info):\n            return isinstance(root, MyType)\n\n    class Query(ObjectType):\n        hello = Field(MyType, default_value=\"hello\")\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\"{ hello { field } }\")\n    assert len(executed.errors) == 1\n    assert (\n        executed.errors[0].message\n        == GraphQLError(\"Expected value of type 'MyType' but got: 'hello'.\").message\n    )\n    assert executed.data == {\"hello\": None}\n\n\ndef test_query_default_value_ignored_by_resolver():\n    class MyType(ObjectType):\n        field = String()\n\n    class Query(ObjectType):\n        hello = Field(\n            MyType,\n            default_value=\"hello\",\n            resolver=lambda *_: MyType(field=\"no default.\"),\n        )\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\"{ hello { field } }\")\n    assert not executed.errors\n    assert executed.data == {\"hello\": {\"field\": \"no default.\"}}\n\n\ndef test_query_resolve_function():\n    class Query(ObjectType):\n        hello = String()\n\n        def resolve_hello(self, info):\n            return \"World\"\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\"{ hello }\")\n    assert not executed.errors\n    assert executed.data == {\"hello\": \"World\"}\n\n\ndef test_query_arguments():\n    class Query(ObjectType):\n        test = String(a_str=String(), a_int=Int())\n\n        def resolve_test(self, info, **args):\n            return json.dumps([self, args], separators=(\",\", \":\"))\n\n    test_schema = Schema(Query)\n\n    result = test_schema.execute(\"{ test }\", None)\n    assert not result.errors\n    assert result.data == {\"test\": \"[null,{}]\"}\n\n    result = test_schema.execute('{ test(aStr: \"String!\") }', \"Source!\")\n    assert not result.errors\n    assert result.data == {\"test\": '[\"Source!\",{\"a_str\":\"String!\"}]'}\n\n    result = test_schema.execute('{ test(aInt: -123, aStr: \"String!\") }', \"Source!\")\n    assert not result.errors\n    assert result.data in [\n        {\"test\": '[\"Source!\",{\"a_str\":\"String!\",\"a_int\":-123}]'},\n        {\"test\": '[\"Source!\",{\"a_int\":-123,\"a_str\":\"String!\"}]'},\n    ]\n\n\ndef test_query_input_field():\n    class Input(InputObjectType):\n        a_field = String()\n        recursive_field = InputField(lambda: Input)\n\n    class Query(ObjectType):\n        test = String(a_input=Input())\n\n        def resolve_test(self, info, **args):\n            return json.dumps([self, args], separators=(\",\", \":\"))\n\n    test_schema = Schema(Query)\n\n    result = test_schema.execute(\"{ test }\", None)\n    assert not result.errors\n    assert result.data == {\"test\": \"[null,{}]\"}\n\n    result = test_schema.execute('{ test(aInput: {aField: \"String!\"} ) }', \"Source!\")\n    assert not result.errors\n    assert result.data == {\"test\": '[\"Source!\",{\"a_input\":{\"a_field\":\"String!\"}}]'}\n\n    result = test_schema.execute(\n        '{ test(aInput: {recursiveField: {aField: \"String!\"}}) }', \"Source!\"\n    )\n    assert not result.errors\n    assert result.data == {\n        \"test\": '[\"Source!\",{\"a_input\":{\"recursive_field\":{\"a_field\":\"String!\"}}}]'\n    }\n\n\ndef test_query_middlewares():\n    class Query(ObjectType):\n        hello = String()\n        other = String()\n\n        def resolve_hello(self, info):\n            return \"World\"\n\n        def resolve_other(self, info):\n            return \"other\"\n\n    def reversed_middleware(next, *args, **kwargs):\n        return next(*args, **kwargs)[::-1]\n\n    hello_schema = Schema(Query)\n\n    executed = hello_schema.execute(\n        \"{ hello, other }\", middleware=[reversed_middleware]\n    )\n    assert not executed.errors\n    assert executed.data == {\"hello\": \"dlroW\", \"other\": \"rehto\"}\n\n\ndef test_objecttype_on_instances():\n    class Ship:\n        def __init__(self, name):\n            self.name = name\n\n    class ShipType(ObjectType):\n        name = String(description=\"Ship name\", required=True)\n\n        def resolve_name(self, info):\n            # Here self will be the Ship instance returned in resolve_ship\n            return self.name\n\n    class Query(ObjectType):\n        ship = Field(ShipType)\n\n        def resolve_ship(self, info):\n            return Ship(name=\"xwing\")\n\n    schema = Schema(query=Query)\n    executed = schema.execute(\"{ ship { name } }\")\n    assert not executed.errors\n    assert executed.data == {\"ship\": {\"name\": \"xwing\"}}\n\n\ndef test_big_list_query_benchmark(benchmark):\n    big_list = range(10000)\n\n    class Query(ObjectType):\n        all_ints = List(Int)\n\n        def resolve_all_ints(self, info):\n            return big_list\n\n    hello_schema = Schema(Query)\n\n    big_list_query = partial(hello_schema.execute, \"{ allInts }\")\n    result = benchmark(big_list_query)\n    assert not result.errors\n    assert result.data == {\"allInts\": list(big_list)}\n\n\ndef test_big_list_query_compiled_query_benchmark(benchmark):\n    big_list = range(100000)\n\n    class Query(ObjectType):\n        all_ints = List(Int)\n\n        def resolve_all_ints(self, info):\n            return big_list\n\n    hello_schema = Schema(Query)\n    graphql_schema = hello_schema.graphql_schema\n    source = Source(\"{ allInts }\")\n    query_ast = parse(source)\n\n    big_list_query = partial(execute, graphql_schema, query_ast)\n    result = benchmark(big_list_query)\n    assert not result.errors\n    assert result.data == {\"allInts\": list(big_list)}\n\n\ndef test_big_list_of_containers_query_benchmark(benchmark):\n    class Container(ObjectType):\n        x = Int()\n\n    big_container_list = [Container(x=x) for x in range(1000)]\n\n    class Query(ObjectType):\n        all_containers = List(Container)\n\n        def resolve_all_containers(self, info):\n            return big_container_list\n\n    hello_schema = Schema(Query)\n\n    big_list_query = partial(hello_schema.execute, \"{ allContainers { x } }\")\n    result = benchmark(big_list_query)\n    assert not result.errors\n    assert result.data == {\"allContainers\": [{\"x\": c.x} for c in big_container_list]}\n\n\ndef test_big_list_of_containers_multiple_fields_query_benchmark(benchmark):\n    class Container(ObjectType):\n        x = Int()\n        y = Int()\n        z = Int()\n        o = Int()\n\n    big_container_list = [Container(x=x, y=x, z=x, o=x) for x in range(1000)]\n\n    class Query(ObjectType):\n        all_containers = List(Container)\n\n        def resolve_all_containers(self, info):\n            return big_container_list\n\n    hello_schema = Schema(Query)\n\n    big_list_query = partial(hello_schema.execute, \"{ allContainers { x, y, z, o } }\")\n    result = benchmark(big_list_query)\n    assert not result.errors\n    assert result.data == {\n        \"allContainers\": [\n            {\"x\": c.x, \"y\": c.y, \"z\": c.z, \"o\": c.o} for c in big_container_list\n        ]\n    }\n\n\ndef test_big_list_of_containers_multiple_fields_custom_resolvers_query_benchmark(\n    benchmark,\n):\n    class Container(ObjectType):\n        x = Int()\n        y = Int()\n        z = Int()\n        o = Int()\n\n        def resolve_x(self, info):\n            return self.x\n\n        def resolve_y(self, info):\n            return self.y\n\n        def resolve_z(self, info):\n            return self.z\n\n        def resolve_o(self, info):\n            return self.o\n\n    big_container_list = [Container(x=x, y=x, z=x, o=x) for x in range(1000)]\n\n    class Query(ObjectType):\n        all_containers = List(Container)\n\n        def resolve_all_containers(self, info):\n            return big_container_list\n\n    hello_schema = Schema(Query)\n\n    big_list_query = partial(hello_schema.execute, \"{ allContainers { x, y, z, o } }\")\n    result = benchmark(big_list_query)\n    assert not result.errors\n    assert result.data == {\n        \"allContainers\": [\n            {\"x\": c.x, \"y\": c.y, \"z\": c.z, \"o\": c.o} for c in big_container_list\n        ]\n    }\n\n\ndef test_query_annotated_resolvers():\n    context = Context(key=\"context\")\n\n    class Query(ObjectType):\n        annotated = String(id=String())\n        context = String()\n        info = String()\n\n        def resolve_annotated(self, info, id):\n            return f\"{self}-{id}\"\n\n        def resolve_context(self, info):\n            assert isinstance(info.context, Context)\n            return f\"{self}-{info.context.key}\"\n\n        def resolve_info(self, info):\n            assert isinstance(info, ResolveInfo)\n            return f\"{self}-{info.field_name}\"\n\n    test_schema = Schema(Query)\n\n    result = test_schema.execute('{ annotated(id:\"self\") }', \"base\")\n    assert not result.errors\n    assert result.data == {\"annotated\": \"base-self\"}\n\n    result = test_schema.execute(\"{ context }\", \"base\", context=context)\n    assert not result.errors\n    assert result.data == {\"context\": \"base-context\"}\n\n    result = test_schema.execute(\"{ info }\", \"base\")\n    assert not result.errors\n    assert result.data == {\"info\": \"base-info\"}\n\n\ndef test_default_as_kwarg_to_NonNull():\n    # Related to https://github.com/graphql-python/graphene/issues/702\n    class User(ObjectType):\n        name = String()\n        is_admin = NonNull(Boolean, default_value=False)\n\n    class Query(ObjectType):\n        user = Field(User)\n\n        def resolve_user(self, *args, **kwargs):\n            return User(name=\"foo\")\n\n    schema = Schema(query=Query)\n    expected = {\"user\": {\"name\": \"foo\", \"isAdmin\": False}}\n    result = schema.execute(\"{ user { name isAdmin } }\")\n\n    assert not result.errors\n    assert result.data == expected\n"
  },
  {
    "path": "graphene/types/tests/test_resolver.py",
    "content": "from ..resolver import (\n    attr_resolver,\n    dict_resolver,\n    dict_or_attr_resolver,\n    get_default_resolver,\n    set_default_resolver,\n)\n\nargs = {}\ncontext = None\ninfo = None\n\ndemo_dict = {\"attr\": \"value\"}\n\n\nclass demo_obj:\n    attr = \"value\"\n\n\ndef test_attr_resolver():\n    resolved = attr_resolver(\"attr\", None, demo_obj, info, **args)\n    assert resolved == \"value\"\n\n\ndef test_attr_resolver_default_value():\n    resolved = attr_resolver(\"attr2\", \"default\", demo_obj, info, **args)\n    assert resolved == \"default\"\n\n\ndef test_dict_resolver():\n    resolved = dict_resolver(\"attr\", None, demo_dict, info, **args)\n    assert resolved == \"value\"\n\n\ndef test_dict_resolver_default_value():\n    resolved = dict_resolver(\"attr2\", \"default\", demo_dict, info, **args)\n    assert resolved == \"default\"\n\n\ndef test_dict_or_attr_resolver():\n    resolved = dict_or_attr_resolver(\"attr\", None, demo_dict, info, **args)\n    assert resolved == \"value\"\n\n    resolved = dict_or_attr_resolver(\"attr\", None, demo_obj, info, **args)\n    assert resolved == \"value\"\n\n\ndef test_get_default_resolver_is_attr_resolver():\n    assert get_default_resolver() == dict_or_attr_resolver\n\n\ndef test_set_default_resolver_workd():\n    default_resolver = get_default_resolver()\n\n    set_default_resolver(dict_resolver)\n    assert get_default_resolver() == dict_resolver\n\n    set_default_resolver(default_resolver)\n"
  },
  {
    "path": "graphene/types/tests/test_scalar.py",
    "content": "from ..objecttype import ObjectType, Field\nfrom ..scalars import Scalar, Int, BigInt, Float, String, Boolean\nfrom ..schema import Schema\nfrom graphql import Undefined\nfrom graphql.language.ast import IntValueNode\n\n\ndef test_scalar():\n    class JSONScalar(Scalar):\n        \"\"\"Documentation\"\"\"\n\n    assert JSONScalar._meta.name == \"JSONScalar\"\n    assert JSONScalar._meta.description == \"Documentation\"\n\n\ndef test_ints():\n    assert Int.parse_value(2**31 - 1) is not Undefined\n    assert Int.parse_value(\"2.0\") == 2\n    assert Int.parse_value(2**31) is Undefined\n\n    assert Int.parse_literal(IntValueNode(value=str(2**31 - 1))) == 2**31 - 1\n    assert Int.parse_literal(IntValueNode(value=str(2**31))) is Undefined\n\n    assert Int.parse_value(-(2**31)) is not Undefined\n    assert Int.parse_value(-(2**31) - 1) is Undefined\n\n    assert BigInt.parse_value(2**31) is not Undefined\n    assert BigInt.parse_value(\"2.0\") == 2\n    assert BigInt.parse_value(-(2**31) - 1) is not Undefined\n\n    assert BigInt.parse_literal(IntValueNode(value=str(2**31 - 1))) == 2**31 - 1\n    assert BigInt.parse_literal(IntValueNode(value=str(2**31))) == 2**31\n\n\ndef return_input(_parent, _info, input):\n    return input\n\n\nclass Optional(ObjectType):\n    int = Int(input=Int(), resolver=return_input)\n    big_int = BigInt(input=BigInt(), resolver=return_input)\n    float = Float(input=Float(), resolver=return_input)\n    bool = Boolean(input=Boolean(), resolver=return_input)\n    string = String(input=String(), resolver=return_input)\n\n\nclass Query(ObjectType):\n    optional = Field(Optional)\n\n    def resolve_optional(self, info):\n        return Optional()\n\n    def resolve_required(self, info, input):\n        return input\n\n\nschema = Schema(query=Query)\n\n\nclass TestInt:\n    def test_query(self):\n        \"\"\"\n        Test that a normal query works.\n        \"\"\"\n        result = schema.execute(\"{ optional { int(input: 20) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"int\": 20}}\n\n    def test_optional_input(self):\n        \"\"\"\n        Test that we can provide a null value to an optional input\n        \"\"\"\n        result = schema.execute(\"{ optional { int(input: null) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"int\": None}}\n\n    def test_invalid_input(self):\n        \"\"\"\n        Test that if an invalid type is provided we get an error\n        \"\"\"\n        result = schema.execute('{ optional { int(input: \"20\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == 'Int cannot represent non-integer value: \"20\"'\n        )\n\n        result = schema.execute('{ optional { int(input: \"a\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert result.errors[0].message == 'Int cannot represent non-integer value: \"a\"'\n\n        result = schema.execute(\"{ optional { int(input: true) } }\")\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == \"Int cannot represent non-integer value: true\"\n        )\n\n\nclass TestBigInt:\n    def test_query(self):\n        \"\"\"\n        Test that a normal query works.\n        \"\"\"\n        value = 2**31\n        result = schema.execute(\"{ optional { bigInt(input: %s) } }\" % value)\n        assert not result.errors\n        assert result.data == {\"optional\": {\"bigInt\": value}}\n\n    def test_optional_input(self):\n        \"\"\"\n        Test that we can provide a null value to an optional input\n        \"\"\"\n        result = schema.execute(\"{ optional { bigInt(input: null) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"bigInt\": None}}\n\n    def test_invalid_input(self):\n        \"\"\"\n        Test that if an invalid type is provided we get an error\n        \"\"\"\n        result = schema.execute('{ optional { bigInt(input: \"20\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == \"Expected value of type 'BigInt', found \\\"20\\\".\"\n        )\n\n        result = schema.execute('{ optional { bigInt(input: \"a\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == \"Expected value of type 'BigInt', found \\\"a\\\".\"\n        )\n\n        result = schema.execute(\"{ optional { bigInt(input: true) } }\")\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == \"Expected value of type 'BigInt', found true.\"\n        )\n\n\nclass TestFloat:\n    def test_query(self):\n        \"\"\"\n        Test that a normal query works.\n        \"\"\"\n        result = schema.execute(\"{ optional { float(input: 20) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"float\": 20.0}}\n\n        result = schema.execute(\"{ optional { float(input: 20.2) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"float\": 20.2}}\n\n    def test_optional_input(self):\n        \"\"\"\n        Test that we can provide a null value to an optional input\n        \"\"\"\n        result = schema.execute(\"{ optional { float(input: null) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"float\": None}}\n\n    def test_invalid_input(self):\n        \"\"\"\n        Test that if an invalid type is provided we get an error\n        \"\"\"\n        result = schema.execute('{ optional { float(input: \"20\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == 'Float cannot represent non numeric value: \"20\"'\n        )\n\n        result = schema.execute('{ optional { float(input: \"a\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == 'Float cannot represent non numeric value: \"a\"'\n        )\n\n        result = schema.execute(\"{ optional { float(input: true) } }\")\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == \"Float cannot represent non numeric value: true\"\n        )\n\n\nclass TestBoolean:\n    def test_query(self):\n        \"\"\"\n        Test that a normal query works.\n        \"\"\"\n        result = schema.execute(\"{ optional { bool(input: true) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"bool\": True}}\n\n        result = schema.execute(\"{ optional { bool(input: false) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"bool\": False}}\n\n    def test_optional_input(self):\n        \"\"\"\n        Test that we can provide a null value to an optional input\n        \"\"\"\n        result = schema.execute(\"{ optional { bool(input: null) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"bool\": None}}\n\n    def test_invalid_input(self):\n        \"\"\"\n        Test that if an invalid type is provided we get an error\n        \"\"\"\n        result = schema.execute('{ optional { bool(input: \"True\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message\n            == 'Boolean cannot represent a non boolean value: \"True\"'\n        )\n\n        result = schema.execute('{ optional { bool(input: \"true\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message\n            == 'Boolean cannot represent a non boolean value: \"true\"'\n        )\n\n        result = schema.execute('{ optional { bool(input: \"a\") } }')\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message\n            == 'Boolean cannot represent a non boolean value: \"a\"'\n        )\n\n        result = schema.execute(\"{ optional { bool(input: 1) } }\")\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message\n            == \"Boolean cannot represent a non boolean value: 1\"\n        )\n\n        result = schema.execute(\"{ optional { bool(input: 0) } }\")\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message\n            == \"Boolean cannot represent a non boolean value: 0\"\n        )\n\n\nclass TestString:\n    def test_query(self):\n        \"\"\"\n        Test that a normal query works.\n        \"\"\"\n        result = schema.execute('{ optional { string(input: \"something something\") } }')\n        assert not result.errors\n        assert result.data == {\"optional\": {\"string\": \"something something\"}}\n\n        result = schema.execute('{ optional { string(input: \"True\") } }')\n        assert not result.errors\n        assert result.data == {\"optional\": {\"string\": \"True\"}}\n\n        result = schema.execute('{ optional { string(input: \"0\") } }')\n        assert not result.errors\n        assert result.data == {\"optional\": {\"string\": \"0\"}}\n\n    def test_optional_input(self):\n        \"\"\"\n        Test that we can provide a null value to an optional input\n        \"\"\"\n        result = schema.execute(\"{ optional { string(input: null) } }\")\n        assert not result.errors\n        assert result.data == {\"optional\": {\"string\": None}}\n\n    def test_invalid_input(self):\n        \"\"\"\n        Test that if an invalid type is provided we get an error\n        \"\"\"\n        result = schema.execute(\"{ optional { string(input: 1) } }\")\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message == \"String cannot represent a non string value: 1\"\n        )\n\n        result = schema.execute(\"{ optional { string(input: 3.2) } }\")\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message\n            == \"String cannot represent a non string value: 3.2\"\n        )\n\n        result = schema.execute(\"{ optional { string(input: true) } }\")\n        assert result.errors\n        assert len(result.errors) == 1\n        assert (\n            result.errors[0].message\n            == \"String cannot represent a non string value: true\"\n        )\n"
  },
  {
    "path": "graphene/types/tests/test_scalars_serialization.py",
    "content": "from graphql import Undefined\nfrom ..scalars import Boolean, Float, Int, String\n\n\ndef test_serializes_output_int():\n    assert Int.serialize(1) == 1\n    assert Int.serialize(0) == 0\n    assert Int.serialize(-1) == -1\n    assert Int.serialize(0.1) == 0\n    assert Int.serialize(1.1) == 1\n    assert Int.serialize(-1.1) == -1\n    assert Int.serialize(1e5) == 100000\n    assert Int.serialize(9876504321) is Undefined\n    assert Int.serialize(-9876504321) is Undefined\n    assert Int.serialize(1e100) is Undefined\n    assert Int.serialize(-1e100) is Undefined\n    assert Int.serialize(\"-1.1\") == -1\n    assert Int.serialize(\"one\") is Undefined\n    assert Int.serialize(False) == 0\n    assert Int.serialize(True) == 1\n\n\ndef test_serializes_output_float():\n    assert Float.serialize(1) == 1.0\n    assert Float.serialize(0) == 0.0\n    assert Float.serialize(-1) == -1.0\n    assert Float.serialize(0.1) == 0.1\n    assert Float.serialize(1.1) == 1.1\n    assert Float.serialize(-1.1) == -1.1\n    assert Float.serialize(\"-1.1\") == -1.1\n    assert Float.serialize(\"one\") is Undefined\n    assert Float.serialize(False) == 0\n    assert Float.serialize(True) == 1\n\n\ndef test_serializes_output_string():\n    assert String.serialize(\"string\") == \"string\"\n    assert String.serialize(1) == \"1\"\n    assert String.serialize(-1.1) == \"-1.1\"\n    assert String.serialize(True) == \"true\"\n    assert String.serialize(False) == \"false\"\n    assert String.serialize(\"\\U0001f601\") == \"\\U0001f601\"\n\n\ndef test_serializes_output_boolean():\n    assert Boolean.serialize(\"string\") is True\n    assert Boolean.serialize(\"\") is False\n    assert Boolean.serialize(1) is True\n    assert Boolean.serialize(0) is False\n    assert Boolean.serialize(True) is True\n    assert Boolean.serialize(False) is False\n"
  },
  {
    "path": "graphene/types/tests/test_schema.py",
    "content": "from textwrap import dedent\n\nfrom pytest import raises\n\nfrom graphql.type import GraphQLObjectType, GraphQLSchema\n\nfrom ..field import Field\nfrom ..objecttype import ObjectType\nfrom ..scalars import String\nfrom ..schema import Schema\n\n\nclass MyOtherType(ObjectType):\n    field = String()\n\n\nclass Query(ObjectType):\n    inner = Field(MyOtherType)\n\n\ndef test_schema():\n    schema = Schema(Query)\n    graphql_schema = schema.graphql_schema\n    assert isinstance(graphql_schema, GraphQLSchema)\n    query_type = graphql_schema.query_type\n    assert isinstance(query_type, GraphQLObjectType)\n    assert query_type.name == \"Query\"\n    assert query_type.graphene_type is Query\n\n\ndef test_schema_get_type():\n    schema = Schema(Query)\n    assert schema.Query == Query\n    assert schema.MyOtherType == MyOtherType\n\n\ndef test_schema_get_type_error():\n    schema = Schema(Query)\n    with raises(AttributeError) as exc_info:\n        schema.X\n\n    assert str(exc_info.value) == 'Type \"X\" not found in the Schema'\n\n\ndef test_schema_str():\n    schema = Schema(Query)\n    assert (\n        str(schema).strip()\n        == dedent(\n            \"\"\"\n        type Query {\n          inner: MyOtherType\n        }\n\n        type MyOtherType {\n          field: String\n        }\n        \"\"\"\n        ).strip()\n    )\n\n\ndef test_schema_introspect():\n    schema = Schema(Query)\n    assert \"__schema\" in schema.introspect()\n\n\ndef test_schema_requires_query_type():\n    schema = Schema()\n    result = schema.execute(\"query {}\")\n\n    assert len(result.errors) == 1\n    error = result.errors[0]\n    assert error.message == \"Query root type must be provided.\"\n"
  },
  {
    "path": "graphene/types/tests/test_structures.py",
    "content": "from functools import partial\n\nfrom pytest import raises\n\nfrom ..scalars import String\nfrom ..structures import List, NonNull\nfrom .utils import MyLazyType\n\n\ndef test_list():\n    _list = List(String)\n    assert _list.of_type == String\n    assert str(_list) == \"[String]\"\n\n\ndef test_list_with_unmounted_type():\n    with raises(Exception) as exc_info:\n        List(String())\n\n    assert (\n        str(exc_info.value)\n        == \"List could not have a mounted String() as inner type. Try with List(String).\"\n    )\n\n\ndef test_list_with_lazy_type():\n    MyType = object()\n    field = List(lambda: MyType)\n    assert field.of_type == MyType\n\n\ndef test_list_with_lazy_partial_type():\n    MyType = object()\n    field = List(partial(lambda: MyType))\n    assert field.of_type == MyType\n\n\ndef test_list_with_string_type():\n    field = List(\"graphene.types.tests.utils.MyLazyType\")\n    assert field.of_type == MyLazyType\n\n\ndef test_list_inherited_works_list():\n    _list = List(List(String))\n    assert isinstance(_list.of_type, List)\n    assert _list.of_type.of_type == String\n\n\ndef test_list_inherited_works_nonnull():\n    _list = List(NonNull(String))\n    assert isinstance(_list.of_type, NonNull)\n    assert _list.of_type.of_type == String\n\n\ndef test_nonnull():\n    nonnull = NonNull(String)\n    assert nonnull.of_type == String\n    assert str(nonnull) == \"String!\"\n\n\ndef test_nonnull_with_lazy_type():\n    MyType = object()\n    field = NonNull(lambda: MyType)\n    assert field.of_type == MyType\n\n\ndef test_nonnull_with_lazy_partial_type():\n    MyType = object()\n    field = NonNull(partial(lambda: MyType))\n    assert field.of_type == MyType\n\n\ndef test_nonnull_with_string_type():\n    field = NonNull(\"graphene.types.tests.utils.MyLazyType\")\n    assert field.of_type == MyLazyType\n\n\ndef test_nonnull_inherited_works_list():\n    _list = NonNull(List(String))\n    assert isinstance(_list.of_type, List)\n    assert _list.of_type.of_type == String\n\n\ndef test_nonnull_inherited_dont_work_nonnull():\n    with raises(Exception) as exc_info:\n        NonNull(NonNull(String))\n\n    assert (\n        str(exc_info.value)\n        == \"Can only create NonNull of a Nullable GraphQLType but got: String!.\"\n    )\n\n\ndef test_nonnull_with_unmounted_type():\n    with raises(Exception) as exc_info:\n        NonNull(String())\n\n    assert (\n        str(exc_info.value)\n        == \"NonNull could not have a mounted String() as inner type. Try with NonNull(String).\"\n    )\n\n\ndef test_list_comparasion():\n    list1 = List(String)\n    list2 = List(String)\n    list3 = List(None)\n\n    list1_argskwargs = List(String, None, b=True)\n    list2_argskwargs = List(String, None, b=True)\n\n    assert list1 == list2\n    assert list1 != list3\n    assert list1_argskwargs == list2_argskwargs\n    assert list1 != list1_argskwargs\n\n\ndef test_nonnull_comparasion():\n    nonnull1 = NonNull(String)\n    nonnull2 = NonNull(String)\n    nonnull3 = NonNull(None)\n\n    nonnull1_argskwargs = NonNull(String, None, b=True)\n    nonnull2_argskwargs = NonNull(String, None, b=True)\n\n    assert nonnull1 == nonnull2\n    assert nonnull1 != nonnull3\n    assert nonnull1_argskwargs == nonnull2_argskwargs\n    assert nonnull1 != nonnull1_argskwargs\n"
  },
  {
    "path": "graphene/types/tests/test_subscribe_async.py",
    "content": "from pytest import mark\n\nfrom graphene import ObjectType, Int, String, Schema, Field\n\n\nclass Query(ObjectType):\n    hello = String()\n\n    def resolve_hello(root, info):\n        return \"Hello, world!\"\n\n\nclass Subscription(ObjectType):\n    count_to_ten = Field(Int)\n\n    async def subscribe_count_to_ten(root, info):\n        for count in range(1, 11):\n            yield count\n\n\nschema = Schema(query=Query, subscription=Subscription)\n\n\n@mark.asyncio\nasync def test_subscription():\n    subscription = \"subscription { countToTen }\"\n    result = await schema.subscribe(subscription)\n    count = 0\n    async for item in result:\n        count = item.data[\"countToTen\"]\n    assert count == 10\n\n\n@mark.asyncio\nasync def test_subscription_fails_with_invalid_query():\n    # It fails if the provided query is invalid\n    subscription = \"subscription { \"\n    result = await schema.subscribe(subscription)\n    assert not result.data\n    assert result.errors\n    assert \"Syntax Error: Expected Name, found <EOF>\" in str(result.errors[0])\n\n\n@mark.asyncio\nasync def test_subscription_fails_when_query_is_not_valid():\n    # It can't subscribe to two fields at the same time, triggering a\n    # validation error.\n    subscription = \"subscription { countToTen, b: countToTen }\"\n    result = await schema.subscribe(subscription)\n    assert not result.data\n    assert result.errors\n    assert \"Anonymous Subscription must select only one top level field.\" in str(\n        result.errors[0]\n    )\n\n\n@mark.asyncio\nasync def test_subscription_with_args():\n    class Query(ObjectType):\n        hello = String()\n\n    class Subscription(ObjectType):\n        count_upwards = Field(Int, limit=Int(required=True))\n\n        async def subscribe_count_upwards(root, info, limit):\n            count = 0\n            while count < limit:\n                count += 1\n                yield count\n\n    schema = Schema(query=Query, subscription=Subscription)\n\n    subscription = \"subscription { countUpwards(limit: 5) }\"\n    result = await schema.subscribe(subscription)\n    count = 0\n    async for item in result:\n        count = item.data[\"countUpwards\"]\n    assert count == 5\n"
  },
  {
    "path": "graphene/types/tests/test_type_map.py",
    "content": "from graphql import Undefined\nfrom graphql.type import (\n    GraphQLArgument,\n    GraphQLEnumType,\n    GraphQLEnumValue,\n    GraphQLField,\n    GraphQLInputField,\n    GraphQLInputObjectType,\n    GraphQLInterfaceType,\n    GraphQLNonNull,\n    GraphQLObjectType,\n    GraphQLString,\n)\n\nfrom ..dynamic import Dynamic\nfrom ..enum import Enum\nfrom ..field import Field\nfrom ..inputfield import InputField\nfrom ..inputobjecttype import InputObjectType\nfrom ..interface import Interface\nfrom ..objecttype import ObjectType\nfrom ..scalars import Int, String\nfrom ..schema import Schema\nfrom ..structures import List, NonNull\n\n\ndef create_type_map(types, auto_camelcase=True):\n    query = type(\"Query\", (ObjectType,), {})\n    schema = Schema(query, types=types, auto_camelcase=auto_camelcase)\n    return schema.graphql_schema.type_map\n\n\ndef test_enum():\n    class MyEnum(Enum):\n        \"\"\"Description\"\"\"\n\n        foo = 1\n        bar = 2\n\n        @property\n        def description(self):\n            return f\"Description {self.name}={self.value}\"\n\n        @property\n        def deprecation_reason(self):\n            if self == MyEnum.foo:\n                return \"Is deprecated\"\n\n    type_map = create_type_map([MyEnum])\n    assert \"MyEnum\" in type_map\n    graphql_enum = type_map[\"MyEnum\"]\n    assert isinstance(graphql_enum, GraphQLEnumType)\n    assert graphql_enum.name == \"MyEnum\"\n    assert graphql_enum.description == \"Description\"\n    assert graphql_enum.values == {\n        \"foo\": GraphQLEnumValue(\n            value=1, description=\"Description foo=1\", deprecation_reason=\"Is deprecated\"\n        ),\n        \"bar\": GraphQLEnumValue(value=2, description=\"Description bar=2\"),\n    }\n\n\ndef test_objecttype():\n    class MyObjectType(ObjectType):\n        \"\"\"Description\"\"\"\n\n        foo = String(\n            bar=String(description=\"Argument description\", default_value=\"x\"),\n            description=\"Field description\",\n        )\n        bar = String(name=\"gizmo\")\n\n        def resolve_foo(self, bar):\n            return bar\n\n    type_map = create_type_map([MyObjectType])\n    assert \"MyObjectType\" in type_map\n    graphql_type = type_map[\"MyObjectType\"]\n    assert isinstance(graphql_type, GraphQLObjectType)\n    assert graphql_type.name == \"MyObjectType\"\n    assert graphql_type.description == \"Description\"\n\n    fields = graphql_type.fields\n    assert list(fields) == [\"foo\", \"gizmo\"]\n    foo_field = fields[\"foo\"]\n    assert isinstance(foo_field, GraphQLField)\n    assert foo_field.description == \"Field description\"\n\n    assert foo_field.args == {\n        \"bar\": GraphQLArgument(\n            GraphQLString,\n            description=\"Argument description\",\n            default_value=\"x\",\n            out_name=\"bar\",\n        )\n    }\n\n\ndef test_required_argument_with_default_value():\n    class MyObjectType(ObjectType):\n        foo = String(bar=String(required=True, default_value=\"x\"))\n\n    type_map = create_type_map([MyObjectType])\n\n    graphql_type = type_map[\"MyObjectType\"]\n    foo_field = graphql_type.fields[\"foo\"]\n\n    bar_argument = foo_field.args[\"bar\"]\n    assert bar_argument.default_value == \"x\"\n    assert isinstance(bar_argument.type, GraphQLNonNull)\n    assert bar_argument.type.of_type == GraphQLString\n\n\ndef test_dynamic_objecttype():\n    class MyObjectType(ObjectType):\n        \"\"\"Description\"\"\"\n\n        bar = Dynamic(lambda: Field(String))\n        own = Field(lambda: MyObjectType)\n\n    type_map = create_type_map([MyObjectType])\n    assert \"MyObjectType\" in type_map\n    assert list(MyObjectType._meta.fields) == [\"bar\", \"own\"]\n    graphql_type = type_map[\"MyObjectType\"]\n\n    fields = graphql_type.fields\n    assert list(fields) == [\"bar\", \"own\"]\n    assert fields[\"bar\"].type == GraphQLString\n    assert fields[\"own\"].type == graphql_type\n\n\ndef test_interface():\n    class MyInterface(Interface):\n        \"\"\"Description\"\"\"\n\n        foo = String(\n            bar=String(description=\"Argument description\", default_value=\"x\"),\n            description=\"Field description\",\n        )\n        bar = String(name=\"gizmo\", first_arg=String(), other_arg=String(name=\"oth_arg\"))\n        own = Field(lambda: MyInterface)\n\n        def resolve_foo(self, args, info):\n            return args.get(\"bar\")\n\n    type_map = create_type_map([MyInterface])\n    assert \"MyInterface\" in type_map\n    graphql_type = type_map[\"MyInterface\"]\n    assert isinstance(graphql_type, GraphQLInterfaceType)\n    assert graphql_type.name == \"MyInterface\"\n    assert graphql_type.description == \"Description\"\n\n    fields = graphql_type.fields\n    assert list(fields) == [\"foo\", \"gizmo\", \"own\"]\n    assert fields[\"own\"].type == graphql_type\n    assert list(fields[\"gizmo\"].args) == [\"firstArg\", \"oth_arg\"]\n    foo_field = fields[\"foo\"]\n    assert isinstance(foo_field, GraphQLField)\n    assert foo_field.description == \"Field description\"\n    assert not foo_field.resolve  # Resolver not attached in interfaces\n    assert foo_field.args == {\n        \"bar\": GraphQLArgument(\n            GraphQLString,\n            description=\"Argument description\",\n            default_value=\"x\",\n            out_name=\"bar\",\n        )\n    }\n\n\ndef test_inputobject():\n    class OtherObjectType(InputObjectType):\n        thingy = NonNull(Int)\n\n    class MyInnerObjectType(InputObjectType):\n        some_field = String()\n        some_other_field = List(OtherObjectType)\n\n    class MyInputObjectType(InputObjectType):\n        \"\"\"Description\"\"\"\n\n        foo_bar = String(description=\"Field description\")\n        bar = String(name=\"gizmo\")\n        baz = NonNull(MyInnerObjectType)\n        own = InputField(lambda: MyInputObjectType)\n\n        def resolve_foo_bar(self, args, info):\n            return args.get(\"bar\")\n\n    type_map = create_type_map([MyInputObjectType])\n    assert \"MyInputObjectType\" in type_map\n    graphql_type = type_map[\"MyInputObjectType\"]\n    assert isinstance(graphql_type, GraphQLInputObjectType)\n    assert graphql_type.name == \"MyInputObjectType\"\n    assert graphql_type.description == \"Description\"\n\n    other_graphql_type = type_map[\"OtherObjectType\"]\n    inner_graphql_type = type_map[\"MyInnerObjectType\"]\n    container = graphql_type.out_type(\n        {\n            \"bar\": \"oh!\",\n            \"baz\": inner_graphql_type.out_type(\n                {\n                    \"some_other_field\": [\n                        other_graphql_type.out_type({\"thingy\": 1}),\n                        other_graphql_type.out_type({\"thingy\": 2}),\n                    ]\n                }\n            ),\n        }\n    )\n    assert isinstance(container, MyInputObjectType)\n    assert \"bar\" in container\n    assert container.bar == \"oh!\"\n    assert \"foo_bar\" not in container\n    assert container.foo_bar is None\n    assert container.baz.some_field is None\n    assert container.baz.some_other_field[0].thingy == 1\n    assert container.baz.some_other_field[1].thingy == 2\n\n    fields = graphql_type.fields\n    assert list(fields) == [\"fooBar\", \"gizmo\", \"baz\", \"own\"]\n    own_field = fields[\"own\"]\n    assert own_field.type == graphql_type\n    foo_field = fields[\"fooBar\"]\n    assert isinstance(foo_field, GraphQLInputField)\n    assert foo_field.description == \"Field description\"\n\n\ndef test_inputobject_undefined(set_default_input_object_type_to_undefined):\n    class OtherObjectType(InputObjectType):\n        optional_field = String()\n\n    type_map = create_type_map([OtherObjectType])\n    assert \"OtherObjectType\" in type_map\n    graphql_type = type_map[\"OtherObjectType\"]\n\n    container = graphql_type.out_type({})\n    assert container.optional_field is Undefined\n\n\ndef test_objecttype_camelcase():\n    class MyObjectType(ObjectType):\n        \"\"\"Description\"\"\"\n\n        foo_bar = String(bar_foo=String())\n\n    type_map = create_type_map([MyObjectType])\n    assert \"MyObjectType\" in type_map\n    graphql_type = type_map[\"MyObjectType\"]\n    assert isinstance(graphql_type, GraphQLObjectType)\n    assert graphql_type.name == \"MyObjectType\"\n    assert graphql_type.description == \"Description\"\n\n    fields = graphql_type.fields\n    assert list(fields) == [\"fooBar\"]\n    foo_field = fields[\"fooBar\"]\n    assert isinstance(foo_field, GraphQLField)\n    assert foo_field.args == {\n        \"barFoo\": GraphQLArgument(\n            GraphQLString, default_value=Undefined, out_name=\"bar_foo\"\n        )\n    }\n\n\ndef test_objecttype_camelcase_disabled():\n    class MyObjectType(ObjectType):\n        \"\"\"Description\"\"\"\n\n        foo_bar = String(bar_foo=String())\n\n    type_map = create_type_map([MyObjectType], auto_camelcase=False)\n    assert \"MyObjectType\" in type_map\n    graphql_type = type_map[\"MyObjectType\"]\n    assert isinstance(graphql_type, GraphQLObjectType)\n    assert graphql_type.name == \"MyObjectType\"\n    assert graphql_type.description == \"Description\"\n\n    fields = graphql_type.fields\n    assert list(fields) == [\"foo_bar\"]\n    foo_field = fields[\"foo_bar\"]\n    assert isinstance(foo_field, GraphQLField)\n    assert foo_field.args == {\n        \"bar_foo\": GraphQLArgument(\n            GraphQLString, default_value=Undefined, out_name=\"bar_foo\"\n        )\n    }\n\n\ndef test_objecttype_with_possible_types():\n    class MyObjectType(ObjectType):\n        \"\"\"Description\"\"\"\n\n        class Meta:\n            possible_types = (dict,)\n\n        foo_bar = String()\n\n    type_map = create_type_map([MyObjectType])\n    graphql_type = type_map[\"MyObjectType\"]\n    assert graphql_type.is_type_of\n    assert graphql_type.is_type_of({}, None) is True\n    assert graphql_type.is_type_of(MyObjectType(), None) is False\n\n\ndef test_interface_with_interfaces():\n    class FooInterface(Interface):\n        foo = String()\n\n    class BarInterface(Interface):\n        class Meta:\n            interfaces = [FooInterface]\n\n        foo = String()\n        bar = String()\n\n    type_map = create_type_map([FooInterface, BarInterface])\n    assert \"FooInterface\" in type_map\n    foo_graphql_type = type_map[\"FooInterface\"]\n    assert isinstance(foo_graphql_type, GraphQLInterfaceType)\n    assert foo_graphql_type.name == \"FooInterface\"\n\n    assert \"BarInterface\" in type_map\n    bar_graphql_type = type_map[\"BarInterface\"]\n    assert isinstance(bar_graphql_type, GraphQLInterfaceType)\n    assert bar_graphql_type.name == \"BarInterface\"\n\n    fields = bar_graphql_type.fields\n    assert list(fields) == [\"foo\", \"bar\"]\n    assert isinstance(fields[\"foo\"], GraphQLField)\n    assert isinstance(fields[\"bar\"], GraphQLField)\n\n    assert list(bar_graphql_type.interfaces) == list([foo_graphql_type])\n"
  },
  {
    "path": "graphene/types/tests/test_union.py",
    "content": "from pytest import raises\n\nfrom ..field import Field\nfrom ..objecttype import ObjectType\nfrom ..union import Union\nfrom ..unmountedtype import UnmountedType\n\n\nclass MyObjectType1(ObjectType):\n    pass\n\n\nclass MyObjectType2(ObjectType):\n    pass\n\n\ndef test_generate_union():\n    class MyUnion(Union):\n        \"\"\"Documentation\"\"\"\n\n        class Meta:\n            types = (MyObjectType1, MyObjectType2)\n\n    assert MyUnion._meta.name == \"MyUnion\"\n    assert MyUnion._meta.description == \"Documentation\"\n    assert MyUnion._meta.types == (MyObjectType1, MyObjectType2)\n\n\ndef test_generate_union_with_meta():\n    class MyUnion(Union):\n        class Meta:\n            name = \"MyOtherUnion\"\n            description = \"Documentation\"\n            types = (MyObjectType1, MyObjectType2)\n\n    assert MyUnion._meta.name == \"MyOtherUnion\"\n    assert MyUnion._meta.description == \"Documentation\"\n\n\ndef test_generate_union_with_no_types():\n    with raises(Exception) as exc_info:\n\n        class MyUnion(Union):\n            pass\n\n    assert str(exc_info.value) == \"Must provide types for Union MyUnion.\"\n\n\ndef test_union_can_be_mounted():\n    class MyUnion(Union):\n        class Meta:\n            types = (MyObjectType1, MyObjectType2)\n\n    my_union_instance = MyUnion()\n    assert isinstance(my_union_instance, UnmountedType)\n    my_union_field = my_union_instance.mount_as(Field)\n    assert isinstance(my_union_field, Field)\n    assert my_union_field.type == MyUnion\n"
  },
  {
    "path": "graphene/types/tests/test_uuid.py",
    "content": "from ..objecttype import ObjectType\nfrom ..schema import Schema\nfrom ..uuid import UUID\nfrom ..structures import NonNull\n\n\nclass Query(ObjectType):\n    uuid = UUID(input=UUID())\n    required_uuid = UUID(input=NonNull(UUID), required=True)\n\n    def resolve_uuid(self, info, input):\n        return input\n\n    def resolve_required_uuid(self, info, input):\n        return input\n\n\nschema = Schema(query=Query)\n\n\ndef test_uuidstring_query():\n    uuid_value = \"dfeb3bcf-70fd-11e7-a61a-6003088f8204\"\n    result = schema.execute(\"\"\"{ uuid(input: \"%s\") }\"\"\" % uuid_value)\n    assert not result.errors\n    assert result.data == {\"uuid\": uuid_value}\n\n\ndef test_uuidstring_query_variable():\n    uuid_value = \"dfeb3bcf-70fd-11e7-a61a-6003088f8204\"\n\n    result = schema.execute(\n        \"\"\"query Test($uuid: UUID){ uuid(input: $uuid) }\"\"\",\n        variables={\"uuid\": uuid_value},\n    )\n    assert not result.errors\n    assert result.data == {\"uuid\": uuid_value}\n\n\ndef test_uuidstring_invalid_argument():\n    uuid_value = {\"not\": \"a string\"}\n\n    result = schema.execute(\n        \"\"\"query Test($uuid: UUID){ uuid(input: $uuid) }\"\"\",\n        variables={\"uuid\": uuid_value},\n    )\n    assert result.errors\n    assert len(result.errors) == 1\n    assert (\n        result.errors[0].message\n        == \"Variable '$uuid' got invalid value {'not': 'a string'}; UUID cannot represent value: {'not': 'a string'}\"\n    )\n\n\ndef test_uuidstring_optional_uuid_input():\n    \"\"\"\n    Test that we can provide a null value to an optional input\n    \"\"\"\n    result = schema.execute(\"{ uuid(input: null) }\")\n    assert not result.errors\n    assert result.data == {\"uuid\": None}\n\n\ndef test_uuidstring_invalid_query():\n    \"\"\"\n    Test that if an invalid type is provided we get an error\n    \"\"\"\n    result = schema.execute(\"{ uuid(input: 1) }\")\n    assert result.errors\n    assert len(result.errors) == 1\n    assert result.errors[0].message == \"Expected value of type 'UUID', found 1.\"\n\n    result = schema.execute('{ uuid(input: \"a\") }')\n    assert result.errors\n    assert len(result.errors) == 1\n    assert (\n        result.errors[0].message\n        == \"Expected value of type 'UUID', found \\\"a\\\"; badly formed hexadecimal UUID string\"\n    )\n\n    result = schema.execute(\"{ requiredUuid(input: null) }\")\n    assert result.errors\n    assert len(result.errors) == 1\n    assert result.errors[0].message == \"Expected value of type 'UUID!', found null.\"\n"
  },
  {
    "path": "graphene/types/tests/utils.py",
    "content": "MyLazyType = object()\n"
  },
  {
    "path": "graphene/types/union.py",
    "content": "from typing import TYPE_CHECKING\n\nfrom .base import BaseOptions, BaseType\nfrom .unmountedtype import UnmountedType\n\n# For static type checking with type checker\nif TYPE_CHECKING:\n    from .objecttype import ObjectType  # NOQA\n    from typing import Iterable, Type  # NOQA\n\n\nclass UnionOptions(BaseOptions):\n    types = ()  # type: Iterable[Type[ObjectType]]\n\n\nclass Union(UnmountedType, BaseType):\n    \"\"\"\n    Union Type Definition\n\n    When a field can return one of a heterogeneous set of types, a Union type\n    is used to describe what types are possible as well as providing a function\n    to determine which type is actually used when the field is resolved.\n\n    The schema in this example can take a search text and return any of the GraphQL object types\n    indicated: Human, Droid or Starship.\n\n    Ambiguous return types can be resolved on each ObjectType through ``Meta.possible_types``\n    attribute or ``is_type_of`` method. Or by implementing ``resolve_type`` class method on the\n    Union.\n\n    .. code:: python\n\n        from graphene import Union, ObjectType, List\n\n        class SearchResult(Union):\n            class Meta:\n                types = (Human, Droid, Starship)\n\n        class Query(ObjectType):\n            search = List(SearchResult.Field(\n                search_text=String(description='Value to search for'))\n            )\n\n    Meta:\n        types (Iterable[graphene.ObjectType]): Required. Collection of types that may be returned\n            by this Union for the graphQL schema.\n        name (optional, str): the name of the GraphQL type (must be unique in schema). Defaults to class\n            name.\n        description (optional, str): the description of the GraphQL type in the schema. Defaults to class\n            docstring.\n    \"\"\"\n\n    @classmethod\n    def __init_subclass_with_meta__(cls, types=None, _meta=None, **options):\n        assert (\n            isinstance(types, (list, tuple)) and len(types) > 0\n        ), f\"Must provide types for Union {cls.__name__}.\"\n\n        if not _meta:\n            _meta = UnionOptions(cls)\n\n        _meta.types = types\n        super(Union, cls).__init_subclass_with_meta__(_meta=_meta, **options)\n\n    @classmethod\n    def get_type(cls):\n        \"\"\"\n        This function is called when the unmounted type (Union instance)\n        is mounted (as a Field, InputField or Argument)\n        \"\"\"\n        return cls\n\n    @classmethod\n    def resolve_type(cls, instance, info):\n        from .objecttype import ObjectType  # NOQA\n\n        if isinstance(instance, ObjectType):\n            return type(instance)\n"
  },
  {
    "path": "graphene/types/unmountedtype.py",
    "content": "from ..utils.orderedtype import OrderedType\n\n\nclass UnmountedType(OrderedType):\n    \"\"\"\n    This class acts a proxy for a Graphene Type, so it can be mounted\n    dynamically as Field, InputField or Argument.\n\n    Instead of writing:\n\n    .. code:: python\n\n        from graphene import ObjectType, Field, String\n\n        class MyObjectType(ObjectType):\n            my_field = Field(String, description='Description here')\n\n    It lets you write:\n\n    .. code:: python\n\n        from graphene import ObjectType, String\n\n        class MyObjectType(ObjectType):\n            my_field = String(description='Description here')\n\n    It is not used directly, but is inherited by other types and streamlines their use in\n    different context:\n\n    - Object Type\n    - Scalar Type\n    - Enum\n    - Interface\n    - Union\n\n    An unmounted type will accept arguments based upon its context (ObjectType, Field or\n    InputObjectType) and pass it on to the appropriate MountedType (Field, Argument or InputField).\n\n    See each Mounted type reference for more information about valid parameters.\n    \"\"\"\n\n    def __init__(self, *args, **kwargs):\n        super(UnmountedType, self).__init__()\n        self.args = args\n        self.kwargs = kwargs\n\n    def get_type(self):\n        \"\"\"\n        This function is called when the UnmountedType instance\n        is mounted (as a Field, InputField or Argument)\n        \"\"\"\n        raise NotImplementedError(f\"get_type not implemented in {self}\")\n\n    def mount_as(self, _as):\n        return _as.mounted(self)\n\n    def Field(self):  # noqa: N802\n        \"\"\"\n        Mount the UnmountedType as Field\n        \"\"\"\n        from .field import Field\n\n        return self.mount_as(Field)\n\n    def InputField(self):  # noqa: N802\n        \"\"\"\n        Mount the UnmountedType as InputField\n        \"\"\"\n        from .inputfield import InputField\n\n        return self.mount_as(InputField)\n\n    def Argument(self):  # noqa: N802\n        \"\"\"\n        Mount the UnmountedType as Argument\n        \"\"\"\n        from .argument import Argument\n\n        return self.mount_as(Argument)\n\n    def __eq__(self, other):\n        return self is other or (\n            isinstance(other, UnmountedType)\n            and self.get_type() == other.get_type()\n            and self.args == other.args\n            and self.kwargs == other.kwargs\n        )\n"
  },
  {
    "path": "graphene/types/utils.py",
    "content": "import inspect\nfrom functools import partial\n\nfrom ..utils.module_loading import import_string\nfrom .mountedtype import MountedType\nfrom .unmountedtype import UnmountedType\n\n\ndef get_field_as(value, _as=None):\n    \"\"\"\n    Get type mounted\n    \"\"\"\n    if isinstance(value, MountedType):\n        return value\n    elif isinstance(value, UnmountedType):\n        if _as is None:\n            return value\n        return _as.mounted(value)\n\n\ndef yank_fields_from_attrs(attrs, _as=None, sort=True):\n    \"\"\"\n    Extract all the fields in given attributes (dict)\n    and return them ordered\n    \"\"\"\n    fields_with_names = []\n    for attname, value in list(attrs.items()):\n        field = get_field_as(value, _as)\n        if not field:\n            continue\n        fields_with_names.append((attname, field))\n\n    if sort:\n        fields_with_names = sorted(fields_with_names, key=lambda f: f[1])\n    return dict(fields_with_names)\n\n\ndef get_type(_type):\n    if isinstance(_type, str):\n        return import_string(_type)\n    if inspect.isfunction(_type) or isinstance(_type, partial):\n        return _type()\n    return _type\n\n\ndef get_underlying_type(_type):\n    \"\"\"Get the underlying type even if it is wrapped in structures like NonNull\"\"\"\n    while hasattr(_type, \"of_type\"):\n        _type = _type.of_type\n    return _type\n"
  },
  {
    "path": "graphene/types/uuid.py",
    "content": "from uuid import UUID as _UUID\n\nfrom graphql.error import GraphQLError\nfrom graphql.language.ast import StringValueNode\nfrom graphql import Undefined\n\nfrom .scalars import Scalar\n\n\nclass UUID(Scalar):\n    \"\"\"\n    Leverages the internal Python implementation of UUID (uuid.UUID) to provide native UUID objects\n    in fields, resolvers and input.\n    \"\"\"\n\n    @staticmethod\n    def serialize(uuid):\n        if isinstance(uuid, str):\n            uuid = _UUID(uuid)\n\n        assert isinstance(uuid, _UUID), f\"Expected UUID instance, received {uuid}\"\n        return str(uuid)\n\n    @staticmethod\n    def parse_literal(node, _variables=None):\n        if isinstance(node, StringValueNode):\n            return _UUID(node.value)\n        return Undefined\n\n    @staticmethod\n    def parse_value(value):\n        if isinstance(value, _UUID):\n            return value\n        try:\n            return _UUID(value)\n        except (ValueError, AttributeError):\n            raise GraphQLError(f\"UUID cannot represent value: {repr(value)}\")\n"
  },
  {
    "path": "graphene/utils/__init__.py",
    "content": ""
  },
  {
    "path": "graphene/utils/crunch.py",
    "content": "import json\nfrom collections.abc import Mapping\n\n\ndef to_key(value):\n    return json.dumps(value)\n\n\ndef insert(value, index, values):\n    key = to_key(value)\n\n    if key not in index:\n        index[key] = len(values)\n        values.append(value)\n        return len(values) - 1\n\n    return index.get(key)\n\n\ndef flatten(data, index, values):\n    if isinstance(data, (list, tuple)):\n        flattened = [flatten(child, index, values) for child in data]\n    elif isinstance(data, Mapping):\n        flattened = {key: flatten(child, index, values) for key, child in data.items()}\n    else:\n        flattened = data\n    return insert(flattened, index, values)\n\n\ndef crunch(data):\n    index = {}\n    values = []\n\n    flatten(data, index, values)\n    return values\n"
  },
  {
    "path": "graphene/utils/dataloader.py",
    "content": "from asyncio import (\n    gather,\n    ensure_future,\n    get_event_loop,\n    iscoroutine,\n    iscoroutinefunction,\n)\nfrom collections import namedtuple\nfrom collections.abc import Iterable\nfrom functools import partial\n\nfrom typing import List\n\nLoader = namedtuple(\"Loader\", \"key,future\")\n\n\ndef iscoroutinefunctionorpartial(fn):\n    return iscoroutinefunction(fn.func if isinstance(fn, partial) else fn)\n\n\nclass DataLoader(object):\n    batch = True\n    max_batch_size = None  # type: int\n    cache = True\n\n    def __init__(\n        self,\n        batch_load_fn=None,\n        batch=None,\n        max_batch_size=None,\n        cache=None,\n        get_cache_key=None,\n        cache_map=None,\n        loop=None,\n    ):\n        self._loop = loop\n\n        if batch_load_fn is not None:\n            self.batch_load_fn = batch_load_fn\n\n        assert iscoroutinefunctionorpartial(\n            self.batch_load_fn\n        ), \"batch_load_fn must be coroutine. Received: {}\".format(self.batch_load_fn)\n\n        if not callable(self.batch_load_fn):\n            raise TypeError(  # pragma: no cover\n                (\n                    \"DataLoader must be have a batch_load_fn which accepts \"\n                    \"Iterable<key> and returns Future<Iterable<value>>, but got: {}.\"\n                ).format(batch_load_fn)\n            )\n\n        if batch is not None:\n            self.batch = batch  # pragma: no cover\n\n        if max_batch_size is not None:\n            self.max_batch_size = max_batch_size\n\n        if cache is not None:\n            self.cache = cache  # pragma: no cover\n\n        self.get_cache_key = get_cache_key or (lambda x: x)\n\n        self._cache = cache_map if cache_map is not None else {}\n        self._queue: List[Loader] = []\n\n    @property\n    def loop(self):\n        if not self._loop:\n            self._loop = get_event_loop()\n\n        return self._loop\n\n    def load(self, key=None):\n        \"\"\"\n        Loads a key, returning a `Future` for the value represented by that key.\n        \"\"\"\n        if key is None:\n            raise TypeError(  # pragma: no cover\n                (\n                    \"The loader.load() function must be called with a value, \"\n                    \"but got: {}.\"\n                ).format(key)\n            )\n\n        cache_key = self.get_cache_key(key)\n\n        # If caching and there is a cache-hit, return cached Future.\n        if self.cache:\n            cached_result = self._cache.get(cache_key)\n            if cached_result:\n                return cached_result\n\n        # Otherwise, produce a new Future for this value.\n        future = self.loop.create_future()\n        # If caching, cache this Future.\n        if self.cache:\n            self._cache[cache_key] = future\n\n        self.do_resolve_reject(key, future)\n        return future\n\n    def do_resolve_reject(self, key, future):\n        # Enqueue this Future to be dispatched.\n        self._queue.append(Loader(key=key, future=future))\n        # Determine if a dispatch of this queue should be scheduled.\n        # A single dispatch should be scheduled per queue at the time when the\n        # queue changes from \"empty\" to \"full\".\n        if len(self._queue) == 1:\n            if self.batch:\n                # If batching, schedule a task to dispatch the queue.\n                enqueue_post_future_job(self.loop, self)\n            else:\n                # Otherwise dispatch the (queue of one) immediately.\n                dispatch_queue(self)  # pragma: no cover\n\n    def load_many(self, keys):\n        \"\"\"\n        Loads multiple keys, returning a list of values\n\n        >>> a, b = await my_loader.load_many([ 'a', 'b' ])\n\n        This is equivalent to the more verbose:\n\n        >>> a, b = await gather(\n        >>>    my_loader.load('a'),\n        >>>    my_loader.load('b')\n        >>> )\n        \"\"\"\n        if not isinstance(keys, Iterable):\n            raise TypeError(  # pragma: no cover\n                (\n                    \"The loader.load_many() function must be called with Iterable<key> \"\n                    \"but got: {}.\"\n                ).format(keys)\n            )\n\n        return gather(*[self.load(key) for key in keys])\n\n    def clear(self, key):\n        \"\"\"\n        Clears the value at `key` from the cache, if it exists. Returns itself for\n        method chaining.\n        \"\"\"\n        cache_key = self.get_cache_key(key)\n        self._cache.pop(cache_key, None)\n        return self\n\n    def clear_all(self):\n        \"\"\"\n        Clears the entire cache. To be used when some event results in unknown\n        invalidations across this particular `DataLoader`. Returns itself for\n        method chaining.\n        \"\"\"\n        self._cache.clear()\n        return self\n\n    def prime(self, key, value):\n        \"\"\"\n        Adds the provied key and value to the cache. If the key already exists, no\n        change is made. Returns itself for method chaining.\n        \"\"\"\n        cache_key = self.get_cache_key(key)\n\n        # Only add the key if it does not already exist.\n        if cache_key not in self._cache:\n            # Cache a rejected future if the value is an Error, in order to match\n            # the behavior of load(key).\n            future = self.loop.create_future()\n            if isinstance(value, Exception):\n                future.set_exception(value)\n            else:\n                future.set_result(value)\n\n            self._cache[cache_key] = future\n\n        return self\n\n\ndef enqueue_post_future_job(loop, loader):\n    async def dispatch():\n        dispatch_queue(loader)\n\n    loop.call_soon(ensure_future, dispatch())\n\n\ndef get_chunks(iterable_obj, chunk_size=1):\n    chunk_size = max(1, chunk_size)\n    return (\n        iterable_obj[i : i + chunk_size]\n        for i in range(0, len(iterable_obj), chunk_size)\n    )\n\n\ndef dispatch_queue(loader):\n    \"\"\"\n    Given the current state of a Loader instance, perform a batch load\n    from its current queue.\n    \"\"\"\n    # Take the current loader queue, replacing it with an empty queue.\n    queue = loader._queue\n    loader._queue = []\n\n    # If a max_batch_size was provided and the queue is longer, then segment the\n    # queue into multiple batches, otherwise treat the queue as a single batch.\n    max_batch_size = loader.max_batch_size\n\n    if max_batch_size and max_batch_size < len(queue):\n        chunks = get_chunks(queue, max_batch_size)\n        for chunk in chunks:\n            ensure_future(dispatch_queue_batch(loader, chunk))\n    else:\n        ensure_future(dispatch_queue_batch(loader, queue))\n\n\nasync def dispatch_queue_batch(loader, queue):\n    # Collect all keys to be loaded in this dispatch\n    keys = [loaded.key for loaded in queue]\n\n    # Call the provided batch_load_fn for this loader with the loader queue's keys.\n    batch_future = loader.batch_load_fn(keys)\n\n    # Assert the expected response from batch_load_fn\n    if not batch_future or not iscoroutine(batch_future):\n        return failed_dispatch(  # pragma: no cover\n            loader,\n            queue,\n            TypeError(\n                (\n                    \"DataLoader must be constructed with a function which accepts \"\n                    \"Iterable<key> and returns Future<Iterable<value>>, but the function did \"\n                    \"not return a Coroutine: {}.\"\n                ).format(batch_future)\n            ),\n        )\n\n    try:\n        values = await batch_future\n        if not isinstance(values, Iterable):\n            raise TypeError(  # pragma: no cover\n                (\n                    \"DataLoader must be constructed with a function which accepts \"\n                    \"Iterable<key> and returns Future<Iterable<value>>, but the function did \"\n                    \"not return a Future of a Iterable: {}.\"\n                ).format(values)\n            )\n\n        values = list(values)\n        if len(values) != len(keys):\n            raise TypeError(  # pragma: no cover\n                (\n                    \"DataLoader must be constructed with a function which accepts \"\n                    \"Iterable<key> and returns Future<Iterable<value>>, but the function did \"\n                    \"not return a Future of a Iterable with the same length as the Iterable \"\n                    \"of keys.\"\n                    \"\\n\\nKeys:\\n{}\"\n                    \"\\n\\nValues:\\n{}\"\n                ).format(keys, values)\n            )\n\n        # Step through the values, resolving or rejecting each Future in the\n        # loaded queue.\n        for loaded, value in zip(queue, values):\n            if isinstance(value, Exception):\n                loaded.future.set_exception(value)\n            else:\n                loaded.future.set_result(value)\n\n    except Exception as e:\n        return failed_dispatch(loader, queue, e)\n\n\ndef failed_dispatch(loader, queue, error):\n    \"\"\"\n    Do not cache individual loads if the entire batch dispatch fails,\n    but still reject each request so they do not hang.\n    \"\"\"\n    for loaded in queue:\n        loader.clear(loaded.key)\n        loaded.future.set_exception(error)\n"
  },
  {
    "path": "graphene/utils/deduplicator.py",
    "content": "from collections.abc import Mapping\n\n\ndef deflate(node, index=None, path=None):\n    if index is None:\n        index = {}\n    if path is None:\n        path = []\n\n    if node and \"id\" in node and \"__typename\" in node:\n        route = \",\".join(path)\n        cache_key = \":\".join([route, str(node[\"__typename\"]), str(node[\"id\"])])\n\n        if index.get(cache_key) is True:\n            return {\"__typename\": node[\"__typename\"], \"id\": node[\"id\"]}\n        else:\n            index[cache_key] = True\n\n    result = {}\n\n    for field_name in node:\n        value = node[field_name]\n\n        new_path = path + [field_name]\n        if isinstance(value, (list, tuple)):\n            result[field_name] = [deflate(child, index, new_path) for child in value]\n        elif isinstance(value, Mapping):\n            result[field_name] = deflate(value, index, new_path)\n        else:\n            result[field_name] = value\n\n    return result\n"
  },
  {
    "path": "graphene/utils/deprecated.py",
    "content": "from warnings import warn\n\n\ndef warn_deprecation(text: str):\n    warn(text, category=DeprecationWarning, stacklevel=2)\n"
  },
  {
    "path": "graphene/utils/get_unbound_function.py",
    "content": "def get_unbound_function(func):\n    if not getattr(func, \"__self__\", True):\n        return func.__func__\n    return func\n"
  },
  {
    "path": "graphene/utils/is_introspection_key.py",
    "content": "def is_introspection_key(key):\n    # from: https://spec.graphql.org/June2018/#sec-Schema\n    # > All types and directives defined within a schema must not have a name which\n    # > begins with \"__\" (two underscores), as this is used exclusively\n    # > by GraphQL’s introspection system.\n    return str(key).startswith(\"__\")\n"
  },
  {
    "path": "graphene/utils/module_loading.py",
    "content": "from functools import partial\nfrom importlib import import_module\n\n\ndef import_string(dotted_path, dotted_attributes=None):\n    \"\"\"\n    Import a dotted module path and return the attribute/class designated by the\n    last name in the path. When a dotted attribute path is also provided, the\n    dotted attribute path would be applied to the attribute/class retrieved from\n    the first step, and return the corresponding value designated by the\n    attribute path. Raise ImportError if the import failed.\n    \"\"\"\n    try:\n        module_path, class_name = dotted_path.rsplit(\".\", 1)\n    except ValueError:\n        raise ImportError(\"%s doesn't look like a module path\" % dotted_path)\n\n    module = import_module(module_path)\n\n    try:\n        result = getattr(module, class_name)\n    except AttributeError:\n        raise ImportError(\n            'Module \"%s\" does not define a \"%s\" attribute/class'\n            % (module_path, class_name)\n        )\n\n    if not dotted_attributes:\n        return result\n    attributes = dotted_attributes.split(\".\")\n    traveled_attributes = []\n    try:\n        for attribute in attributes:\n            traveled_attributes.append(attribute)\n            result = getattr(result, attribute)\n        return result\n    except AttributeError:\n        raise ImportError(\n            'Module \"%s\" does not define a \"%s\" attribute inside attribute/class \"%s\"'\n            % (module_path, \".\".join(traveled_attributes), class_name)\n        )\n\n\ndef lazy_import(dotted_path, dotted_attributes=None):\n    return partial(import_string, dotted_path, dotted_attributes)\n"
  },
  {
    "path": "graphene/utils/orderedtype.py",
    "content": "from functools import total_ordering\n\n\n@total_ordering\nclass OrderedType:\n    creation_counter = 1\n\n    def __init__(self, _creation_counter=None):\n        self.creation_counter = _creation_counter or self.gen_counter()\n\n    @staticmethod\n    def gen_counter():\n        counter = OrderedType.creation_counter\n        OrderedType.creation_counter += 1\n        return counter\n\n    def reset_counter(self):\n        self.creation_counter = self.gen_counter()\n\n    def __eq__(self, other):\n        # Needed for @total_ordering\n        if isinstance(self, type(other)):\n            return self.creation_counter == other.creation_counter\n        return NotImplemented\n\n    def __lt__(self, other):\n        # This is needed because bisect does not take a comparison function.\n        if isinstance(other, OrderedType):\n            return self.creation_counter < other.creation_counter\n        return NotImplemented\n\n    def __gt__(self, other):\n        # This is needed because bisect does not take a comparison function.\n        if isinstance(other, OrderedType):\n            return self.creation_counter > other.creation_counter\n        return NotImplemented\n\n    def __hash__(self):\n        return hash(self.creation_counter)\n"
  },
  {
    "path": "graphene/utils/props.py",
    "content": "class _OldClass:\n    pass\n\n\nclass _NewClass:\n    pass\n\n\n_all_vars = set(dir(_OldClass) + dir(_NewClass))\n\n\ndef props(x):\n    return {\n        key: vars(x).get(key, getattr(x, key)) for key in dir(x) if key not in _all_vars\n    }\n"
  },
  {
    "path": "graphene/utils/resolve_only_args.py",
    "content": "from functools import wraps\nfrom typing_extensions import deprecated\n\n\n@deprecated(\"This function is deprecated\")\ndef resolve_only_args(func):\n    @wraps(func)\n    def wrapped_func(root, info, **args):\n        return func(root, **args)\n\n    return wrapped_func\n"
  },
  {
    "path": "graphene/utils/str_converters.py",
    "content": "import re\n\n\n# Adapted from this response in Stackoverflow\n# http://stackoverflow.com/a/19053800/1072990\ndef to_camel_case(snake_str):\n    components = snake_str.split(\"_\")\n    # We capitalize the first letter of each component except the first one\n    # with the 'capitalize' method and join them together.\n    return components[0] + \"\".join(x.capitalize() if x else \"_\" for x in components[1:])\n\n\n# From this response in Stackoverflow\n# http://stackoverflow.com/a/1176023/1072990\ndef to_snake_case(name):\n    s1 = re.sub(\"(.)([A-Z][a-z]+)\", r\"\\1_\\2\", name)\n    return re.sub(\"([a-z0-9])([A-Z])\", r\"\\1_\\2\", s1).lower()\n"
  },
  {
    "path": "graphene/utils/subclass_with_meta.py",
    "content": "from inspect import isclass\n\nfrom .props import props\n\n\nclass SubclassWithMeta_Meta(type):\n    _meta = None\n\n    def __str__(cls):\n        if cls._meta:\n            return cls._meta.name\n        return cls.__name__\n\n    def __repr__(cls):\n        return f\"<{cls.__name__} meta={repr(cls._meta)}>\"\n\n\nclass SubclassWithMeta(metaclass=SubclassWithMeta_Meta):\n    \"\"\"This class improves __init_subclass__ to receive automatically the options from meta\"\"\"\n\n    def __init_subclass__(cls, **meta_options):\n        \"\"\"This method just terminates the super() chain\"\"\"\n        _Meta = getattr(cls, \"Meta\", None)\n        _meta_props = {}\n        if _Meta:\n            if isinstance(_Meta, dict):\n                _meta_props = _Meta\n            elif isclass(_Meta):\n                _meta_props = props(_Meta)\n            else:\n                raise Exception(\n                    f\"Meta have to be either a class or a dict. Received {_Meta}\"\n                )\n            delattr(cls, \"Meta\")\n        options = dict(meta_options, **_meta_props)\n\n        abstract = options.pop(\"abstract\", False)\n        if abstract:\n            assert not options, (\n                \"Abstract types can only contain the abstract attribute. \"\n                f\"Received: abstract, {', '.join(options)}\"\n            )\n        else:\n            super_class = super(cls, cls)\n            if hasattr(super_class, \"__init_subclass_with_meta__\"):\n                super_class.__init_subclass_with_meta__(**options)\n\n    @classmethod\n    def __init_subclass_with_meta__(cls, **meta_options):\n        \"\"\"This method just terminates the super() chain\"\"\"\n"
  },
  {
    "path": "graphene/utils/tests/__init__.py",
    "content": ""
  },
  {
    "path": "graphene/utils/tests/test_crunch.py",
    "content": "from pytest import mark\n\nfrom ..crunch import crunch\n\n\n@mark.parametrize(\n    \"description,uncrunched,crunched\",\n    [\n        [\"number primitive\", 0, [0]],\n        [\"boolean primitive\", True, [True]],\n        [\"string primitive\", \"string\", [\"string\"]],\n        [\"empty array\", [], [[]]],\n        [\"single-item array\", [None], [None, [0]]],\n        [\n            \"multi-primitive all distinct array\",\n            [None, 0, True, \"string\"],\n            [None, 0, True, \"string\", [0, 1, 2, 3]],\n        ],\n        [\n            \"multi-primitive repeated array\",\n            [True, True, True, True],\n            [True, [0, 0, 0, 0]],\n        ],\n        [\"one-level nested array\", [[1, 2, 3]], [1, 2, 3, [0, 1, 2], [3]]],\n        [\"two-level nested array\", [[[1, 2, 3]]], [1, 2, 3, [0, 1, 2], [3], [4]]],\n        [\"empty object\", {}, [{}]],\n        [\"single-item object\", {\"a\": None}, [None, {\"a\": 0}]],\n        [\n            \"multi-item all distinct object\",\n            {\"a\": None, \"b\": 0, \"c\": True, \"d\": \"string\"},\n            [None, 0, True, \"string\", {\"a\": 0, \"b\": 1, \"c\": 2, \"d\": 3}],\n        ],\n        [\n            \"multi-item repeated object\",\n            {\"a\": True, \"b\": True, \"c\": True, \"d\": True},\n            [True, {\"a\": 0, \"b\": 0, \"c\": 0, \"d\": 0}],\n        ],\n        [\n            \"complex array\",\n            [{\"a\": True, \"b\": [1, 2, 3]}, [1, 2, 3]],\n            [True, 1, 2, 3, [1, 2, 3], {\"a\": 0, \"b\": 4}, [5, 4]],\n        ],\n        [\n            \"complex object\",\n            {\"a\": True, \"b\": [1, 2, 3], \"c\": {\"a\": True, \"b\": [1, 2, 3]}},\n            [True, 1, 2, 3, [1, 2, 3], {\"a\": 0, \"b\": 4}, {\"a\": 0, \"b\": 4, \"c\": 5}],\n        ],\n    ],\n)\ndef test_crunch(description, uncrunched, crunched):\n    assert crunch(uncrunched) == crunched\n"
  },
  {
    "path": "graphene/utils/tests/test_dataloader.py",
    "content": "from asyncio import gather\nfrom collections import namedtuple\nfrom functools import partial\nfrom unittest.mock import Mock\n\nfrom graphene.utils.dataloader import DataLoader\nfrom pytest import mark, raises\n\nfrom graphene import ObjectType, String, Schema, Field, List\n\nCHARACTERS = {\n    \"1\": {\"name\": \"Luke Skywalker\", \"sibling\": \"3\"},\n    \"2\": {\"name\": \"Darth Vader\", \"sibling\": None},\n    \"3\": {\"name\": \"Leia Organa\", \"sibling\": \"1\"},\n}\n\nget_character = Mock(side_effect=lambda character_id: CHARACTERS[character_id])\n\n\nclass CharacterType(ObjectType):\n    name = String()\n    sibling = Field(lambda: CharacterType)\n\n    async def resolve_sibling(character, info):\n        if character[\"sibling\"]:\n            return await info.context.character_loader.load(character[\"sibling\"])\n        return None\n\n\nclass Query(ObjectType):\n    skywalker_family = List(CharacterType)\n\n    async def resolve_skywalker_family(_, info):\n        return await info.context.character_loader.load_many([\"1\", \"2\", \"3\"])\n\n\nmock_batch_load_fn = Mock(\n    side_effect=lambda character_ids: [get_character(id) for id in character_ids]\n)\n\n\nclass CharacterLoader(DataLoader):\n    async def batch_load_fn(self, character_ids):\n        return mock_batch_load_fn(character_ids)\n\n\nContext = namedtuple(\"Context\", \"character_loader\")\n\n\n@mark.asyncio\nasync def test_basic_dataloader():\n    schema = Schema(query=Query)\n\n    character_loader = CharacterLoader()\n    context = Context(character_loader=character_loader)\n\n    query = \"\"\"\n        {\n            skywalkerFamily {\n                name\n                sibling {\n                    name\n                }\n            }\n        }\n    \"\"\"\n\n    result = await schema.execute_async(query, context=context)\n\n    assert not result.errors\n    assert result.data == {\n        \"skywalkerFamily\": [\n            {\"name\": \"Luke Skywalker\", \"sibling\": {\"name\": \"Leia Organa\"}},\n            {\"name\": \"Darth Vader\", \"sibling\": None},\n            {\"name\": \"Leia Organa\", \"sibling\": {\"name\": \"Luke Skywalker\"}},\n        ]\n    }\n\n    assert mock_batch_load_fn.call_count == 1\n    assert get_character.call_count == 3\n\n\ndef id_loader(**options):\n    load_calls = []\n\n    async def default_resolve(x):\n        return x\n\n    resolve = options.pop(\"resolve\", default_resolve)\n\n    async def fn(keys):\n        load_calls.append(keys)\n        return await resolve(keys)\n        # return keys\n\n    identity_loader = DataLoader(fn, **options)\n    return identity_loader, load_calls\n\n\n@mark.asyncio\nasync def test_build_a_simple_data_loader():\n    async def call_fn(keys):\n        return keys\n\n    identity_loader = DataLoader(call_fn)\n\n    promise1 = identity_loader.load(1)\n\n    value1 = await promise1\n    assert value1 == 1\n\n\n@mark.asyncio\nasync def test_can_build_a_data_loader_from_a_partial():\n    value_map = {1: \"one\"}\n\n    async def call_fn(context, keys):\n        return [context.get(key) for key in keys]\n\n    partial_fn = partial(call_fn, value_map)\n    identity_loader = DataLoader(partial_fn)\n\n    promise1 = identity_loader.load(1)\n\n    value1 = await promise1\n    assert value1 == \"one\"\n\n\n@mark.asyncio\nasync def test_supports_loading_multiple_keys_in_one_call():\n    async def call_fn(keys):\n        return keys\n\n    identity_loader = DataLoader(call_fn)\n\n    promise_all = identity_loader.load_many([1, 2])\n\n    values = await promise_all\n    assert values == [1, 2]\n\n    promise_all = identity_loader.load_many([])\n\n    values = await promise_all\n    assert values == []\n\n\n@mark.asyncio\nasync def test_batches_multiple_requests():\n    identity_loader, load_calls = id_loader()\n\n    promise1 = identity_loader.load(1)\n    promise2 = identity_loader.load(2)\n\n    p = gather(promise1, promise2)\n\n    value1, value2 = await p\n\n    assert value1 == 1\n    assert value2 == 2\n\n    assert load_calls == [[1, 2]]\n\n\n@mark.asyncio\nasync def test_batches_multiple_requests_with_max_batch_sizes():\n    identity_loader, load_calls = id_loader(max_batch_size=2)\n\n    promise1 = identity_loader.load(1)\n    promise2 = identity_loader.load(2)\n    promise3 = identity_loader.load(3)\n\n    p = gather(promise1, promise2, promise3)\n\n    value1, value2, value3 = await p\n\n    assert value1 == 1\n    assert value2 == 2\n    assert value3 == 3\n\n    assert load_calls == [[1, 2], [3]]\n\n\n@mark.asyncio\nasync def test_coalesces_identical_requests():\n    identity_loader, load_calls = id_loader()\n\n    promise1 = identity_loader.load(1)\n    promise2 = identity_loader.load(1)\n\n    assert promise1 == promise2\n    p = gather(promise1, promise2)\n\n    value1, value2 = await p\n\n    assert value1 == 1\n    assert value2 == 1\n\n    assert load_calls == [[1]]\n\n\n@mark.asyncio\nasync def test_caches_repeated_requests():\n    identity_loader, load_calls = id_loader()\n\n    a, b = await gather(identity_loader.load(\"A\"), identity_loader.load(\"B\"))\n\n    assert a == \"A\"\n    assert b == \"B\"\n\n    assert load_calls == [[\"A\", \"B\"]]\n\n    a2, c = await gather(identity_loader.load(\"A\"), identity_loader.load(\"C\"))\n\n    assert a2 == \"A\"\n    assert c == \"C\"\n\n    assert load_calls == [[\"A\", \"B\"], [\"C\"]]\n\n    a3, b2, c2 = await gather(\n        identity_loader.load(\"A\"), identity_loader.load(\"B\"), identity_loader.load(\"C\")\n    )\n\n    assert a3 == \"A\"\n    assert b2 == \"B\"\n    assert c2 == \"C\"\n\n    assert load_calls == [[\"A\", \"B\"], [\"C\"]]\n\n\n@mark.asyncio\nasync def test_clears_single_value_in_loader():\n    identity_loader, load_calls = id_loader()\n\n    a, b = await gather(identity_loader.load(\"A\"), identity_loader.load(\"B\"))\n\n    assert a == \"A\"\n    assert b == \"B\"\n\n    assert load_calls == [[\"A\", \"B\"]]\n\n    identity_loader.clear(\"A\")\n\n    a2, b2 = await gather(identity_loader.load(\"A\"), identity_loader.load(\"B\"))\n\n    assert a2 == \"A\"\n    assert b2 == \"B\"\n\n    assert load_calls == [[\"A\", \"B\"], [\"A\"]]\n\n\n@mark.asyncio\nasync def test_clears_all_values_in_loader():\n    identity_loader, load_calls = id_loader()\n\n    a, b = await gather(identity_loader.load(\"A\"), identity_loader.load(\"B\"))\n\n    assert a == \"A\"\n    assert b == \"B\"\n\n    assert load_calls == [[\"A\", \"B\"]]\n\n    identity_loader.clear_all()\n\n    a2, b2 = await gather(identity_loader.load(\"A\"), identity_loader.load(\"B\"))\n\n    assert a2 == \"A\"\n    assert b2 == \"B\"\n\n    assert load_calls == [[\"A\", \"B\"], [\"A\", \"B\"]]\n\n\n@mark.asyncio\nasync def test_allows_priming_the_cache():\n    identity_loader, load_calls = id_loader()\n\n    identity_loader.prime(\"A\", \"A\")\n\n    a, b = await gather(identity_loader.load(\"A\"), identity_loader.load(\"B\"))\n\n    assert a == \"A\"\n    assert b == \"B\"\n\n    assert load_calls == [[\"B\"]]\n\n\n@mark.asyncio\nasync def test_does_not_prime_keys_that_already_exist():\n    identity_loader, load_calls = id_loader()\n\n    identity_loader.prime(\"A\", \"X\")\n\n    a1 = await identity_loader.load(\"A\")\n    b1 = await identity_loader.load(\"B\")\n\n    assert a1 == \"X\"\n    assert b1 == \"B\"\n\n    identity_loader.prime(\"A\", \"Y\")\n    identity_loader.prime(\"B\", \"Y\")\n\n    a2 = await identity_loader.load(\"A\")\n    b2 = await identity_loader.load(\"B\")\n\n    assert a2 == \"X\"\n    assert b2 == \"B\"\n\n    assert load_calls == [[\"B\"]]\n\n\n# # Represents Errors\n@mark.asyncio\nasync def test_resolves_to_error_to_indicate_failure():\n    async def resolve(keys):\n        mapped_keys = [\n            key if key % 2 == 0 else Exception(\"Odd: {}\".format(key)) for key in keys\n        ]\n        return mapped_keys\n\n    even_loader, load_calls = id_loader(resolve=resolve)\n\n    with raises(Exception) as exc_info:\n        await even_loader.load(1)\n\n    assert str(exc_info.value) == \"Odd: 1\"\n\n    value2 = await even_loader.load(2)\n    assert value2 == 2\n    assert load_calls == [[1], [2]]\n\n\n@mark.asyncio\nasync def test_can_represent_failures_and_successes_simultaneously():\n    async def resolve(keys):\n        mapped_keys = [\n            key if key % 2 == 0 else Exception(\"Odd: {}\".format(key)) for key in keys\n        ]\n        return mapped_keys\n\n    even_loader, load_calls = id_loader(resolve=resolve)\n\n    promise1 = even_loader.load(1)\n    promise2 = even_loader.load(2)\n\n    with raises(Exception) as exc_info:\n        await promise1\n\n    assert str(exc_info.value) == \"Odd: 1\"\n    value2 = await promise2\n    assert value2 == 2\n    assert load_calls == [[1, 2]]\n\n\n@mark.asyncio\nasync def test_caches_failed_fetches():\n    async def resolve(keys):\n        mapped_keys = [Exception(\"Error: {}\".format(key)) for key in keys]\n        return mapped_keys\n\n    error_loader, load_calls = id_loader(resolve=resolve)\n\n    with raises(Exception) as exc_info:\n        await error_loader.load(1)\n\n    assert str(exc_info.value) == \"Error: 1\"\n\n    with raises(Exception) as exc_info:\n        await error_loader.load(1)\n\n    assert str(exc_info.value) == \"Error: 1\"\n\n    assert load_calls == [[1]]\n\n\n@mark.asyncio\nasync def test_caches_failed_fetches_2():\n    identity_loader, load_calls = id_loader()\n\n    identity_loader.prime(1, Exception(\"Error: 1\"))\n\n    with raises(Exception) as _:\n        await identity_loader.load(1)\n\n    assert load_calls == []\n\n\n# It is resilient to job queue ordering\n@mark.asyncio\nasync def test_batches_loads_occuring_within_promises():\n    identity_loader, load_calls = id_loader()\n\n    async def load_b_1():\n        return await load_b_2()\n\n    async def load_b_2():\n        return await identity_loader.load(\"B\")\n\n    values = await gather(identity_loader.load(\"A\"), load_b_1())\n\n    assert values == [\"A\", \"B\"]\n\n    assert load_calls == [[\"A\", \"B\"]]\n\n\n@mark.asyncio\nasync def test_catches_error_if_loader_resolver_fails():\n    exc = Exception(\"AOH!\")\n\n    def do_resolve(x):\n        raise exc\n\n    a_loader, a_load_calls = id_loader(resolve=do_resolve)\n\n    with raises(Exception) as exc_info:\n        await a_loader.load(\"A1\")\n\n    assert exc_info.value == exc\n\n\n@mark.asyncio\nasync def test_can_call_a_loader_from_a_loader():\n    deep_loader, deep_load_calls = id_loader()\n    a_loader, a_load_calls = id_loader(\n        resolve=lambda keys: deep_loader.load(tuple(keys))\n    )\n    b_loader, b_load_calls = id_loader(\n        resolve=lambda keys: deep_loader.load(tuple(keys))\n    )\n\n    a1, b1, a2, b2 = await gather(\n        a_loader.load(\"A1\"),\n        b_loader.load(\"B1\"),\n        a_loader.load(\"A2\"),\n        b_loader.load(\"B2\"),\n    )\n\n    assert a1 == \"A1\"\n    assert b1 == \"B1\"\n    assert a2 == \"A2\"\n    assert b2 == \"B2\"\n\n    assert a_load_calls == [[\"A1\", \"A2\"]]\n    assert b_load_calls == [[\"B1\", \"B2\"]]\n    assert deep_load_calls == [[(\"A1\", \"A2\"), (\"B1\", \"B2\")]]\n\n\n@mark.asyncio\nasync def test_dataloader_clear_with_missing_key_works():\n    async def do_resolve(x):\n        return x\n\n    a_loader, a_load_calls = id_loader(resolve=do_resolve)\n    assert a_loader.clear(\"A1\") == a_loader\n"
  },
  {
    "path": "graphene/utils/tests/test_deduplicator.py",
    "content": "import datetime\nimport graphene\nfrom graphene import relay\nfrom graphene.types.resolver import dict_resolver\n\nfrom ..deduplicator import deflate\n\n\ndef test_does_not_modify_object_without_typename_and_id():\n    response = {\"foo\": \"bar\"}\n\n    deflated_response = deflate(response)\n    assert deflated_response == {\"foo\": \"bar\"}\n\n\ndef test_does_not_modify_first_instance_of_an_object():\n    response = {\n        \"data\": [\n            {\"__typename\": \"foo\", \"id\": 1, \"name\": \"foo\"},\n            {\"__typename\": \"foo\", \"id\": 1, \"name\": \"foo\"},\n        ]\n    }\n\n    deflated_response = deflate(response)\n\n    assert deflated_response == {\n        \"data\": [\n            {\"__typename\": \"foo\", \"id\": 1, \"name\": \"foo\"},\n            {\"__typename\": \"foo\", \"id\": 1},\n        ]\n    }\n\n\ndef test_does_not_modify_first_instance_of_an_object_nested():\n    response = {\n        \"data\": [\n            {\n                \"__typename\": \"foo\",\n                \"bar1\": {\"__typename\": \"bar\", \"id\": 1, \"name\": \"bar\"},\n                \"bar2\": {\"__typename\": \"bar\", \"id\": 1, \"name\": \"bar\"},\n                \"id\": 1,\n            },\n            {\n                \"__typename\": \"foo\",\n                \"bar1\": {\"__typename\": \"bar\", \"id\": 1, \"name\": \"bar\"},\n                \"bar2\": {\"__typename\": \"bar\", \"id\": 1, \"name\": \"bar\"},\n                \"id\": 2,\n            },\n        ]\n    }\n\n    deflated_response = deflate(response)\n\n    assert deflated_response == {\n        \"data\": [\n            {\n                \"__typename\": \"foo\",\n                \"bar1\": {\"__typename\": \"bar\", \"id\": 1, \"name\": \"bar\"},\n                \"bar2\": {\"__typename\": \"bar\", \"id\": 1, \"name\": \"bar\"},\n                \"id\": 1,\n            },\n            {\n                \"__typename\": \"foo\",\n                \"bar1\": {\"__typename\": \"bar\", \"id\": 1},\n                \"bar2\": {\"__typename\": \"bar\", \"id\": 1},\n                \"id\": 2,\n            },\n        ]\n    }\n\n\ndef test_does_not_modify_input():\n    response = {\n        \"data\": [\n            {\"__typename\": \"foo\", \"id\": 1, \"name\": \"foo\"},\n            {\"__typename\": \"foo\", \"id\": 1, \"name\": \"foo\"},\n        ]\n    }\n\n    deflate(response)\n\n    assert response == {\n        \"data\": [\n            {\"__typename\": \"foo\", \"id\": 1, \"name\": \"foo\"},\n            {\"__typename\": \"foo\", \"id\": 1, \"name\": \"foo\"},\n        ]\n    }\n\n\nTEST_DATA = {\n    \"events\": [\n        {\"id\": \"568\", \"date\": datetime.date(2017, 5, 19), \"movie\": \"1198359\"},\n        {\"id\": \"234\", \"date\": datetime.date(2017, 5, 20), \"movie\": \"1198359\"},\n    ],\n    \"movies\": {\n        \"1198359\": {\n            \"id\": \"1198359\",\n            \"name\": \"King Arthur: Legend of the Sword\",\n            \"synopsis\": (\n                \"When the child Arthur's father is murdered, Vortigern, \"\n                \"Arthur's uncle, seizes the crown. Robbed of his birthright and \"\n                \"with no idea who he truly is...\"\n            ),\n        }\n    },\n}\n\n\ndef test_example_end_to_end():\n    class Movie(graphene.ObjectType):\n        class Meta:\n            interfaces = (relay.Node,)\n            default_resolver = dict_resolver\n\n        name = graphene.String(required=True)\n        synopsis = graphene.String(required=True)\n\n    class Event(graphene.ObjectType):\n        class Meta:\n            interfaces = (relay.Node,)\n            default_resolver = dict_resolver\n\n        movie = graphene.Field(Movie, required=True)\n        date = graphene.types.datetime.Date(required=True)\n\n        def resolve_movie(event, info):\n            return TEST_DATA[\"movies\"][event[\"movie\"]]\n\n    class Query(graphene.ObjectType):\n        events = graphene.List(graphene.NonNull(Event), required=True)\n\n        def resolve_events(_, info):\n            return TEST_DATA[\"events\"]\n\n    schema = graphene.Schema(query=Query)\n    query = \"\"\"\\\n        {\n            events {\n                __typename\n                id\n                date\n                movie {\n                    __typename\n                    id\n                    name\n                    synopsis\n                }\n            }\n        }\n    \"\"\"\n    result = schema.execute(query)\n    assert not result.errors\n\n    data = deflate(result.data)\n    assert data == {\n        \"events\": [\n            {\n                \"__typename\": \"Event\",\n                \"id\": \"RXZlbnQ6NTY4\",\n                \"date\": \"2017-05-19\",\n                \"movie\": {\n                    \"__typename\": \"Movie\",\n                    \"id\": \"TW92aWU6MTE5ODM1OQ==\",\n                    \"name\": \"King Arthur: Legend of the Sword\",\n                    \"synopsis\": (\n                        \"When the child Arthur's father is murdered, Vortigern, \"\n                        \"Arthur's uncle, seizes the crown. Robbed of his birthright and \"\n                        \"with no idea who he truly is...\"\n                    ),\n                },\n            },\n            {\n                \"__typename\": \"Event\",\n                \"id\": \"RXZlbnQ6MjM0\",\n                \"date\": \"2017-05-20\",\n                \"movie\": {\"__typename\": \"Movie\", \"id\": \"TW92aWU6MTE5ODM1OQ==\"},\n            },\n        ]\n    }\n"
  },
  {
    "path": "graphene/utils/tests/test_deprecated.py",
    "content": "from .. import deprecated\nfrom ..deprecated import warn_deprecation\n\n\ndef test_warn_deprecation(mocker):\n    mocker.patch.object(deprecated, \"warn\")\n\n    warn_deprecation(\"OH!\")\n    deprecated.warn.assert_called_with(\"OH!\", stacklevel=2, category=DeprecationWarning)\n"
  },
  {
    "path": "graphene/utils/tests/test_module_loading.py",
    "content": "from pytest import raises\n\nfrom graphene import ObjectType, String\n\nfrom ..module_loading import import_string, lazy_import\n\n\ndef test_import_string():\n    MyString = import_string(\"graphene.String\")\n    assert MyString == String\n\n    MyObjectTypeMeta = import_string(\"graphene.ObjectType\", \"__doc__\")\n    assert MyObjectTypeMeta == ObjectType.__doc__\n\n\ndef test_import_string_module():\n    with raises(Exception) as exc_info:\n        import_string(\"graphenea\")\n\n    assert str(exc_info.value) == \"graphenea doesn't look like a module path\"\n\n\ndef test_import_string_class():\n    with raises(Exception) as exc_info:\n        import_string(\"graphene.Stringa\")\n\n    assert (\n        str(exc_info.value)\n        == 'Module \"graphene\" does not define a \"Stringa\" attribute/class'\n    )\n\n\ndef test_import_string_attributes():\n    with raises(Exception) as exc_info:\n        import_string(\"graphene.String\", \"length\")\n\n    assert (\n        str(exc_info.value)\n        == 'Module \"graphene\" does not define a \"length\" attribute inside attribute/class '\n        '\"String\"'\n    )\n\n    with raises(Exception) as exc_info:\n        import_string(\"graphene.ObjectType\", \"__class__.length\")\n\n    assert (\n        str(exc_info.value)\n        == 'Module \"graphene\" does not define a \"__class__.length\" attribute inside '\n        'attribute/class \"ObjectType\"'\n    )\n\n    with raises(Exception) as exc_info:\n        import_string(\"graphene.ObjectType\", \"__classa__.__base__\")\n\n    assert (\n        str(exc_info.value)\n        == 'Module \"graphene\" does not define a \"__classa__\" attribute inside attribute/class '\n        '\"ObjectType\"'\n    )\n\n\ndef test_lazy_import():\n    f = lazy_import(\"graphene.String\")\n    MyString = f()\n    assert MyString == String\n\n    f = lazy_import(\"graphene.ObjectType\", \"__doc__\")\n    MyObjectTypeMeta = f()\n    assert MyObjectTypeMeta == ObjectType.__doc__\n"
  },
  {
    "path": "graphene/utils/tests/test_orderedtype.py",
    "content": "from ..orderedtype import OrderedType\n\n\ndef test_orderedtype():\n    one = OrderedType()\n    two = OrderedType()\n    three = OrderedType()\n\n    assert one < two < three\n\n\ndef test_orderedtype_eq():\n    one = OrderedType()\n    two = OrderedType()\n\n    assert one == one\n    assert one != two\n\n\ndef test_orderedtype_hash():\n    one = OrderedType()\n    two = OrderedType()\n\n    assert hash(one) == hash(one)\n    assert hash(one) != hash(two)\n\n\ndef test_orderedtype_resetcounter():\n    one = OrderedType()\n    two = OrderedType()\n    one.reset_counter()\n\n    assert one > two\n\n\ndef test_orderedtype_non_orderabletypes():\n    one = OrderedType()\n\n    assert one.__lt__(1) == NotImplemented\n    assert one.__gt__(1) == NotImplemented\n    assert one != 1\n"
  },
  {
    "path": "graphene/utils/tests/test_resolve_only_args.py",
    "content": "from .. import deprecated\nfrom ..resolve_only_args import resolve_only_args\n\n\ndef test_resolve_only_args(mocker):\n    mocker.patch.object(deprecated, \"warn_deprecation\")\n\n    def resolver(root, **args):\n        return root, args\n\n    wrapped_resolver = resolve_only_args(resolver)\n    result = wrapped_resolver(1, 2, a=3)\n    assert result == (1, {\"a\": 3})\n"
  },
  {
    "path": "graphene/utils/tests/test_resolver_from_annotations.py",
    "content": ""
  },
  {
    "path": "graphene/utils/tests/test_str_converters.py",
    "content": "# coding: utf-8\nfrom ..str_converters import to_camel_case, to_snake_case\n\n\ndef test_snake_case():\n    assert to_snake_case(\"snakesOnAPlane\") == \"snakes_on_a_plane\"\n    assert to_snake_case(\"SnakesOnAPlane\") == \"snakes_on_a_plane\"\n    assert to_snake_case(\"SnakesOnA_Plane\") == \"snakes_on_a__plane\"\n    assert to_snake_case(\"snakes_on_a_plane\") == \"snakes_on_a_plane\"\n    assert to_snake_case(\"snakes_on_a__plane\") == \"snakes_on_a__plane\"\n    assert to_snake_case(\"IPhoneHysteria\") == \"i_phone_hysteria\"\n    assert to_snake_case(\"iPhoneHysteria\") == \"i_phone_hysteria\"\n\n\ndef test_camel_case():\n    assert to_camel_case(\"snakes_on_a_plane\") == \"snakesOnAPlane\"\n    assert to_camel_case(\"snakes_on_a__plane\") == \"snakesOnA_Plane\"\n    assert to_camel_case(\"i_phone_hysteria\") == \"iPhoneHysteria\"\n    assert to_camel_case(\"field_i18n\") == \"fieldI18n\"\n"
  },
  {
    "path": "graphene/utils/tests/test_trim_docstring.py",
    "content": "from ..trim_docstring import trim_docstring\n\n\ndef test_trim_docstring():\n    class WellDocumentedObject:\n        \"\"\"\n        This object is very well-documented. It has multiple lines in its\n        description.\n\n        Multiple paragraphs too\n        \"\"\"\n\n    assert (\n        trim_docstring(WellDocumentedObject.__doc__)\n        == \"This object is very well-documented. It has multiple lines in its\\n\"\n        \"description.\\n\\nMultiple paragraphs too\"\n    )\n\n    class UndocumentedObject:\n        pass\n\n    assert trim_docstring(UndocumentedObject.__doc__) is None\n"
  },
  {
    "path": "graphene/utils/thenables.py",
    "content": "\"\"\"\nThis file is used mainly as a bridge for thenable abstractions.\n\"\"\"\n\nfrom inspect import isawaitable\n\n\ndef await_and_execute(obj, on_resolve):\n    async def build_resolve_async():\n        return on_resolve(await obj)\n\n    return build_resolve_async()\n\n\ndef maybe_thenable(obj, on_resolve):\n    \"\"\"\n    Execute a on_resolve function once the thenable is resolved,\n    returning the same type of object inputed.\n    If the object is not thenable, it should return on_resolve(obj)\n    \"\"\"\n    if isawaitable(obj):\n        return await_and_execute(obj, on_resolve)\n\n    # If it's not awaitable, return the function executed over the object\n    return on_resolve(obj)\n"
  },
  {
    "path": "graphene/utils/trim_docstring.py",
    "content": "import inspect\n\n\ndef trim_docstring(docstring):\n    # Cleans up whitespaces from an indented docstring\n    #\n    # See https://www.python.org/dev/peps/pep-0257/\n    # and https://docs.python.org/2/library/inspect.html#inspect.cleandoc\n    return inspect.cleandoc(docstring) if docstring else None\n"
  },
  {
    "path": "graphene/validation/__init__.py",
    "content": "from .depth_limit import depth_limit_validator\nfrom .disable_introspection import DisableIntrospection\n\n\n__all__ = [\"DisableIntrospection\", \"depth_limit_validator\"]\n"
  },
  {
    "path": "graphene/validation/depth_limit.py",
    "content": "# This is a Python port of https://github.com/stems/graphql-depth-limit\n# which is licensed under the terms of the MIT license, reproduced below.\n#\n# -----------\n#\n# MIT License\n#\n# Copyright (c) 2017 Stem\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to deal\n# in the Software without restriction, including without limitation the rights\n# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n# copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in all\n# copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n# SOFTWARE.\n\ntry:\n    from re import Pattern\nexcept ImportError:\n    # backwards compatibility for v3.6\n    from typing import Pattern\nfrom typing import Callable, Dict, List, Optional, Union, Tuple\n\nfrom graphql import GraphQLError\nfrom graphql.validation import ValidationContext, ValidationRule\nfrom graphql.language import (\n    DefinitionNode,\n    FieldNode,\n    FragmentDefinitionNode,\n    FragmentSpreadNode,\n    InlineFragmentNode,\n    Node,\n    OperationDefinitionNode,\n)\n\nfrom ..utils.is_introspection_key import is_introspection_key\n\n\nIgnoreType = Union[Callable[[str], bool], Pattern, str]\n\n\ndef depth_limit_validator(\n    max_depth: int,\n    ignore: Optional[List[IgnoreType]] = None,\n    callback: Optional[Callable[[Dict[str, int]], None]] = None,\n):\n    class DepthLimitValidator(ValidationRule):\n        def __init__(self, validation_context: ValidationContext):\n            document = validation_context.document\n            definitions = document.definitions\n\n            fragments = get_fragments(definitions)\n            queries = get_queries_and_mutations(definitions)\n            query_depths = {}\n\n            for name in queries:\n                query_depths[name] = determine_depth(\n                    node=queries[name],\n                    fragments=fragments,\n                    depth_so_far=0,\n                    max_depth=max_depth,\n                    context=validation_context,\n                    operation_name=name,\n                    ignore=ignore,\n                )\n            if callable(callback):\n                callback(query_depths)\n            super().__init__(validation_context)\n\n    return DepthLimitValidator\n\n\ndef get_fragments(\n    definitions: Tuple[DefinitionNode, ...],\n) -> Dict[str, FragmentDefinitionNode]:\n    fragments = {}\n    for definition in definitions:\n        if isinstance(definition, FragmentDefinitionNode):\n            fragments[definition.name.value] = definition\n    return fragments\n\n\n# This will actually get both queries and mutations.\n# We can basically treat those the same\ndef get_queries_and_mutations(\n    definitions: Tuple[DefinitionNode, ...],\n) -> Dict[str, OperationDefinitionNode]:\n    operations = {}\n\n    for definition in definitions:\n        if isinstance(definition, OperationDefinitionNode):\n            operation = definition.name.value if definition.name else \"anonymous\"\n            operations[operation] = definition\n    return operations\n\n\ndef determine_depth(\n    node: Node,\n    fragments: Dict[str, FragmentDefinitionNode],\n    depth_so_far: int,\n    max_depth: int,\n    context: ValidationContext,\n    operation_name: str,\n    ignore: Optional[List[IgnoreType]] = None,\n) -> int:\n    if depth_so_far > max_depth:\n        context.report_error(\n            GraphQLError(\n                f\"'{operation_name}' exceeds maximum operation depth of {max_depth}.\",\n                [node],\n            )\n        )\n        return depth_so_far\n    if isinstance(node, FieldNode):\n        should_ignore = is_introspection_key(node.name.value) or is_ignored(\n            node, ignore\n        )\n\n        if should_ignore or not node.selection_set:\n            return 0\n        return 1 + max(\n            map(\n                lambda selection: determine_depth(\n                    node=selection,\n                    fragments=fragments,\n                    depth_so_far=depth_so_far + 1,\n                    max_depth=max_depth,\n                    context=context,\n                    operation_name=operation_name,\n                    ignore=ignore,\n                ),\n                node.selection_set.selections,\n            )\n        )\n    elif isinstance(node, FragmentSpreadNode):\n        return determine_depth(\n            node=fragments[node.name.value],\n            fragments=fragments,\n            depth_so_far=depth_so_far,\n            max_depth=max_depth,\n            context=context,\n            operation_name=operation_name,\n            ignore=ignore,\n        )\n    elif isinstance(\n        node, (InlineFragmentNode, FragmentDefinitionNode, OperationDefinitionNode)\n    ):\n        return max(\n            map(\n                lambda selection: determine_depth(\n                    node=selection,\n                    fragments=fragments,\n                    depth_so_far=depth_so_far,\n                    max_depth=max_depth,\n                    context=context,\n                    operation_name=operation_name,\n                    ignore=ignore,\n                ),\n                node.selection_set.selections,\n            )\n        )\n    else:\n        raise Exception(\n            f\"Depth crawler cannot handle: {node.kind}.\"\n        )  # pragma: no cover\n\n\ndef is_ignored(node: FieldNode, ignore: Optional[List[IgnoreType]] = None) -> bool:\n    if ignore is None:\n        return False\n    for rule in ignore:\n        field_name = node.name.value\n        if isinstance(rule, str):\n            if field_name == rule:\n                return True\n        elif isinstance(rule, Pattern):\n            if rule.match(field_name):\n                return True\n        elif callable(rule):\n            if rule(field_name):\n                return True\n        else:\n            raise ValueError(f\"Invalid ignore option: {rule}.\")\n    return False\n"
  },
  {
    "path": "graphene/validation/disable_introspection.py",
    "content": "from graphql import GraphQLError\nfrom graphql.language import FieldNode\nfrom graphql.validation import ValidationRule\n\nfrom ..utils.is_introspection_key import is_introspection_key\n\n\nclass DisableIntrospection(ValidationRule):\n    def enter_field(self, node: FieldNode, *_args):\n        field_name = node.name.value\n        if is_introspection_key(field_name):\n            self.report_error(\n                GraphQLError(\n                    f\"Cannot query '{field_name}': introspection is disabled.\", node\n                )\n            )\n"
  },
  {
    "path": "graphene/validation/tests/__init__.py",
    "content": ""
  },
  {
    "path": "graphene/validation/tests/test_depth_limit_validator.py",
    "content": "import re\n\nfrom pytest import raises\nfrom graphql import parse, get_introspection_query, validate\n\nfrom ...types import Schema, ObjectType, Interface\nfrom ...types import String, Int, List, Field\nfrom ..depth_limit import depth_limit_validator\n\n\nclass PetType(Interface):\n    name = String(required=True)\n\n    class meta:\n        name = \"Pet\"\n\n\nclass CatType(ObjectType):\n    class meta:\n        name = \"Cat\"\n        interfaces = (PetType,)\n\n\nclass DogType(ObjectType):\n    class meta:\n        name = \"Dog\"\n        interfaces = (PetType,)\n\n\nclass AddressType(ObjectType):\n    street = String(required=True)\n    number = Int(required=True)\n    city = String(required=True)\n    country = String(required=True)\n\n    class Meta:\n        name = \"Address\"\n\n\nclass HumanType(ObjectType):\n    name = String(required=True)\n    email = String(required=True)\n    address = Field(AddressType, required=True)\n    pets = List(PetType, required=True)\n\n    class Meta:\n        name = \"Human\"\n\n\nclass Query(ObjectType):\n    user = Field(HumanType, required=True, name=String())\n    version = String(required=True)\n    user1 = Field(HumanType, required=True)\n    user2 = Field(HumanType, required=True)\n    user3 = Field(HumanType, required=True)\n\n    @staticmethod\n    def resolve_user(root, info, name=None):\n        pass\n\n\nschema = Schema(query=Query)\n\n\ndef run_query(query: str, max_depth: int, ignore=None):\n    document = parse(query)\n\n    result = None\n\n    def callback(query_depths):\n        nonlocal result\n        result = query_depths\n\n    errors = validate(\n        schema=schema.graphql_schema,\n        document_ast=document,\n        rules=(\n            depth_limit_validator(\n                max_depth=max_depth, ignore=ignore, callback=callback\n            ),\n        ),\n    )\n\n    return errors, result\n\n\ndef test_should_count_depth_without_fragment():\n    query = \"\"\"\n    query read0 {\n      version\n    }\n    query read1 {\n      version\n      user {\n        name\n      }\n    }\n    query read2 {\n      matt: user(name: \"matt\") {\n        email\n      }\n      andy: user(name: \"andy\") {\n        email\n        address {\n          city\n        }\n      }\n    }\n    query read3 {\n      matt: user(name: \"matt\") {\n        email\n      }\n      andy: user(name: \"andy\") {\n        email\n        address {\n          city\n        }\n        pets {\n          name\n          owner {\n            name\n          }\n        }\n      }\n    }\n    \"\"\"\n\n    expected = {\"read0\": 0, \"read1\": 1, \"read2\": 2, \"read3\": 3}\n\n    errors, result = run_query(query, 10)\n    assert not errors\n    assert result == expected\n\n\ndef test_should_count_with_fragments():\n    query = \"\"\"\n    query read0 {\n      ... on Query {\n        version\n      }\n    }\n    query read1 {\n      version\n      user {\n        ... on Human {\n          name\n        }\n      }\n    }\n    fragment humanInfo on Human {\n      email\n    }\n    fragment petInfo on Pet {\n      name\n      owner {\n        name\n      }\n    }\n    query read2 {\n      matt: user(name: \"matt\") {\n        ...humanInfo\n      }\n      andy: user(name: \"andy\") {\n        ...humanInfo\n        address {\n          city\n        }\n      }\n    }\n    query read3 {\n      matt: user(name: \"matt\") {\n        ...humanInfo\n      }\n      andy: user(name: \"andy\") {\n        ... on Human {\n          email\n        }\n        address {\n          city\n        }\n        pets {\n          ...petInfo\n        }\n      }\n    }\n  \"\"\"\n\n    expected = {\"read0\": 0, \"read1\": 1, \"read2\": 2, \"read3\": 3}\n\n    errors, result = run_query(query, 10)\n    assert not errors\n    assert result == expected\n\n\ndef test_should_ignore_the_introspection_query():\n    errors, result = run_query(get_introspection_query(), 10)\n    assert not errors\n    assert result == {\"IntrospectionQuery\": 0}\n\n\ndef test_should_catch_very_deep_query():\n    query = \"\"\"{\n    user {\n      pets {\n        owner {\n          pets {\n            owner {\n              pets {\n                name\n              }\n            }\n          }\n        }\n      }\n    }\n    }\n    \"\"\"\n    errors, result = run_query(query, 4)\n\n    assert len(errors) == 1\n    assert errors[0].message == \"'anonymous' exceeds maximum operation depth of 4.\"\n\n\ndef test_should_ignore_field():\n    query = \"\"\"\n    query read1 {\n      user { address { city } }\n    }\n    query read2 {\n      user1 { address { city } }\n      user2 { address { city } }\n      user3 { address { city } }\n    }\n    \"\"\"\n\n    errors, result = run_query(\n        query,\n        10,\n        ignore=[\"user1\", re.compile(\"user2\"), lambda field_name: field_name == \"user3\"],\n    )\n\n    expected = {\"read1\": 2, \"read2\": 0}\n    assert not errors\n    assert result == expected\n\n\ndef test_should_raise_invalid_ignore():\n    query = \"\"\"\n    query read1 {\n      user { address { city } }\n    }\n    \"\"\"\n    with raises(ValueError, match=\"Invalid ignore option:\"):\n        run_query(query, 10, ignore=[True])\n"
  },
  {
    "path": "graphene/validation/tests/test_disable_introspection.py",
    "content": "from graphql import parse, validate\n\nfrom ...types import Schema, ObjectType, String\nfrom ..disable_introspection import DisableIntrospection\n\n\nclass Query(ObjectType):\n    name = String(required=True)\n\n    @staticmethod\n    def resolve_name(root, info):\n        return \"Hello world!\"\n\n\nschema = Schema(query=Query)\n\n\ndef run_query(query: str):\n    document = parse(query)\n\n    return validate(\n        schema=schema.graphql_schema,\n        document_ast=document,\n        rules=(DisableIntrospection,),\n    )\n\n\ndef test_disallows_introspection_queries():\n    errors = run_query(\"{ __schema { queryType { name } } }\")\n\n    assert len(errors) == 1\n    assert errors[0].message == \"Cannot query '__schema': introspection is disabled.\"\n\n\ndef test_allows_non_introspection_queries():\n    errors = run_query(\"{ name }\")\n    assert len(errors) == 0\n"
  },
  {
    "path": "mypy.ini",
    "content": "[mypy]\nignore_missing_imports = True\n\n[mypy-graphene.pyutils.*]\nignore_errors = True\n\n[mypy-graphene.types.scalars]\nignore_errors = True\n\n[mypy-graphene.types.generic]\nignore_errors = True\n\n[mypy-graphene.types.tests.*]\nignore_errors = True\n\n[mypy-graphene.relay.tests.*]\nignore_errors = True\n"
  },
  {
    "path": "setup.cfg",
    "content": "[coverage:run]\nomit = graphene/pyutils/*,*/tests/*,graphene/types/scalars.py\n\n[bdist_wheel]\nuniversal=1\n"
  },
  {
    "path": "setup.py",
    "content": "import ast\nimport codecs\nimport re\nimport sys\n\nfrom setuptools import find_packages, setup\nfrom setuptools.command.test import test as TestCommand\n\n_version_re = re.compile(r\"VERSION\\s+=\\s+(.*)\")\n\nwith open(\"graphene/__init__.py\", \"rb\") as f:\n    version = ast.literal_eval(_version_re.search(f.read().decode(\"utf-8\")).group(1))\n\npath_copy = sys.path[:]\n\nsys.path.append(\"graphene\")\ntry:\n    from pyutils.version import get_version\n\n    version = get_version(version)\nexcept Exception:\n    version = \".\".join([str(v) for v in version])\n\nsys.path[:] = path_copy\n\n\nclass PyTest(TestCommand):\n    user_options = [(\"pytest-args=\", \"a\", \"Arguments to pass to py.test\")]\n\n    def initialize_options(self):\n        TestCommand.initialize_options(self)\n        self.pytest_args = []\n\n    def finalize_options(self):\n        TestCommand.finalize_options(self)\n        self.test_args = []\n        self.test_suite = True\n\n    def run_tests(self):\n        # import here, cause outside the eggs aren't loaded\n        import pytest\n\n        errno = pytest.main(self.pytest_args)\n        sys.exit(errno)\n\n\ntests_require = [\n    \"pytest>=8,<9\",\n    \"pytest-benchmark>=4,<5\",\n    \"pytest-cov>=5,<6\",\n    \"pytest-mock>=3,<4\",\n    \"pytest-asyncio>=0.16,<2\",\n    \"coveralls>=3.3,<5\",\n]\n\ndev_requires = [\n    \"ruff==0.5.0\",\n    \"types-python-dateutil>=2.8.1,<3\",\n    \"mypy>=1.10,<2\",\n] + tests_require\n\nsetup(\n    name=\"graphene\",\n    version=version,\n    description=\"GraphQL Framework for Python\",\n    long_description=codecs.open(\n        \"README.md\", \"r\", encoding=\"ascii\", errors=\"replace\"\n    ).read(),\n    long_description_content_type=\"text/markdown\",\n    url=\"https://github.com/graphql-python/graphene\",\n    author=\"Syrus Akbary\",\n    author_email=\"me@syrusakbary.com\",\n    license=\"MIT\",\n    classifiers=[\n        \"Development Status :: 5 - Production/Stable\",\n        \"Intended Audience :: Developers\",\n        \"Topic :: Software Development :: Libraries\",\n        \"Programming Language :: Python :: 3.8\",\n        \"Programming Language :: Python :: 3.9\",\n        \"Programming Language :: Python :: 3.10\",\n        \"Programming Language :: Python :: 3.11\",\n        \"Programming Language :: Python :: 3.12\",\n        \"Programming Language :: Python :: 3.13\",\n    ],\n    keywords=\"api graphql protocol rest relay graphene\",\n    packages=find_packages(exclude=[\"examples*\"]),\n    install_requires=[\n        \"graphql-core>=3.1,<3.3\",\n        \"graphql-relay>=3.1,<3.3\",\n        \"python-dateutil>=2.7.0,<3\",\n        \"typing-extensions>=4.7.1,<5\",\n    ],\n    tests_require=tests_require,\n    extras_require={\"test\": tests_require, \"dev\": dev_requires},\n    cmdclass={\"test\": PyTest},\n)\n"
  },
  {
    "path": "tox.ini",
    "content": "[tox]\nenvlist = py3{8,9,10,11,12,13}, mypy, pre-commit\nskipsdist = true\n\n[testenv]\ndeps =\n    .[test]\ncommands =\n    pytest --cov=graphene graphene --cov-report=term --cov-report=xml examples {posargs}\n\n[testenv:pre-commit]\nbasepython = python3.10\ndeps =\n    pre-commit>=3.7,<4\nsetenv =\n    LC_CTYPE=en_US.UTF-8\ncommands =\n    pre-commit run --all-files --show-diff-on-failure\n\n[testenv:mypy]\nbasepython = python3.10\ndeps =\n    .[dev]\ncommands =\n    mypy graphene\n\n[pytest]\n"
  }
]