Full Code of graphql-python/graphene for AI

master 82903263080b cached
189 files
480.1 KB
117.2k tokens
1029 symbols
1 requests
Download .txt
Showing preview only (523K chars total). Download the full file or copy to clipboard to get everything.
Repository: graphql-python/graphene
Branch: master
Commit: 82903263080b
Files: 189
Total size: 480.1 KB

Directory structure:
gitextract_dd7rqbyb/

├── .coveragerc
├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   └── feature_request.md
│   ├── stale.yml
│   └── workflows/
│       ├── build.yaml
│       ├── deploy.yml
│       ├── lint.yml
│       └── tests.yml
├── .gitignore
├── .pre-commit-config.yaml
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.md
├── SECURITY.md
├── UPGRADE-v1.0.md
├── UPGRADE-v2.0.md
├── bin/
│   └── convert_documentation
├── docs/
│   ├── Makefile
│   ├── _static/
│   │   └── .gitkeep
│   ├── api/
│   │   └── index.rst
│   ├── conf.py
│   ├── execution/
│   │   ├── dataloader.rst
│   │   ├── execute.rst
│   │   ├── fileuploading.rst
│   │   ├── index.rst
│   │   ├── middleware.rst
│   │   ├── queryvalidation.rst
│   │   └── subscriptions.rst
│   ├── index.rst
│   ├── quickstart.rst
│   ├── relay/
│   │   ├── connection.rst
│   │   ├── index.rst
│   │   ├── mutations.rst
│   │   └── nodes.rst
│   ├── requirements.txt
│   ├── testing/
│   │   └── index.rst
│   └── types/
│       ├── enums.rst
│       ├── index.rst
│       ├── interfaces.rst
│       ├── list-and-nonnull.rst
│       ├── mutations.rst
│       ├── objecttypes.rst
│       ├── scalars.rst
│       ├── schema.rst
│       └── unions.rst
├── examples/
│   ├── __init__.py
│   ├── complex_example.py
│   ├── context_example.py
│   ├── simple_example.py
│   ├── starwars/
│   │   ├── __init__.py
│   │   ├── data.py
│   │   ├── schema.py
│   │   └── tests/
│   │       ├── __init__.py
│   │       ├── test_query.py
│   │       └── test_schema.py
│   └── starwars_relay/
│       ├── __init__.py
│       ├── data.py
│       ├── schema.py
│       └── tests/
│           ├── __init__.py
│           ├── test_connections.py
│           ├── test_mutation.py
│           └── test_objectidentification.py
├── graphene/
│   ├── __init__.py
│   ├── pyutils/
│   │   ├── __init__.py
│   │   └── version.py
│   ├── relay/
│   │   ├── __init__.py
│   │   ├── connection.py
│   │   ├── id_type.py
│   │   ├── mutation.py
│   │   ├── node.py
│   │   └── tests/
│   │       ├── __init__.py
│   │       ├── test_connection.py
│   │       ├── test_connection_async.py
│   │       ├── test_connection_query.py
│   │       ├── test_custom_global_id.py
│   │       ├── test_global_id.py
│   │       ├── test_mutation.py
│   │       ├── test_mutation_async.py
│   │       ├── test_node.py
│   │       └── test_node_custom.py
│   ├── test/
│   │   └── __init__.py
│   ├── tests/
│   │   ├── __init__.py
│   │   └── issues/
│   │       ├── __init__.py
│   │       ├── test_1293.py
│   │       ├── test_1394.py
│   │       ├── test_1419.py
│   │       ├── test_313.py
│   │       ├── test_356.py
│   │       ├── test_425.py
│   │       ├── test_490.py
│   │       ├── test_720.py
│   │       ├── test_881.py
│   │       └── test_956.py
│   ├── types/
│   │   ├── __init__.py
│   │   ├── argument.py
│   │   ├── base.py
│   │   ├── base64.py
│   │   ├── context.py
│   │   ├── datetime.py
│   │   ├── decimal.py
│   │   ├── definitions.py
│   │   ├── dynamic.py
│   │   ├── enum.py
│   │   ├── field.py
│   │   ├── generic.py
│   │   ├── inputfield.py
│   │   ├── inputobjecttype.py
│   │   ├── interface.py
│   │   ├── json.py
│   │   ├── mountedtype.py
│   │   ├── mutation.py
│   │   ├── objecttype.py
│   │   ├── resolver.py
│   │   ├── scalars.py
│   │   ├── schema.py
│   │   ├── structures.py
│   │   ├── tests/
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_argument.py
│   │   │   ├── test_base.py
│   │   │   ├── test_base64.py
│   │   │   ├── test_datetime.py
│   │   │   ├── test_decimal.py
│   │   │   ├── test_definition.py
│   │   │   ├── test_dynamic.py
│   │   │   ├── test_enum.py
│   │   │   ├── test_field.py
│   │   │   ├── test_generic.py
│   │   │   ├── test_inputfield.py
│   │   │   ├── test_inputobjecttype.py
│   │   │   ├── test_interface.py
│   │   │   ├── test_json.py
│   │   │   ├── test_mountedtype.py
│   │   │   ├── test_mutation.py
│   │   │   ├── test_objecttype.py
│   │   │   ├── test_query.py
│   │   │   ├── test_resolver.py
│   │   │   ├── test_scalar.py
│   │   │   ├── test_scalars_serialization.py
│   │   │   ├── test_schema.py
│   │   │   ├── test_structures.py
│   │   │   ├── test_subscribe_async.py
│   │   │   ├── test_type_map.py
│   │   │   ├── test_union.py
│   │   │   ├── test_uuid.py
│   │   │   └── utils.py
│   │   ├── union.py
│   │   ├── unmountedtype.py
│   │   ├── utils.py
│   │   └── uuid.py
│   ├── utils/
│   │   ├── __init__.py
│   │   ├── crunch.py
│   │   ├── dataloader.py
│   │   ├── deduplicator.py
│   │   ├── deprecated.py
│   │   ├── get_unbound_function.py
│   │   ├── is_introspection_key.py
│   │   ├── module_loading.py
│   │   ├── orderedtype.py
│   │   ├── props.py
│   │   ├── resolve_only_args.py
│   │   ├── str_converters.py
│   │   ├── subclass_with_meta.py
│   │   ├── tests/
│   │   │   ├── __init__.py
│   │   │   ├── test_crunch.py
│   │   │   ├── test_dataloader.py
│   │   │   ├── test_deduplicator.py
│   │   │   ├── test_deprecated.py
│   │   │   ├── test_module_loading.py
│   │   │   ├── test_orderedtype.py
│   │   │   ├── test_resolve_only_args.py
│   │   │   ├── test_resolver_from_annotations.py
│   │   │   ├── test_str_converters.py
│   │   │   └── test_trim_docstring.py
│   │   ├── thenables.py
│   │   └── trim_docstring.py
│   └── validation/
│       ├── __init__.py
│       ├── depth_limit.py
│       ├── disable_introspection.py
│       └── tests/
│           ├── __init__.py
│           ├── test_depth_limit_validator.py
│           └── test_disable_introspection.py
├── mypy.ini
├── setup.cfg
├── setup.py
└── tox.ini

================================================
FILE CONTENTS
================================================

================================================
FILE: .coveragerc
================================================
[run]
omit = graphene/pyutils/*,*/tests/*


================================================
FILE: .editorconfig
================================================
# http://editorconfig.org

root = true

[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

[*.{py,rst,ini}]
indent_style = space
indent_size = 4


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: "\U0001F41B bug"
assignees: ''

---

**Note: for support questions, please use stackoverflow**. This repository's issues are reserved for feature requests and bug reports.

* **What is the current behavior?**



* **If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem** via
a github repo, https://repl.it or similar.



* **What is the expected behavior?**



* **What is the motivation / use case for changing the behavior?**



* **Please tell us about your environment:**

  - Version:
  - Platform:

* **Other information** (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow)


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: false


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: "✨ enhancement"
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .github/stale.yml
================================================
# Number of days of inactivity before an issue becomes stale
daysUntilStale: false
# Number of days of inactivity before a stale issue is closed
daysUntilClose: false
# Issues with these labels will never be considered stale
exemptLabels:
  - pinned
  - security
  - 🐛 bug
  - 📖 documentation
  - 🙋 help wanted
  - ✨ enhancement
  - good first issue
  - work in progress
# Label to use when marking an issue as stale
staleLabel: wontfix
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: false
# markComment: >
  # This issue has been automatically marked as stale because it has not had
  # recent activity. It will be closed if no further activity occurs. Thank you
  # for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false


================================================
FILE: .github/workflows/build.yaml
================================================
name: 📦 Build

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v4
    - name: Set up Python 3.10
      uses: actions/setup-python@v5
      with:
        python-version: "3.10"
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install build twine
    - name: Building package
      run: python3 -m build
    - name: Check package with Twine
      run: twine check dist/*


================================================
FILE: .github/workflows/deploy.yml
================================================
name: 🚀 Deploy to PyPI

on:
  push:
    tags:
      - 'v*'

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python 3.10
      uses: actions/setup-python@v5
      with:
        python-version: "3.10"
    - name: Build wheel and source tarball
      run: |
        pip install wheel
        python setup.py sdist bdist_wheel
    - name: Publish a Python distribution to PyPI
      uses: pypa/gh-action-pypi-publish@v1.1.0
      with:
        user: __token__
        password: ${{ secrets.pypi_password }}


================================================
FILE: .github/workflows/lint.yml
================================================
name: 💅 Lint

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4
    - name: Set up Python 3.10
      uses: actions/setup-python@v5
      with:
        python-version: "3.10"
    - name: Install dependencies
      run: |
        python -m pip install --upgrade pip
        pip install tox
    - name: Run lint
      run: tox
      env:
        TOXENV: pre-commit
    - name: Run mypy
      run: tox
      env:
        TOXENV: mypy


================================================
FILE: .github/workflows/tests.yml
================================================
name: 📄 Tests
on:
  push:
    branches:
      - master
      - '*.x'
    paths-ignore:
      - 'docs/**'
      - '*.md'
      - '*.rst'
  pull_request:
    branches:
      - master
      - '*.x'
    paths-ignore:
      - 'docs/**'
      - '*.md'
      - '*.rst'
jobs:
  tests:
    # runs the test suite
    name: ${{ matrix.name }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      matrix:
        include:
          - {name: '3.13', python: '3.13', os: ubuntu-latest, tox: py313}
          - {name: '3.12', python: '3.12', os: ubuntu-latest, tox: py312}
          - {name: '3.11', python: '3.11', os: ubuntu-latest, tox: py311}
          - {name: '3.10', python: '3.10', os: ubuntu-latest, tox: py310}
          - {name: '3.9', python: '3.9', os: ubuntu-latest, tox: py39}
          - {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38}
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: ${{ matrix.python }}

      - name: update pip
        run: |
          python -m pip install --upgrade pip
          pip install --upgrade setuptools wheel

      - name: get pip cache dir
        id: pip-cache
        run: echo "dir=$(pip cache dir)" >> $GITHUB_OUTPUT
      - name: cache pip dependencies
        uses: actions/cache@v3
        with:
          path: ${{ steps.pip-cache.outputs.dir }}
          key: pip|${{ runner.os }}|${{ matrix.python }}|${{ hashFiles('setup.py') }}
      - run: pip install tox
      - run: tox -e ${{ matrix.tox }}
      - name: Upload coverage.xml
        if: ${{ matrix.python == '3.10' }}
        uses: actions/upload-artifact@v4
        with:
          name: graphene-coverage
          path: coverage.xml
          if-no-files-found: error
      - name: Upload coverage.xml to codecov
        if: ${{ matrix.python == '3.10' }}
        uses: codecov/codecov-action@v4


================================================
FILE: .gitignore
================================================
# Created by https://www.gitignore.io

### Python ###
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]

# C extensions
*.so

# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
*.egg-info/
.installed.cfg
*.egg

# PyInstaller
#  Usually these files are written by a python script from a template
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec

# Installer logs
pip-log.txt
pip-delete-this-directory.txt

# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
.pytest_cache
nosetests.xml
coverage.xml
*.cover
.pytest_cache/

# Translations
*.mo
*.pot

# Django stuff:
*.log

# Sphinx documentation
docs/_build/

# PyBuilder
target/

# VirtualEnv
.env
.venv
env/
venv/

# Typing
.mypy_cache/

/tests/django.sqlite

/graphene/index.json
/graphene/meta.json

/meta.json
/index.json

/docs/playground/graphene-js/pypyjs-release-nojit/
/docs/static/playground/lib

/docs/static/playground

# PyCharm
.idea
*.iml

# Databases
*.sqlite3
.vscode
.mypy_cache
.ruff_cache


================================================
FILE: .pre-commit-config.yaml
================================================
default_language_version:
  python: python3.10

repos:
-   repo: https://github.com/pre-commit/pre-commit-hooks
    rev: v4.3.0
    hooks:
    -   id: check-merge-conflict
    -   id: check-json
    -   id: check-yaml
    -   id: debug-statements
    -   id: end-of-file-fixer
        exclude: ^docs/.*$
    -   id: pretty-format-json
        args:
        - --autofix
    -   id: trailing-whitespace
        exclude: README.md
-   repo: https://github.com/asottile/pyupgrade
    rev: v2.37.3
    hooks:
    -   id: pyupgrade
-   repo: https://github.com/astral-sh/ruff-pre-commit
    # Ruff version.
    rev: v0.5.0
    hooks:
        - id: ruff
        - id: ruff-format
          args: [ --check ]


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2015-Present Syrus Akbary

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: MANIFEST.in
================================================
global-exclude tests/*
recursive-exclude tests *
recursive-exclude tests_py35 *
recursive-exclude examples *
include LICENSE


================================================
FILE: Makefile
================================================
.PHONY: help
help:
	@echo "Please use \`make <target>' where <target> is one of"
	@grep -E '^\.PHONY: [a-zA-Z_-]+ .*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = "(: |##)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}'

.PHONY: install-dev ## Install development dependencies
install-dev:
	pip install -e ".[dev]"

.PHONY: test ## Run tests
test:
	py.test graphene examples

.PHONY: docs ## Generate docs
docs: install-dev
	cd docs && make install && make html

.PHONY: docs-live ## Generate docs with live reloading
docs-live: install-dev
	cd docs && make install && make livehtml

.PHONY: format
format:
	black graphene examples setup.py

.PHONY: lint
lint:
	flake8 graphene examples setup.py


================================================
FILE: README.md
================================================
# ![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)

[💬 Join the community on Discord](https://discord.gg/T6Gp6NFYHe)

**We are looking for contributors**! Please check the current issues to see how you can help ❤️

## Introduction

[Graphene](http://graphene-python.org) is an opinionated Python library for building GraphQL schemas/types fast and easily.

- **Easy to use:** Graphene helps you use GraphQL in Python without effort.
- **Relay:** Graphene has builtin support for Relay.
- **Data agnostic:** Graphene supports any kind of data source: SQL (Django, SQLAlchemy), Mongo, custom Python objects, etc.
  We believe that by providing a complete API you could plug Graphene anywhere your data lives and make your data available
  through GraphQL.

## Integrations

Graphene has multiple integrations with different frameworks:

| integration       | Package                                                                                 |
| ----------------- | --------------------------------------------------------------------------------------- |
| SQLAlchemy        | [graphene-sqlalchemy](https://github.com/graphql-python/graphene-sqlalchemy/)           |
| Mongo             | [graphene-mongo](https://github.com/graphql-python/graphene-mongo/)                     |
| Apollo Federation | [graphene-federation](https://github.com/graphql-python/graphene-federation/)           |
| Django            | [graphene-django](https://github.com/graphql-python/graphene-django/)                   |

Also, 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).

## Installation

To install `graphene`, just run this command in your shell

```bash
pip install "graphene>=3.1"
```

## Examples

Here is one example for you to get started:

```python
import graphene

class Query(graphene.ObjectType):
    hello = graphene.String(description='A typical hello world')

    def resolve_hello(self, info):
        return 'World'

schema = graphene.Schema(query=Query)
```

Then Querying `graphene.Schema` is as simple as:

```python
query = '''
    query SayHello {
      hello
    }
'''
result = schema.execute(query)
```

If you want to learn even more, you can also check the following [examples](examples/):

- **Basic Schema**: [Starwars example](examples/starwars)
- **Relay Schema**: [Starwars Relay example](examples/starwars_relay)

## Documentation

Documentation and links to additional resources are available at
https://docs.graphene-python.org/en/latest/

## Contributing

After cloning this repo, create a [virtualenv](https://virtualenv.pypa.io/en/stable/) and ensure dependencies are installed by running:

```sh
virtualenv venv
source venv/bin/activate
pip install -e ".[test]"
```

Well-written tests and maintaining good test coverage is important to this project. While developing, run new and existing tests with:

```sh
pytest graphene/relay/tests/test_node.py # Single file
pytest graphene/relay # All tests in directory
```

Add the `-s` flag if you have introduced breakpoints into the code for debugging.
Add the `-v` ("verbose") flag to get more detailed test output. For even more detailed output, use `-vv`.
Check out the [pytest documentation](https://docs.pytest.org/en/latest/) for more options and test running controls.

Regularly ensure your `pre-commit` hooks are up to date and enabled:

```sh
pre-commit install
```

You can also run the benchmarks with:

```sh
pytest graphene --benchmark-only
```

Graphene 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:

```sh
tox
```

If you wish to run against a specific version defined in the `tox.ini` file:

```sh
tox -e py39
```

Tox 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!

### Building Documentation

The documentation is generated using the excellent [Sphinx](http://www.sphinx-doc.org/) and a custom theme.

An HTML version of the documentation is produced by running:

```sh
make docs
```


================================================
FILE: SECURITY.md
================================================
# Security Policy

## Supported Versions

Support 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.
The preferred mitigation strategy is via an upgrade to Graphene 3.

| Version | Supported          |
| ------- | ------------------ |
| 3.x     | :white_check_mark: |
| <3.x    | :x:                |

## Reporting a Vulnerability

Please use responsible disclosure by contacting a core maintainer via Discord or E-Mail.


================================================
FILE: UPGRADE-v1.0.md
================================================
# v1.0 Upgrade Guide

Big 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.

## Backwards Compatibility and Deprecation Warnings

This has been a community project from the start, we need your help making the upgrade as smooth as possible for everybody!
We have done our best to provide backwards compatibility with deprecated APIs.

## Deprecations

- `with_context` is no longer needed. Resolvers now always take the context argument.
  Before:

  ```python
  def resolve_xxx(root, args, info):
      # ...
  ```

  With 1.0:

  ```python
  def resolve_xxx(root, args, context, info):
      # ...
  ```

- `ObjectType` and `Interface` no longer accept the `abstract` option in the `Meta`.
  Inheriting fields should be now achieved using `AbstractType` inheritance.

  Before:

  ```python
  class MyBaseQuery(graphene.ObjectType):
      my_field = String()
      class Meta:
          abstract = True

  class Query(MyBaseQuery):
      pass

  ```

  With 1.0:

  ```python
  class MyBaseQuery(graphene.AbstractType):
      my_field = String()

  class Query(MyBaseQuery, graphene.ObjectType):
      pass
  ```

- The `type_name` option in the Meta in types is now `name`

- Type references no longer work with strings, but with functions.

  Before:

  ```python
  class Query(graphene.ObjectType):
      user = graphene.Field('User')
      users = graphene.List('User')
  ```

  With 1.0:

  ```python
  class Query(graphene.ObjectType):
      user = graphene.Field(lambda: User)
      users = graphene.List(lambda: User)
  ```

## Schema

Schemas in graphene `1.0` are `Immutable`, that means that once you create a `graphene.Schema` any
change in their attributes will not have any effect.
The `name` argument is removed from the Schema.

The arguments `executor` and `middlewares` are also removed from the `Schema` definition.
You can still use them, but by calling explicitly in the `execute` method in `graphql`.

```python
# Old way
schema = graphene.Schema(name='My Schema')
schema.query = Query
schema.mutation = Mutation

# New way
schema = graphene.Schema(
    query=Query,
    mutation=Mutation
)
```

## Interfaces

For implementing an Interface in an ObjectType, you have to add it onto `Meta.interfaces`.

Like:

```python
from graphene import Interface, ObjectType, String

class Character(Interface):
    name = String()

class Human(Character): # Old way, Human will still be an Interface
    pass

class Droid(ObjectType): # New way, you have to specify the ObjectType
    class Meta:
        interfaces = (Character, )
```

## Mutations

Mutation fields have changed the way of usage, before if you have the mutation `MyMutation` you
only have to reference with `graphene.Field(MyMutation)` now it's simply `MyMutation.Field()`

Example:

```python
from graphene import ObjectType, Mutation, String

class ReverseString(Mutation):
    class Input:
        input = String(required=True)

    reversed = String()

    def mutate(root, args, context, info):
        reversed = args.get('input')[::-1]
        return ReverseString(reversed=reversed)

class Query(ObjectType):
    reverse_string = graphene.Field(ReverseString) # Old way, will not include the mutation arguments by default
    reverse_string = ReverseString.Field()
```

## Nodes

Apart from implementing as shown in the previous section, to use the node field you have to
specify the node Type.

Example:

```python
from graphene import ObjectType, relay

class Query(ObjectType):
    node = relay.NodeField() # Old way, NodeField no longer exists. Use Node.Field
    node = relay.Node.Field() # New way
```

Also, if you wanted to create an `ObjectType` that implements `Node`, you have to do it
explicitly.

## Django

The Django integration with Graphene now has an independent package: `graphene-django`.
For installing, you have to replace the old `graphene[django]` with `graphene-django`.

- As the package is now independent, you now have to import from `graphene_django`.
- **DjangoNode no longer exists**, please use `relay.Node` instead:

  ```python
  from graphene.relay import Node
  from graphene_django import DjangoObjectType

  class Droid(DjangoObjectType):
      class Meta:
          interfaces = (Node, )
  ```

## SQLAlchemy

The SQLAlchemy integration with Graphene now has an independent package: `graphene-sqlalchemy`.
For installing, you have to replace the old `graphene[sqlalchemy]` with `graphene-sqlalchemy`.

- As the package is now independent, you have to import now from `graphene_sqlalchemy`.
- **SQLAlchemyNode no longer exists**, please use `relay.Node` instead:

  ```python
  from graphene.relay import Node
  from graphene_sqlalchemy import SQLAlchemyObjectType

  class Droid(SQLAlchemyObjectType):
      class Meta:
          interfaces = (Node, )
  ```


================================================
FILE: UPGRADE-v2.0.md
================================================
# v2.0 Upgrade Guide

`ObjectType`, `Interface`, `InputObjectType`, `Scalar` and `Enum` implementations
have been quite simplified, without the need to define a explicit Metaclass for each subtype.

It also improves the field resolvers, [simplifying the code](#simpler-resolvers) the
developer has to write to use them.

**Deprecations:**

- [`AbstractType`](#abstracttype-deprecated)
- [`resolve_only_args`](#resolve_only_args)
- [`Mutation.Input`](#mutationinput)

**Breaking changes:**

- [`Simpler Resolvers`](#simpler-resolvers)
- [`Node Connections`](#node-connections)

**New Features!**

- [`InputObjectType`](#inputobjecttype)
- [`Meta as Class arguments`](#meta-as-class-arguments) (_only available for Python 3_)

> The type metaclasses are now deleted as they are no longer necessary. If your code was depending
> 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).

## Deprecations

### AbstractType deprecated

AbstractType is deprecated in graphene 2.0, you can now use normal inheritance instead.

Before:

```python
class CommonFields(AbstractType):
    name = String()

class Pet(CommonFields, Interface):
    pass
```

With 2.0:

```python
class CommonFields(object):
    name = String()

class Pet(CommonFields, Interface):
    pass
```

### resolve_only_args

`resolve_only_args` is now deprecated as the resolver API has been simplified.

Before:

```python
class User(ObjectType):
    name = String()

    @resolve_only_args
    def resolve_name(root):
        return root.name
```

With 2.0:

```python
class User(ObjectType):
    name = String()

    def resolve_name(root, info):
        return root.name
```

### Mutation.Input

`Mutation.Input` is now deprecated in favor of using `Mutation.Arguments` (`ClientIDMutation` still uses `Input`).

Before:

```python
class User(Mutation):
    class Input:
        name = String()
```

With 2.0:

```python
class User(Mutation):
    class Arguments:
        name = String()
```

## Breaking Changes

### Simpler resolvers

All the resolvers in graphene have been simplified.
Prior to Graphene `2.0`, all resolvers required four arguments: `(root, args, context, info)`.
Now, resolver `args` are passed as keyword arguments to the function, and `context` argument dissapeared in favor of `info.context`.

Before:

```python
my_field = graphene.String(my_arg=graphene.String())

def resolve_my_field(root, args, context, info):
    my_arg = args.get('my_arg')
    return ...
```

With 2.0:

```python
my_field = graphene.String(my_arg=graphene.String())

def resolve_my_field(root, info, my_arg):
    return ...
```

**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).**
You may need something like this:

```python
def resolve_my_field(root, info, known_field1, known_field2, **args): ## get other args with: args.get('arg_key')
```

And, if you need the context in the resolver, you can use `info.context`:

```python
my_field = graphene.String(my_arg=graphene.String())

def resolve_my_field(root, info, my_arg):
    context = info.context
    return ...
```

### Node Connections

Node types no longer have a `Connection` by default.
In 2.0 and onwards `Connection`s should be defined explicitly.

Before:

```python
class User(ObjectType):
    class Meta:
        interfaces = [relay.Node]
    name = String()

class Query(ObjectType):
    user_connection = relay.ConnectionField(User)
```

With 2.0:

```python
class User(ObjectType):
    class Meta:
        interfaces = [relay.Node]
    name = String()

class UserConnection(relay.Connection):
    class Meta:
        node = User

class Query(ObjectType):
    user_connection = relay.ConnectionField(UserConnection)
```

## Node.get_node

The method `get_node` in `ObjectTypes` that have `Node` as interface, changes its API.
From `def get_node(cls, id, context, info)` to `def get_node(cls, info, id)`.

```python
class MyObject(ObjectType):
    class Meta:
        interfaces = (Node, )

    @classmethod
    def get_node(cls, id, context, info):
        return ...
```

To:

```python
class MyObject(ObjectType):
    class Meta:
        interfaces = (Node, )

    @classmethod
    def get_node(cls, info, id):
        return ...
```

## Node.get_node_from_global_id

The 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.

Before:

```python
class RootQuery(object):
    ...
    node = Field(relay.Node, id=ID(required=True))

    def resolve_node(root, args, context, info):
        node = relay.Node.get_node_from_global_id(args['id'], context, info)
        return node
```

Now:

```python
class RootQuery(object):
    ...
    node = Field(relay.Node, id=ID(required=True))

    def resolve_node(root, info, id):
        node = relay.Node.get_node_from_global_id(info, id)
        return node
```

## Mutation.mutate

Now only receives (`root`, `info`, `**kwargs`) and is not a @classmethod

Before:

```python
class SomeMutation(Mutation):
    ...

    @classmethod
    def mutate(cls, instance, args, context, info):
        ...
```

With 2.0:

```python
class SomeMutation(Mutation):
    ...

    def mutate(root, info, **args):
        ...
```

With 2.0 you can also get your declared (as above) `args` this way:

```python
class SomeMutation(Mutation):
    class Arguments:
        first_name = String(required=True)
        last_name = String(required=True)
    ...

    def mutate(root, info, first_name, last_name):
        ...
```

## ClientIDMutation.mutate_and_get_payload

Now only receives (`root`, `info`, `**input`)

### Middlewares

If you are using Middelwares, you need to some adjustments:

Before:

```python
class MyGrapheneMiddleware(object):
    def resolve(self, next_mw, root, args, context, info):

        ## Middleware code

        return next_mw(root, args, context, info)
```

With 2.0:

```python
class MyGrapheneMiddleware(object):
    def resolve(self, next_mw, root, info, **args):
        context = info.context

        ## Middleware code

        info.context = context
        return next_mw(root, info, **args)
```

## New Features

### InputObjectType

If you are using `InputObjectType`, you now can access
its fields via `getattr` (`my_input.myattr`) when resolving, instead of
the classic way `my_input['myattr']`.

And also use custom defined properties on your input class.

Example. Before:

```python
class UserInput(InputObjectType):
    id = ID(required=True)

def is_valid_input(input):
    return input.get('id').startswith('userid_')

class Query(ObjectType):
    user = graphene.Field(User, input=UserInput())

    @resolve_only_args
    def resolve_user(root, input):
        user_id = input.get('id')
        if is_valid_input(user_id):
            return get_user(user_id)
```

With 2.0:

```python
class UserInput(InputObjectType):
    id = ID(required=True)

    @property
    def is_valid(root):
        return root.id.startswith('userid_')

class Query(ObjectType):
    user = graphene.Field(User, input=UserInput())

    def resolve_user(root, info, input):
        if input.is_valid:
            return get_user(input.id)
```

### Meta as Class arguments

Now you can use the meta options as class arguments (**ONLY PYTHON 3**).

Before:

```python
class Dog(ObjectType):
    class Meta:
        interfaces = [Pet]
    name = String()
```

With 2.0:

```python
class Dog(ObjectType, interfaces=[Pet]):
    name = String()
```

### Abstract types

Now you can create abstact types super easily, without the need of subclassing the meta.

```python
class Base(ObjectType):
    class Meta:
        abstract = True

    id = ID()

    def resolve_id(root, info):
        return f"{root.__class__.__name__}_{root.id}"
```

### UUID Scalar

In Graphene 2.0 there is a new dedicated scalar for UUIDs, `UUID`.


================================================
FILE: bin/convert_documentation
================================================
#!/bin/bash

pandoc README.md --from markdown --to rst -s -o README.rst


================================================
FILE: docs/Makefile
================================================
# Makefile for Sphinx documentation
#

# You can set these variables from the command line.
SPHINXOPTS    =
SPHINXBUILD   = sphinx-build
PAPER         =
BUILDDIR      = _build

# Internal variables.
PAPEROPT_a4     = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS  = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .

.PHONY: help
help:
	@echo "Please use \`make <target>' where <target> is one of"
	@grep -E '^\.PHONY: [a-zA-Z_-]+ .*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = "(: |##)"}; {printf "\033[36m%-30s\033[0m %s\n", $$2, $$3}'

.PHONY: install ## to install all documentation related requirements
install:
	pip install -r requirements.txt

.PHONY: clean ## to remove all built documentation
clean:
	rm -rf $(BUILDDIR)/*

.PHONY: html ## to make standalone HTML files
html:
	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."

.PHONY: dirhtml ## to make HTML files named index.html in directories
dirhtml:
	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
	@echo
	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."

.PHONY: singlehtml ## to make a single large HTML file
singlehtml:
	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
	@echo
	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."

.PHONY: pickle ## to make pickle files
pickle:
	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
	@echo
	@echo "Build finished; now you can process the pickle files."

.PHONY: json ## to make JSON files
json:
	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
	@echo
	@echo "Build finished; now you can process the JSON files."

.PHONY: htmlhelp ## to make HTML files and a HTML help project
htmlhelp:
	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
	@echo
	@echo "Build finished; now you can run HTML Help Workshop with the" \
	      ".hhp project file in $(BUILDDIR)/htmlhelp."

.PHONY: qthelp ## to make HTML files and a qthelp project
qthelp:
	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
	@echo
	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Graphene.qhcp"
	@echo "To view the help file:"
	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Graphene.qhc"

.PHONY: applehelp ## to make an Apple Help Book
applehelp:
	$(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
	@echo
	@echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
	@echo "N.B. You won't be able to view it unless you put it in" \
	      "~/Library/Documentation/Help or install it in your application" \
	      "bundle."

.PHONY: devhelp ## to make HTML files and a Devhelp project
devhelp:
	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
	@echo
	@echo "Build finished."
	@echo "To view the help file:"
	@echo "# mkdir -p $$HOME/.local/share/devhelp/Graphene"
	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Graphene"
	@echo "# devhelp"

.PHONY: epub ## to make an epub
epub:
	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
	@echo
	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."

.PHONY: epub3 ## to make an epub3
epub3:
	$(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
	@echo
	@echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."

.PHONY: latex ## to make LaTeX files, you can set PAPER=a4 or PAPER=letter
latex:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo
	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
	@echo "Run \`make' in that directory to run these through (pdf)latex" \
	      "(use \`make latexpdf' here to do that automatically)."

.PHONY: latexpdf ## to make LaTeX files and run them through pdflatex
latexpdf:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through pdflatex..."
	$(MAKE) -C $(BUILDDIR)/latex all-pdf
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

.PHONY: latexpdfja ## to make LaTeX files and run them through platex/dvipdfmx
latexpdfja:
	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
	@echo "Running LaTeX files through platex and dvipdfmx..."
	$(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."

.PHONY: text ## to make text files
text:
	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
	@echo
	@echo "Build finished. The text files are in $(BUILDDIR)/text."

.PHONY: man ## to make manual pages
man:
	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
	@echo
	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."

.PHONY: texinfo ## to make Texinfo files
texinfo:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo
	@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
	@echo "Run \`make' in that directory to run these through makeinfo" \
	      "(use \`make info' here to do that automatically)."

.PHONY: info ## to make Texinfo files and run them through makeinfo
info:
	$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
	@echo "Running Texinfo files through makeinfo..."
	make -C $(BUILDDIR)/texinfo info
	@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."

.PHONY: gettext ## to make PO message catalogs
gettext:
	$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
	@echo
	@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."

.PHONY: changes ## to make an overview of all changed/added/deprecated items
changes:
	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
	@echo
	@echo "The overview file is in $(BUILDDIR)/changes."

.PHONY: linkcheck ## to check all external links for integrity
linkcheck:
	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
	@echo
	@echo "Link check complete; look for any errors in the above output " \
	      "or in $(BUILDDIR)/linkcheck/output.txt."

.PHONY: doctest ## to run all doctests embedded in the documentation (if enabled)
doctest:
	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
	@echo "Testing of doctests in the sources finished, look at the " \
	      "results in $(BUILDDIR)/doctest/output.txt."

.PHONY: coverage ## to run coverage check of the documentation (if enabled)
coverage:
	$(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
	@echo "Testing of coverage in the sources finished, look at the " \
	      "results in $(BUILDDIR)/coverage/python.txt."

.PHONY: xml ## to make Docutils-native XML files
xml:
	$(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
	@echo
	@echo "Build finished. The XML files are in $(BUILDDIR)/xml."

.PHONY: pseudoxml ## to make pseudoxml-XML files for display purposes
pseudoxml:
	$(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
	@echo
	@echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."

.PHONY: dummy ## to check syntax errors of document sources
dummy:
	$(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
	@echo
	@echo "Build finished. Dummy builder generates no files."

.PHONY: livehtml ## to build and serve live-reloading documentation
livehtml:
	sphinx-autobuild -b html --watch ../graphene $(ALLSPHINXOPTS) $(BUILDDIR)/html


================================================
FILE: docs/_static/.gitkeep
================================================


================================================
FILE: docs/api/index.rst
================================================
API Reference
=============

Schema
------

.. autoclass:: graphene.types.schema.Schema
    :members:

.. Uncomment sections / types as API documentation is fleshed out
.. in each class

Object types
------------

.. autoclass:: graphene.ObjectType

.. autoclass:: graphene.InputObjectType

.. autoclass:: graphene.Mutation
    :members:

.. _fields-mounted-types:

Fields (Mounted Types)
----------------------

.. autoclass:: graphene.Field

.. autoclass:: graphene.Argument

.. autoclass:: graphene.InputField

Fields (Unmounted Types)
------------------------

.. autoclass:: graphene.types.unmountedtype.UnmountedType

GraphQL Scalars
---------------

.. autoclass:: graphene.Int()

.. autoclass:: graphene.Float()

.. autoclass:: graphene.String()

.. autoclass:: graphene.Boolean()

.. autoclass:: graphene.ID()

Graphene Scalars
----------------

.. autoclass:: graphene.Date()

.. autoclass:: graphene.DateTime()

.. autoclass:: graphene.Time()

.. autoclass:: graphene.Decimal()

.. autoclass:: graphene.UUID()

.. autoclass:: graphene.JSONString()

.. autoclass:: graphene.Base64()

Enum
----

.. autoclass:: graphene.Enum()

Structures
----------

.. autoclass:: graphene.List

.. autoclass:: graphene.NonNull

Type Extension
--------------

.. autoclass:: graphene.Interface()

.. autoclass:: graphene.Union()

Execution Metadata
------------------

.. autoclass:: graphene.ResolveInfo

.. autoclass:: graphene.Context

.. autoclass:: graphql.ExecutionResult

.. Relay
.. -----

.. .. autoclass:: graphene.Node

.. .. autoclass:: graphene.GlobalID

.. .. autoclass:: graphene.ClientIDMutation

.. .. autoclass:: graphene.Connection

.. .. autoclass:: graphene.ConnectionField

.. .. autoclass:: graphene.PageInfo


================================================
FILE: docs/conf.py
================================================
import os
import sys

import sphinx_graphene_theme

on_rtd = os.environ.get("READTHEDOCS", None) == "True"

# -*- coding: utf-8 -*-
#
# Graphene documentation build configuration file, created by
# sphinx-quickstart on Sun Sep 11 18:30:51 2016.
#
# This file is execfile()d with the current directory set to its
# containing dir.
#
# Note that not all possible configuration values are present in this
# autogenerated file.
#
# All configuration values have a default; values that are commented out
# serve to show the default.

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#

sys.path.insert(0, os.path.abspath(".."))

# -- General configuration ------------------------------------------------

# If your documentation needs a minimal Sphinx version, state it here.
#
# needs_sphinx = '1.0'

# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
    "sphinx.ext.autodoc",
    "sphinx.ext.intersphinx",
    "sphinx.ext.todo",
    "sphinx.ext.coverage",
    "sphinx.ext.viewcode",
    "sphinx.ext.napoleon",
]
if not on_rtd:
    extensions += ["sphinx.ext.githubpages"]

# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]

# The suffix(es) of source filenames.
# You can specify multiple suffix as a list of string:
#
# source_suffix = ['.rst', '.md']
source_suffix = ".rst"

# The encoding of source files.
#
# source_encoding = 'utf-8-sig'

# The master toctree document.
master_doc = "index"

# General information about the project.
project = "Graphene"
copyright = "Graphene 2016"
author = "Syrus Akbary"

# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
version = "1.0"
# The full version, including alpha/beta/rc tags.
release = "1.0"

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
#
# This is also used if you do content translation via gettext catalogs.
# Usually you set "language" from the command line for these cases.
# language = None

# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
#
# today = ''
#
# Else, today_fmt is used as the format for a strftime call.
#
# today_fmt = '%B %d, %Y'

# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]

# The reST default role (used for this markup: `text`) to use for all
# documents.
#
# default_role = None

# If true, '()' will be appended to :func: etc. cross-reference text.
#
# add_function_parentheses = True

# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
#
# add_module_names = True

# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
#
# show_authors = False

# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"

# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []

# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False

# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = True


# -- Options for HTML output ----------------------------------------------

# The theme to use for HTML and HTML Help pages.  See the documentation for
# a list of builtin themes.
#
# html_theme = 'alabaster'
# if on_rtd:
#     html_theme = 'sphinx_rtd_theme'

html_theme = "sphinx_graphene_theme"

html_theme_path = [sphinx_graphene_theme.get_html_theme_path()]

# Theme options are theme-specific and customize the look and feel of a theme
# further.  For a list of options available for each theme, see the
# documentation.
#
# html_theme_options = {}

# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = []

# The name for this set of Sphinx documents.
# "<project> v<release> documentation" by default.
#
# html_title = u'Graphene v1.0'

# A shorter title for the navigation bar.  Default is the same as html_title.
#
# html_short_title = None

# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
#
# html_logo = None

# The name of an image file (relative to this directory) to use as a favicon of
# the docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
#
# html_favicon = None

# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]

# Add any extra paths that contain custom files (such as robots.txt or
# .htaccess) here, relative to this directory. These files are copied
# directly to the root of the documentation.
#
# html_extra_path = []

# If not None, a 'Last updated on:' timestamp is inserted at every page
# bottom, using the given strftime format.
# The empty string is equivalent to '%b %d, %Y'.
#
# html_last_updated_fmt = None

# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
#
# html_use_smartypants = True

# Custom sidebar templates, maps document names to template names.
#
# html_sidebars = {}

# Additional templates that should be rendered to pages, maps page names to
# template names.
#
# html_additional_pages = {}

# If false, no module index is generated.
#
# html_domain_indices = True

# If false, no index is generated.
#
# html_use_index = True

# If true, the index is split into individual pages for each letter.
#
# html_split_index = False

# If true, links to the reST sources are added to the pages.
#
# html_show_sourcelink = True

# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
#
# html_show_sphinx = True

# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
#
# html_show_copyright = True

# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it.  The value of this option must be the
# base URL from which the finished HTML is served.
#
# html_use_opensearch = ''

# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None

# Language to be used for generating the HTML full-text search index.
# Sphinx supports the following languages:
#   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
#   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr', 'zh'
#
# html_search_language = 'en'

# A dictionary with options for the search language support, empty by default.
# 'ja' uses this config value.
# 'zh' user can custom change `jieba` dictionary path.
#
# html_search_options = {'type': 'default'}

# The name of a javascript file (relative to the configuration directory) that
# implements a search results scorer. If empty, the default will be used.
#
# html_search_scorer = 'scorer.js'

# Output file base name for HTML help builder.
htmlhelp_basename = "Graphenedoc"

# -- Options for LaTeX output ---------------------------------------------

latex_elements = {
    # The paper size ('letterpaper' or 'a4paper').
    #
    # 'papersize': 'letterpaper',
    # The font size ('10pt', '11pt' or '12pt').
    #
    # 'pointsize': '10pt',
    # Additional stuff for the LaTeX preamble.
    #
    # 'preamble': '',
    # Latex figure (float) alignment
    #
    # 'figure_align': 'htbp',
}

# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
#  author, documentclass [howto, manual, or own class]).
latex_documents = [
    (master_doc, "Graphene.tex", "Graphene Documentation", "Syrus Akbary", "manual")
]

# The name of an image file (relative to this directory) to place at the top of
# the title page.
#
# latex_logo = None

# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
#
# latex_use_parts = False

# If true, show page references after internal links.
#
# latex_show_pagerefs = False

# If true, show URL addresses after external links.
#
# latex_show_urls = False

# Documents to append as an appendix to all manuals.
#
# latex_appendices = []

# It false, will not define \strong, \code, 	itleref, \crossref ... but only
# \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added
# packages.
#
# latex_keep_old_macro_names = True

# If false, no module index is generated.
#
# latex_domain_indices = True


# -- Options for manual page output ---------------------------------------

# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [(master_doc, "graphene", "Graphene Documentation", [author], 1)]

# If true, show URL addresses after external links.
#
# man_show_urls = False


# -- Options for Texinfo output -------------------------------------------

# Grouping the document tree into Texinfo files. List of tuples
# (source start file, target name, title, author,
#  dir menu entry, description, category)
texinfo_documents = [
    (
        master_doc,
        "Graphene",
        "Graphene Documentation",
        author,
        "Graphene",
        "One line description of project.",
        "Miscellaneous",
    )
]

# Documents to append as an appendix to all manuals.
#
# texinfo_appendices = []

# If false, no module index is generated.
#
# texinfo_domain_indices = True

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#
# texinfo_show_urls = 'footnote'

# If true, do not generate a @detailmenu in the "Top" node's menu.
#
# texinfo_no_detailmenu = False


# -- Options for Epub output ----------------------------------------------

# Bibliographic Dublin Core info.
epub_title = project
epub_author = author
epub_publisher = author
epub_copyright = copyright

# The basename for the epub file. It defaults to the project name.
# epub_basename = project

# The HTML theme for the epub output. Since the default themes are not
# optimized for small screen space, using the same theme for HTML and epub
# output is usually not wise. This defaults to 'epub', a theme designed to save
# visual space.
#
# epub_theme = 'epub'

# The language of the text. It defaults to the language option
# or 'en' if the language is not set.
#
# epub_language = ''

# The scheme of the identifier. Typical schemes are ISBN or URL.
# epub_scheme = ''

# The unique identifier of the text. This can be a ISBN number
# or the project homepage.
#
# epub_identifier = ''

# A unique identification for the text.
#
# epub_uid = ''

# A tuple containing the cover image and cover page html template filenames.
#
# epub_cover = ()

# A sequence of (type, uri, title) tuples for the guide element of content.opf.
#
# epub_guide = ()

# HTML files that should be inserted before the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#
# epub_pre_files = []

# HTML files that should be inserted after the pages created by sphinx.
# The format is a list of tuples containing the path and title.
#
# epub_post_files = []

# A list of files that should not be packed into the epub file.
epub_exclude_files = ["search.html"]

# The depth of the table of contents in toc.ncx.
#
# epub_tocdepth = 3

# Allow duplicate toc entries.
#
# epub_tocdup = True

# Choose between 'default' and 'includehidden'.
#
# epub_tocscope = 'default'

# Fix unsupported image types using the Pillow.
#
# epub_fix_images = False

# Scale large images.
#
# epub_max_image_width = 0

# How to display URL addresses: 'footnote', 'no', or 'inline'.
#
# epub_show_urls = 'inline'

# If false, no index is generated.
#
# epub_use_index = True


# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
    "https://docs.python.org/": None,
    "python": ("https://docs.python.org/", None),
    "graphene_django": (
        "http://docs.graphene-python.org/projects/django/en/latest/",
        None,
    ),
    "graphene_sqlalchemy": (
        "http://docs.graphene-python.org/projects/sqlalchemy/en/latest/",
        None,
    ),
}


================================================
FILE: docs/execution/dataloader.rst
================================================
Dataloader
==========

DataLoader is a generic utility to be used as part of your application's
data fetching layer to provide a simplified and consistent API over
various remote data sources such as databases or web services via batching
and caching. It is provided by a separate package `aiodataloader <https://pypi.org/project/aiodataloader/>`.


Batching
--------

Batching is not an advanced feature, it's DataLoader's primary feature.
Create loaders by providing a batch loading function.

.. code:: python

    from aiodataloader import DataLoader

    class UserLoader(DataLoader):
        async def batch_load_fn(self, keys):
            # Here we call a function to return a user for each key in keys
            return [get_user(id=key) for key in keys]


A batch loading async function accepts a list of keys, and returns a list of ``values``.


``DataLoader`` will coalesce all individual loads which occur within a
single frame of execution (executed once the wrapping event loop is resolved)
and then call your batch function with all requested keys.


.. code:: python

    user_loader = UserLoader()

    user1 = await user_loader.load(1)
    user1_best_friend = await user_loader.load(user1.best_friend_id)

    user2 = await user_loader.load(2)
    user2_best_friend = await user_loader.load(user2.best_friend_id)


A naive application may have issued *four* round-trips to a backend for the
required information, but with ``DataLoader`` this application will make at most *two*.

Note that loaded values are one-to-one with the keys and must have the same
order. This means that if you load all values from a single query, you must
make sure that you then order the query result for the results to match the keys:


.. code:: python

   class UserLoader(DataLoader):
       async def batch_load_fn(self, keys):
           users = {user.id: user for user in User.objects.filter(id__in=keys)}
           return [users.get(user_id) for user_id in keys]


``DataLoader`` allows you to decouple unrelated parts of your application without
sacrificing the performance of batch data-loading. While the loader presents
an API that loads individual values, all concurrent requests will be coalesced
and presented to your batch loading function. This allows your application to
safely distribute data fetching requirements throughout your application and
maintain minimal outgoing data requests.



Using with Graphene
-------------------

DataLoader pairs nicely well with Graphene/GraphQL. GraphQL fields are designed
to be stand-alone functions. Without a caching or batching mechanism, it's easy
for a naive GraphQL server to issue new database requests each time a field is resolved.

Consider the following GraphQL request:


.. code::

    {
      me {
        name
        bestFriend {
          name
        }
        friends(first: 5) {
          name
          bestFriend {
            name
          }
        }
      }
    }


If ``me``, ``bestFriend`` and ``friends`` each need to send a request to the backend,
there could be at most 13 database requests!


When using DataLoader, we could define the User type using our previous example with
leaner code and at most 4 database requests, and possibly fewer if there are cache hits.


.. code:: python

    class User(graphene.ObjectType):
        name = graphene.String()
        best_friend = graphene.Field(lambda: User)
        friends = graphene.List(lambda: User)

        async def resolve_best_friend(root, info):
            return await user_loader.load(root.best_friend_id)

        async def resolve_friends(root, info):
            return await user_loader.load_many(root.friend_ids)


================================================
FILE: docs/execution/execute.rst
================================================
.. _SchemaExecute:

Executing a query
=================

For executing a query against a schema, you can directly call the ``execute`` method on it.


.. code:: python

    from graphene import Schema

    schema = Schema(...)
    result = schema.execute('{ name }')

``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.


.. _SchemaExecuteContext:

Context
_______

You can pass context to a query via ``context``.


.. code:: python

    from graphene import ObjectType, String, Schema

    class Query(ObjectType):
        name = String()

        def resolve_name(root, info):
            return info.context.get('name')

    schema = Schema(Query)
    result = schema.execute('{ name }', context={'name': 'Syrus'})
    assert result.data['name'] == 'Syrus'


Variables
_________

You can pass variables to a query via ``variables``.


.. code:: python

    from graphene import ObjectType, Field, ID, Schema

    class Query(ObjectType):
        user = Field(User, id=ID(required=True))

        def resolve_user(root, info, id):
            return get_user_by_id(id)

    schema = Schema(Query)
    result = schema.execute(
        '''
          query getUser($id: ID) {
            user(id: $id) {
              id
              firstName
              lastName
            }
          }
        ''',
        variables={'id': 12},
    )

Root Value
__________

Value used for :ref:`ResolverParamParent` in root queries and mutations can be overridden using ``root`` parameter.

.. code:: python

    from graphene import ObjectType, Field, Schema

    class Query(ObjectType):
        me = Field(User)

        def resolve_user(root, info):
            return {'id': root.id, 'firstName': root.name}

    schema = Schema(Query)
    user_root = User(id=12, name='bob')
    result = schema.execute(
        '''
        query getUser {
            user {
                id
                firstName
                lastName
            }
        }
        ''',
        root=user_root
    )
    assert result.data['user']['id'] == user_root.id

Operation Name
______________

If there are multiple operations defined in a query string, ``operation_name`` should be used to indicate which should be executed.

.. code:: python

    from graphene import ObjectType, Field, Schema

    class Query(ObjectType):
        user = Field(User)

        def resolve_user(root, info):
            return get_user_by_id(12)

    schema = Schema(Query)
    query_string = '''
        query getUserWithFirstName {
            user {
                id
                firstName
                lastName
            }
        }
        query getUserWithFullName {
            user {
                id
                fullName
            }
        }
    '''
    result = schema.execute(
        query_string,
        operation_name='getUserWithFullName'
    )
    assert result.data['user']['fullName']


================================================
FILE: docs/execution/fileuploading.rst
================================================
File uploading
==============

File uploading is not part of the official GraphQL spec yet and is not natively
implemented in Graphene.

If 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
uploads and conforms to the unoffical GraphQL `multipart request spec <https://github.com/jaydenseric/graphql-multipart-request-spec>`_.


================================================
FILE: docs/execution/index.rst
================================================
=========
Execution
=========

.. toctree::
   :maxdepth: 2

   execute
   middleware
   dataloader
   fileuploading
   subscriptions
   queryvalidation


================================================
FILE: docs/execution/middleware.rst
================================================
Middleware
==========

You can use ``middleware`` to affect the evaluation of fields in your schema.

A middleware is any object or function that responds to ``resolve(next_middleware, *args)``.

Inside that method, it should either:

- Send ``resolve`` to the next middleware to continue the evaluation; or
- Return a value to end the evaluation early.


Resolve arguments
-----------------

Middlewares ``resolve`` is invoked with several arguments:

- ``next`` represents the execution chain. Call ``next`` to continue evaluation.
- ``root`` is the root value object passed throughout the query.
- ``info`` is the resolver info.
- ``args`` is the dict of arguments passed to the field.

Example
-------

This middleware only continues evaluation if the ``field_name`` is not ``'user'``

.. code:: python

    class AuthorizationMiddleware(object):
        def resolve(self, next, root, info, **args):
            if info.field_name == 'user':
                return None
            return next(root, info, **args)


And then execute it with:

.. code:: python

    result = schema.execute('THE QUERY', middleware=[AuthorizationMiddleware()])

If the ``middleware`` argument includes multiple middlewares,
these middlewares will be executed bottom-up, i.e. from last to first.

Functional example
------------------

Middleware can also be defined as a function. Here we define a middleware that
logs the time it takes to resolve each field:

.. code:: python

    from time import time as timer

    def timing_middleware(next, root, info, **args):
        start = timer()
        return_value = next(root, info, **args)
        duration = round((timer() - start) * 1000, 2)
        parent_type_name = root._meta.name if root and hasattr(root, '_meta') else ''
        logger.debug(f"{parent_type_name}.{info.field_name}: {duration} ms")
        return return_value


And then execute it with:

.. code:: python

    result = schema.execute('THE QUERY', middleware=[timing_middleware])


================================================
FILE: docs/execution/queryvalidation.rst
================================================
Query Validation
================
GraphQL uses query validators to check if Query AST is valid and can be executed. Every GraphQL server implements
standard query validators. For example, there is an validator that tests if queried field exists on queried type, that
makes query fail with "Cannot query field on type" error if it doesn't.

To help with common use cases, graphene provides a few validation rules out of the box.


Depth limit Validator
---------------------
The depth limit validator helps to prevent execution of malicious
queries. It takes in the following arguments.

- ``max_depth`` is the maximum allowed depth for any operation in a GraphQL document.
- ``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
- ``callback`` Called each time validation runs. Receives an Object which is a map of the depths for each operation.

Usage
-----

Here is how you would implement depth-limiting on your schema.

.. code:: python

    from graphql import validate, parse
    from graphene import ObjectType, Schema, String
    from graphene.validation import depth_limit_validator


    class MyQuery(ObjectType):
        name = String(required=True)


    schema = Schema(query=MyQuery)

    # queries which have a depth more than 20
    # will not be executed.

    validation_errors = validate(
        schema=schema.graphql_schema,
        document_ast=parse('THE QUERY'),
        rules=(
            depth_limit_validator(
                max_depth=20
            ),
        )
    )


Disable Introspection
---------------------
the disable introspection validation rule ensures that your schema cannot be introspected.
This is a useful security measure in production environments.

Usage
-----

Here is how you would disable introspection for your schema.

.. code:: python

    from graphql import validate, parse
    from graphene import ObjectType, Schema, String
    from graphene.validation import DisableIntrospection


    class MyQuery(ObjectType):
        name = String(required=True)


    schema = Schema(query=MyQuery)

    # introspection queries will not be executed.

    validation_errors = validate(
        schema=schema.graphql_schema,
        document_ast=parse('THE QUERY'),
        rules=(
            DisableIntrospection,
        )
    )


Implementing custom validators
------------------------------
All 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>`_
base class importable from the graphql.validation.rules module. Query validators are visitor classes. They are
instantiated at the time of query validation with one required argument (context: ASTValidationContext). In order to
perform validation, your validator class should define one or more of enter_* and leave_* methods. For possible
enter/leave items as well as details on function documentation, please see contents of the visitor module. To make
validation fail, you should call validator's report_error method with the instance of GraphQLError describing failure
reason. Here is an example query validator that visits field definitions in GraphQL query and fails query validation
if any of those fields are blacklisted:

.. code:: python

    from graphql import GraphQLError
    from graphql.language import FieldNode
    from graphql.validation import ValidationRule


    my_blacklist = (
        "disallowed_field",
    )


    def is_blacklisted_field(field_name: str):
        return field_name.lower() in my_blacklist


    class BlackListRule(ValidationRule):
        def enter_field(self, node: FieldNode, *_args):
            field_name = node.name.value
            if not is_blacklisted_field(field_name):
                return

            self.report_error(
                GraphQLError(
                    f"Cannot query '{field_name}': field is blacklisted.", node,
                )
            )



================================================
FILE: docs/execution/subscriptions.rst
================================================
.. _SchemaSubscription:

Subscriptions
=============

To create a subscription, you can directly call the ``subscribe`` method on the
schema. This method is async and must be awaited.

.. code:: python

    import asyncio
    from datetime import datetime
    from graphene import ObjectType, String, Schema, Field

    # Every schema requires a query.
    class Query(ObjectType):
        hello = String()

        def resolve_hello(root, info):
            return "Hello, world!"

    class Subscription(ObjectType):
        time_of_day = String()

        async def subscribe_time_of_day(root, info):
            while True:
                yield datetime.now().isoformat()
                await asyncio.sleep(1)

    schema = Schema(query=Query, subscription=Subscription)

    async def main(schema):
        subscription = 'subscription { timeOfDay }'
        result = await schema.subscribe(subscription)
        async for item in result:
            print(item.data['timeOfDay'])

    asyncio.run(main(schema))

The ``result`` is an async iterator which yields items in the same manner as a query.


================================================
FILE: docs/index.rst
================================================
Graphene
========

Contents:

.. toctree::
   :maxdepth: 2

   quickstart
   types/index
   execution/index
   relay/index
   testing/index
   api/index

.. _Integrations:

Integrations
------------

* `Graphene-Django <http://docs.graphene-python.org/projects/django/en/latest/>`_ (`source <https://github.com/graphql-python/graphene-django/>`_)
* Flask-Graphql (`source <https://github.com/graphql-python/flask-graphql>`_)
* `Graphene-SQLAlchemy <http://docs.graphene-python.org/projects/sqlalchemy/en/latest/>`_ (`source <https://github.com/graphql-python/graphene-sqlalchemy/>`_)
* `Graphene-Mongo <http://graphene-mongo.readthedocs.io/en/latest/>`_ (`source <https://github.com/graphql-python/graphene-mongo>`_)
* `Starlette <https://www.starlette.io/graphql/>`_ (`source <https://github.com/encode/starlette>`_)
* `FastAPI <https://fastapi.tiangolo.com/advanced/graphql/>`_ (`source <https://github.com/tiangolo/fastapi>`_)


================================================
FILE: docs/quickstart.rst
================================================
Getting started
===============

Introduction
------------

What is GraphQL?
~~~~~~~~~~~~~~~~

GraphQL is a query language for your API.

It provides a standard way to:

* *describe data provided by a server* in a statically typed **Schema**
* *request data* in a **Query** which exactly describes your data requirements and
* *receive data* in a **Response** containing only the data you requested.

For an introduction to GraphQL and an overview of its concepts, please refer to `the official GraphQL documentation`_.

.. _the official GraphQL documentation: http://graphql.org/learn/

What is Graphene?
~~~~~~~~~~~~~~~~~

Graphene is a library that provides tools to implement a GraphQL API in Python using a *code-first* approach.

Compare 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.

.. _Apollo Server: https://www.apollographql.com/docs/apollo-server/

.. _Ariadne: https://ariadnegraphql.org/

Graphene 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.

An example in Graphene
----------------------

Let’s build a basic GraphQL schema to say "hello" and "goodbye" in Graphene.

When we send a **Query** requesting only one **Field**, ``hello``, and specify a value for the ``firstName`` **Argument**...

.. code::

    {
      hello(firstName: "friend")
    }

...we would expect the following Response containing only the data requested (the ``goodbye`` field is not resolved).

.. code::

   {
     "data": {
       "hello": "Hello friend!"
     }
   }


Requirements
~~~~~~~~~~~~

-  Python (3.8, 3.9, 3.10, 3.11, 3.12, pypy)
-  Graphene (3.0)

Project setup
~~~~~~~~~~~~~

.. code:: bash

    pip install "graphene>=3.0"

Creating a basic Schema
~~~~~~~~~~~~~~~~~~~~~~~

In Graphene, we can define a simple schema using the following code:

.. code:: python

    from graphene import ObjectType, String, Schema

    class Query(ObjectType):
        # this defines a Field `hello` in our Schema with a single Argument `first_name`
        # By default, the argument name will automatically be camel-based into firstName in the generated schema
        hello = String(first_name=String(default_value="stranger"))
        goodbye = String()

        # our Resolver method takes the GraphQL context (root, info) as well as
        # Argument (first_name) for the Field and returns data for the query Response
        def resolve_hello(root, info, first_name):
            return f'Hello {first_name}!'

        def resolve_goodbye(root, info):
            return 'See ya!'

    schema = Schema(query=Query)


A 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`.

Our 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**.

For 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`.

Schema Definition Language (SDL)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

In the `GraphQL Schema Definition Language`_, we could describe the fields defined by our example code as shown below.

.. _GraphQL Schema Definition Language: https://graphql.org/learn/schema/

.. code::

    type Query {
      hello(firstName: String = "stranger"): String
      goodbye: String
    }

Further examples in this documentation will use SDL to describe schema created by ObjectTypes and other fields.

Querying
~~~~~~~~

Then we can start querying our **Schema** by passing a GraphQL query string to ``execute``:

.. code:: python

    # we can query for our field (with the default argument)
    query_string = '{ hello }'
    result = schema.execute(query_string)
    print(result.data['hello'])
    # "Hello stranger!"

    # or passing the argument in the query
    query_with_argument = '{ hello(firstName: "GraphQL") }'
    result = schema.execute(query_with_argument)
    print(result.data['hello'])
    # "Hello GraphQL!"

Next steps
~~~~~~~~~~

Congrats! You got your first Graphene schema working!

Normally, 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.


================================================
FILE: docs/relay/connection.rst
================================================
Connection
==========

A connection is a vitaminized version of a List that provides ways of
slicing and paginating through it. The way you create Connection types
in ``graphene`` is using ``relay.Connection`` and ``relay.ConnectionField``.

Quick example
-------------

If we want to create a custom Connection on a given node, we have to subclass the
``Connection`` class.

In the following example, ``extra`` will be an extra field in the connection,
and ``other`` an extra field in the Connection Edge.

.. code:: python

    class ShipConnection(Connection):
        extra = String()

        class Meta:
            node = Ship

        class Edge:
            other = String()

The ``ShipConnection`` connection class, will have automatically a ``pageInfo`` field,
and a ``edges`` field (which is a list of ``ShipConnection.Edge``).
This ``Edge`` will have a ``node`` field linking to the specified node
(in ``ShipConnection.Meta``) and the field ``other`` that we defined in the class.

Connection Field
----------------
You can create connection fields in any Connection, in case any ObjectType
that implements ``Node`` will have a default Connection.

.. code:: python

    class Faction(graphene.ObjectType):
        name = graphene.String()
        ships = relay.ConnectionField(ShipConnection)

        def resolve_ships(root, info):
            return []


================================================
FILE: docs/relay/index.rst
================================================
Relay
=====

Graphene has complete support for `Relay`_ and offers some utils to make
integration from Python easy.


.. toctree::
   :maxdepth: 2

   nodes
   connection
   mutations


Useful links
------------

-  `Getting started with Relay`_
-  `Relay Global Identification Specification`_
-  `Relay Cursor Connection Specification`_

.. _Relay: https://relay.dev/docs/guides/graphql-server-specification/
.. _Getting started with Relay: https://relay.dev/docs/getting-started/step-by-step-guide/
.. _Relay Global Identification Specification: https://relay.dev/graphql/objectidentification.htm
.. _Relay Cursor Connection Specification: https://relay.dev/graphql/connections.htm


================================================
FILE: docs/relay/mutations.rst
================================================
Mutations
=========

Most APIs don’t just allow you to read data, they also allow you to
write.

In GraphQL, this is done using mutations. Just like queries,
Relay puts some additional requirements on mutations, but Graphene
nicely manages that for you. All you need to do is make your mutation a
subclass of ``relay.ClientIDMutation``.

.. code:: python

    class IntroduceShip(relay.ClientIDMutation):

        class Input:
            ship_name = graphene.String(required=True)
            faction_id = graphene.String(required=True)

        ship = graphene.Field(Ship)
        faction = graphene.Field(Faction)

        @classmethod
        def mutate_and_get_payload(cls, root, info, **input):
            ship_name = input.ship_name
            faction_id = input.faction_id
            ship = create_ship(ship_name, faction_id)
            faction = get_faction(faction_id)
            return IntroduceShip(ship=ship, faction=faction)



Accepting Files
---------------

Mutations can also accept files, that's how it will work with different integrations:

.. code:: python

    class UploadFile(graphene.ClientIDMutation):
         class Input:
             pass
             # nothing needed for uploading file

         # your return fields
         success = graphene.String()

        @classmethod
        def mutate_and_get_payload(cls, root, info, **input):
            # When using it in Django, context will be the request
            files = info.context.FILES
            # Or, if used in Flask, context will be the flask global request
            # files = context.files

            # do something with files

            return UploadFile(success=True)


================================================
FILE: docs/relay/nodes.rst
================================================
Nodes
=====

A ``Node`` is an Interface provided by ``graphene.relay`` that contains
a single field ``id`` (which is a ``ID!``). Any object that inherits
from it has to implement a ``get_node`` method for retrieving a
``Node`` by an *id*.


Quick example
-------------

Example usage (taken from the `Starwars Relay example`_):

.. code:: python

    class Ship(graphene.ObjectType):
        '''A ship in the Star Wars saga'''
        class Meta:
            interfaces = (relay.Node, )

        name = graphene.String(description='The name of the ship.')

        @classmethod
        def get_node(cls, info, id):
            return get_ship(id)

The ``id`` returned by the ``Ship`` type when you query it will be a
scalar which contains enough info for the server to know its type and
its id.

For example, the instance ``Ship(id=1)`` will return ``U2hpcDox`` as the
id when you query it (which is the base64 encoding of ``Ship:1``), and
which could be useful later if we want to query a node by its id.


Custom Nodes
------------

You can use the predefined ``relay.Node`` or you can subclass it, defining
custom ways of how a node id is encoded (using the ``to_global_id`` method in the class)
or how we can retrieve a Node given a encoded id (with the ``get_node_from_global_id`` method).

Example of a custom node:

.. code:: python

    class CustomNode(Node):

        class Meta:
            name = 'Node'

        @staticmethod
        def to_global_id(type_, id):
            return f"{type_}:{id}"

        @staticmethod
        def get_node_from_global_id(info, global_id, only_type=None):
            type_, id = global_id.split(':')
            if only_type:
                # We assure that the node type that we want to retrieve
                # is the same that was indicated in the field type
                assert type_ == only_type._meta.name, 'Received not compatible node.'

            if type_ == 'User':
                return get_user(id)
            elif type_ == 'Photo':
                return get_photo(id)


The ``get_node_from_global_id`` method will be called when ``CustomNode.Field`` is resolved.


Accessing node types
--------------------

If we want to retrieve node instances from a ``global_id`` (scalar that identifies an instance by it's type name and id),
we can simply do ``Node.get_node_from_global_id(info, global_id)``.

In the case we want to restrict the instance retrieval to a specific type, we can do:
``Node.get_node_from_global_id(info, global_id, only_type=Ship)``. This will raise an error
if the ``global_id`` doesn't correspond to a Ship type.


Node Root field
---------------

As is required in the `Relay specification`_, the server must implement
a root field called ``node`` that returns a ``Node`` Interface.

For this reason, ``graphene`` provides the field ``relay.Node.Field``,
which links to any type in the Schema which implements ``Node``.
Example usage:

.. code:: python

    class Query(graphene.ObjectType):
        # Should be CustomNode.Field() if we want to use our custom Node
        node = relay.Node.Field()

.. _Relay specification: https://facebook.github.io/relay/docs/graphql-relay-specification.html
.. _Starwars Relay example: https://github.com/graphql-python/graphene/blob/master/examples/starwars_relay/schema.py


================================================
FILE: docs/requirements.txt
================================================
# Required library
Sphinx==6.1.3
sphinx-autobuild==2021.3.14
# Docs template
http://graphene-python.org/sphinx_graphene_theme.zip


================================================
FILE: docs/testing/index.rst
================================================
===================
Testing in Graphene
===================


Automated 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:

- When you’re writing new code, you can use tests to validate your code works as expected.
- When you’re refactoring or modifying old code, you can use tests to ensure your changes haven’t affected your application’s behavior unexpectedly.

Testing 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.

With 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.


Testing tools
-------------

Graphene provides a small set of tools that come in handy when writing tests.


Test Client
~~~~~~~~~~~

The 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.

Some of the things you can do with the test client are:

- Simulate Queries and Mutations and observe the response.
- Test that a given query request is rendered by a given Django template, with a template context that contains certain values.


Overview and a quick example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

To use the test client, instantiate ``graphene.test.Client`` and retrieve GraphQL responses:


.. code:: python

    from graphene.test import Client

    def test_hey():
        client = Client(my_schema)
        executed = client.execute('''{ hey }''')
        assert executed == {
            'data': {
                'hey': 'hello!'
            }
        }


Execute parameters
~~~~~~~~~~~~~~~~~~

You can also add extra keyword arguments to the ``execute`` method, such as
``context``, ``root``, ``variables``, ...:


.. code:: python

    from graphene.test import Client

    def test_hey():
        client = Client(my_schema)
        executed = client.execute('''{ hey }''', context={'user': 'Peter'})
        assert executed == {
            'data': {
                'hey': 'hello Peter!'
            }
        }


================================================
FILE: docs/types/enums.rst
================================================
Enums
=====

An ``Enum`` is a special ``GraphQL`` type that represents a set of
symbolic names (members) bound to unique, constant values.

Definition
----------

You can create an ``Enum`` using classes:

.. code:: python

    import graphene

    class Episode(graphene.Enum):
        NEWHOPE = 4
        EMPIRE = 5
        JEDI = 6

But also using instances of Enum:

.. code:: python

    Episode = graphene.Enum('Episode', [('NEWHOPE', 4), ('EMPIRE', 5), ('JEDI', 6)])

Value descriptions
------------------

It's possible to add a description to an enum value, for that the enum value
needs to have the ``description`` property on it.

.. code:: python

    class Episode(graphene.Enum):
        NEWHOPE = 4
        EMPIRE = 5
        JEDI = 6

        @property
        def description(self):
            if self == Episode.NEWHOPE:
                return 'New Hope Episode'
            return 'Other episode'


Usage with Python Enums
-----------------------

In case the Enums are already defined it's possible to reuse them using
the ``Enum.from_enum`` function.

.. code:: python

    graphene.Enum.from_enum(AlreadyExistingPyEnum)

``Enum.from_enum`` supports a ``description`` and ``deprecation_reason`` lambdas as input so
you can add description etc. to your enum without changing the original:

.. code:: python

    graphene.Enum.from_enum(
        AlreadyExistingPyEnum,
        description=lambda v: return 'foo' if v == AlreadyExistingPyEnum.Foo else 'bar'
    )


Notes
-----

``graphene.Enum`` uses |enum.Enum|_ internally (or a backport if
that's not available) and can be used in a similar way, with the exception of
member getters.

In the Python ``Enum`` implementation you can access a member by initing the Enum.

.. code:: python

    from enum import Enum

    class Color(Enum):
        RED = 1
        GREEN = 2
        BLUE = 3

    assert Color(1) == Color.RED


However, in Graphene ``Enum`` you need to call `.get` to have the same effect:

.. code:: python

    from graphene import Enum

    class Color(Enum):
        RED = 1
        GREEN = 2
        BLUE = 3

    assert Color.get(1) == Color.RED

.. |enum.Enum| replace:: ``enum.Enum``
.. _enum.Enum: https://docs.python.org/3/library/enum.html


================================================
FILE: docs/types/index.rst
================================================
.. _TypesReference:

===============
Types Reference
===============

.. toctree::
   :maxdepth: 1

   schema
   scalars
   list-and-nonnull
   objecttypes
   enums
   interfaces
   unions
   mutations


================================================
FILE: docs/types/interfaces.rst
================================================
.. _Interfaces:

Interfaces
==========

An *Interface* is an abstract type that defines a certain set of fields that a
type must include to implement the interface.

For example, you can define an Interface ``Character`` that represents any
character in the Star Wars trilogy:

.. code:: python

    import graphene

    class Character(graphene.Interface):
        id = graphene.ID(required=True)
        name = graphene.String(required=True)
        friends = graphene.List(lambda: Character)


Any ObjectType that implements ``Character`` will have these exact fields, with
these arguments and return types.

For example, here are some types that might implement ``Character``:

.. code:: python

    class Human(graphene.ObjectType):
        class Meta:
            interfaces = (Character, )

        starships = graphene.List(Starship)
        home_planet = graphene.String()

    class Droid(graphene.ObjectType):
        class Meta:
            interfaces = (Character, )

        primary_function = graphene.String()


Both of these types have all of the fields from the ``Character`` interface,
but also bring in extra fields, ``home_planet``, ``starships`` and
``primary_function``, that are specific to that particular type of character.

The full GraphQL schema definition will look like this:

.. code::

    interface Character {
        id: ID!
        name: String!
        friends: [Character]
    }

    type Human implements Character {
        id: ID!
        name: String!
        friends: [Character]
        starships: [Starship]
        homePlanet: String
    }

    type Droid implements Character {
        id: ID!
        name: String!
        friends: [Character]
        primaryFunction: String
    }

Interfaces are useful when you want to return an object or set of objects,
which might be of several different types.

For example, you can define a field ``hero`` that resolves to any
``Character``, depending on the episode, like this:

.. code:: python

    class Query(graphene.ObjectType):
        hero = graphene.Field(
            Character,
            required=True,
            episode=graphene.Int(required=True)
        )

        def resolve_hero(root, info, episode):
            # Luke is the hero of Episode V
            if episode == 5:
                return get_human(name='Luke Skywalker')
            return get_droid(name='R2-D2')

    schema = graphene.Schema(query=Query, types=[Human, Droid])

This allows you to directly query for fields that exist on the Character interface
as well as selecting specific fields on any type that implements the interface
using `inline fragments <https://graphql.org/learn/queries/#inline-fragments>`_.

For example, the following query:

.. code::

    query HeroForEpisode($episode: Int!) {
        hero(episode: $episode) {
            __typename
            name
            ... on Droid {
                primaryFunction
            }
            ... on Human {
                homePlanet
            }
        }
    }

Will return the following data with variables ``{ "episode": 4 }``:

.. code:: json

    {
        "data": {
            "hero": {
                "__typename": "Droid",
                "name": "R2-D2",
                "primaryFunction": "Astromech"
            }
        }
    }

And different data with the variables ``{ "episode": 5 }``:

.. code:: json

    {
        "data": {
            "hero": {
                "__typename": "Human",
                "name": "Luke Skywalker",
                "homePlanet": "Tatooine"
            }
        }
    }

Resolving data objects to types
-------------------------------

As you build out your schema in Graphene it's common for your resolvers to
return objects that represent the data backing your GraphQL types rather than
instances of the Graphene types (e.g. Django or SQLAlchemy models). This works
well with ``ObjectType`` and ``Scalar`` fields, however when you start using
Interfaces you might come across this error:

.. code::

    "Abstract type Character must resolve to an Object type at runtime for field Query.hero ..."

This happens because Graphene doesn't have enough information to convert the
data object into a Graphene type needed to resolve the ``Interface``. To solve
this you can define a ``resolve_type`` class method on the ``Interface`` which
maps a data object to a Graphene type:

.. code:: python

    class Character(graphene.Interface):
        id = graphene.ID(required=True)
        name = graphene.String(required=True)

        @classmethod
        def resolve_type(cls, instance, info):
            if instance.type == 'DROID':
                return Droid
            return Human


================================================
FILE: docs/types/list-and-nonnull.rst
================================================
Lists and Non-Null
==================

Object types, scalars, and enums are the only kinds of types you can
define in Graphene. But when you use the types in other parts of the
schema, or in your query variable declarations, you can apply additional
type modifiers that affect validation of those values.

NonNull
-------

.. code:: python

    import graphene

    class Character(graphene.ObjectType):
        name = graphene.NonNull(graphene.String)


Here, we're using a ``String`` type and marking it as Non-Null by wrapping
it using the ``NonNull`` class. This means that our server always expects
to return a non-null value for this field, and if it ends up getting a
null value that will actually trigger a GraphQL execution error,
letting the client know that something has gone wrong.


The previous ``NonNull`` code snippet is also equivalent to:

.. code:: python

    import graphene

    class Character(graphene.ObjectType):
        name = graphene.String(required=True)


List
----

.. code:: python

    import graphene

    class Character(graphene.ObjectType):
        appears_in = graphene.List(graphene.String)

Lists work in a similar way: We can use a type modifier to mark a type as a
``List``, which indicates that this field will return a list of that type.
It works the same for arguments, where the validation step will expect a list
for that value.

NonNull Lists
-------------

By default items in a list will be considered nullable. To define a list without
any nullable items the type needs to be marked as ``NonNull``. For example:

.. code:: python

    import graphene

    class Character(graphene.ObjectType):
        appears_in = graphene.List(graphene.NonNull(graphene.String))

The above results in the type definition:

.. code::

    type Character {
        appearsIn: [String!]
    }


================================================
FILE: docs/types/mutations.rst
================================================
Mutations
=========

A Mutation is a special ObjectType that also defines an Input.

Quick example
-------------

This example defines a Mutation:

.. code:: python

    import graphene

    class CreatePerson(graphene.Mutation):
        class Arguments:
            name = graphene.String()

        ok = graphene.Boolean()
        person = graphene.Field(lambda: Person)

        def mutate(root, info, name):
            person = Person(name=name)
            ok = True
            return CreatePerson(person=person, ok=ok)

**person** and **ok** are the output fields of the Mutation when it is
resolved.

**Arguments** attributes are the arguments that the Mutation
``CreatePerson`` needs for resolving, in this case **name** will be the
only argument for the mutation.

**mutate** is the function that will be applied once the mutation is
called. This method is just a special resolver that we can change
data within. It takes the same arguments as the standard query :ref:`ResolverArguments`.

So, we can finish our schema like this:

.. code:: python

    # ... the Mutation Class

    class Person(graphene.ObjectType):
        name = graphene.String()
        age = graphene.Int()

    class MyMutations(graphene.ObjectType):
        create_person = CreatePerson.Field()

    # We must define a query for our schema
    class Query(graphene.ObjectType):
        person = graphene.Field(Person)

    schema = graphene.Schema(query=Query, mutation=MyMutations)

Executing the Mutation
----------------------

Then, if we query (``schema.execute(query_str)``) the following:

.. code::

    mutation myFirstMutation {
        createPerson(name:"Peter") {
            person {
                name
            }
            ok
        }
    }

We should receive:

.. code:: json

    {
        "createPerson": {
            "person" : {
                "name": "Peter"
            },
            "ok": true
        }
    }

InputFields and InputObjectTypes
----------------------------------
InputFields are used in mutations to allow nested input data for mutations.

To use an InputField you define an InputObjectType that specifies the structure of your input data:


.. code:: python

    import graphene

    class PersonInput(graphene.InputObjectType):
        name = graphene.String(required=True)
        age = graphene.Int(required=True)

    class CreatePerson(graphene.Mutation):
        class Arguments:
            person_data = PersonInput(required=True)

        person = graphene.Field(Person)

        def mutate(root, info, person_data=None):
            person = Person(
                name=person_data.name,
                age=person_data.age
            )
            return CreatePerson(person=person)


Note that  **name** and **age** are part of **person_data** now.

Using the above mutation your new query would look like this:

.. code::

    mutation myFirstMutation {
        createPerson(personData: {name:"Peter", age: 24}) {
            person {
                name,
                age
            }
        }
    }

InputObjectTypes can also be fields of InputObjectTypes allowing you to have
as complex of input data as you need:

.. code:: python

    import graphene

    class LatLngInput(graphene.InputObjectType):
        lat = graphene.Float()
        lng = graphene.Float()

    #A location has a latlng associated to it
    class LocationInput(graphene.InputObjectType):
        name = graphene.String()
        latlng = graphene.InputField(LatLngInput)

Output type example
-------------------
To return an existing ObjectType instead of a mutation-specific type, set the **Output** attribute to the desired ObjectType:

.. code:: python

    import graphene

    class CreatePerson(graphene.Mutation):
        class Arguments:
            name = graphene.String()

        Output = Person

        def mutate(root, info, name):
            return Person(name=name)

Then, if we query (``schema.execute(query_str)``) with the following:

.. code::

    mutation myFirstMutation {
        createPerson(name:"Peter") {
            name
            __typename
        }
    }

We should receive:

.. code:: json

    {
        "createPerson": {
            "name": "Peter",
            "__typename": "Person"
        }
    }


================================================
FILE: docs/types/objecttypes.rst
================================================
.. _ObjectType:

ObjectType
==========

A Graphene *ObjectType* is the building block used to define the relationship between **Fields** in your **Schema** and how their data is retrieved.

The basics:

- Each ObjectType is a Python class that inherits from ``graphene.ObjectType``.
- Each attribute of the ObjectType represents a ``Field``.
- Each ``Field`` has a :ref:`resolver method<Resolvers>` to fetch data (or :ref:`DefaultResolver`).

Quick example
-------------

This example model defines a Person, with a first and a last name:

.. code:: python

    from graphene import ObjectType, String

    class Person(ObjectType):
        first_name = String()
        last_name = String()
        full_name = String()

        def resolve_full_name(parent, info):
            return f"{parent.first_name} {parent.last_name}"

This *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.

The above ``Person`` ObjectType has the following schema representation:

.. code::

    type Person {
      firstName: String
      lastName: String
      fullName: String
    }

.. _Resolvers:

Resolvers
---------

A **Resolver** is a method that helps us answer **Queries** by fetching data for a **Field** in our **Schema**.

Resolvers are lazily executed, so if a field is not included in a query, its resolver will not be executed.

Each 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``.

Each resolver method takes the parameters:

* :ref:`ResolverParamParent` for the value object use to resolve most fields
* :ref:`ResolverParamInfo` for query and schema meta information and per-request context
* :ref:`ResolverParamGraphQLArguments` as defined on the **Field**.

.. _ResolverArguments:

Resolver Parameters
~~~~~~~~~~~~~~~~~~~

.. _ResolverParamParent:

Parent Value Object (*parent*)
******************************

This parameter is typically used to derive the values for most fields on an *ObjectType*.

The 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.

Resolver example
^^^^^^^^^^^^^^^^

If we have a schema with Person type and one field on the root query.

.. code:: python

    from graphene import ObjectType, String, Field

    def get_human(name):
        first_name, last_name = name.split()
        return Person(first_name, last_name)

    class Person(ObjectType):
        full_name = String()

        def resolve_full_name(parent, info):
            return f"{parent.first_name} {parent.last_name}"

    class Query(ObjectType):
        me = Field(Person)

        def resolve_me(parent, info):
            # returns an object that represents a Person
            return get_human(name="Luke Skywalker")

When we execute a query against that schema.

.. code:: python

    schema = Schema(query=Query)

    query_string = "{ me { fullName } }"
    result = schema.execute(query_string)

    assert result.data["me"] == {"fullName": "Luke Skywalker"}

Then we go through the following steps to resolve this query:

* ``parent`` is set with the root_value from query execution (None).
* ``Query.resolve_me`` called with ``parent`` None which returns a value object ``Person("Luke", "Skywalker")``.
* This value object is then used as ``parent`` while calling ``Person.resolve_full_name`` to resolve the scalar String value "Luke Skywalker".
* The scalar value is serialized and sent back in the query response.

Each 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`.

Naming convention
^^^^^^^^^^^^^^^^^

This :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.

.. _ResolverParamInfo:

GraphQL Execution Info (*info*)
*******************************

The second parameter provides two things:

* reference to meta information about the execution of the current GraphQL Query (fields, schema, parsed query, etc.)
* access to per-request ``context`` which can be used to store user authentication, data loader instances or anything else useful for resolving the query.

Only context will be required for most applications. See :ref:`SchemaExecuteContext` for more information about setting context.

.. _ResolverParamGraphQLArguments:

GraphQL Arguments (*\*\*kwargs*)
********************************

Any arguments that a field defines gets passed to the resolver function as
keyword arguments. For example:

.. code:: python

    from graphene import ObjectType, Field, String

    class Query(ObjectType):
        human_by_name = Field(Human, name=String(required=True))

        def resolve_human_by_name(parent, info, name):
            return get_human(name=name)

You can then execute the following query:

.. code::

    query {
        humanByName(name: "Luke Skywalker") {
            firstName
            lastName
        }
    }

*Note:* There are several arguments to a field that are "reserved" by Graphene
(see :ref:`fields-mounted-types`).
You can still define an argument that clashes with one of these fields by using
the ``args`` parameter like so:

.. code:: python

    from graphene import ObjectType, Field, String

    class Query(ObjectType):
        answer = String(args={'description': String()})

        def resolve_answer(parent, info, description):
            return description


Convenience Features of Graphene Resolvers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. _ResolverImplicitStaticMethod:

Implicit staticmethod
*********************

One 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.

The two resolvers in this example are effectively the same.

.. code:: python

    from graphene import ObjectType, String

    class Person(ObjectType):
        first_name = String()
        last_name = String()

        @staticmethod
        def resolve_first_name(parent, info):
            '''
            Decorating a Python method with `staticmethod` ensures that `self` will not be provided as an
            argument. However, Graphene does not need this decorator for this behavior.
            '''
            return parent.first_name

        def resolve_last_name(parent, info):
            '''
            Normally the first argument for this method would be `self`, but Graphene executes this as
            a staticmethod implicitly.
            '''
            return parent.last_name

        # ...

If you prefer your code to be more explicit, feel free to use ``@staticmethod`` decorators. Otherwise, your code may be cleaner without them!

.. _DefaultResolver:

Default Resolver
****************

If a resolver method is not defined for a **Field** attribute on our *ObjectType*, Graphene supplies a default resolver.

If 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.

.. code:: python

    from collections import namedtuple

    from graphene import ObjectType, String, Field, Schema

    PersonValueObject = namedtuple("Person", ["first_name", "last_name"])

    class Person(ObjectType):
        first_name = String()
        last_name = String()

    class Query(ObjectType):
        me = Field(Person)
        my_best_friend = Field(Person)

        def resolve_me(parent, info):
            # always pass an object for `me` field
            return PersonValueObject(first_name="Luke", last_name="Skywalker")

        def resolve_my_best_friend(parent, info):
            # always pass a dictionary for `my_best_fiend_field`
            return {"first_name": "R2", "last_name": "D2"}

    schema = Schema(query=Query)
    result = schema.execute('''
        {
            me { firstName lastName }
            myBestFriend { firstName lastName }
        }
    ''')
    # With default resolvers we can resolve attributes from an object..
    assert result.data["me"] == {"firstName": "Luke", "lastName": "Skywalker"}

    # With default resolvers, we can also resolve keys from a dictionary..
    assert result.data["myBestFriend"] == {"firstName": "R2", "lastName": "D2"}

Advanced
~~~~~~~~

GraphQL Argument defaults
*************************

If you define an argument for a field that is not required (and in a query
execution it is not provided as an argument) it will not be passed to the
resolver function at all. This is so that the developer can differentiate
between a ``undefined`` value for an argument and an explicit ``null`` value.

For example, given this schema:

.. code:: python

    from graphene import ObjectType, String

    class Query(ObjectType):
        hello = String(required=True, name=String())

        def resolve_hello(parent, info, name):
            return name if name else 'World'

And this query:

.. code::

    query {
        hello
    }

An error will be thrown:

.. code::

    TypeError: resolve_hello() missing 1 required positional argument: 'name'

You can fix this error in several ways. Either by combining all keyword arguments
into a dict:

.. code:: python

    from graphene import ObjectType, String

    class Query(ObjectType):
        hello = String(required=True, name=String())

        def resolve_hello(parent, info, **kwargs):
            name = kwargs.get('name', 'World')
            return f'Hello, {name}!'

Or by setting a default value for the keyword argument:

.. code:: python

    from graphene import ObjectType, String

    class Query(ObjectType):
        hello = String(required=True, name=String())

        def resolve_hello(parent, info, name='World'):
            return f'Hello, {name}!'

One can also set a default value for an Argument in the GraphQL schema itself using Graphene!

.. code:: python

    from graphene import ObjectType, String

    class Query(ObjectType):
        hello = String(
            required=True,
            name=String(default_value='World')
        )

        def resolve_hello(parent, info, name):
            return f'Hello, {name}!'

Resolvers outside the class
***************************

A field can use a custom resolver from outside the class:

.. code:: python

    from graphene import ObjectType, String

    def resolve_full_name(person, info):
        return f"{person.first_name} {person.last_name}"

    class Person(ObjectType):
        first_name = String()
        last_name = String()
        full_name = String(resolver=resolve_full_name)


Instances as value objects
**************************

Graphene ``ObjectType``\ s can act as value objects too. So with the
previous example you could use ``Person`` to capture data for each of the *ObjectType*'s fields.

.. code:: python

    peter = Person(first_name='Peter', last_name='Griffin')

    peter.first_name  # prints "Peter"
    peter.last_name  # prints "Griffin"

Field camelcasing
*****************

Graphene automatically camelcases fields on *ObjectType* from ``field_name`` to ``fieldName`` to conform with GraphQL standards. See :ref:`SchemaAutoCamelCase` for more information.

*ObjectType* Configuration - Meta class
---------------------------------------

Graphene uses a Meta inner class on *ObjectType* to set different options.

GraphQL type name
~~~~~~~~~~~~~~~~~

By default the type name in the GraphQL schema will be the same as the class name
that defines the ``ObjectType``. This can be changed by setting the ``name``
property on the ``Meta`` class:

.. code:: python

    from graphene import ObjectType

    class MyGraphQlSong(ObjectType):
        class Meta:
            name = 'Song'

GraphQL Description
~~~~~~~~~~~~~~~~~~~

The schema description of an *ObjectType* can be set as a docstring on the Python object or on the Meta inner class.

.. code:: python

    from graphene import ObjectType

    class MyGraphQlSong(ObjectType):
        ''' We can set the schema description for an Object Type here on a docstring '''
        class Meta:
            description = 'But if we set the description in Meta, this value is used instead'

Interfaces & Possible Types
~~~~~~~~~~~~~~~~~~~~~~~~~~~

Setting ``interfaces`` in Meta inner class specifies the GraphQL Interfaces that this Object implements.

Providing ``possible_types`` helps Graphene resolve ambiguous types such as interfaces or Unions.

See :ref:`Interfaces` for more information.

.. code:: python

    from graphene import ObjectType, Node

    Song = namedtuple('Song', ('title', 'artist'))

    class MyGraphQlSong(ObjectType):
        class Meta:
            interfaces = (Node, )
            possible_types = (Song, )

.. _Interface: /docs/interfaces/


================================================
FILE: docs/types/scalars.rst
================================================
.. _Scalars:

Scalars
=======

Scalar types represent concrete values at the leaves of a query. There are
several built in types that Graphene provides out of the box which represent common
values in Python. You can also create your own Scalar types to better express
values that you might have in your data model.

All Scalar types accept the following arguments. All are optional:

``name``: *string*

    Override the name of the Field.

``description``: *string*

    A description of the type to show in the GraphiQL browser.

``required``: *boolean*

    If ``True``, the server will enforce a value for this field. See `NonNull <../list-and-nonnull.html#nonnull>`_. Default is ``False``.

``deprecation_reason``: *string*

    Provide a deprecation reason for the Field.

``default_value``: *any*

    Provide a default value for the Field.



Built in scalars
----------------

Graphene defines the following base Scalar Types that match the default `GraphQL types <https://graphql.org/learn/schema/#scalar-types>`_:

``graphene.String``
^^^^^^^^^^^^^^^^^^^

    Represents textual data, represented as UTF-8
    character sequences. The String type is most often used by GraphQL to
    represent free-form human-readable text.

``graphene.Int``
^^^^^^^^^^^^^^^^

    Represents non-fractional signed whole numeric
    values. Int is a signed 32‐bit integer per the
    `GraphQL spec <https://facebook.github.io/graphql/June2018/#sec-Int>`_

``graphene.Float``
^^^^^^^^^^^^^^^^^^

    Represents signed double-precision fractional
    values as specified by
    `IEEE 754 <http://en.wikipedia.org/wiki/IEEE_floating_point>`_.

``graphene.Boolean``
^^^^^^^^^^^^^^^^^^^^

    Represents `true` or `false`.

``graphene.ID``
^^^^^^^^^^^^^^^

    Represents a unique identifier, often used to
    refetch an object or as key for a cache. The ID type appears in a JSON
    response as a String; however, it is not intended to be human-readable.
    When expected as an input type, any string (such as `"4"`) or integer
    (such as `4`) input value will be accepted as an ID.

----

Graphene also provides custom scalars for common values:

``graphene.Date``
^^^^^^^^^^^^^^^^^

    Represents a Date value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.

.. code:: python

    import datetime
    from graphene import Schema, ObjectType, Date

    class Query(ObjectType):
        one_week_from = Date(required=True, date_input=Date(required=True))

        def resolve_one_week_from(root, info, date_input):
            assert date_input == datetime.date(2006, 1, 2)
            return date_input + datetime.timedelta(weeks=1)

    schema = Schema(query=Query)

    results = schema.execute("""
        query {
            oneWeekFrom(dateInput: "2006-01-02")
        }
    """)

    assert results.data == {"oneWeekFrom": "2006-01-09"}


``graphene.DateTime``
^^^^^^^^^^^^^^^^^^^^^

    Represents a DateTime value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.

.. code:: python

    import datetime
    from graphene import Schema, ObjectType, DateTime

    class Query(ObjectType):
        one_hour_from = DateTime(required=True, datetime_input=DateTime(required=True))

        def resolve_one_hour_from(root, info, datetime_input):
            assert datetime_input == datetime.datetime(2006, 1, 2, 15, 4, 5)
            return datetime_input + datetime.timedelta(hours=1)

    schema = Schema(query=Query)

    results = schema.execute("""
        query {
            oneHourFrom(datetimeInput: "2006-01-02T15:04:05")
        }
    """)

    assert results.data == {"oneHourFrom": "2006-01-02T16:04:05"}

``graphene.Time``
^^^^^^^^^^^^^^^^^

    Represents a Time value as specified by `iso8601 <https://en.wikipedia.org/wiki/ISO_8601>`_.

.. code:: python

    import datetime
    from graphene import Schema, ObjectType, Time

    class Query(ObjectType):
        one_hour_from = Time(required=True, time_input=Time(required=True))

        def resolve_one_hour_from(root, info, time_input):
            assert time_input == datetime.time(15, 4, 5)
            tmp_time_input = datetime.datetime.combine(datetime.date(1, 1, 1), time_input)
            return (tmp_time_input + datetime.timedelta(hours=1)).time()

    schema = Schema(query=Query)

    results = schema.execute("""
        query {
            oneHourFrom(timeInput: "15:04:05")
        }
    """)

    assert results.data == {"oneHourFrom": "16:04:05"}

``graphene.Decimal``
^^^^^^^^^^^^^^^^^^^^

    Represents a Python Decimal value.

.. code:: python

    import decimal
    from graphene import Schema, ObjectType, Decimal

    class Query(ObjectType):
        add_one_to = Decimal(required=True, decimal_input=Decimal(required=True))

        def resolve_add_one_to(root, info, decimal_input):
            assert decimal_input == decimal.Decimal("10.50")
            return decimal_input + decimal.Decimal("1")

    schema = Schema(query=Query)

    results = schema.execute("""
        query {
            addOneTo(decimalInput: "10.50")
        }
    """)

    assert results.data == {"addOneTo": "11.50"}

``graphene.JSONString``
^^^^^^^^^^^^^^^^^^^^^^^

    Represents a JSON string.

.. code:: python

    from graphene import Schema, ObjectType, JSONString, String

    class Query(ObjectType):
        update_json_key = JSONString(
            required=True,
            json_input=JSONString(required=True),
            key=String(required=True),
            value=String(required=True)
        )

        def resolve_update_json_key(root, info, json_input, key, value):
            assert json_input == {"name": "Jane"}
            json_input[key] = value
            return json_input

    schema = Schema(query=Query)

    results = schema.execute("""
        query {
            updateJsonKey(jsonInput: "{\\"name\\": \\"Jane\\"}", key: "name", value: "Beth")
        }
    """)

    assert results.data == {"updateJsonKey": "{\"name\": \"Beth\"}"}


``graphene.Base64``
^^^^^^^^^^^^^^^^^^^

    Represents a Base64 encoded string.

.. code:: python

    from graphene import Schema, ObjectType, Base64

    class Query(ObjectType):
        increment_encoded_id = Base64(
            required=True,
            base64_input=Base64(required=True),
        )

        def resolve_increment_encoded_id(root, info, base64_input):
            assert base64_input == "4"
            return int(base64_input) + 1

    schema = Schema(query=Query)

    results = schema.execute("""
        query {
            incrementEncodedId(base64Input: "NA==")
        }
    """)

    assert results.data == {"incrementEncodedId": "NQ=="}



Custom scalars
--------------

You can create custom scalars for your schema.
The following is an example for creating a DateTime scalar:

.. code:: python

    import datetime
    from graphene.types import Scalar
    from graphql.language import ast

    class DateTime(Scalar):
        '''DateTime Scalar Description'''

        @staticmethod
        def serialize(dt):
            return dt.isoformat()

        @staticmethod
        def parse_literal(node, _variables=None):
            if isinstance(node, ast.StringValueNode):
                return datetime.datetime.strptime(
                    node.value, "%Y-%m-%dT%H:%M:%S.%f")

        @staticmethod
        def parse_value(value):
            return datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f")

Mounting Scalars
----------------

Scalars mounted in a ``ObjectType``, ``Interface`` or ``Mutation`` act as
``Field``\ s.

.. code:: python

    class Person(graphene.ObjectType):
        name = graphene.String()

    # Is equivalent to:
    class Person(graphene.ObjectType):
        name = graphene.Field(graphene.String)


**Note:** when using the ``Field`` constructor directly, pass the type and
not an instance.

Types mounted in a ``Field`` act as ``Argument``\ s.


.. code:: python

    graphene.Field(graphene.String, to=graphene.String())

    # Is equivalent to:
    graphene.Field(graphene.String, to=graphene.Argument(graphene.String))


================================================
FILE: docs/types/schema.rst
================================================
Schema
======

A GraphQL **Schema** defines the types and relationships between **Fields** in your API.

A Schema is created by supplying the root :ref:`ObjectType` of each operation, query (mandatory), mutation and subscription.

Schema will collect all type definitions related to the root operations and then supply them to the validator and executor.

.. code:: python

    my_schema = Schema(
        query=MyRootQuery,
        mutation=MyRootMutation,
        subscription=MyRootSubscription
    )

A 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:

* Query fetches data
* Mutation changes data and retrieves the changes
* Subscription sends changes to clients in real-time

Review the `GraphQL documentation on Schema`_ for a brief overview of fields, schema and operations.

.. _GraphQL documentation on Schema: https://graphql.org/learn/schema/


Querying
--------

To query a schema, call the ``execute`` method on it. See :ref:`SchemaExecute` for more details.


.. code:: python

    query_string = 'query whoIsMyBestFriend { myBestFriend { lastName } }'
    my_schema.execute(query_string)

Types
-----

There are some cases where the schema cannot access all of the types that we plan to have.
For example, when a field returns an ``Interface``, the schema doesn't know about any of the
implementations.

In this case, we need to use the ``types`` argument when creating the Schema:


.. code:: python

    my_schema = Schema(
        query=MyRootQuery,
        types=[SomeExtraObjectType, ]
    )

.. _SchemaAutoCamelCase:

Auto camelCase field names
--------------------------

By default all field and argument names (that are not
explicitly set with the ``name`` arg) will be converted from
``snake_case`` to ``camelCase`` (as the API is usually being consumed by a js/mobile client)

For example with the ObjectType the ``last_name`` field name is converted to ``lastName``:

.. code:: python

    class Person(graphene.ObjectType):
        last_name = graphene.String()
        other_name = graphene.String(name='_other_Name')

In case you don't want to apply this transformation, provide a ``name`` argument to the field constructor.
``other_name`` converts to ``_other_Name`` (without further transformations).

Your query should look like:

.. code::

    {
        lastName
        _other_Name
    }


To disable this behavior, set the ``auto_camelcase`` to ``False`` upon schema instantiation:

.. code:: python

    my_schema = Schema(
        query=MyRootQuery,
        auto_camelcase=False,
    )


================================================
FILE: docs/types/unions.rst
================================================
Unions
======

Union types are very similar to interfaces, but they don't get
to specify any common fields between the types.

The basics:

- Each Union is a Python class that inherits from ``graphene.Union``.
- Unions don't have any fields on it, just links to the possible ObjectTypes.

Quick example
-------------

This example model defines several ObjectTypes with their own fields.
``SearchResult`` is the implementation of ``Union`` of this object types.

.. code:: python

    import graphene

    class Human(graphene.ObjectType):
        name = graphene.String()
        born_in = graphene.String()

    class Droid(graphene.ObjectType):
        name = graphene.String()
        primary_function = graphene.String()

    class Starship(graphene.ObjectType):
        name = graphene.String()
        length = graphene.Int()

    class SearchResult(graphene.Union):
        class Meta:
            types = (Human, Droid, Starship)


Wherever we return a SearchResult type in our schema, we might get a Human, a Droid, or a Starship.
Note that members of a union type need to be concrete object types;
you can't create a union type out of interfaces or other unions.

The above types have the following representation in a schema:

.. code::

    type Droid {
      name: String
      primaryFunction: String
    }

    type Human {
      name: String
      bornIn: String
    }

    type Ship {
      name: String
      length: Int
    }

    union SearchResult = Human | Droid | Starship



================================================
FILE: examples/__init__.py
================================================


================================================
FILE: examples/complex_example.py
================================================
import graphene


class GeoInput(graphene.InputObjectType):
    lat = graphene.Float(required=True)
    lng = graphene.Float(required=True)

    @property
    def latlng(self):
        return f"({self.lat},{self.lng})"


class Address(graphene.ObjectType):
    latlng = graphene.String()


class Query(graphene.ObjectType):
    address = graphene.Field(Address, geo=GeoInput(required=True))

    def resolve_address(root, info, geo):
        return Address(latlng=geo.latlng)


class CreateAddress(graphene.Mutation):
    class Arguments:
        geo = GeoInput(required=True)

    Output = Address

    def mutate(root, info, geo):
        return Address(latlng=geo.latlng)


class Mutation(graphene.ObjectType):
    create_address = CreateAddress.Field()


schema = graphene.Schema(query=Query, mutation=Mutation)
query = """
    query something{
      address(geo: {lat:32.2, lng:12}) {
        latlng
      }
    }
"""
mutation = """
    mutation addAddress{
      createAddress(geo: {lat:32.2, lng:12}) {
        latlng
      }
    }
"""


def test_query():
    result = schema.execute(query)
    assert not result.errors
    assert result.data == {"address": {"latlng": "(32.2,12.0)"}}


def test_mutation():
    result = schema.execute(mutation)
    assert not result.errors
    assert result.data == {"createAddress": {"latlng": "(32.2,12.0)"}}


if __name__ == "__main__":
    result = schema.execute(query)
    print(result.data["address"]["latlng"])


================================================
FILE: examples/context_example.py
================================================
import graphene


class User(graphene.ObjectType):
    id = graphene.ID()
    name = graphene.String()


class Query(graphene.ObjectType):
    me = graphene.Field(User)

    def resolve_me(root, info):
        return info.context["user"]


schema = graphene.Schema(query=Query)
query = """
    query something{
      me {
        id
        name
      }
    }
"""


def test_query():
    result = schema.execute(query, context={"user": User(id="1", name="Syrus")})
    assert not result.errors
    assert result.data == {"me": {"id": "1", "name": "Syrus"}}


if __name__ == "__main__":
    result = schema.execute(query, context={"user": User(id="X", name="Console")})
    print(result.data["me"])


================================================
FILE: examples/simple_example.py
================================================
import graphene


class Patron(graphene.ObjectType):
    id = graphene.ID()
    name = graphene.String()
    age = graphene.Int()


class Query(graphene.ObjectType):
    patron = graphene.Field(Patron)

    def resolve_patron(root, info):
        return Patron(id=1, name="Syrus", age=27)


schema = graphene.Schema(query=Query)
query = """
    query something{
      patron {
        id
        name
        age
      }
    }
"""


def test_query():
    result = schema.execute(query)
    assert not result.errors
    assert result.data == {"patron": {"id": "1", "name": "Syrus", "age": 27}}


if __name__ == "__main__":
    result = schema.execute(query)
    print(result.data["patron"])


================================================
FILE: examples/starwars/__init__.py
================================================


================================================
FILE: examples/starwars/data.py
================================================
human_data = {}
droid_data = {}


def setup():
    from .schema import Human, Droid

    global human_data, droid_data
    luke = Human(
        id="1000",
        name="Luke Skywalker",
        friends=["1002", "1003", "2000", "2001"],
        appears_in=[4, 5, 6],
        home_planet="Tatooine",
    )

    vader = Human(
        id="1001",
        name="Darth Vader",
        friends=["1004"],
        appears_in=[4, 5, 6],
        home_planet="Tatooine",
    )

    han = Human(
        id="1002",
        name="Han Solo",
        friends=["1000", "1003", "2001"],
        appears_in=[4, 5, 6],
        home_planet=None,
    )

    leia = Human(
        id="1003",
        name="Leia Organa",
        friends=["1000", "1002", "2000", "2001"],
        appears_in=[4, 5, 6],
        home_planet="Alderaan",
    )

    tarkin = Human(
        id="1004",
        name="Wilhuff Tarkin",
        friends=["1001"],
        appears_in=[4],
        home_planet=None,
    )

    human_data = {
        "1000": luke,
        "1001": vader,
        "1002": han,
        "1003": leia,
        "1004": tarkin,
    }

    c3po = Droid(
        id="2000",
        name="C-3PO",
        friends=["1000", "1002", "1003", "2001"],
        appears_in=[4, 5, 6],
        primary_function="Protocol",
    )

    r2d2 = Droid(
        id="2001",
        name="R2-D2",
        friends=["1000", "1002", "1003"],
        appears_in=[4, 5, 6],
        primary_function="Astromech",
    )

    droid_data = {"2000": c3po, "2001": r2d2}


def get_character(id):
    return human_data.get(id) or droid_data.get(id)


def get_friends(character):
    return map(get_character, character.friends)


def get_hero(episode):
    if episode == 5:
        return human_data["1000"]
    return droid_data["2001"]


def get_human(id):
    return human_data.get(id)


def get_droid(id):
    return droid_data.get(id)


================================================
FILE: examples/starwars/schema.py
================================================
import graphene

from .data import get_character, get_droid, get_hero, get_human


class Episode(graphene.Enum):
    NEWHOPE = 4
    EMPIRE = 5
    JEDI = 6


class Character(graphene.Interface):
    id = graphene.ID()
    name = graphene.String()
    friends = graphene.List(lambda: Character)
    appears_in = graphene.List(Episode)

    def resolve_friends(self, info):
        # The character friends is a list of strings
        return [get_character(f) for f in self.friends]


class Human(graphene.ObjectType):
    class Meta:
        interfaces = (Character,)

    home_planet = graphene.String()


class Droid(graphene.ObjectType):
    class Meta:
        interfaces = (Character,)

    primary_function = graphene.String()


class Query(graphene.ObjectType):
    hero = graphene.Field(Character, episode=Episode())
    human = graphene.Field(Human, id=graphene.String())
    droid = graphene.Field(Droid, id=graphene.String())

    def resolve_hero(root, info, episode=None):
        return get_hero(episode)

    def resolve_human(root, info, id):
        return get_human(id)

    def resolve_droid(root, info, id):
        return get_droid(id)


schema = graphene.Schema(query=Query)


================================================
FILE: examples/starwars/tests/__init__.py
================================================


================================================
FILE: examples/starwars/tests/test_query.py
================================================
from graphene.test import Client

from ..data import setup
from ..schema import schema

setup()

client = Client(schema)


def test_hero_name_query():
    result = client.execute("""
        query HeroNameQuery {
          hero {
            name
          }
        }
    """)
    assert result == {"data": {"hero": {"name": "R2-D2"}}}


def test_hero_name_and_friends_query():
    result = client.execute("""
        query HeroNameAndFriendsQuery {
          hero {
            id
            name
            friends {
              name
            }
          }
        }
    """)
    assert result == {
        "data": {
            "hero": {
                "id": "2001",
                "name": "R2-D2",
                "friends": [
                    {"name": "Luke Skywalker"},
                    {"name": "Han Solo"},
                    {"name": "Leia Organa"},
                ],
            }
        }
    }


def test_nested_query():
    result = client.execute("""
        query NestedQuery {
          hero {
            name
            friends {
              name
              appearsIn
              friends {
                name
              }
            }
          }
        }
    """)
    assert result == {
        "data": {
            "hero": {
                "name": "R2-D2",
                "friends": [
                    {
                        "name": "Luke Skywalker",
                        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
                        "friends": [
                            {"name": "Han Solo"},
                            {"name": "Leia Organa"},
                            {"name": "C-3PO"},
                            {"name": "R2-D2"},
                        ],
                    },
                    {
                        "name": "Han Solo",
                        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
                        "friends": [
                            {"name": "Luke Skywalker"},
                            {"name": "Leia Organa"},
                            {"name": "R2-D2"},
                        ],
                    },
                    {
                        "name": "Leia Organa",
                        "appearsIn": ["NEWHOPE", "EMPIRE", "JEDI"],
                        "friends": [
                            {"name": "Luke Skywalker"},
                            {"name": "Han Solo"},
                            {"name": "C-3PO"},
                            {"name": "R2-D2"},
                        ],
                    },
                ],
            }
        }
    }


def test_fetch_luke_query():
    result = client.execute("""
        query FetchLukeQuery {
          human(id: "1000") {
            name
          }
        }
    """)
    assert result == {"data": {"human": {"name": "Luke Skywalker"}}}


def test_fetch_some_id_query():
    result = client.execute(
        """
        query FetchSomeIDQuery($someId: String!) {
          human(id: $someId) {
            name
          }
        }
    """,
        variables={"someId": "1000"},
    )
    assert result == {"data": {"human": {"name": "Luke Skywalker"}}}


def test_fetch_some_id_query2():
    result = client.execute(
        """
        query FetchSomeIDQuery($someId: String!) {
          human(id: $someId) {
            name
          }
        }
    """,
        variables={"someId": "1002"},
    )
    assert result == {"data": {"human": {"name": "Han Solo"}}}


def test_invalid_id_query():
    result = client.execute(
        """
        query humanQuery($id: String!) {
          human(id: $id) {
            name
          }
        }
    """,
        variables={"id": "not a valid id"},
    )
    assert result == {"data": {"human": None}}


def test_fetch_luke_aliased():
    result = client.execute("""
        query FetchLukeAliased {
          luke: human(id: "1000") {
            name
          }
        }
    """)
    assert result == {"data": {"luke": {"name": "Luke Skywalker"}}}


def test_fetch_luke_and_leia_aliased():
    result = client.execute("""
        query FetchLukeAndLeiaAliased {
          luke: human(id: "1000") {
            name
          }
          leia: human(id: "1003") {
            name
          }
        }
    """)
    assert result == {
        "data": {"luke": {"name": "Luke Skywalker"}, "leia": {"name": "Leia Organa"}}
    }


def test_duplicate_fields():
    result = client.execute("""
        query DuplicateFields {
          luke: human(id: "1000") {
            name
            homePlanet
          }
          leia: human(id: "1003") {
            name
            homePlanet
          }
        }
    """)
    assert result == {
        "data": {
            "luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
            "leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
        }
    }


def test_use_fragment():
    result = client.execute("""
        query UseFragment {
          luke: human(id: "1000") {
            ...HumanFragment
          }
          leia: human(id: "1003") {
            ...HumanFragment
          }
        }
        fragment HumanFragment on Human {
          name
          homePlanet
        }
    """)
    assert result == {
        "data": {
            "luke": {"name": "Luke Skywalker", "homePlanet": "Tatooine"},
            "leia": {"name": "Leia Organa", "homePlanet": "Alderaan"},
        }
    }


def test_check_type_of_r2():
    result = client.execute("""
        query CheckTypeOfR2 {
          hero {
            __typename
            name
          }
        }
    """)
    assert result == {"data": {"hero": {"__typename": "Droid", "name": "R2-D2"}}}


def test_check_type_of_luke():
    result = client.execute("""
        query CheckTypeOfLuke {
          hero(episode: EMPIRE) {
            __typename
            name
          }
        }
    """)
    assert result == {
        "data": {"hero": {"__typename": "Human", "name": "Luke Skywalker"}}
    }


================================================
FILE: examples/starwars/tests/test_schema.py
================================================


================================================
FILE: examples/starwars_relay/__init__.py
================================================


================================================
FILE: examples/starwars_relay/data.py
================================================
data = {}


def setup():
    global data

    from .schema import Ship, Faction

    xwing = Ship(id="1", name="X-Wing")

    ywing = Ship(id="2", name="Y-Wing")

    awing = Ship(id="3", name="A-Wing")

    # Yeah, technically it's Corellian. But it flew in the service of the rebels,
    # so for the purposes of this demo it's a rebel ship.
    falcon = Ship(id="4", name="Millennium Falcon")

    homeOne = Ship(id="5", name="Home One")

    tieFighter = Ship(id="6", name="TIE Fighter")

    tieInterceptor = Ship(id="7", name="TIE Interceptor")

    executor = Ship(id="8", name="Executor")

    rebels = Faction(
        id="1", name="Alliance to Restore the Republic", ships=["1", "2", "3", "4", "5"]
    )

    empire = Faction(id="2", name="Galactic Empire", ships=["6", "7", "8"])

    data = {
        "Faction": {"1": rebels, "2": empire},
        "Ship": {
            "1": xwing,
            "2": ywing,
            "3": awing,
            "4": falcon,
            "5": homeOne,
            "6": tieFighter,
            "7": tieInterceptor,
            "8": executor,
        },
    }


def create_ship(ship_name, faction_id):
    from .schema import Ship

    next_ship = len(data["Ship"].keys()) + 1
    new_ship = Ship(id=str(next_ship), name=ship_name)
    data["Ship"][new_ship.id] = new_ship
    data["Faction"][faction_id].ships.append(new_ship.id)
    return new_ship


def get_ship(_id):
    return data["Ship"][_id]


def get_faction(_id):
    return data["Faction"][_id]


def get_rebels():
    return get_faction("1")


def get_empire():
    return get_faction("2")


================================================
FILE: examples/starwars_relay/schema.py
================================================
import graphene
from graphene import relay

from .data import create_ship, get_empire, get_faction, get_rebels, get_ship


class Ship(graphene.ObjectType):
    """A ship in the Star Wars saga"""

    class Meta:
        interfaces = (relay.Node,)

    name = graphene.String(description="The name of the ship.")

    @classmethod
    def get_node(cls, info, id):
        return get_ship(id)


class ShipConnection(relay.Connection):
    class Meta:
        node = Ship


class Faction(graphene.ObjectType):
    """A faction in the Star Wars saga"""

    class Meta:
        interfaces = (relay.Node,)

    name = graphene.String(description="The name of the faction.")
    ships = relay.ConnectionField(
        ShipConnection, description="The ships used by the faction."
    )

    def resolve_ships(self, info, **args):
        # Transform the instance ship_ids into real instances
        return [get_ship(ship_id) for ship_id in self.ships]

    @classmethod
    def get_node(cls, info, id):
        return get_faction(id)


class IntroduceShip(relay.ClientIDMutation):
    class Input:
        ship_name = graphene.String(required=True)
        faction_id = graphene.String(required=True)

    ship = graphene.Field(Ship)
    faction = graphene.Field(Faction)

    @classmethod
    def mutate_and_get_payload(
        cls, root, info, ship_name, faction_id, client_mutation_id=None
    ):
        ship = create_ship(ship_name, faction_id)
        faction = get_faction(faction_id)
        return IntroduceShip(ship=ship, faction=faction)


class Query(graphene.ObjectType):
    rebels = graphene.Field(Faction)
    empire = graphene.Field(Faction)
    node = relay.Node.Field()

    def resolve_rebels(root, info):
        return get_rebels()

    def resolve_empire(root, info):
        return get_empire()


class Mutation(graphene.ObjectType):
    introduce_ship = IntroduceShip.Field()


schema = graphene.Schema(query=Query, mutation=Mutation)


================================================
FILE: examples/starwars_relay/tests/__init__.py
================================================


================================================
FILE: examples/starwars_relay/tests/test_connections.py
================================================
from graphene.test import Client

from ..data import setup
from ..schema import schema

setup()

client = Client(schema)


def test_correct_fetch_first_ship_rebels():
    result = client.execute("""
        query RebelsShipsQuery {
          rebels {
            name,
            ships(first: 1) {
              pageInfo {
                startCursor
                endCursor
                hasNextPage
                hasPreviousPage
              }
              edges {
                cursor
                node {
                  name
                }
              }
            }
          }
        }
    """)
    assert result == {
        "data": {
            "rebels": {
                "name": "Alliance to Restore the Republic",
                "ships": {
                    "pageInfo": {
                        "startCursor": "YXJyYXljb25uZWN0aW9uOjA=",
                        "endCursor": "YXJyYXljb25uZWN0aW9uOjA=",
                        "hasNextPage": True,
                        "hasPreviousPage": False,
                    },
                    "edges": [
                        {
                            "cursor": "YXJyYXljb25uZWN0aW9uOjA=",
                            "node": {"name": "X-Wing"},
                        }
                    ],
                },
            }
        }
    }


================================================
FILE: examples/starwars_relay/tests/test_mutation.py
================================================
from graphene.test import Client

from ..data import setup
from ..schema import schema

setup()

client = Client(schema)


def test_mutations():
    result = client.execute("""
        mutation MyMutation {
          introduceShip(input:{clientMutationId:"abc", shipName: "Peter", factionId: "1"}) {
            ship {
              id
              name
            }
            faction {
              name
              ships {
                edges {
                  node {
                    id
                    name
                  }
                }
              }
            }
          }
        }
    """)
    assert result == {
        "data": {
            "introduceShip": {
                "ship": {"id": "U2hpcDo5", "name": "Peter"},
                "faction": {
                    "name": "Alliance to Restore the Republic",
                    "ships": {
                        "edges": [
                            {"node": {"id": "U2hpcDox", "name": "X-Wing"}},
                            {"node": {"id": "U2hpcDoy", "name": "Y-Wing"}},
                            {"node": {"id": "U2hpcDoz", "name": "A-Wing"}},
                            {"node": {"id": "U2hpcDo0", "name": "Millennium Falcon"}},
                            {"node": {"id": "U2hpcDo1", "name": "Home One"}},
                            {"node": {"id": "U2hpcDo5", "name": "Peter"}},
                        ]
                    },
                },
            }
        }
    }


================================================
FILE: examples/starwars_relay/tests/test_objectidentification.py
================================================
import textwrap

from graphene.test import Client

from ..data import setup
from ..schema import schema

setup()

client = Client(schema)


def test_str_schema():
    assert str(schema).strip() == textwrap.dedent(
        '''\
        type Query {
          rebels: Faction
          empire: Faction
          node(
            """The ID of the object"""
            id: ID!
          ): Node
        }

        """A faction in the Star Wars saga"""
        type Faction implements Node {
          """The ID of the object"""
          id: ID!

          """The name of the faction."""
          name: String

          """The ships used by the faction."""
          ships(before: String, after: String, first: Int, last: Int): ShipConnection
        }

        """An object with an ID"""
        interface Node {
          """The ID of the object"""
          id: ID!
        }

        type ShipConnection {
          """Pagination data for this connection."""
          pageInfo: PageInfo!

          """Contains the nodes in this connection."""
          edges: [ShipEdge]!
        }

        """
        The Relay compliant `PageInfo` type, containing data necessary to paginate this connection.
        """
        type PageInfo {
          """When paginating forwards, are there more items?"""
          hasNextPage: Boolean!

          """When paginating backwards, are there more items?"""
          hasPreviousPage: Boolean!

          """When paginating backwards, the cursor to continue."""
          startCursor: String

          """When paginating forwards, the cursor to continue."""
          endCursor: String
        }

        """A Relay edge containing a `Ship` and its cursor."""
        type ShipEdge {
          """The item at the end of the edge"""
          node: Ship

          """A cursor for use in pagination"""
          cursor: String!
        }

        """A ship in the Star Wars saga"""
        type Ship implements Node {
          """The ID of the object"""
          id: ID!

          """The name of the ship."""
          name: String
        }

        type Mutation {
          introduceShip(input: IntroduceShipInput!): IntroduceShipPayload
        }

        type IntroduceShipPayload {
          ship: Ship
          faction: Faction
          clientMutationId: String
        }

        input IntroduceShipInput {
          shipName: String!
          factionId: String!
          clientMutationId: String
        }'''
    )


def test_correctly_fetches_id_name_rebels():
    result = client.execute("""
      query RebelsQuery {
        rebels {
          id
          name
        }
      }
    """)
    assert result == {
        "data": {
            "rebels": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}
        }
    }


def test_correctly_refetches_rebels():
    result = client.execute("""
      query RebelsRefetchQuery {
        node(id: "RmFjdGlvbjox") {
          id
          ... on Faction {
            name
          }
        }
      }
    """)
    assert result == {
        "data": {
            "node": {"id": "RmFjdGlvbjox", "name": "Alliance to Restore the Republic"}
        }
    }


def test_correctly_fetches_id_name_empire():
    result = client.execute("""
      query EmpireQuery {
        empire {
          id
          name
        }
      }
    """)
    assert result == {
        "data": {"empire": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
    }


def test_correctly_refetches_empire():
    result = client.execute("""
      query EmpireRefetchQuery {
        node(id: "RmFjdGlvbjoy") {
          id
          ... on Faction {
            name
          }
        }
      }
    """)
    assert result == {
        "data": {"node": {"id": "RmFjdGlvbjoy", "name": "Galactic Empire"}}
    }


def test_correctly_refetches_xwing():
    result = client.execute("""
      query XWingRefetchQuery {
        node(id: "U2hpcDox") {
          id
          ... on Ship {
            name
          }
        }
      }
    """)
    assert result == {"data": {"node": {"id": "U2hpcDox", "name": "X-Wing"}}}


================================================
FILE: graphene/__init__.py
================================================
from .pyutils.version import get_version
from .relay import (
    BaseGlobalIDType,
    ClientIDMutation,
    Connection,
    ConnectionField,
    DefaultGlobalIDType,
    GlobalID,
    Node,
    PageInfo,
    SimpleGlobalIDType,
    UUIDGlobalIDType,
    is_node,
)
from .types import (
    ID,
    UUID,
    Argument,
    Base64,
    BigInt,
    Boolean,
    Context,
    Date,
    DateTime,
    Decimal,
    Dynamic,
    Enum,
    Field,
    Float,
    InputField,
    InputObjectType,
    Int,
    Interface,
    JSONString,
    List,
    Mutation,
    NonNull,
    ObjectType,
    ResolveInfo,
    Scalar,
    Schema,
    String,
    Time,
    Union,
)
from .utils.module_loading import lazy_import
from .utils.resolve_only_args import resolve_only_args

VERSION = (3, 4, 3, "final", 0)


__version__ = get_version(VERSION)

__all__ = [
    "__version__",
    "Argument",
    "Base64",
    "BigInt",
    "BaseGlobalIDType",
    "Boolean",
    "ClientIDMutation",
    "Connection",
    "ConnectionField",
    "Context",
    "Date",
    "DateTime",
    "Decimal",
    "DefaultGlobalIDType",
    "Dynamic",
    "Enum",
    "Field",
    "Float",
    "GlobalID",
    "ID",
    "InputField",
    "InputObjectType",
    "Int",
    "Interface",
    "JSONString",
    "List",
    "Mutation",
    "Node",
    "NonNull",
    "ObjectType",
    "PageInfo",
    "ResolveInfo",
    "Scalar",
    "Schema",
    "SimpleGlobalIDType",
    "String",
    "Time",
    "Union",
    "UUID",
    "UUIDGlobalIDType",
    "is_node",
    "lazy_import",
    "resolve_only_args",
]


================================================
FILE: graphene/pyutils/__init__.py
================================================


================================================
FILE: graphene/pyutils/version.py
================================================
import datetime
import os
import subprocess


def get_version(version=None):
    "Returns a PEP 440-compliant version number from VERSION."
    version = get_complete_version(version)

    # Now build the two parts of the version number:
    # main = X.Y[.Z]
    # sub = .devN - for pre-alpha releases
    #     | {a|b|rc}N - for alpha, beta, and rc releases

    main = get_main_version(version)

    sub = ""
    if version[3] == "alpha" and version[4] == 0:
        git_changeset = get_git_changeset()
        sub = ".dev%s" % git_changeset if git_changeset else ".dev"
    elif version[3] != "final":
        mapping = {"alpha": "a", "beta": "b", "rc": "rc"}
        sub = mapping[version[3]] + str(version[4])

    return str(main + sub)


def get_main_version(version=None):
    "Returns main version (X.Y[.Z]) from VERSION."
    version = get_complete_version(version)
    parts = 2 if version[2] == 0 else 3
    return ".".join(str(x) for x in version[:parts])


def get_complete_version(version=None):
    """Returns a tuple of the graphene version. If version argument is non-empty,
    then checks for correctness of the tuple provided.
    """
    if version is None:
        from graphene import VERSION as version
    else:
        assert len(version) == 5
        assert version[3] in ("alpha", "beta", "rc", "final")

    return version


def get_docs_version(version=None):
    version = get_complete_version(version)
    if version[3] != "final":
        return "dev"
    else:
        return "%d.%d" % version[:2]


def get_git_changeset():
    """Returns a numeric identifier of the latest git changeset.
    The result is the UTC timestamp of the changeset in YYYYMMDDHHMMSS format.
    This value isn't guaranteed to be unique, but collisions are very unlikely,
    so it's sufficient for generating the development version numbers.
    """
    repo_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    try:
        git_log = subprocess.Popen(
            "git log --pretty=format:%ct --quiet -1 HEAD",
            stdout=subprocess.PIPE,
            stderr=subprocess.PIPE,
            shell=True,
            cwd=repo_dir,
            universal_newlines=True,
        )
        timestamp = git_log.communicate()[0]
        timestamp = datetime.datetime.utcfromtimestamp(int(timestamp))
    except Exception:
        return None
    return timestamp.strftime("%Y%m%d%H%M%S")


================================================
FILE: graphene/relay/__init__.py
================================================
from .node import Node, is_node, GlobalID
from .mutation import ClientIDMutation
from .connection import Connection, ConnectionField, PageInfo
from .id_type import (
    BaseGlobalIDType,
    DefaultGlobalIDType,
    SimpleGlobalIDType,
    UUIDGlobalIDType,
)

__all__ = [
    "BaseGlobalIDType",
    "ClientIDMutation",
    "Connection",
    "ConnectionField",
    "DefaultGlobalIDType",
    "GlobalID",
    "Node",
    "PageInfo",
    "SimpleGlobalIDType",
    "UUIDGlobalIDType",
    "is_node",
]


================================================
FILE: graphene/relay/connection.py
================================================
import re
from collections.abc import Iterable
from functools import partial
from typing import Type

from graphql_relay import connection_from_array

from ..types import Boolean, Enum, Int, Interface, List, NonNull, Scalar, String, Union
from ..types.field import Field
from ..types.objecttype import ObjectType, ObjectTypeOptions
from ..utils.thenables import maybe_thenable
from .node import is_node, AbstractNode


def get_edge_class(
    connection_class: Type["Connection"],
    _node: Type[AbstractNode],
    base_name: str,
    strict_types: bool = False,
):
    edge_class = getattr(connection_class, "Edge", None)

    class EdgeBase:
        node = Field(
            NonNull(_node) if strict_types else _node,
            description="The item at the end of the edge",
        )
        cursor = String(required=True, description="A cursor for use in pagination")

    class EdgeMeta:
        description = f"A Relay edge containing a `{base_name}` and its cursor."

    edge_name = f"{base_name}Edge"

    edge_bases = [edge_class, EdgeBase] if edge_class else [EdgeBase]
    if not isinstance(edge_class, ObjectType):
        edge_bases = [*edge_bases, ObjectType]

    return type(edge_name, tuple(edge_bases), {"Meta": EdgeMeta})


class PageInfo(ObjectType):
    class Meta:
        description = (
            "The Relay compliant `PageInfo` type, containing data necessary to"
            " paginate this connection."
        )

    has_next_page = Boolean(
        required=True,
        name="hasNextPage",
        description="When paginating forwards, are there more items?",
    )

    has_previous_page = Boolean(
        required=True,
        name="hasPreviousPage",
        description="When paginating backwards, are there more items?",
    )

    start_cursor = String(
        name="startCursor",
        description="When paginating backwards, the cursor to continue.",
    )

    end_cursor = String(
        name="endCursor",
        description="When paginating forwards, the cursor to continue.",
    )


# noinspection PyPep8Naming
def page_info_adapter(startCursor, endCursor, hasPreviousPage, hasNextPage):
    """Adapter for creating PageInfo instances"""
    return PageInfo(
        start_cursor=startCursor,
        end_cursor=endCursor,
        has_previous_page=hasPreviousPage,
        has_next_page=hasNextPage,
    )


class ConnectionOptions(ObjectTypeOptions):
    node = None


class Connection(ObjectType):
    class Meta:
        abstract = True

    @classmethod
    def __init_subclass_with_meta__(
        cls, node=None, name=None, strict_types=False, _meta=None, **options
    ):
        if not _meta:
            _meta = ConnectionOptions(cls)
        assert node, f"You have to provide a node in {cls.__name__}.Meta"
        assert isinstance(node, NonNull) or issubclass(
            node, (Scalar, Enum, ObjectType, Interface, Union, NonNull)
        ), f'Received incompatible node "{node}" for Connection {cls.__name__}.'

        base_name = re.sub("Connection$", "", name or cls.__name__) or node._meta.name
        if not name:
            name = f"{base_name}Connection"

        options["name"] = name

        _meta.node = node

        if not _meta.fields:
            _meta.fields = {}

        if "page_info" not in _meta.fields:
            _meta.fields["page_info"] = Field(
                PageInfo,
                name="pageInfo",
                required=True,
                description="Pagination data for this connection.",
            )

        if "edges" not in _meta.fields:
            edge_class = get_edge_class(cls, node, base_name, strict_types)  # type: ignore
            cls.Edge = edge_class
            _meta.fields["edges"] = Field(
                NonNull(List(NonNull(edge_class) if strict_types else edge_class)),
                description="Contains the nodes in this connection.",
            )

        return super(Connection, cls).__init_subclass_with_meta__(
            _meta=_meta, **options
        )


# noinspection PyPep8Naming
def connection_adapter(cls, edges, pageInfo):
    """Adapter for creating Connection instances"""
    return cls(edges=edges, page_info=pageInfo)


class IterableConnectionField(Field):
    def __init__(self, type_, *args, **kwargs):
        kwargs.setdefault("before", String())
        kwargs.setdefault("after", String())
        kwargs.setdefault("first", Int())
        kwargs.setdefault("last", Int())
        super(IterableConnectionField, self).__init__(type_, *args, **kwargs)

    @property
    def type(self):
        type_ = super(IterableConnectionField, self).type
        connection_type = type_
        if isinstance(type_, NonNull):
            connection_type = type_.of_type

        if is_node(connection_type):
            raise Exception(
                "ConnectionFields now need a explicit ConnectionType for Nodes.\n"
                "Read more: https://github.com/graphql-python/graphene/blob/v2.0.0/UPGRADE-v2.0.md#node-connections"
            )

        assert issubclass(
            connection_type, Connection
        ), f'{self.__class__.__name__} type has to be a subclass of Connection. Received "{connection_type}".'
        return type_

    @classmethod
    def resolve_connection(cls, connection_type, args, resolved):
        if isinstance(resolved, connection_type):
            return resolved

        assert isinstance(resolved, Iterable), (
            f"Resolved value from the connection field has to be an iterable or instance of {connection_type}. "
            f'Received "{resolved}"'
        )
        connection = connection_from_array(
            resolved,
            args,
            connection_type=partial(connection_adapter, connection_type),
            edge_type=connection_type.Edge,
            page_info_type=page_info_adapter,
        )
        connection.iterable = resolved
        return connection

    @classmethod
    def connection_resolver(cls, resolver, connection_type, root, info, **args):
        resolved = resolver(root, info, **args)

        if isinstance(connection_type, NonNull):
            connection_type = connection_type.of_type

        on_resolve = partial(cls.resolve_connection, connection_type, args)
        return maybe_thenable(resolved, on_resolve)

    def wrap_resolve(self, parent_resolver):
        resolver = super(IterableConnectionField, self).wrap_resolve(parent_resolver)
        return partial(self.connection_resolver, resolver, self.type)


ConnectionField = IterableConnectionField


================================================
FILE: graphene/relay/id_type.py
================================================
from graphql_relay import from_global_id, to_global_id

from ..types import ID, UUID
from ..types.base import BaseType

from typing import Type


class BaseGlobalIDType:
    """
    Base class that define the required attributes/method for a type.
    """

    graphene_type: Type[BaseType] = ID

    @classmethod
    def resolve_global_id(cls, info, global_id):
        # return _type, _id
        raise NotImplementedError

    @classmethod
    def to_global_id(cls, _type, _id):
        # return _id
        raise NotImplementedError


class DefaultGlobalIDType(BaseGlobalIDType):
    """
    Default global ID type: base64 encoded version of "<node type name>: <node id>".
    """

    graphene_type = ID

    @classmethod
    def resolve_global_id(cls, info, global_id):
        try:
            _type, _id = from_global_id(global_id)
            if not _type:
                raise ValueError("Invalid Global ID")
            return _type, _id
        except Exception as e:
            raise Exception(
                f'Unable to parse global ID "{global_id}". '
                'Make sure it is a base64 encoded string in the format: "TypeName:id". '
                f"Exception message: {e}"
            )

    @classmethod
    def to_global_id(cls, _type, _id):
        return to_global_id(_type, _id)


class SimpleGlobalIDType(BaseGlobalIDType):
    """
    Simple global ID type: simply the id of the object.
    To be used carefully as the user is responsible for ensuring that the IDs are indeed global
    (otherwise it could cause request caching issues).
    """

    graphene_type = ID

    @classmethod
    def resolve_global_id(cls, info, global_id):
        _type = info.return_type.graphene_type._meta.name
        return _type, global_id

    @classmethod
    def to_global_id(cls, _type, _id):
        return _id


class UUIDGlobalIDType(BaseGlobalIDType):
    """
    UUID global ID type.
    By definition UUID are global so they are used as they are.
    """

    graphene_type = UUID

    @classmethod
    def resolve_global_id(cls, info, global_id):
        _type = info.return_type.graphene_type._meta.name
        return _type, global_id

    @classmethod
    def to_global_id(cls, _type, _id):
        return _id


================================================
FILE: graphene/relay/mutation.py
================================================
import re

from ..types import Field, InputObjectType, String
from ..types.mutation import Mutation
from ..utils.thenables import maybe_thenable


class ClientIDMutation(Mutation):
    class Meta:
        abstract = True

    @classmethod
    def __init_subclass_with_meta__(
        cls, output=None, input_fields=None, arguments=None, name=None, **options
    ):
        input_class = getattr(cls, "Input", None)
        base_name = re.sub("Payload$", "", name or cls.__name__)

        assert not output, "Can't specify any output"
        assert not arguments, "Can't specify any arguments"

        bases = (InputObjectType,)
        if input_class:
            bases += (input_class,)

        if not input_fields:
            input_fields = {}

        cls.Input = type(
            f"{base_name}Input",
            bases,
            dict(input_fields, client_mutation_id=String(name="clientMutationId")),
        )

        arguments = dict(
            input=cls.Input(required=True)
            # 'client_mutation_id': String(name='clientMutationId')
        )
        mutate_and_get_payload = getattr(cls, "mutate_and_get_payload", None)
        if cls.mutate and cls.mutate.__func__ == ClientIDMutation.mutate.__func__:
            assert mutate_and_get_payload, (
                f"{name or cls.__name__}.mutate_and_get_payload method is required"
                " in a ClientIDMutation."
            )

        if not name:
            name = f"{base_name}Payload"

        super(ClientIDMutation, cls).__init_subclass_with_meta__(
            output=None, arguments=arguments, name=name, **options
        )
        cls._meta.fields["client_mutation_id"] = Field(String, name="clientMutationId")

    @classmethod
    def mutate(cls, root, info, input):
        def on_resolve(payload):
            try:
                payload.client_mutation_id = input.get("client_mutation_id")
            except Exception:
                raise Exception(
                    f"Cannot set client_mutation_id in the payload object {repr(payload)}"
                )
            return payload

        result = cls.mutate_and_get_payload(root, info, **input)
        return maybe_thenable(result, on_resolve)


================================================
FILE: graphene/relay/node.py
================================================
from functools import partial
from inspect import isclass

from ..types import Field, Interface, ObjectType
from ..types.interface import InterfaceOptions
from ..types.utils import get_type
from .id_type import BaseGlobalIDType, DefaultGlobalIDType


def is_node(objecttype):
    """
    Check if the given objecttype has Node as an interface
    """
    if not isclass(objecttype):
        return False

    if not issubclass(objecttype, ObjectType):
        return False

    return any(issubclass(i, Node) for i in objecttype._meta.interfaces)


class GlobalID(Field):
    def __init__(
        self,
        node=None,
        parent_type=None,
        required=True,
        global_id_type=DefaultGlobalIDType,
        *args,
        **kwargs,
    ):
        super(GlobalID, self).__init__(
            global_id_type.graphene_type, required=required, *args, **kwargs
        )
        self.node = node or Node
        self.parent_type_name = parent_type._meta.name if parent_type else None

    @staticmethod
    def id_resolver(parent_resolver, node, root, info, parent_type_name=None, **args):
        type_id = parent_resolver(root, info, **args)
        parent_type_name = parent_type_name or info.parent_type.name
        return node.to_global_id(parent_type_name, type_id)  # root._meta.name

    def wrap_resolve(self, parent_resolver):
        return partial(
            self.id_resolver,
            parent_resolver,
            self.node,
            parent_type_name=self.parent_type_name,
        )


class NodeField(Field):
    def __init__(self, node, type_=False, **kwargs):
        assert issubclass(node, Node), "NodeField can only operate in Nodes"
        self.node_type = node
        self.field_type = type_
        global_id_type = node._meta.global_id_type

        super(NodeField, self).__init__(
            # If we don't specify a type, the field type will be the node interface
            type_ or node,
            id=global_id_type.graphene_type(
                required=True, description="The ID of the object"
            ),
            **kwargs,
        )

    def wrap_resolve(self, parent_resolver):
        return partial(self.node_type.node_resolver, get_type(self.field_type))


class AbstractNode(Interface):
    class Meta:
        abstract = True

    @classmethod
    def __init_subclass_with_meta__(cls, global_id_type=DefaultGlobalIDType, **options):
        assert issubclass(
            global_id_type, BaseGlobalIDType
        ), "Custom ID type need to be implemented as a subclass of BaseGlobalIDType."
        _meta = InterfaceOptions(cls)
        _meta.global_id_type = global_id_type
        _meta.fields = {
            "id": GlobalID(
                cls, global_id_type=global_id_type, description="The ID of the object"
            )
        }
        super(AbstractNode, cls).__init_subclass_with_meta__(_meta=_meta, **options)

    @classmethod
    def resolve_global_id(cls, info, global_id):
        return cls._meta.global_id_type.resolve_global_id(info, global_id)


class Node(AbstractNode):
    """An object with an ID"""

    @classmethod
    def Field(cls, *args, **kwargs):  # noqa: N802
        return NodeField(cls, *args, **kwargs)

    @classmethod
    def node_resolver(cls, only_type, root, info, id):
        return cls.get_node_from_global_id(info, id, only_type=only_type)

    @classmethod
    def get_node_from_global_id(cls, info, global_id, only_type=None):
        _type, _id = cls.resolve_global_id(info, global_id)

        graphene_type = info.schema.get_type(_type)
        if graphene_type is None:
            raise Exception(f'Relay Node "{_type}" not found in schema')

        graphene_type = graphene_type.graphene_type

        if only_type:
            assert (
                graphene_type == only_type
            ), f"Must receive a {only_type._meta.name} id."

        # We make sure the ObjectType implements the "Node" interface
        if cls not in graphene_type._meta.interfaces:
            raise Exception(
                f'ObjectType "{_type}" does not implement the "{cls}" interface.'
            )

        get_node = getattr(graphene_type, "get_node", None)
        if get_node:
            return get_node(info, _id)

    @classmethod
    def to_global_id(cls, type_, id):
        return cls._meta.global_id_type.to_global_id(type_, id)


================================================
FILE: graphene/relay/tests/__init__.py
================================================


================================================
FILE: graphene/relay/tests/test_connection.py
================================================
import re

from pytest import raises

from ...types import Argument, Field, Int, List, NonNull, ObjectType, Schema, String
from ..connection import (
    Connection,
    ConnectionField,
    PageInfo,
    ConnectionOptions,
    get_edge_class,
)
from ..node import Node


class MyObject(ObjectType):
    class Meta:
        interfaces = [Node]

    field = String()


def test_connection():
    class MyObjectConnection(Connection):
        extra = String()

        class Meta:
            node = MyObject

        class Edge:
            other = String()

    assert MyObjectConnection._meta.name == "MyObjectConnection"
    fields = MyObjectConnection._meta.fields
    assert list(fields) == ["page_info", "edges", "extra"]
    edge_field = fields["edges"]
    pageinfo_field = fields["page_info"]

    assert isinstance(edge_field, Field)
    assert isinstance(edge_field.type, NonNull)
    assert isinstance(edge_field.type.of_type, List)
    assert edge_field.type.of_type.of_type == MyObjectConnection.Edge

    assert isinstance(pageinfo_field, Field)
    assert isinstance(pageinfo_field.type, NonNull)
    assert pageinfo_field.type.of_type == PageInfo


def test_connection_inherit_abstracttype():
    class BaseConnection:
        extra = String()

    class MyObjectConnection(BaseConnection, Connection):
        class Meta:
            node = MyObject

    assert MyObjectConnection._meta.name == "MyObjectConnection"
    fields = MyObjectConnection._meta.fields
    assert list(fields) == ["page_info", "edges", "extra"]


def test_connection_extra_abstract_fields():
    class ConnectionWithNodes(Connection):
        class Meta:
            abstract = True

        @classmethod
        def __init_subclass_with_meta__(cls, node=None, name=None, **options):
            _meta = ConnectionOptions(cls)

            _meta.fields = {
                "nodes": Field(
                    NonNull(List(node)),
                    description="Contains all the nodes in this connection.",
                ),
            }

            return super(ConnectionWithNodes, cls).__init_subclass_with_meta__(
                node=node, name=name, _meta=_meta, **options
            )

    class MyObjectConnection(ConnectionWithNodes):
        class Meta:
            node = MyObject

        class Edge:
            other = String()

    assert MyObjectConnection._meta.name == "MyObjectConnection"
    fields = MyObjectConnection._meta.fields
    assert list(fields) == ["nodes", "page_info", "edges"]
    edge_field = fields["edges"]
    pageinfo_field = fields["page_info"]
    nodes_field = fields["nodes"]

    assert isinstance(edge_field, Field)
    assert isinstance(edge_field.type, NonNull)
    assert isinstance(edge_field.type.of_type, List)
    assert edge_field.type.of_type.of_type == MyObjectConnection.Edge

    assert isinstance(pageinfo_field, Field)
    assert isinstance(pageinfo_field.type, NonNull)
    assert pageinfo_field.type.of_type == PageInfo

    assert isinstance(nodes_field, Field)
    assert isinstance(nodes_field.type, NonNull)
    assert isinstance(nodes_field.type.of_type, List)
    assert nodes_field.type.of_type.of_type == MyObject


def test_connection_override_fields():
    class ConnectionWithNodes(Connection):
        class Meta:
            abstract = True

        @classmethod
        def __init_subclass_with_meta__(cls, node=None, name=None, **options):
            _meta = ConnectionOptions(cls)
            base_name = (
                re.sub("Connection$", "", name or cls.__name__) or node._meta.name
            )

            edge_class = get_edge_class(cls, node, base_name)

            _meta.fields = {
                "page_info": Field(
                    NonNull(
                        PageInfo,
                        name="pageInfo",
                        required=True,
                        description="Pagination data for this connection.",
                    )
                ),
                "edges": Field(
                    NonNull(List(NonNull(edge_class))),
                    description="Contains the nodes in this connection.",
                ),
            }

            return super(ConnectionWithNodes, cls).__init_subclass_with_meta__(
                node=node, name=name, _meta=_meta, **options
            )

    class MyObjectConnection(ConnectionWithNodes):
        class Meta:
            node = MyObject

    assert MyObjectConnection._meta.name == "MyObjectConnection"
    fields = MyObjectConnection._meta.fields
    assert list(fields) == ["page_info", "edges"]
    edge_field = fields["edges"]
    pageinfo_field = fields["page_info"]

    assert isinstance(edge_field, Field)
    assert isinstance(edge_field.type, NonNull)
    assert isinstance(edge_field.type.of_type, List)
    assert isinstance(edge_field.type.of_type.of_type, NonNull)

    assert edge_field.type.of_type.of_type.of_type.__name__ == "MyObjectEdge"

    # This page info is NonNull
    assert isinstance(pageinfo_field, Field)
    assert isinstance(edge_field.type, NonNull)
    assert pageinfo_field.type.of_type == PageInfo


def test_connection_name():
    custom_name = "MyObjectCustomNameConnection"

    class BaseConnection:
        extra = String()

    class MyObjectConnection(BaseConnection, Connection):
        class Meta:
            node = MyObject
            name = custom_name

    assert MyObjectConnection._meta.name == custom_name


def test_edge():
    class MyObjectConnection(Connection):
        class Meta:
            node = MyObject

        class Edge:
            other = String()

    Edge = MyObjectConnection.Edge
    assert Edge._meta.name == "MyObjectEdge"
    edge_fields = Edge._meta.fields
    assert list(edge_fields) == ["node", "cursor", "other"]

    assert isinstance(edge_fields["node"], Field)
    assert edge_fields["node"].type == MyObject

    assert isinstance(edge_fields["other"], Field)
    assert edge_fields["other"].type == String


def test_edge_with_bases():
    class BaseEdge:
        extra = String()

    class MyObjectConnection(Connection):
        class Meta:
            node = MyObject

        class Edge(BaseEdge):
            other = String()

    Edge = MyObjectConnection.Edge
    assert Edge._meta.name == "MyObjectEdge"
    edge_fields = Edge._meta.fields
    assert list(edge_fields) == ["node", "cursor", "extra", "other"]

    assert isinstance(edge_fields["node"], Field)
    assert edge_fields["node"].type == MyObject

    assert isinstance(edge_fields["other"], Field)
    assert edge_fields["other"].type == String


def test_edge_with_nonnull_node():
    class MyObjectConnection(Connection):
        class Meta:
            node = NonNull(MyObject)

    edge_fields = MyObjectConnection.Edge._meta.fields
    assert isinstance(edge_fields["node"], Field)
    assert isinstance(edge_fields["node"].type, NonNull)
    assert edge_fields["node"].type.of_type == MyObject


def test_pageinfo():
    assert PageInfo._meta.name == "PageInfo"
    fields = PageInfo._meta.fields
    assert list(fields) == [
        "has_next_page",
        "has_previous_page",
        "start_cursor",
        "end_cursor",
    ]


def test_connectionfield():
    class MyObjectConnection(Connection):
        class Meta:
            node = MyObject

    field = ConnectionField(MyObjectConnection)
    assert field.args == {
        "before": Argument(String),
        "after": Argument(String),
        "first": Argument(Int),
        "last": Argument(Int),
    }


def test_connectionfield_node_deprecated():
    field = ConnectionField(MyObject)
    with raises(Exception) as exc_info:
        field.type

    assert "ConnectionFields now need a explicit ConnectionType for Nodes." in str(
        exc_info.value
    )


def test_connectionfield_custom_args():
    class MyObjectConnection(Connection):
        class Meta:
            node = MyObject

    field = ConnectionField(
        MyObjectConnection, before=String(required=True), extra=String()
    )
    assert field.args == {
        "before": Argument(NonNull(String)),
        "after": Argument(String),
        "first": Argument(Int),
        "last": Argument(Int),
        "extra": Argument(String),
    }


def test_connectionfield_required():
    class MyObjectConnection(Connection):
        class Meta:
            node = MyObject

    class Query(ObjectType):
        test_connection = ConnectionField(MyObjectConnection, required=True)

        def resolve_test_connection(root, info, **args):
            return []

    schema = Schema(query=Query)
    executed = schema.execute("{ testConnection { edges { cursor } } }")
    assert not executed.errors
    assert executed.data == {"testConnection": {"edges": []}}


def test_connectionfield_strict_types():
    class MyObjectConnection(Connection):
        class Meta:
            node = MyObject
            strict_types = True

    connection_field = ConnectionField(MyObjectConnection)
    edges_field_type = connection_field.type._meta.fields["edges"].type
    assert isinstance(edges_field_type, NonNull)

    edges_list_element_type = edges_field_type.of_type.of_type
    assert isinstance(edges_list_element_type, NonNull)

    node_field = edges_list_element_type.of_type._meta.fields["node"]
    assert isinstance(node_field.type, NonNull)


================================================
FILE: graphene/relay/tests/test_connection_async.py
================================================
from pytest import mark

from graphql_relay.utils import base64

from graphene.types import ObjectType, Schema, String
from graphene.relay.connection import Connection, ConnectionField, PageInfo
from graphene.relay.node import Node

letter_chars = ["A", "B", "C", "D", "E"]


class Letter(ObjectType):
    class Meta:
        interfaces = (Node,)

    letter = String()


class LetterConnection(Connection):
    class Meta:
        node = Letter


class Query(ObjectType):
    letters = ConnectionField(LetterConnection)
    connection_letters = ConnectionField(LetterConnection)
    async_letters = ConnectionField(LetterConnection)

    node = Node.Field()

    def resolve_letters(self, info, **args):
        return list(letters.values())

    async def resolve_async_letters(self, info, **args):
        return list(letters.values())

    def resolve_connection_letters(self, info, **args):
        return LetterConnection(
            page_info=PageInfo(has_next_page=True, has_previous_page=False),
            edges=[
                LetterConnection.Edge(node=Letter(id=0, letter="A"), cursor="a-cursor")
            ],
        )


schema = Schema(Query)

letters = {letter: Letter(id=i, letter=letter) for i, letter in enumerate(letter_chars)}


def edges(selected_letters):
    return [
        {
            "node": {"id": base64("Letter:%s" % letter.id), "letter": letter.letter},
            "cursor": base64("arrayconnection:%s" % letter.id),
        }
        for letter in [letters[i] for i in selected_letters]
    ]


def cursor_for(ltr):
    letter = letters[ltr]
    return base64("arrayconnection:%s" % letter.id)


def execute(args=""):
    if args:
        args = "(" + args + ")"

    return schema.execute(
        """
    {
        letters%s {
            edges {
                node {
                    id
                    letter
                }
                cursor
            }
            pageInfo {
                hasPreviousPage
                hasNextPage
                startCursor
                endCursor
            }
        }
    }
    """
        % args
    )


@mark.asyncio
async def test_connection_async():
    result = await schema.execute_async(
        """
    {
        asyncLetters(first:1) {
            edges {
                node {
                    id
                    letter
                }
            }
            pageInfo {
                hasPreviousPage
                hasNextPage
            }
        }
    }
    """
    )

    assert not result.errors
    assert result.data == {
        "asyncLetters": {
            "edges": [{"node": {"id": "TGV0dGVyOjA=", "letter": "A"}}],
            "pageInfo": {"hasPreviousPage": False, "hasNextPage": True},
        }
    }


================================================
FILE: graphene/relay/tests/test_connection_query.py
================================================
from pytest import mark

from graphql_relay.utils import base64

from ...types import ObjectType, Schema, String
from ..connection import Connection, ConnectionField, PageInfo
from ..node import Node

letter_chars = ["A", "B", "C", "D", "E"]


class Letter(ObjectType):
    class Meta:
        interfaces = (Node,)

    letter = String()


class LetterConnection(Connection):
    class Meta:
        node = Letter


class Query(ObjectType):
    letters = ConnectionField(LetterConnection)
    connection_letters = ConnectionField(LetterConnection)
    async_letters = ConnectionField(LetterConnection)

    node = Node.Field()

    def resolve_letters(self, info, **args):
        return list(letters.values())

    async def resolve_async_letters(self, info, **args):
        return list(letters.values())

    def resolve_connection_letters(self, info, **args):
        return LetterConnection(
            page_info=PageInfo(has_next_page=True, has_previous_page=False),
            edges=[
                LetterConnection.Edge(node=Letter(id=0, letter="A"), cursor="a-cursor")
            ],
        )


schema = Schema(Query)

letters = {letter: Letter(id=i, letter=letter) for i, letter in enumerate(letter_chars)}


def edges(selected_letters):
    return [
        {
            "node": {"id": base64("Letter:%s" % letter.id), "letter": letter.letter},
            "cursor": base64("arrayconnection:%s" % letter.id),
        }
        for letter in [letters[i] for i in selected_letters]
    ]


def cursor_for(ltr):
    letter = letters[ltr]
    return base64("arrayconnection:%s" % letter.id)


async def execute(args=""):
    if args:
        args = "(" + args + ")"
    return await schema.execute_async(
        """
    {
        letters%s {
            edges {
                node {
                    id
                    letter
                }
                cursor
            }
            pageInfo {
                hasPreviousPage
                hasNextPage
                startCursor
                endCursor
            }
        }
    }
    """
        % args
    )


async def check(args, letters, has_previous_page=False, has_next_page=False):
    result = await execute(args)
    expected_edges = edges(letters)
    expected_page_info = {
        "hasPreviousPage": has_previous_page,
        "hasNextPage": has_next_page,
        "endCursor": expected_edges[-1]["cursor"] if expected_edges else None,
        "startCursor": expected_edges[0]["cursor"] if expected_edges else None,
    }

    assert not result.errors
    assert result.data == {
        "letters": {"edges": expected_edges, "pageInfo": expected_page_info}
    }


@mark.asyncio
async def test_returns_all_elements_without_filters():
    await check("", "ABCDE")


@mark.asyncio
async def test_respects_a_smaller_first():
    await check("first: 2", "AB", has_next_page=True)


@mark.asyncio
async def test_respects_an_overly_large_first():
    await check("first: 10", "ABCDE")


@mark.asyncio
async def test_respects_a_smaller_last():
    await check("last: 2", "DE", has_previous_page=True)


@mark.asyncio
async def test_respects_an_overly_large_last():
    await check("last: 10", "ABCDE")


@mark.asyncio
async def test_respects_first_and_after():
    await check(f'first: 2, after: "{cursor_for("B")}"', "CD", has_next_page=True)


@mark.asyncio
async def test_respects_first_and_after_with_long_first():
    await check(f'first: 10, after: "{cursor_for("B")}"', "CDE")


@mark.asyncio
async def test_respects_last_and_before():
    await check(f'last: 2, before: "{cursor_for("D")}"', "BC", has_previous_page=True)


@mark.asyncio
async def test_respects_last_and_before_with_long_last():
    await check(f'last: 10, before: "{cursor_for("D")}"', "ABC")


@mark.asyncio
async def test_respects_first_and_after_and_before_too_few():
    await check(
        f'first: 2, after: "{cursor_for("A")}", before: "{cursor_for("E")}"',
        "BC",
        has_next_page=True,
    )


@mark.asyncio
async def test_respects_first_and_after_and_before_too_many():
    await check(
        f'first: 4, after: "{cursor_for("A")}", before: "{cursor_for("E")}"', "BCD"
    )


@mark.asyncio
async def test_respects_first_and_after_and_before_exactly_right():
    await check(
        f'first: 3, after: "{cursor_for("A")}", before: "{cursor_for("E")}"', "BCD"
    )


@mark.asyncio
async def test_respects_last_and_after_and_before_too_few():
    await check(
        f'last: 2, after: "{cursor_for("A")}", before: "{cursor_for("E")}"',
        "CD",
        has_previous_page=True,
    )


@mark.asyncio
async def test_respects_last_and_after_and_before_too_many():
    await check(
        f'last: 4, after: "{cursor_for("A")}", before: "{cursor_for("E")}"', "BCD"
    )


@mark.asyncio
async def test_respects_last_and_after_and_before_exactly_right():
    await check(
        f'last: 3, after: "{cursor_for("A")}", before: "{cursor_for("E")}"', "BCD"
    )


@mark.asyncio
async def test_returns_no_elements_if_first_is_0():
    await check("first: 0", "", has_next_page=True)


@mark.asyncio
async def test_returns_all_elements_if_cursors_are_invalid():
    await check('before: "invalid" after: "invalid"', "ABCDE")


@mark.asyncio
async def test_returns_all_elements_if_cursors_are_on_the_outside():
    await check(
        f'before: "{base64("arrayconnection:%s" % 6)}" after: "{base64("arrayconnection:%s" % -1)}"',
        "ABCDE",
    )


@mark.asyncio
async def test_returns_no_elements_if_cursors_cross():
    await check(
        f'before: "{base64("arrayconnection:%s" % 2)}" after: "{base64("arrayconnection:%s" % 4)}"',
        "",
    )


@mark.asyncio
async def test_connection_type_nodes():
    result = await schema.execute_async(
        """
    {
        connectionLetters {
            edges {
                node {
                    id
                    letter
                }
                cursor
            }
            pageInfo {
                hasPreviousPage
                hasNextPage
            }
        }
    }
    """
    )

    assert not result.errors
    assert result.data == {
        "connectionLetters": {
            "edges": [
                {"node": {"id": "TGV0dGVyOjA=", "letter": "A"}, "cursor": "a-cursor"}
            ],
            "pageInfo": {"hasPreviousPage": False, "hasNextPage": True},
        }
    }


@mark.asyncio
async def test_connection_async():
    result = await schema.execute_async(
        """
    {
        asyncLetters(first:1) {
            edges {
                node {
                    id
                    letter
                }
            }
            pageInfo {
                hasPreviousPage
                hasNextPage
            }
        }
    }
    """
    )

    assert not result.errors
    assert result.data == {
        "asyncLetters": {
            "edges": [{"node": {"id": "TGV0dGVyOjA=", "letter": "A"}}],
            "pageInfo": {"hasPreviousPage": False, "hasNextPage": True},
        }
    }


================================================
FILE: graphene/relay/tests/test_custom_global_id.py
================================================
import re
from uuid import uuid4

from graphql import graphql_sync

from ..id_type import BaseGlobalIDType, SimpleGlobalIDType, UUIDGlobalIDType
from ..node import Node
from ...types import Int, ObjectType, Schema, String


class TestUUIDGlobalID:
    def setup_method(self):
        self.user_list = [
            {"id": uuid4(), "name": "First"},
            {"id": uuid4(), "name": "Second"},
            {"id": uuid4(), "name": "Third"},
            {"id": uuid4(), "name": "Fourth"},
        ]
        self.users = {user["id"]: user for user in self.user_list}

        class CustomNode(Node):
            class Meta:
                global_id_type = UUIDGlobalIDType

        class User(ObjectType):
            class Meta:
                interfaces = [CustomNode]

            name = String()

            @classmethod
            def get_node(cls, _type, _id):
                return self.users[_id]

        class RootQuery(ObjectType):
            user = CustomNode.Field(User)

        self.schema = Schema(query=RootQuery, types=[User])
        self.graphql_schema = self.schema.graphql_schema

    def test_str_schema_correct(self):
        """
        Check that the schema has the expected and custom node interface and user type and that they both use UUIDs
        """
        parsed = re.findall(r"(.+) \{\n\s*([\w\W]*?)\n\}", str(self.schema))
        types = [t for t, f in parsed]
        fields = [f for t, f in parsed]
        custom_node_interface = "interface CustomNode"
        assert custom_node_interface in types
        assert (
            '"""The ID of the object"""\n  id: UUID!'
            == fields[types.index(custom_node_interface)]
        )
        user_type = "type User implements CustomNode"
        assert user_type in types
        assert (
            '"""The ID of the object"""\n  id: UUID!\n  name: String'
            == fields[types.index(user_type)]
        )

    def test_get_by_id(self):
        query = """query userById($id: UUID!) {
            user(id: $id) {
                id
                name
            }
        }"""
        # UUID need to be converted to string for serialization
        result = graphql_sync(
            self.graphql_schema,
            query,
            variable_values={"id": str(self.user_list[0]["id"])},
        )
        assert not result.errors
        assert result.data["user"]["id"] == str(self.user_list[0]["id"])
        assert result.data["user"]["name"] == self.user_list[0]["name"]


class TestSimpleGlobalID:
    def setup_method(self):
        self.user_list = [
            {"id": "my global primary key in clear 1", "name": "First"},
            {"id": "my global primary key in clear 2", "name": "Second"},
            {"id": "my global primary key in clear 3", "name": "Third"},
            {"id": "my global primary key in clear 4", "name": "Fourth"},
        ]
        self.users = {user["id"]: user for user in self.user_list}

        class CustomNode(Node):
            class Meta:
                global_id_type = SimpleGlobalIDType

        class User(ObjectType):
            class Meta:
                interfaces = [CustomNode]

            name = String()

            @classmethod
            def get_node(cls, _type, _id):
                return self.users[_id]

        class RootQuery(ObjectType):
            user = CustomNode.Field(User)

        self.schema = Schema(query=RootQuery, types=[User])
        self.graphql_schema = self.schema.graphql_schema

    def test_str_schema_correct(self):
        """
        Check that the schema has the expected and custom node interface and user type and that they both use UUIDs
        """
        parsed = re.findall(r"(.+) \{\n\s*([\w\W]*?)\n\}", str(self.schema))
        types = [t for t, f in parsed]
        fields = [f for t, f in parsed]
        custom_node_interface = "interface CustomNode"
        assert custom_node_interface in types
        assert (
            '"""The ID of the object"""\n  id: ID!'
            == fields[types.index(custom_node_interface)]
        )
        user_type = "type User implements CustomNode"
        assert user_type in types
        assert (
            '"""The ID of the object"""\n  id: ID!\n  name: String'
            == fields[types.index(user_type)]
        )

    def test_get_by_id(self):
        query = """query {
            user(id: "my global primary key in clear 3") {
                id
                name
            }
        }"""
        result = graphql_sync(self.graphql_schema, query)
        assert not result.errors
        assert result.data["user"]["id"] == self.user_list[2]["id"]
        assert result.data["user"]["name"] == self.user_list[2]["name"]


class TestCustomGlobalID:
    def setup_method(self):
        self.user_list = [
            {"id": 1, "name": "First"},
            {"id": 2, "name": "Second"},
            {"id": 3, "name": "Third"},
            {"id": 4, "name": "Fourth"},
        ]
        self.users = {user["id"]: user for user in self.user_list}

        class CustomGlobalIDType(BaseGlobalIDType):
            """
            Global id that is simply and integer in clear.
            """

            graphene_type = Int

            @classmethod
            def resolve_global_id(cls, info, global_id):
                _type = info.return_type.graphene_type._meta.name
                return _type, global_id

            @classmethod
            def to_global_id(cls, _type, _id):
                return _id

        class CustomNode(Node):
            class Meta:
                global_id_type = CustomGlobalIDType

        class User(ObjectType):
            class Meta:
                interfaces = [CustomNode]

            name = String()

            @classmethod
            def get_node(cls, _type, _id):
                return self.users[_id]

        class RootQuery(ObjectType):
            user = CustomNode.Field(User)

        self.schema = Schema(query=RootQuery, types=[User])
        self.graphql_schema = self.schema.graphql_schema

    def test_str_schema_correct(self):
        """
        Check that the schema has the expected and custom node interface and user type and that they both use UUIDs
        """
        parsed = re.findall(r"(.+) \{\n\s*([\w\W]*?)\n\}", str(self.schema))
        types = [t for t, f in parsed]
        fields = [f for t, f in parsed]
        custom_node_interface = "interface CustomNode"
        assert custom_node_interface in types
        assert (
            '"""The ID of the object"""\n  id: Int!'
            == fields[types.index(custom_node_interface)]
        )
        user_type = "type User implements CustomNode"
        assert user_type in types
        assert (
            '"""The ID of the object"""\n  id: Int!\n  name: String'
            == fields[types.index(user_type)]
        )

    def test_get_by_id(self):
        query = """query {
            user(id: 2) {
                id
                name
            }
        }"""
        result = graphql_sync(self.graphql_schema, query)
        assert not result.errors
        assert result.data["user"]["id"] == self.user_list[1]["id"]
        assert result.data["user"]["name"] == self.user_list[1]["name"]


class TestIncompleteCustomGlobalID:
    def setup_method(self):
        self.user_list = [
            {"id": 1, "name": "First"},
            {"id": 2, "name": "Second"},
            {"id": 3, "name": "Third"},
            {"id": 4, "name": "Fourth"},
        ]
        self.users = {user["id"]: user for user in self.user_list}

    def test_must_define_to_global_id(self):
        """
        Test that if the `to_global_id` method is not defined, we can query the object, but we can't request its ID.
        """

        class CustomGlobalIDType(BaseGlobalIDType):
            graphene_type = Int

            @classmethod
            def resolve_global_id(cls, info, global_id):
                _type = info.return_type.graphene_type._meta.name
                return _type, global_id

        class CustomNode(Node):
            class Meta:
                global_id_
Download .txt
gitextract_dd7rqbyb/

├── .coveragerc
├── .editorconfig
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.md
│   │   ├── config.yml
│   │   └── feature_request.md
│   ├── stale.yml
│   └── workflows/
│       ├── build.yaml
│       ├── deploy.yml
│       ├── lint.yml
│       └── tests.yml
├── .gitignore
├── .pre-commit-config.yaml
├── LICENSE
├── MANIFEST.in
├── Makefile
├── README.md
├── SECURITY.md
├── UPGRADE-v1.0.md
├── UPGRADE-v2.0.md
├── bin/
│   └── convert_documentation
├── docs/
│   ├── Makefile
│   ├── _static/
│   │   └── .gitkeep
│   ├── api/
│   │   └── index.rst
│   ├── conf.py
│   ├── execution/
│   │   ├── dataloader.rst
│   │   ├── execute.rst
│   │   ├── fileuploading.rst
│   │   ├── index.rst
│   │   ├── middleware.rst
│   │   ├── queryvalidation.rst
│   │   └── subscriptions.rst
│   ├── index.rst
│   ├── quickstart.rst
│   ├── relay/
│   │   ├── connection.rst
│   │   ├── index.rst
│   │   ├── mutations.rst
│   │   └── nodes.rst
│   ├── requirements.txt
│   ├── testing/
│   │   └── index.rst
│   └── types/
│       ├── enums.rst
│       ├── index.rst
│       ├── interfaces.rst
│       ├── list-and-nonnull.rst
│       ├── mutations.rst
│       ├── objecttypes.rst
│       ├── scalars.rst
│       ├── schema.rst
│       └── unions.rst
├── examples/
│   ├── __init__.py
│   ├── complex_example.py
│   ├── context_example.py
│   ├── simple_example.py
│   ├── starwars/
│   │   ├── __init__.py
│   │   ├── data.py
│   │   ├── schema.py
│   │   └── tests/
│   │       ├── __init__.py
│   │       ├── test_query.py
│   │       └── test_schema.py
│   └── starwars_relay/
│       ├── __init__.py
│       ├── data.py
│       ├── schema.py
│       └── tests/
│           ├── __init__.py
│           ├── test_connections.py
│           ├── test_mutation.py
│           └── test_objectidentification.py
├── graphene/
│   ├── __init__.py
│   ├── pyutils/
│   │   ├── __init__.py
│   │   └── version.py
│   ├── relay/
│   │   ├── __init__.py
│   │   ├── connection.py
│   │   ├── id_type.py
│   │   ├── mutation.py
│   │   ├── node.py
│   │   └── tests/
│   │       ├── __init__.py
│   │       ├── test_connection.py
│   │       ├── test_connection_async.py
│   │       ├── test_connection_query.py
│   │       ├── test_custom_global_id.py
│   │       ├── test_global_id.py
│   │       ├── test_mutation.py
│   │       ├── test_mutation_async.py
│   │       ├── test_node.py
│   │       └── test_node_custom.py
│   ├── test/
│   │   └── __init__.py
│   ├── tests/
│   │   ├── __init__.py
│   │   └── issues/
│   │       ├── __init__.py
│   │       ├── test_1293.py
│   │       ├── test_1394.py
│   │       ├── test_1419.py
│   │       ├── test_313.py
│   │       ├── test_356.py
│   │       ├── test_425.py
│   │       ├── test_490.py
│   │       ├── test_720.py
│   │       ├── test_881.py
│   │       └── test_956.py
│   ├── types/
│   │   ├── __init__.py
│   │   ├── argument.py
│   │   ├── base.py
│   │   ├── base64.py
│   │   ├── context.py
│   │   ├── datetime.py
│   │   ├── decimal.py
│   │   ├── definitions.py
│   │   ├── dynamic.py
│   │   ├── enum.py
│   │   ├── field.py
│   │   ├── generic.py
│   │   ├── inputfield.py
│   │   ├── inputobjecttype.py
│   │   ├── interface.py
│   │   ├── json.py
│   │   ├── mountedtype.py
│   │   ├── mutation.py
│   │   ├── objecttype.py
│   │   ├── resolver.py
│   │   ├── scalars.py
│   │   ├── schema.py
│   │   ├── structures.py
│   │   ├── tests/
│   │   │   ├── __init__.py
│   │   │   ├── conftest.py
│   │   │   ├── test_argument.py
│   │   │   ├── test_base.py
│   │   │   ├── test_base64.py
│   │   │   ├── test_datetime.py
│   │   │   ├── test_decimal.py
│   │   │   ├── test_definition.py
│   │   │   ├── test_dynamic.py
│   │   │   ├── test_enum.py
│   │   │   ├── test_field.py
│   │   │   ├── test_generic.py
│   │   │   ├── test_inputfield.py
│   │   │   ├── test_inputobjecttype.py
│   │   │   ├── test_interface.py
│   │   │   ├── test_json.py
│   │   │   ├── test_mountedtype.py
│   │   │   ├── test_mutation.py
│   │   │   ├── test_objecttype.py
│   │   │   ├── test_query.py
│   │   │   ├── test_resolver.py
│   │   │   ├── test_scalar.py
│   │   │   ├── test_scalars_serialization.py
│   │   │   ├── test_schema.py
│   │   │   ├── test_structures.py
│   │   │   ├── test_subscribe_async.py
│   │   │   ├── test_type_map.py
│   │   │   ├── test_union.py
│   │   │   ├── test_uuid.py
│   │   │   └── utils.py
│   │   ├── union.py
│   │   ├── unmountedtype.py
│   │   ├── utils.py
│   │   └── uuid.py
│   ├── utils/
│   │   ├── __init__.py
│   │   ├── crunch.py
│   │   ├── dataloader.py
│   │   ├── deduplicator.py
│   │   ├── deprecated.py
│   │   ├── get_unbound_function.py
│   │   ├── is_introspection_key.py
│   │   ├── module_loading.py
│   │   ├── orderedtype.py
│   │   ├── props.py
│   │   ├── resolve_only_args.py
│   │   ├── str_converters.py
│   │   ├── subclass_with_meta.py
│   │   ├── tests/
│   │   │   ├── __init__.py
│   │   │   ├── test_crunch.py
│   │   │   ├── test_dataloader.py
│   │   │   ├── test_deduplicator.py
│   │   │   ├── test_deprecated.py
│   │   │   ├── test_module_loading.py
│   │   │   ├── test_orderedtype.py
│   │   │   ├── test_resolve_only_args.py
│   │   │   ├── test_resolver_from_annotations.py
│   │   │   ├── test_str_converters.py
│   │   │   └── test_trim_docstring.py
│   │   ├── thenables.py
│   │   └── trim_docstring.py
│   └── validation/
│       ├── __init__.py
│       ├── depth_limit.py
│       ├── disable_introspection.py
│       └── tests/
│           ├── __init__.py
│           ├── test_depth_limit_validator.py
│           └── test_disable_introspection.py
├── mypy.ini
├── setup.cfg
├── setup.py
└── tox.ini
Download .txt
SYMBOL INDEX (1029 symbols across 118 files)

FILE: examples/complex_example.py
  class GeoInput (line 4) | class GeoInput(graphene.InputObjectType):
    method latlng (line 9) | def latlng(self):
  class Address (line 13) | class Address(graphene.ObjectType):
  class Query (line 17) | class Query(graphene.ObjectType):
    method resolve_address (line 20) | def resolve_address(root, info, geo):
  class CreateAddress (line 24) | class CreateAddress(graphene.Mutation):
    class Arguments (line 25) | class Arguments:
    method mutate (line 30) | def mutate(root, info, geo):
  class Mutation (line 34) | class Mutation(graphene.ObjectType):
  function test_query (line 55) | def test_query():
  function test_mutation (line 61) | def test_mutation():

FILE: examples/context_example.py
  class User (line 4) | class User(graphene.ObjectType):
  class Query (line 9) | class Query(graphene.ObjectType):
    method resolve_me (line 12) | def resolve_me(root, info):
  function test_query (line 27) | def test_query():

FILE: examples/simple_example.py
  class Patron (line 4) | class Patron(graphene.ObjectType):
  class Query (line 10) | class Query(graphene.ObjectType):
    method resolve_patron (line 13) | def resolve_patron(root, info):
  function test_query (line 29) | def test_query():

FILE: examples/starwars/data.py
  function setup (line 5) | def setup():
  function get_character (line 76) | def get_character(id):
  function get_friends (line 80) | def get_friends(character):
  function get_hero (line 84) | def get_hero(episode):
  function get_human (line 90) | def get_human(id):
  function get_droid (line 94) | def get_droid(id):

FILE: examples/starwars/schema.py
  class Episode (line 6) | class Episode(graphene.Enum):
  class Character (line 12) | class Character(graphene.Interface):
    method resolve_friends (line 18) | def resolve_friends(self, info):
  class Human (line 23) | class Human(graphene.ObjectType):
    class Meta (line 24) | class Meta:
  class Droid (line 30) | class Droid(graphene.ObjectType):
    class Meta (line 31) | class Meta:
  class Query (line 37) | class Query(graphene.ObjectType):
    method resolve_hero (line 42) | def resolve_hero(root, info, episode=None):
    method resolve_human (line 45) | def resolve_human(root, info, id):
    method resolve_droid (line 48) | def resolve_droid(root, info, id):

FILE: examples/starwars/tests/test_query.py
  function test_hero_name_query (line 11) | def test_hero_name_query():
  function test_hero_name_and_friends_query (line 22) | def test_hero_name_and_friends_query():
  function test_nested_query (line 49) | def test_nested_query():
  function test_fetch_luke_query (line 104) | def test_fetch_luke_query():
  function test_fetch_some_id_query (line 115) | def test_fetch_some_id_query():
  function test_fetch_some_id_query2 (line 129) | def test_fetch_some_id_query2():
  function test_invalid_id_query (line 143) | def test_invalid_id_query():
  function test_fetch_luke_aliased (line 157) | def test_fetch_luke_aliased():
  function test_fetch_luke_and_leia_aliased (line 168) | def test_fetch_luke_and_leia_aliased():
  function test_duplicate_fields (line 184) | def test_duplicate_fields():
  function test_use_fragment (line 205) | def test_use_fragment():
  function test_check_type_of_r2 (line 228) | def test_check_type_of_r2():
  function test_check_type_of_luke (line 240) | def test_check_type_of_luke():

FILE: examples/starwars_relay/data.py
  function setup (line 4) | def setup():
  function create_ship (line 48) | def create_ship(ship_name, faction_id):
  function get_ship (line 58) | def get_ship(_id):
  function get_faction (line 62) | def get_faction(_id):
  function get_rebels (line 66) | def get_rebels():
  function get_empire (line 70) | def get_empire():

FILE: examples/starwars_relay/schema.py
  class Ship (line 7) | class Ship(graphene.ObjectType):
    class Meta (line 10) | class Meta:
    method get_node (line 16) | def get_node(cls, info, id):
  class ShipConnection (line 20) | class ShipConnection(relay.Connection):
    class Meta (line 21) | class Meta:
  class Faction (line 25) | class Faction(graphene.ObjectType):
    class Meta (line 28) | class Meta:
    method resolve_ships (line 36) | def resolve_ships(self, info, **args):
    method get_node (line 41) | def get_node(cls, info, id):
  class IntroduceShip (line 45) | class IntroduceShip(relay.ClientIDMutation):
    class Input (line 46) | class Input:
    method mutate_and_get_payload (line 54) | def mutate_and_get_payload(
  class Query (line 62) | class Query(graphene.ObjectType):
    method resolve_rebels (line 67) | def resolve_rebels(root, info):
    method resolve_empire (line 70) | def resolve_empire(root, info):
  class Mutation (line 74) | class Mutation(graphene.ObjectType):

FILE: examples/starwars_relay/tests/test_connections.py
  function test_correct_fetch_first_ship_rebels (line 11) | def test_correct_fetch_first_ship_rebels():

FILE: examples/starwars_relay/tests/test_mutation.py
  function test_mutations (line 11) | def test_mutations():

FILE: examples/starwars_relay/tests/test_objectidentification.py
  function test_str_schema (line 13) | def test_str_schema():
  function test_correctly_fetches_id_name_rebels (line 104) | def test_correctly_fetches_id_name_rebels():
  function test_correctly_refetches_rebels (line 120) | def test_correctly_refetches_rebels():
  function test_correctly_fetches_id_name_empire (line 138) | def test_correctly_fetches_id_name_empire():
  function test_correctly_refetches_empire (line 152) | def test_correctly_refetches_empire():
  function test_correctly_refetches_xwing (line 168) | def test_correctly_refetches_xwing():

FILE: graphene/pyutils/version.py
  function get_version (line 6) | def get_version(version=None):
  function get_main_version (line 28) | def get_main_version(version=None):
  function get_complete_version (line 35) | def get_complete_version(version=None):
  function get_docs_version (line 48) | def get_docs_version(version=None):
  function get_git_changeset (line 56) | def get_git_changeset():

FILE: graphene/relay/connection.py
  function get_edge_class (line 15) | def get_edge_class(
  class PageInfo (line 42) | class PageInfo(ObjectType):
    class Meta (line 43) | class Meta:
  function page_info_adapter (line 73) | def page_info_adapter(startCursor, endCursor, hasPreviousPage, hasNextPa...
  class ConnectionOptions (line 83) | class ConnectionOptions(ObjectTypeOptions):
  class Connection (line 87) | class Connection(ObjectType):
    class Meta (line 88) | class Meta:
    method __init_subclass_with_meta__ (line 92) | def __init_subclass_with_meta__(
  function connection_adapter (line 135) | def connection_adapter(cls, edges, pageInfo):
  class IterableConnectionField (line 140) | class IterableConnectionField(Field):
    method __init__ (line 141) | def __init__(self, type_, *args, **kwargs):
    method type (line 149) | def type(self):
    method resolve_connection (line 167) | def resolve_connection(cls, connection_type, args, resolved):
    method connection_resolver (line 186) | def connection_resolver(cls, resolver, connection_type, root, info, **...
    method wrap_resolve (line 195) | def wrap_resolve(self, parent_resolver):

FILE: graphene/relay/id_type.py
  class BaseGlobalIDType (line 9) | class BaseGlobalIDType:
    method resolve_global_id (line 17) | def resolve_global_id(cls, info, global_id):
    method to_global_id (line 22) | def to_global_id(cls, _type, _id):
  class DefaultGlobalIDType (line 27) | class DefaultGlobalIDType(BaseGlobalIDType):
    method resolve_global_id (line 35) | def resolve_global_id(cls, info, global_id):
    method to_global_id (line 49) | def to_global_id(cls, _type, _id):
  class SimpleGlobalIDType (line 53) | class SimpleGlobalIDType(BaseGlobalIDType):
    method resolve_global_id (line 63) | def resolve_global_id(cls, info, global_id):
    method to_global_id (line 68) | def to_global_id(cls, _type, _id):
  class UUIDGlobalIDType (line 72) | class UUIDGlobalIDType(BaseGlobalIDType):
    method resolve_global_id (line 81) | def resolve_global_id(cls, info, global_id):
    method to_global_id (line 86) | def to_global_id(cls, _type, _id):

FILE: graphene/relay/mutation.py
  class ClientIDMutation (line 8) | class ClientIDMutation(Mutation):
    class Meta (line 9) | class Meta:
    method __init_subclass_with_meta__ (line 13) | def __init_subclass_with_meta__(
    method mutate (line 55) | def mutate(cls, root, info, input):

FILE: graphene/relay/node.py
  function is_node (line 10) | def is_node(objecttype):
  class GlobalID (line 23) | class GlobalID(Field):
    method __init__ (line 24) | def __init__(
    method id_resolver (line 40) | def id_resolver(parent_resolver, node, root, info, parent_type_name=No...
    method wrap_resolve (line 45) | def wrap_resolve(self, parent_resolver):
  class NodeField (line 54) | class NodeField(Field):
    method __init__ (line 55) | def __init__(self, node, type_=False, **kwargs):
    method wrap_resolve (line 70) | def wrap_resolve(self, parent_resolver):
  class AbstractNode (line 74) | class AbstractNode(Interface):
    class Meta (line 75) | class Meta:
    method __init_subclass_with_meta__ (line 79) | def __init_subclass_with_meta__(cls, global_id_type=DefaultGlobalIDTyp...
    method resolve_global_id (line 93) | def resolve_global_id(cls, info, global_id):
  class Node (line 97) | class Node(AbstractNode):
    method Field (line 101) | def Field(cls, *args, **kwargs):  # noqa: N802
    method node_resolver (line 105) | def node_resolver(cls, only_type, root, info, id):
    method get_node_from_global_id (line 109) | def get_node_from_global_id(cls, info, global_id, only_type=None):
    method to_global_id (line 134) | def to_global_id(cls, type_, id):

FILE: graphene/relay/tests/test_connection.py
  class MyObject (line 16) | class MyObject(ObjectType):
    class Meta (line 17) | class Meta:
  function test_connection (line 23) | def test_connection():
  function test_connection_inherit_abstracttype (line 49) | def test_connection_inherit_abstracttype():
  function test_connection_extra_abstract_fields (line 62) | def test_connection_extra_abstract_fields():
  function test_connection_override_fields (line 111) | def test_connection_override_fields():
  function test_connection_name (line 167) | def test_connection_name():
  function test_edge (line 181) | def test_edge():
  function test_edge_with_bases (line 201) | def test_edge_with_bases():
  function test_edge_with_nonnull_node (line 224) | def test_edge_with_nonnull_node():
  function test_pageinfo (line 235) | def test_pageinfo():
  function test_connectionfield (line 246) | def test_connectionfield():
  function test_connectionfield_node_deprecated (line 260) | def test_connectionfield_node_deprecated():
  function test_connectionfield_custom_args (line 270) | def test_connectionfield_custom_args():
  function test_connectionfield_required (line 287) | def test_connectionfield_required():
  function test_connectionfield_strict_types (line 304) | def test_connectionfield_strict_types():

FILE: graphene/relay/tests/test_connection_async.py
  class Letter (line 12) | class Letter(ObjectType):
    class Meta (line 13) | class Meta:
  class LetterConnection (line 19) | class LetterConnection(Connection):
    class Meta (line 20) | class Meta:
  class Query (line 24) | class Query(ObjectType):
    method resolve_letters (line 31) | def resolve_letters(self, info, **args):
    method resolve_async_letters (line 34) | async def resolve_async_letters(self, info, **args):
    method resolve_connection_letters (line 37) | def resolve_connection_letters(self, info, **args):
  function edges (line 51) | def edges(selected_letters):
  function cursor_for (line 61) | def cursor_for(ltr):
  function execute (line 66) | def execute(args=""):
  function test_connection_async (line 95) | async def test_connection_async():

FILE: graphene/relay/tests/test_connection_query.py
  class Letter (line 12) | class Letter(ObjectType):
    class Meta (line 13) | class Meta:
  class LetterConnection (line 19) | class LetterConnection(Connection):
    class Meta (line 20) | class Meta:
  class Query (line 24) | class Query(ObjectType):
    method resolve_letters (line 31) | def resolve_letters(self, info, **args):
    method resolve_async_letters (line 34) | async def resolve_async_letters(self, info, **args):
    method resolve_connection_letters (line 37) | def resolve_connection_letters(self, info, **args):
  function edges (line 51) | def edges(selected_letters):
  function cursor_for (line 61) | def cursor_for(ltr):
  function execute (line 66) | async def execute(args=""):
  function check (line 93) | async def check(args, letters, has_previous_page=False, has_next_page=Fa...
  function test_returns_all_elements_without_filters (line 110) | async def test_returns_all_elements_without_filters():
  function test_respects_a_smaller_first (line 115) | async def test_respects_a_smaller_first():
  function test_respects_an_overly_large_first (line 120) | async def test_respects_an_overly_large_first():
  function test_respects_a_smaller_last (line 125) | async def test_respects_a_smaller_last():
  function test_respects_an_overly_large_last (line 130) | async def test_respects_an_overly_large_last():
  function test_respects_first_and_after (line 135) | async def test_respects_first_and_after():
  function test_respects_first_and_after_with_long_first (line 140) | async def test_respects_first_and_after_with_long_first():
  function test_respects_last_and_before (line 145) | async def test_respects_last_and_before():
  function test_respects_last_and_before_with_long_last (line 150) | async def test_respects_last_and_before_with_long_last():
  function test_respects_first_and_after_and_before_too_few (line 155) | async def test_respects_first_and_after_and_before_too_few():
  function test_respects_first_and_after_and_before_too_many (line 164) | async def test_respects_first_and_after_and_before_too_many():
  function test_respects_first_and_after_and_before_exactly_right (line 171) | async def test_respects_first_and_after_and_before_exactly_right():
  function test_respects_last_and_after_and_before_too_few (line 178) | async def test_respects_last_and_after_and_before_too_few():
  function test_respects_last_and_after_and_before_too_many (line 187) | async def test_respects_last_and_after_and_before_too_many():
  function test_respects_last_and_after_and_before_exactly_right (line 194) | async def test_respects_last_and_after_and_before_exactly_right():
  function test_returns_no_elements_if_first_is_0 (line 201) | async def test_returns_no_elements_if_first_is_0():
  function test_returns_all_elements_if_cursors_are_invalid (line 206) | async def test_returns_all_elements_if_cursors_are_invalid():
  function test_returns_all_elements_if_cursors_are_on_the_outside (line 211) | async def test_returns_all_elements_if_cursors_are_on_the_outside():
  function test_returns_no_elements_if_cursors_cross (line 219) | async def test_returns_no_elements_if_cursors_cross():
  function test_connection_type_nodes (line 227) | async def test_connection_type_nodes():
  function test_connection_async (line 260) | async def test_connection_async():

FILE: graphene/relay/tests/test_custom_global_id.py
  class TestUUIDGlobalID (line 11) | class TestUUIDGlobalID:
    method setup_method (line 12) | def setup_method(self):
    method test_str_schema_correct (line 41) | def test_str_schema_correct(self):
    method test_get_by_id (line 61) | def test_get_by_id(self):
  class TestSimpleGlobalID (line 79) | class TestSimpleGlobalID:
    method setup_method (line 80) | def setup_method(self):
    method test_str_schema_correct (line 109) | def test_str_schema_correct(self):
    method test_get_by_id (line 129) | def test_get_by_id(self):
  class TestCustomGlobalID (line 142) | class TestCustomGlobalID:
    method setup_method (line 143) | def setup_method(self):
    method test_str_schema_correct (line 188) | def test_str_schema_correct(self):
    method test_get_by_id (line 208) | def test_get_by_id(self):
  class TestIncompleteCustomGlobalID (line 221) | class TestIncompleteCustomGlobalID:
    method setup_method (line 222) | def setup_method(self):
    method test_must_define_to_global_id (line 231) | def test_must_define_to_global_id(self):
    method test_must_define_resolve_global_id (line 284) | def test_must_define_resolve_global_id(self):

FILE: graphene/relay/tests/test_global_id.py
  class CustomNode (line 8) | class CustomNode(Node):
    class Meta (line 9) | class Meta:
  class User (line 13) | class User(ObjectType):
    class Meta (line 14) | class Meta:
  class Info (line 20) | class Info:
    method __init__ (line 21) | def __init__(self, parent_type):
  function test_global_id_defaults_to_required_and_node (line 32) | def test_global_id_defaults_to_required_and_node():
  function test_global_id_allows_overriding_of_node_and_required (line 39) | def test_global_id_allows_overriding_of_node_and_required():
  function test_global_id_defaults_to_info_parent_type (line 45) | def test_global_id_defaults_to_info_parent_type():
  function test_global_id_allows_setting_customer_parent_type (line 53) | def test_global_id_allows_setting_customer_parent_type():

FILE: graphene/relay/tests/test_mutation.py
  class SharedFields (line 17) | class SharedFields:
  class MyNode (line 21) | class MyNode(ObjectType):
  class SaySomething (line 28) | class SaySomething(ClientIDMutation):
    class Input (line 29) | class Input:
    method mutate_and_get_payload (line 35) | def mutate_and_get_payload(self, info, what, client_mutation_id=None):
  class FixedSaySomething (line 39) | class FixedSaySomething:
    method __init__ (line 42) | def __init__(self, phrase):
  class SaySomethingFixed (line 46) | class SaySomethingFixed(ClientIDMutation):
    class Input (line 47) | class Input:
    method mutate_and_get_payload (line 53) | def mutate_and_get_payload(self, info, what, client_mutation_id=None):
  class SaySomethingAsync (line 57) | class SaySomethingAsync(ClientIDMutation):
    class Input (line 58) | class Input:
    method mutate_and_get_payload (line 64) | async def mutate_and_get_payload(self, info, what, client_mutation_id=...
  class MyEdge (line 69) | class MyEdge(ObjectType):
  class OtherMutation (line 74) | class OtherMutation(ClientIDMutation):
    class Input (line 75) | class Input(SharedFields):
    method mutate_and_get_payload (line 82) | def mutate_and_get_payload(
  class RootQuery (line 92) | class RootQuery(ObjectType):
  class Mutation (line 96) | class Mutation(ObjectType):
  function test_no_mutate_and_get_payload (line 106) | def test_no_mutate_and_get_payload():
  function test_mutation (line 118) | def test_mutation():
  function test_mutation_input (line 134) | def test_mutation_input():
  function test_subclassed_mutation (line 145) | def test_subclassed_mutation():
  function test_subclassed_mutation_input (line 157) | def test_subclassed_mutation_input():
  function test_node_query (line 170) | def test_node_query():
  function test_node_query_fixed (line 178) | def test_node_query_fixed():
  function test_node_query_async (line 188) | async def test_node_query_async():
  function test_edge_query (line 196) | def test_edge_query():

FILE: graphene/relay/tests/test_mutation_async.py
  class SharedFields (line 9) | class SharedFields(object):
  class MyNode (line 13) | class MyNode(ObjectType):
  class SaySomethingAsync (line 20) | class SaySomethingAsync(ClientIDMutation):
    class Input (line 21) | class Input:
    method mutate_and_get_payload (line 27) | async def mutate_and_get_payload(self, info, what, client_mutation_id=...
  class MyEdge (line 32) | class MyEdge(ObjectType):
  class OtherMutation (line 37) | class OtherMutation(ClientIDMutation):
    class Input (line 38) | class Input(SharedFields):
    method mutate_and_get_payload (line 45) | def mutate_and_get_payload(
  class RootQuery (line 55) | class RootQuery(ObjectType):
  class Mutation (line 59) | class Mutation(ObjectType):
  function test_node_query_promise (line 69) | async def test_node_query_promise():
  function test_edge_query (line 79) | async def test_edge_query():

FILE: graphene/relay/tests/test_node.py
  class SharedNodeFields (line 10) | class SharedNodeFields:
    method resolve_something_else (line 14) | def resolve_something_else(*_):
  class MyNode (line 18) | class MyNode(ObjectType):
    class Meta (line 19) | class Meta:
    method get_node (line 25) | def get_node(info, id):
  class MyOtherNode (line 29) | class MyOtherNode(SharedNodeFields, ObjectType):
    class Meta (line 32) | class Meta:
    method resolve_extra_field (line 35) | def resolve_extra_field(self, *_):
    method get_node (line 39) | def get_node(info, id):
  class RootQuery (line 43) | class RootQuery(ObjectType):
  function test_node_good (line 53) | def test_node_good():
  function test_node_query (line 60) | def test_node_query():
  function test_subclassed_node_query (line 68) | def test_subclassed_node_query():
  function test_node_requesting_non_node (line 83) | def test_node_requesting_non_node():
  function test_node_requesting_unknown_type (line 95) | def test_node_requesting_unknown_type():
  function test_node_query_incorrect_id (line 104) | def test_node_query_incorrect_id():
  function test_node_field (line 113) | def test_node_field():
  function test_node_field_custom (line 119) | def test_node_field_custom():
  function test_node_field_args (line 125) | def test_node_field_args():
  function test_node_field_only_type (line 136) | def test_node_field_only_type():
  function test_node_field_only_type_wrong (line 144) | def test_node_field_only_type_wrong():
  function test_node_field_only_lazy_type (line 154) | def test_node_field_only_lazy_type():
  function test_node_field_only_lazy_type_wrong (line 163) | def test_node_field_only_lazy_type_wrong():
  function test_str_schema (line 173) | def test_str_schema():

FILE: graphene/relay/tests/test_node_custom.py
  class CustomNode (line 10) | class CustomNode(Node):
    class Meta (line 11) | class Meta:
    method to_global_id (line 15) | def to_global_id(type_, id):
    method get_node_from_global_id (line 19) | def get_node_from_global_id(info, id, only_type=None):
  class BasePhoto (line 27) | class BasePhoto(Interface):
  class User (line 31) | class User(ObjectType):
    class Meta (line 32) | class Meta:
  class Photo (line 38) | class Photo(ObjectType):
    class Meta (line 39) | class Meta:
  class RootQuery (line 48) | class RootQuery(ObjectType):
  function test_str_schema_correct (line 56) | def test_str_schema_correct():
  function test_gets_the_correct_id_for_users (line 102) | def test_gets_the_correct_id_for_users():
  function test_gets_the_correct_id_for_photos (line 116) | def test_gets_the_correct_id_for_photos():
  function test_gets_the_correct_name_for_users (line 130) | def test_gets_the_correct_name_for_users():
  function test_gets_the_correct_width_for_photos (line 147) | def test_gets_the_correct_width_for_photos():
  function test_gets_the_correct_typename_for_users (line 164) | def test_gets_the_correct_typename_for_users():
  function test_gets_the_correct_typename_for_photos (line 179) | def test_gets_the_correct_typename_for_photos():
  function test_ignores_photo_fragments_on_user (line 194) | def test_ignores_photo_fragments_on_user():
  function test_returns_null_for_bad_ids (line 211) | def test_returns_null_for_bad_ids():
  function test_have_correct_node_interface (line 225) | def test_have_correct_node_interface():
  function test_has_correct_node_root_field (line 264) | def test_has_correct_node_root_field():

FILE: graphene/test/__init__.py
  function default_format_error (line 6) | def default_format_error(error):
  function format_execution_result (line 12) | def format_execution_result(execution_result, format_error):
  class Client (line 21) | class Client:
    method __init__ (line 22) | def __init__(self, schema, format_error=None, **execute_options):
    method format_result (line 28) | def format_result(self, result):
    method execute (line 31) | def execute(self, *args, **kwargs):
    method execute_async (line 35) | async def execute_async(self, *args, **kwargs):

FILE: graphene/tests/issues/test_1293.py
  class Filters (line 9) | class Filters(graphene.InputObjectType):
  class SetDatetime (line 20) | class SetDatetime(graphene.Mutation):
    class Arguments (line 21) | class Arguments:
    method mutate (line 26) | def mutate(root, info, filters):
  class Query (line 30) | class Query(graphene.ObjectType):
  class Mutations (line 34) | class Mutations(graphene.ObjectType):
  function test_schema_printable_with_default_datetime_value (line 38) | def test_schema_printable_with_default_datetime_value():

FILE: graphene/tests/issues/test_1394.py
  class Query (line 4) | class Query(ObjectType):
    method resolve_hello (line 7) | def resolve_hello(self, info, input):
  function test_required_input_provided (line 16) | def test_required_input_provided():
  function test_required_input_missing (line 26) | def test_required_input_missing():

FILE: graphene/tests/issues/test_1419.py
  function test_parse_literal_with_variables (line 32) | def test_parse_literal_with_variables(input_type, input_value):

FILE: graphene/tests/issues/test_313.py
  class Query (line 6) | class Query(graphene.ObjectType):
  class Success (line 10) | class Success(graphene.ObjectType):
  class Error (line 14) | class Error(graphene.ObjectType):
  class CreatePostResult (line 18) | class CreatePostResult(graphene.Union):
    class Meta (line 19) | class Meta:
  class CreatePost (line 23) | class CreatePost(graphene.Mutation):
    class Arguments (line 24) | class Arguments:
    method mutate (line 29) | def mutate(self, info, text):
  class Mutations (line 35) | class Mutations(graphene.ObjectType):
  function test_create_post (line 42) | def test_create_post():

FILE: graphene/tests/issues/test_356.py
  class SomeTypeOne (line 9) | class SomeTypeOne(graphene.ObjectType):
  class SomeTypeTwo (line 13) | class SomeTypeTwo(graphene.ObjectType):
  class MyUnion (line 17) | class MyUnion(graphene.Union):
    class Meta (line 18) | class Meta:
  function test_issue (line 22) | def test_issue():

FILE: graphene/tests/issues/test_425.py
  class SpecialOptions (line 10) | class SpecialOptions(ObjectTypeOptions):
  class SpecialObjectType (line 14) | class SpecialObjectType(ObjectType):
    method __init_subclass_with_meta__ (line 16) | def __init_subclass_with_meta__(cls, other_attr="default", **options):
  function test_special_objecttype_could_be_subclassed (line 24) | def test_special_objecttype_could_be_subclassed():
  function test_special_objecttype_could_be_subclassed_default (line 32) | def test_special_objecttype_could_be_subclassed_default():
  function test_special_objecttype_inherit_meta_options (line 39) | def test_special_objecttype_inherit_meta_options():
  class SpecialInputObjectTypeOptions (line 49) | class SpecialInputObjectTypeOptions(ObjectTypeOptions):
  class SpecialInputObjectType (line 53) | class SpecialInputObjectType(InputObjectType):
    method __init_subclass_with_meta__ (line 55) | def __init_subclass_with_meta__(cls, other_attr="default", **options):
  function test_special_inputobjecttype_could_be_subclassed (line 63) | def test_special_inputobjecttype_could_be_subclassed():
  function test_special_inputobjecttype_could_be_subclassed_default (line 71) | def test_special_inputobjecttype_could_be_subclassed_default():
  function test_special_inputobjecttype_inherit_meta_options (line 78) | def test_special_inputobjecttype_inherit_meta_options():
  class SpecialEnumOptions (line 86) | class SpecialEnumOptions(EnumOptions):
  class SpecialEnum (line 90) | class SpecialEnum(Enum):
    method __init_subclass_with_meta__ (line 92) | def __init_subclass_with_meta__(cls, other_attr="default", **options):
  function test_special_enum_could_be_subclassed (line 98) | def test_special_enum_could_be_subclassed():
  function test_special_enum_could_be_subclassed_default (line 106) | def test_special_enum_could_be_subclassed_default():
  function test_special_enum_inherit_meta_options (line 113) | def test_special_enum_inherit_meta_options():

FILE: graphene/tests/issues/test_490.py
  class Query (line 6) | class Query(graphene.ObjectType):
    method resolve_some_field (line 9) | def resolve_some_field(self, info, from_=None):
  function test_issue (line 13) | def test_issue():

FILE: graphene/tests/issues/test_720.py
  class MyInputClass (line 9) | class MyInputClass(graphene.InputObjectType):
    method __init_subclass_with_meta__ (line 11) | def __init_subclass_with_meta__(
  class MyInput (line 22) | class MyInput(MyInputClass):
    class Meta (line 23) | class Meta:
  class Query (line 27) | class Query(graphene.ObjectType):
    method resolve_myField (line 30) | def resolve_myField(parent, info, input):
  function test_issue (line 34) | def test_issue():

FILE: graphene/tests/issues/test_881.py
  class PickleEnum (line 6) | class PickleEnum(Enum):
  function test_enums_pickling (line 12) | def test_enums_pickling():

FILE: graphene/tests/issues/test_956.py
  function test_issue (line 4) | def test_issue():

FILE: graphene/types/argument.py
  class Argument (line 10) | class Argument(MountedType):
    method __init__ (line 45) | def __init__(
    method type (line 70) | def type(self):
    method __eq__ (line 73) | def __eq__(self, other):
  function to_arguments (line 83) | def to_arguments(args, extra_args=None):

FILE: graphene/types/base.py
  class BaseOptions (line 7) | class BaseOptions:
    method __init__ (line 13) | def __init__(self, class_type: Type):
    method freeze (line 16) | def freeze(self):
    method __setattr__ (line 19) | def __setattr__(self, name, value):
    method __repr__ (line 25) | def __repr__(self):
  class BaseType (line 32) | class BaseType(SubclassWithMeta):
    method create_type (line 34) | def create_type(cls, class_name, **options):
    method __init_subclass_with_meta__ (line 38) | def __init_subclass_with_meta__(

FILE: graphene/types/base64.py
  class Base64 (line 10) | class Base64(Scalar):
    method serialize (line 16) | def serialize(value):
    method parse_literal (line 25) | def parse_literal(cls, node, _variables=None):
    method parse_value (line 33) | def parse_value(value):

FILE: graphene/types/context.py
  class Context (line 1) | class Context:
    method __init__ (line 23) | def __init__(self, **params):

FILE: graphene/types/datetime.py
  class Date (line 11) | class Date(Scalar):
    method serialize (line 19) | def serialize(date):
    method parse_literal (line 27) | def parse_literal(cls, node, _variables=None):
    method parse_value (line 35) | def parse_value(value):
  class DateTime (line 46) | class DateTime(Scalar):
    method serialize (line 54) | def serialize(dt):
    method parse_literal (line 60) | def parse_literal(cls, node, _variables=None):
    method parse_value (line 68) | def parse_value(value):
  class Time (line 81) | class Time(Scalar):
    method serialize (line 89) | def serialize(time):
    method parse_literal (line 95) | def parse_literal(cls, node, _variables=None):
    method parse_value (line 103) | def parse_value(cls, value):

FILE: graphene/types/decimal.py
  class Decimal (line 9) | class Decimal(Scalar):
    method serialize (line 15) | def serialize(dec):
    method parse_literal (line 24) | def parse_literal(cls, node, _variables=None):
    method parse_value (line 30) | def parse_value(value):

FILE: graphene/types/definitions.py
  class GrapheneGraphQLType (line 13) | class GrapheneGraphQLType:
    method __init__ (line 19) | def __init__(self, *args, **kwargs):
    method __copy__ (line 23) | def __copy__(self):
  class GrapheneInterfaceType (line 29) | class GrapheneInterfaceType(GrapheneGraphQLType, GraphQLInterfaceType):
  class GrapheneUnionType (line 33) | class GrapheneUnionType(GrapheneGraphQLType, GraphQLUnionType):
  class GrapheneObjectType (line 37) | class GrapheneObjectType(GrapheneGraphQLType, GraphQLObjectType):
  class GrapheneScalarType (line 41) | class GrapheneScalarType(GrapheneGraphQLType, GraphQLScalarType):
  class GrapheneEnumType (line 45) | class GrapheneEnumType(GrapheneGraphQLType, GraphQLEnumType):
    method serialize (line 46) | def serialize(self, value):
  class GrapheneInputObjectType (line 61) | class GrapheneInputObjectType(GrapheneGraphQLType, GraphQLInputObjectType):

FILE: graphene/types/dynamic.py
  class Dynamic (line 7) | class Dynamic(MountedType):
    method __init__ (line 13) | def __init__(self, type_, with_schema=False, _creation_counter=None):
    method get_type (line 19) | def get_type(self, schema=None):

FILE: graphene/types/enum.py
  function eq_enum (line 9) | def eq_enum(self, other):
  function hash_enum (line 15) | def hash_enum(self):
  class EnumOptions (line 22) | class EnumOptions(BaseOptions):
  class EnumMeta (line 27) | class EnumMeta(SubclassWithMeta_Meta):
    method __new__ (line 28) | def __new__(cls, name_, bases, classdict, **options):
    method get (line 40) | def get(cls, value):
    method __getitem__ (line 43) | def __getitem__(cls, value):
    method __prepare__ (line 46) | def __prepare__(name, bases, **kwargs):  # noqa: N805
    method __call__ (line 49) | def __call__(cls, *args, **kwargs):  # noqa: N805
    method __iter__ (line 61) | def __iter__(cls):
    method from_enum (line 64) | def from_enum(cls, enum, name=None, description=None, deprecation_reas...
  class Enum (line 76) | class Enum(UnmountedType, BaseType, metaclass=EnumMeta):
    method __init_subclass_with_meta__ (line 102) | def __init_subclass_with_meta__(cls, enum=None, _meta=None, **options):
    method get_type (line 113) | def get_type(cls):

FILE: graphene/types/field.py
  function source_resolver (line 16) | def source_resolver(source, root, info, **args):
  class Field (line 23) | class Field(MountedType):
    method __init__ (line 67) | def __init__(
    method type (line 116) | def type(self):
    method wrap_resolve (line 121) | def wrap_resolve(self, parent_resolver):
    method wrap_subscribe (line 134) | def wrap_subscribe(self, parent_subscribe):

FILE: graphene/types/generic.py
  class GenericScalar (line 15) | class GenericScalar(Scalar):
    method identity (line 23) | def identity(value):
    method parse_literal (line 30) | def parse_literal(ast, _variables=None):

FILE: graphene/types/inputfield.py
  class InputField (line 8) | class InputField(MountedType):
    method __init__ (line 49) | def __init__(
    method type (line 73) | def type(self):

FILE: graphene/types/inputobjecttype.py
  class InputObjectTypeOptions (line 13) | class InputObjectTypeOptions(BaseOptions):
  function set_input_object_type_default_value (line 30) | def set_input_object_type_default_value(default_value):
  class InputObjectTypeContainer (line 43) | class InputObjectTypeContainer(dict, BaseType):  # type: ignore
    class Meta (line 44) | class Meta:
    method __init__ (line 47) | def __init__(self, *args, **kwargs):
    method __init_subclass__ (line 52) | def __init_subclass__(cls, *args, **kwargs):
  class InputObjectType (line 56) | class InputObjectType(UnmountedType, BaseType):
    method __init_subclass_with_meta__ (line 93) | def __init_subclass_with_meta__(cls, container=None, _meta=None, **opt...
    method get_type (line 111) | def get_type(cls):

FILE: graphene/types/interface.py
  class InterfaceOptions (line 12) | class InterfaceOptions(BaseOptions):
  class Interface (line 17) | class Interface(BaseType):
    method __init_subclass_with_meta__ (line 50) | def __init_subclass_with_meta__(cls, _meta=None, interfaces=(), **opti...
    method resolve_type (line 69) | def resolve_type(cls, instance, info):
    method __init__ (line 75) | def __init__(self, *args, **kwargs):

FILE: graphene/types/json.py
  class JSONString (line 9) | class JSONString(Scalar):
    method serialize (line 18) | def serialize(dt):
    method parse_literal (line 22) | def parse_literal(node, _variables=None):
    method parse_value (line 31) | def parse_value(value):

FILE: graphene/types/mountedtype.py
  class MountedType (line 5) | class MountedType(OrderedType):
    method mounted (line 7) | def mounted(cls, unmounted):  # noqa: N802

FILE: graphene/types/mutation.py
  class MutationOptions (line 17) | class MutationOptions(ObjectTypeOptions):
  class Mutation (line 24) | class Mutation(ObjectType):
    method __init_subclass_with_meta__ (line 69) | def __init_subclass_with_meta__(
    method Field (line 122) | def Field(

FILE: graphene/types/objecttype.py
  class ObjectTypeOptions (line 15) | class ObjectTypeOptions(BaseOptions):
  class ObjectTypeMeta (line 20) | class ObjectTypeMeta(BaseTypeMeta):
    method __new__ (line 21) | def __new__(cls, name_, bases, namespace, **options):
  class ObjectType (line 51) | class ObjectType(BaseType, metaclass=ObjectTypeMeta):
    method __init_subclass_with_meta__ (line 124) | def __init_subclass_with_meta__(

FILE: graphene/types/resolver.py
  function attr_resolver (line 1) | def attr_resolver(attname, default_value, root, info, **args):
  function dict_resolver (line 5) | def dict_resolver(attname, default_value, root, info, **args):
  function dict_or_attr_resolver (line 9) | def dict_or_attr_resolver(attname, default_value, root, info, **args):
  function set_default_resolver (line 17) | def set_default_resolver(resolver):
  function get_default_resolver (line 23) | def get_default_resolver():

FILE: graphene/types/scalars.py
  class ScalarOptions (line 15) | class ScalarOptions(BaseOptions):
  class Scalar (line 19) | class Scalar(UnmountedType, BaseType):
    method __init_subclass_with_meta__ (line 29) | def __init_subclass_with_meta__(cls, **options):
    method get_type (line 38) | def get_type(cls):
  class Int (line 55) | class Int(Scalar):
    method coerce_int (line 64) | def coerce_int(value):
    method parse_literal (line 80) | def parse_literal(ast, _variables=None):
  class BigInt (line 88) | class BigInt(Scalar):
    method coerce_int (line 96) | def coerce_int(value):
    method parse_literal (line 110) | def parse_literal(ast, _variables=None):
  class Float (line 116) | class Float(Scalar):
    method coerce_float (line 124) | def coerce_float(value: Any) -> float:
    method parse_literal (line 134) | def parse_literal(ast, _variables=None):
  class String (line 140) | class String(Scalar):
    method coerce_string (line 148) | def coerce_string(value):
    method parse_literal (line 157) | def parse_literal(ast, _variables=None):
  class Boolean (line 163) | class Boolean(Scalar):
    method parse_literal (line 172) | def parse_literal(ast, _variables=None):
  class ID (line 178) | class ID(Scalar):
    method parse_literal (line 191) | def parse_literal(ast, _variables=None):

FILE: graphene/types/schema.py
  function assert_valid_root_type (line 59) | def assert_valid_root_type(type_):
  function is_graphene_type (line 69) | def is_graphene_type(type_):
  function is_type_of_from_possible_types (line 78) | def is_type_of_from_possible_types(possible_types, root, _info):
  function identity_resolve (line 83) | def identity_resolve(root, info, **arguments):
  class TypeMap (line 87) | class TypeMap(dict):
    method __init__ (line 88) | def __init__(
    method add_type (line 114) | def add_type(self, graphene_type):
    method create_scalar (line 146) | def create_scalar(graphene_type):
    method create_enum (line 169) | def create_enum(graphene_type):
    method create_objecttype (line 207) | def create_objecttype(self, graphene_type):
    method create_interface (line 234) | def create_interface(self, graphene_type):
    method create_inputobjecttype (line 260) | def create_inputobjecttype(self, graphene_type):
    method construct_union (line 271) | def construct_union(self, graphene_type):
    method get_name (line 298) | def get_name(self, name):
    method create_fields_for_type (line 303) | def create_fields_for_type(self, graphene_type, is_input_type=False):
    method get_function_for_type (line 373) | def get_function_for_type(self, graphene_type, func_name, name, defaul...
    method resolve_type (line 394) | def resolve_type(self, resolve_type_func, type_name, root, info, _type):
  class Schema (line 404) | class Schema:
    method __init__ (line 425) | def __init__(
    method __str__ (line 448) | def __str__(self):
    method __getattr__ (line 451) | def __getattr__(self, type_name):
    method lazy (line 464) | def lazy(self, _type):
    method execute (line 467) | def execute(self, *args, **kwargs):
    method execute_async (line 494) | async def execute_async(self, *args, **kwargs):
    method subscribe (line 501) | async def subscribe(self, query, *args, **kwargs):
    method introspect (line 518) | def introspect(self):
  function normalize_execute_kwargs (line 525) | def normalize_execute_kwargs(kwargs):

FILE: graphene/types/structures.py
  class Structure (line 5) | class Structure(UnmountedType):
    method __init__ (line 11) | def __init__(self, of_type, *args, **kwargs):
    method of_type (line 23) | def of_type(self):
    method get_type (line 26) | def get_type(self):
  class List (line 34) | class List(Structure):
    method __str__ (line 51) | def __str__(self):
    method __eq__ (line 54) | def __eq__(self, other):
  class NonNull (line 62) | class NonNull(Structure):
    method __init__ (line 85) | def __init__(self, *args, **kwargs):
    method __str__ (line 91) | def __str__(self):
    method __eq__ (line 94) | def __eq__(self, other):

FILE: graphene/types/tests/conftest.py
  function set_default_input_object_type_to_undefined (line 8) | def set_default_input_object_type_to_undefined():

FILE: graphene/types/tests/test_argument.py
  function test_argument (line 12) | def test_argument():
  function test_argument_comparasion (line 20) | def test_argument_comparasion():
  function test_argument_required (line 40) | def test_argument_required():
  function test_to_arguments (line 45) | def test_to_arguments():
  function test_to_arguments_deprecated (line 55) | def test_to_arguments_deprecated():
  function test_to_arguments_required_deprecated (line 66) | def test_to_arguments_required_deprecated():
  function test_to_arguments_raises_if_field (line 79) | def test_to_arguments_raises_if_field():
  function test_to_arguments_raises_if_inputfield (line 91) | def test_to_arguments_raises_if_inputfield():
  function test_argument_with_lazy_type (line 103) | def test_argument_with_lazy_type():
  function test_argument_with_lazy_partial_type (line 109) | def test_argument_with_lazy_partial_type():

FILE: graphene/types/tests/test_base.py
  class CustomOptions (line 4) | class CustomOptions(BaseOptions):
  class CustomType (line 8) | class CustomType(BaseType):
    method __init_subclass_with_meta__ (line 10) | def __init_subclass_with_meta__(cls, **options):
  function test_basetype (line 15) | def test_basetype():
  function test_basetype_nones (line 24) | def test_basetype_nones():
  function test_basetype_custom (line 37) | def test_basetype_custom():
  function test_basetype_create (line 50) | def test_basetype_create():
  function test_basetype_create_extra (line 58) | def test_basetype_create_extra():

FILE: graphene/types/tests/test_base64.py
  class Query (line 11) | class Query(ObjectType):
    method resolve_base64 (line 17) | def resolve_base64(self, info, _in=None, _match=None):
    method resolve_bytes_as_base64 (line 22) | def resolve_bytes_as_base64(self, info):
    method resolve_string_as_base64 (line 25) | def resolve_string_as_base64(self, info):
    method resolve_number_as_base64 (line 28) | def resolve_number_as_base64(self, info):
  function test_base64_query (line 35) | def test_base64_query():
  function test_base64_query_with_variable (line 44) | def test_base64_query_with_variable():
  function test_base64_query_none (line 60) | def test_base64_query_none():
  function test_base64_query_invalid (line 66) | def test_base64_query_invalid():
  function test_base64_from_bytes (line 79) | def test_base64_from_bytes():
  function test_base64_from_string (line 86) | def test_base64_from_string():
  function test_base64_from_number (line 93) | def test_base64_from_number():

FILE: graphene/types/tests/test_datetime.py
  class Query (line 12) | class Query(ObjectType):
    method resolve_datetime (line 17) | def resolve_datetime(self, info, _in=None):
    method resolve_date (line 20) | def resolve_date(self, info, _in=None):
    method resolve_time (line 23) | def resolve_time(self, info, _at=None):
  function sample_datetime (line 31) | def sample_datetime():
  function sample_time (line 37) | def sample_time(sample_datetime):
  function sample_date (line 49) | def sample_date(sample_datetime):
  function test_datetime_query (line 54) | def test_datetime_query(sample_datetime):
  function test_datetime_query_with_variables (line 62) | def test_datetime_query_with_variables(sample_datetime):
  function test_date_query (line 79) | def test_date_query(sample_date):
  function test_date_query_with_variables (line 87) | def test_date_query_with_variables(sample_date):
  function test_time_query (line 104) | def test_time_query(sample_time):
  function test_time_query_with_variables (line 112) | def test_time_query_with_variables(sample_time):
  function test_bad_datetime_query (line 129) | def test_bad_datetime_query():
  function test_bad_date_query (line 144) | def test_bad_date_query():
  function test_bad_time_query (line 158) | def test_bad_time_query():
  function test_datetime_query_variable (line 172) | def test_datetime_query_variable(sample_datetime):
  function test_date_query_variable (line 192) | def test_date_query_variable(sample_date):
  function test_time_query_variable (line 211) | def test_time_query_variable(sample_time):
  function test_support_isoformat (line 230) | def test_support_isoformat():
  function test_bad_variables (line 242) | def test_bad_variables(sample_date, sample_datetime, sample_time):

FILE: graphene/types/tests/test_decimal.py
  class Query (line 8) | class Query(ObjectType):
    method resolve_decimal (line 11) | def resolve_decimal(self, info, input):
  function test_decimal_string_query (line 18) | def test_decimal_string_query():
  function test_decimal_string_query_variable (line 26) | def test_decimal_string_query_variable():
  function test_bad_decimal_query (line 38) | def test_bad_decimal_query():
  function test_decimal_string_query_integer (line 63) | def test_decimal_string_query_integer():

FILE: graphene/types/tests/test_definition.py
  class Image (line 17) | class Image(ObjectType):
  class Author (line 23) | class Author(ObjectType):
  class Article (line 30) | class Article(ObjectType):
  class Query (line 38) | class Query(ObjectType):
  class Mutation (line 43) | class Mutation(ObjectType):
  class Subscription (line 47) | class Subscription(ObjectType):
  class MyObjectType (line 51) | class MyObjectType(ObjectType):
  class MyInterface (line 55) | class MyInterface(Interface):
  class MyUnion (line 59) | class MyUnion(Union):
    class Meta (line 60) | class Meta:
  class MyEnum (line 64) | class MyEnum(Enum):
  class MyInputObjectType (line 68) | class MyInputObjectType(InputObjectType):
  function test_defines_a_query_only_schema (line 72) | def test_defines_a_query_only_schema():
  function test_defines_a_mutation_schema (line 99) | def test_defines_a_mutation_schema():
  function test_defines_a_subscription_schema (line 110) | def test_defines_a_subscription_schema():
  function test_includes_nested_input_objects_in_the_map (line 121) | def test_includes_nested_input_objects_in_the_map():
  function test_includes_interfaces_thunk_subtypes_in_the_type_map (line 140) | def test_includes_interfaces_thunk_subtypes_in_the_type_map():
  function test_includes_types_in_union (line 157) | def test_includes_types_in_union():
  function test_maps_enum (line 178) | def test_maps_enum():
  function test_includes_interfaces_subtypes_in_the_type_map (line 199) | def test_includes_interfaces_subtypes_in_the_type_map():
  function test_stringifies_simple_types (line 216) | def test_stringifies_simple_types():
  function test_does_not_mutate_passed_field_definitions (line 294) | def test_does_not_mutate_passed_field_definitions():
  function test_graphene_graphql_type_can_be_copied (line 320) | def test_graphene_graphql_type_can_be_copied():

FILE: graphene/types/tests/test_dynamic.py
  function test_dynamic (line 8) | def test_dynamic():
  function test_nonnull (line 14) | def test_nonnull():
  function test_list (line 20) | def test_list():
  function test_list_non_null (line 26) | def test_list_non_null():
  function test_partial (line 32) | def test_partial():

FILE: graphene/types/tests/test_enum.py
  function test_enum_construction (line 13) | def test_enum_construction():
  function test_enum_construction_meta (line 37) | def test_enum_construction_meta():
  function test_enum_instance_construction (line 51) | def test_enum_instance_construction():
  function test_enum_from_builtin_enum (line 58) | def test_enum_from_builtin_enum():
  function test_enum_custom_description_in_constructor (line 68) | def test_enum_custom_description_in_constructor():
  function test_enum_from_python3_enum_uses_default_builtin_doc (line 78) | def test_enum_from_python3_enum_uses_default_builtin_doc():
  function test_enum_from_builtin_enum_accepts_lambda_description (line 83) | def test_enum_from_builtin_enum_accepts_lambda_description():
  function test_enum_from_python3_enum_uses_enum_doc (line 118) | def test_enum_from_python3_enum_uses_enum_doc():
  function test_enum_value_from_class (line 137) | def test_enum_value_from_class():
  function test_enum_value_as_unmounted_field (line 148) | def test_enum_value_as_unmounted_field():
  function test_enum_value_as_unmounted_inputfield (line 160) | def test_enum_value_as_unmounted_inputfield():
  function test_enum_value_as_unmounted_argument (line 172) | def test_enum_value_as_unmounted_argument():
  function test_enum_can_be_compared (line 184) | def test_enum_can_be_compared():
  function test_enum_can_be_initialized (line 195) | def test_enum_can_be_initialized():
  function test_enum_can_retrieve_members (line 206) | def test_enum_can_retrieve_members():
  function test_enum_to_enum_comparison_should_differ (line 217) | def test_enum_to_enum_comparison_should_differ():
  function test_enum_skip_meta_from_members (line 233) | def test_enum_skip_meta_from_members():
  function test_enum_types (line 249) | def test_enum_types():
  function test_enum_resolver (line 288) | def test_enum_resolver():
  function test_enum_resolver_compat (line 312) | def test_enum_resolver_compat():
  function test_enum_with_name (line 346) | def test_enum_with_name():
  function test_enum_resolver_invalid (line 392) | def test_enum_resolver_invalid():
  function test_field_enum_argument (line 415) | def test_field_enum_argument():
  function test_mutation_enum_input (line 450) | def test_mutation_enum_input():
  function test_mutation_enum_input_type (line 492) | def test_mutation_enum_input_type():
  function test_hashable_enum (line 538) | def test_hashable_enum():
  function test_hashable_instance_creation_enum (line 553) | def test_hashable_instance_creation_enum():
  function test_enum_iteration (line 563) | def test_enum_iteration():
  function test_iterable_instance_creation_enum (line 575) | def test_iterable_instance_creation_enum():
  function test_enum_description_member_not_interpreted_as_property (line 586) | def test_enum_description_member_not_interpreted_as_property():

FILE: graphene/types/tests/test_field.py
  class MyInstance (line 12) | class MyInstance:
    method value_method (line 16) | def value_method(self):
  function test_field_basic (line 20) | def test_field_basic():
  function test_field_required (line 47) | def test_field_required():
  function test_field_default_value_not_callable (line 54) | def test_field_default_value_not_callable():
  function test_field_source (line 63) | def test_field_source():
  function test_field_source_dict_or_attr (line 69) | def test_field_source_dict_or_attr():
  function test_field_with_lazy_type (line 76) | def test_field_with_lazy_type():
  function test_field_with_lazy_partial_type (line 82) | def test_field_with_lazy_partial_type():
  function test_field_with_string_type (line 88) | def test_field_with_string_type():
  function test_field_not_source_and_resolver (line 93) | def test_field_not_source_and_resolver():
  function test_field_source_func (line 103) | def test_field_source_func():
  function test_field_source_method (line 109) | def test_field_source_method():
  function test_field_source_as_argument (line 115) | def test_field_source_as_argument():
  function test_field_name_as_argument (line 122) | def test_field_name_as_argument():
  function test_field_source_argument_as_kw (line 129) | def test_field_source_argument_as_kw():

FILE: graphene/types/tests/test_generic.py
  class Query (line 6) | class Query(ObjectType):
    method resolve_generic (line 9) | def resolve_generic(self, info, input=None):
  function test_generic_query_variable (line 16) | def test_generic_query_variable():
  function test_generic_parse_literal_query (line 48) | def test_generic_parse_literal_query():

FILE: graphene/types/tests/test_inputfield.py
  function test_inputfield_required (line 10) | def test_inputfield_required():
  function test_inputfield_deprecated (line 17) | def test_inputfield_deprecated():
  function test_inputfield_required_deprecated (line 25) | def test_inputfield_required_deprecated():
  function test_inputfield_with_lazy_type (line 33) | def test_inputfield_with_lazy_type():
  function test_inputfield_with_lazy_partial_type (line 39) | def test_inputfield_with_lazy_partial_type():
  function test_inputfield_with_string_type (line 45) | def test_inputfield_with_string_type():

FILE: graphene/types/tests/test_inputobjecttype.py
  class MyType (line 14) | class MyType:
  class MyScalar (line 18) | class MyScalar(UnmountedType):
    method get_type (line 19) | def get_type(self):
  function test_generate_inputobjecttype (line 23) | def test_generate_inputobjecttype():
  function test_generate_inputobjecttype_with_meta (line 32) | def test_generate_inputobjecttype_with_meta():
  function test_generate_inputobjecttype_with_fields (line 42) | def test_generate_inputobjecttype_with_fields():
  function test_ordered_fields_in_inputobjecttype (line 49) | def test_ordered_fields_in_inputobjecttype():
  function test_generate_inputobjecttype_unmountedtype (line 59) | def test_generate_inputobjecttype_unmountedtype():
  function test_generate_inputobjecttype_as_argument (line 67) | def test_generate_inputobjecttype_as_argument():
  function test_generate_inputobjecttype_inherit_abstracttype (line 83) | def test_generate_inputobjecttype_inherit_abstracttype():
  function test_generate_inputobjecttype_inherit_abstracttype_reversed (line 97) | def test_generate_inputobjecttype_inherit_abstracttype_reversed():
  function test_inputobjecttype_of_input (line 111) | def test_inputobjecttype_of_input():
  function test_inputobjecttype_default_input_as_undefined (line 144) | def test_inputobjecttype_default_input_as_undefined(

FILE: graphene/types/tests/test_interface.py
  class MyType (line 9) | class MyType:
  class MyScalar (line 13) | class MyScalar(UnmountedType):
    method get_type (line 14) | def get_type(self):
  function test_generate_interface (line 18) | def test_generate_interface():
  function test_generate_interface_with_meta (line 27) | def test_generate_interface_with_meta():
  function test_generate_interface_with_fields (line 42) | def test_generate_interface_with_fields():
  function test_ordered_fields_in_interface (line 49) | def test_ordered_fields_in_interface():
  function test_generate_interface_unmountedtype (line 59) | def test_generate_interface_unmountedtype():
  function test_generate_interface_inherit_abstracttype (line 67) | def test_generate_interface_inherit_abstracttype():
  function test_generate_interface_inherit_interface (line 78) | def test_generate_interface_inherit_interface():
  function test_generate_interface_inherit_abstracttype_reversed (line 90) | def test_generate_interface_inherit_abstracttype_reversed():
  function test_resolve_type_default (line 101) | def test_resolve_type_default():
  function test_resolve_type_custom (line 130) | def test_resolve_type_custom():
  function test_resolve_type_custom_interferes (line 169) | def test_resolve_type_custom_interferes():

FILE: graphene/types/tests/test_json.py
  class Query (line 6) | class Query(ObjectType):
    method resolve_json (line 9) | def resolve_json(self, info, input):
  function test_jsonstring_query (line 16) | def test_jsonstring_query():
  function test_jsonstring_query_variable (line 29) | def test_jsonstring_query_variable():
  function test_jsonstring_optional_uuid_input (line 40) | def test_jsonstring_optional_uuid_input():
  function test_jsonstring_invalid_query (line 49) | def test_jsonstring_invalid_query():

FILE: graphene/types/tests/test_mountedtype.py
  class CustomField (line 5) | class CustomField(Field):
    method __init__ (line 6) | def __init__(self, *args, **kwargs):
  function test_mounted_type (line 11) | def test_mounted_type():
  function test_mounted_type_custom (line 18) | def test_mounted_type_custom():

FILE: graphene/types/tests/test_mutation.py
  class MyType (line 13) | class MyType(Interface):
  function test_generate_mutation_no_args (line 17) | def test_generate_mutation_no_args():
  function test_generate_mutation_with_meta (line 31) | def test_generate_mutation_with_meta():
  function test_mutation_raises_exception_if_no_mutate (line 48) | def test_mutation_raises_exception_if_no_mutate():
  function test_mutation_custom_output_type (line 57) | def test_mutation_custom_output_type():
  function test_mutation_execution (line 78) | def test_mutation_execution():
  function test_mutation_no_fields_output (line 111) | def test_mutation_no_fields_output():
  function test_mutation_allow_to_have_custom_args (line 137) | def test_mutation_allow_to_have_custom_args():
  function test_mutation_default_args_output (line 162) | def test_mutation_default_args_output():
  function test_mutation_as_subclass (line 184) | def test_mutation_as_subclass():

FILE: graphene/types/tests/test_objecttype.py
  class MyType (line 12) | class MyType(Interface):
  class Container (line 16) | class Container(ObjectType):
  class MyInterface (line 21) | class MyInterface(Interface):
  class ContainerWithInterface (line 25) | class ContainerWithInterface(ObjectType):
    class Meta (line 26) | class Meta:
  class MyScalar (line 33) | class MyScalar(UnmountedType):
    method get_type (line 34) | def get_type(self):
  function test_generate_objecttype (line 38) | def test_generate_objecttype():
  function test_generate_objecttype_with_meta (line 52) | def test_generate_objecttype_with_meta():
  function test_generate_lazy_objecttype (line 64) | def test_generate_lazy_objecttype():
  function test_generate_objecttype_with_fields (line 77) | def test_generate_objecttype_with_fields():
  function test_generate_objecttype_with_private_attributes (line 84) | def test_generate_objecttype_with_private_attributes():
  function test_ordered_fields_in_objecttype (line 102) | def test_ordered_fields_in_objecttype():
  function test_generate_objecttype_inherit_abstracttype (line 112) | def test_generate_objecttype_inherit_abstracttype():
  function test_generate_objecttype_inherit_abstracttype_reversed (line 126) | def test_generate_objecttype_inherit_abstracttype_reversed():
  function test_generate_objecttype_unmountedtype (line 140) | def test_generate_objecttype_unmountedtype():
  function test_parent_container_get_fields (line 148) | def test_parent_container_get_fields():
  function test_parent_container_interface_get_fields (line 152) | def test_parent_container_interface_get_fields():
  function test_objecttype_as_container_only_args (line 156) | def test_objecttype_as_container_only_args():
  function test_objecttype_repr (line 162) | def test_objecttype_repr():
  function test_objecttype_eq (line 167) | def test_objecttype_eq():
  function test_objecttype_as_container_args_kwargs (line 176) | def test_objecttype_as_container_args_kwargs():
  function test_objecttype_as_container_few_kwargs (line 182) | def test_objecttype_as_container_few_kwargs():
  function test_objecttype_as_container_all_kwargs (line 187) | def test_objecttype_as_container_all_kwargs():
  function test_objecttype_as_container_extra_args (line 193) | def test_objecttype_as_container_extra_args():
  function test_objecttype_as_container_invalid_kwargs (line 199) | def test_objecttype_as_container_invalid_kwargs():
  function test_objecttype_container_benchmark (line 205) | def test_objecttype_container_benchmark(benchmark):
  function test_generate_objecttype_description (line 211) | def test_generate_objecttype_description():
  function test_objecttype_with_possible_types (line 222) | def test_objecttype_with_possible_types():
  function test_objecttype_with_possible_types_and_is_type_of_should_raise (line 230) | def test_objecttype_with_possible_types_and_is_type_of_should_raise():
  function test_objecttype_no_fields_output (line 247) | def test_objecttype_no_fields_output():
  function test_abstract_objecttype_can_str (line 270) | def test_abstract_objecttype_can_str():
  function test_objecttype_meta_with_annotations (line 280) | def test_objecttype_meta_with_annotations():
  function test_objecttype_meta_arguments (line 294) | def test_objecttype_meta_arguments():
  function test_objecttype_type_name (line 305) | def test_objecttype_type_name():

FILE: graphene/types/tests/test_query.py
  function test_query (line 25) | def test_query():
  function test_query_source (line 36) | def test_query_source():
  function test_query_union (line 53) | def test_query_union():
  function test_query_interface (line 91) | def test_query_interface():
  function test_query_dynamic (line 136) | def test_query_dynamic():
  function test_query_default_value (line 153) | def test_query_default_value():
  function test_query_wrong_default_value (line 167) | def test_query_wrong_default_value():
  function test_query_default_value_ignored_by_resolver (line 189) | def test_query_default_value_ignored_by_resolver():
  function test_query_resolve_function (line 207) | def test_query_resolve_function():
  function test_query_arguments (line 221) | def test_query_arguments():
  function test_query_input_field (line 246) | def test_query_input_field():
  function test_query_middlewares (line 276) | def test_query_middlewares():
  function test_objecttype_on_instances (line 299) | def test_objecttype_on_instances():
  function test_big_list_query_benchmark (line 323) | def test_big_list_query_benchmark(benchmark):
  function test_big_list_query_compiled_query_benchmark (line 340) | def test_big_list_query_compiled_query_benchmark(benchmark):
  function test_big_list_of_containers_query_benchmark (line 360) | def test_big_list_of_containers_query_benchmark(benchmark):
  function test_big_list_of_containers_multiple_fields_query_benchmark (line 380) | def test_big_list_of_containers_multiple_fields_query_benchmark(benchmark):
  function test_big_list_of_containers_multiple_fields_custom_resolvers_query_benchmark (line 407) | def test_big_list_of_containers_multiple_fields_custom_resolvers_query_b...
  function test_query_annotated_resolvers (line 448) | def test_query_annotated_resolvers():
  function test_default_as_kwarg_to_NonNull (line 482) | def test_default_as_kwarg_to_NonNull():

FILE: graphene/types/tests/test_resolver.py
  class demo_obj (line 16) | class demo_obj:
  function test_attr_resolver (line 20) | def test_attr_resolver():
  function test_attr_resolver_default_value (line 25) | def test_attr_resolver_default_value():
  function test_dict_resolver (line 30) | def test_dict_resolver():
  function test_dict_resolver_default_value (line 35) | def test_dict_resolver_default_value():
  function test_dict_or_attr_resolver (line 40) | def test_dict_or_attr_resolver():
  function test_get_default_resolver_is_attr_resolver (line 48) | def test_get_default_resolver_is_attr_resolver():
  function test_set_default_resolver_workd (line 52) | def test_set_default_resolver_workd():

FILE: graphene/types/tests/test_scalar.py
  function test_scalar (line 8) | def test_scalar():
  function test_ints (line 16) | def test_ints():
  function return_input (line 35) | def return_input(_parent, _info, input):
  class Optional (line 39) | class Optional(ObjectType):
  class Query (line 47) | class Query(ObjectType):
    method resolve_optional (line 50) | def resolve_optional(self, info):
    method resolve_required (line 53) | def resolve_required(self, info, input):
  class TestInt (line 60) | class TestInt:
    method test_query (line 61) | def test_query(self):
    method test_optional_input (line 69) | def test_optional_input(self):
    method test_invalid_input (line 77) | def test_invalid_input(self):
  class TestBigInt (line 101) | class TestBigInt:
    method test_query (line 102) | def test_query(self):
    method test_optional_input (line 111) | def test_optional_input(self):
    method test_invalid_input (line 119) | def test_invalid_input(self):
  class TestFloat (line 145) | class TestFloat:
    method test_query (line 146) | def test_query(self):
    method test_optional_input (line 158) | def test_optional_input(self):
    method test_invalid_input (line 166) | def test_invalid_input(self):
  class TestBoolean (line 192) | class TestBoolean:
    method test_query (line 193) | def test_query(self):
    method test_optional_input (line 205) | def test_optional_input(self):
    method test_invalid_input (line 213) | def test_invalid_input(self):
  class TestString (line 258) | class TestString:
    method test_query (line 259) | def test_query(self):
    method test_optional_input (line 275) | def test_optional_input(self):
    method test_invalid_input (line 283) | def test_invalid_input(self):

FILE: graphene/types/tests/test_scalars_serialization.py
  function test_serializes_output_int (line 5) | def test_serializes_output_int():
  function test_serializes_output_float (line 23) | def test_serializes_output_float():
  function test_serializes_output_string (line 36) | def test_serializes_output_string():
  function test_serializes_output_boolean (line 45) | def test_serializes_output_boolean():

FILE: graphene/types/tests/test_schema.py
  class MyOtherType (line 13) | class MyOtherType(ObjectType):
  class Query (line 17) | class Query(ObjectType):
  function test_schema (line 21) | def test_schema():
  function test_schema_get_type (line 31) | def test_schema_get_type():
  function test_schema_get_type_error (line 37) | def test_schema_get_type_error():
  function test_schema_str (line 45) | def test_schema_str():
  function test_schema_introspect (line 63) | def test_schema_introspect():
  function test_schema_requires_query_type (line 68) | def test_schema_requires_query_type():

FILE: graphene/types/tests/test_structures.py
  function test_list (line 10) | def test_list():
  function test_list_with_unmounted_type (line 16) | def test_list_with_unmounted_type():
  function test_list_with_lazy_type (line 26) | def test_list_with_lazy_type():
  function test_list_with_lazy_partial_type (line 32) | def test_list_with_lazy_partial_type():
  function test_list_with_string_type (line 38) | def test_list_with_string_type():
  function test_list_inherited_works_list (line 43) | def test_list_inherited_works_list():
  function test_list_inherited_works_nonnull (line 49) | def test_list_inherited_works_nonnull():
  function test_nonnull (line 55) | def test_nonnull():
  function test_nonnull_with_lazy_type (line 61) | def test_nonnull_with_lazy_type():
  function test_nonnull_with_lazy_partial_type (line 67) | def test_nonnull_with_lazy_partial_type():
  function test_nonnull_with_string_type (line 73) | def test_nonnull_with_string_type():
  function test_nonnull_inherited_works_list (line 78) | def test_nonnull_inherited_works_list():
  function test_nonnull_inherited_dont_work_nonnull (line 84) | def test_nonnull_inherited_dont_work_nonnull():
  function test_nonnull_with_unmounted_type (line 94) | def test_nonnull_with_unmounted_type():
  function test_list_comparasion (line 104) | def test_list_comparasion():
  function test_nonnull_comparasion (line 118) | def test_nonnull_comparasion():

FILE: graphene/types/tests/test_subscribe_async.py
  class Query (line 6) | class Query(ObjectType):
    method resolve_hello (line 9) | def resolve_hello(root, info):
  class Subscription (line 13) | class Subscription(ObjectType):
    method subscribe_count_to_ten (line 16) | async def subscribe_count_to_ten(root, info):
  function test_subscription (line 25) | async def test_subscription():
  function test_subscription_fails_with_invalid_query (line 35) | async def test_subscription_fails_with_invalid_query():
  function test_subscription_fails_when_query_is_not_valid (line 45) | async def test_subscription_fails_when_query_is_not_valid():
  function test_subscription_with_args (line 58) | async def test_subscription_with_args():

FILE: graphene/types/tests/test_type_map.py
  function create_type_map (line 27) | def create_type_map(types, auto_camelcase=True):
  function test_enum (line 33) | def test_enum():
  function test_objecttype (line 63) | def test_objecttype():
  function test_required_argument_with_default_value (line 99) | def test_required_argument_with_default_value():
  function test_dynamic_objecttype (line 114) | def test_dynamic_objecttype():
  function test_interface (line 132) | def test_interface():
  function test_inputobject (line 171) | def test_inputobject():
  function test_inputobject_undefined (line 230) | def test_inputobject_undefined(set_default_input_object_type_to_undefined):
  function test_objecttype_camelcase (line 242) | def test_objecttype_camelcase():
  function test_objecttype_camelcase_disabled (line 266) | def test_objecttype_camelcase_disabled():
  function test_objecttype_with_possible_types (line 290) | def test_objecttype_with_possible_types():
  function test_interface_with_interfaces (line 306) | def test_interface_with_interfaces():

FILE: graphene/types/tests/test_union.py
  class MyObjectType1 (line 9) | class MyObjectType1(ObjectType):
  class MyObjectType2 (line 13) | class MyObjectType2(ObjectType):
  function test_generate_union (line 17) | def test_generate_union():
  function test_generate_union_with_meta (line 29) | def test_generate_union_with_meta():
  function test_generate_union_with_no_types (line 40) | def test_generate_union_with_no_types():
  function test_union_can_be_mounted (line 49) | def test_union_can_be_mounted():

FILE: graphene/types/tests/test_uuid.py
  class Query (line 7) | class Query(ObjectType):
    method resolve_uuid (line 11) | def resolve_uuid(self, info, input):
    method resolve_required_uuid (line 14) | def resolve_required_uuid(self, info, input):
  function test_uuidstring_query (line 21) | def test_uuidstring_query():
  function test_uuidstring_query_variable (line 28) | def test_uuidstring_query_variable():
  function test_uuidstring_invalid_argument (line 39) | def test_uuidstring_invalid_argument():
  function test_uuidstring_optional_uuid_input (line 54) | def test_uuidstring_optional_uuid_input():
  function test_uuidstring_invalid_query (line 63) | def test_uuidstring_invalid_query():

FILE: graphene/types/union.py
  class UnionOptions (line 12) | class UnionOptions(BaseOptions):
  class Union (line 16) | class Union(UnmountedType, BaseType):
    method __init_subclass_with_meta__ (line 54) | def __init_subclass_with_meta__(cls, types=None, _meta=None, **options):
    method get_type (line 66) | def get_type(cls):
    method resolve_type (line 74) | def resolve_type(cls, instance, info):

FILE: graphene/types/unmountedtype.py
  class UnmountedType (line 4) | class UnmountedType(OrderedType):
    method __init__ (line 42) | def __init__(self, *args, **kwargs):
    method get_type (line 47) | def get_type(self):
    method mount_as (line 54) | def mount_as(self, _as):
    method Field (line 57) | def Field(self):  # noqa: N802
    method InputField (line 65) | def InputField(self):  # noqa: N802
    method Argument (line 73) | def Argument(self):  # noqa: N802
    method __eq__ (line 81) | def __eq__(self, other):

FILE: graphene/types/utils.py
  function get_field_as (line 9) | def get_field_as(value, _as=None):
  function yank_fields_from_attrs (line 21) | def yank_fields_from_attrs(attrs, _as=None, sort=True):
  function get_type (line 38) | def get_type(_type):
  function get_underlying_type (line 46) | def get_underlying_type(_type):

FILE: graphene/types/uuid.py
  class UUID (line 10) | class UUID(Scalar):
    method serialize (line 17) | def serialize(uuid):
    method parse_literal (line 25) | def parse_literal(node, _variables=None):
    method parse_value (line 31) | def parse_value(value):

FILE: graphene/utils/crunch.py
  function to_key (line 5) | def to_key(value):
  function insert (line 9) | def insert(value, index, values):
  function flatten (line 20) | def flatten(data, index, values):
  function crunch (line 30) | def crunch(data):

FILE: graphene/utils/dataloader.py
  function iscoroutinefunctionorpartial (line 17) | def iscoroutinefunctionorpartial(fn):
  class DataLoader (line 21) | class DataLoader(object):
    method __init__ (line 26) | def __init__(
    method loop (line 68) | def loop(self):
    method load (line 74) | def load(self, key=None):
    method do_resolve_reject (line 103) | def do_resolve_reject(self, key, future):
    method load_many (line 117) | def load_many(self, keys):
    method clear (line 140) | def clear(self, key):
    method clear_all (line 149) | def clear_all(self):
    method prime (line 158) | def prime(self, key, value):
  function enqueue_post_future_job (line 180) | def enqueue_post_future_job(loop, loader):
  function get_chunks (line 187) | def get_chunks(iterable_obj, chunk_size=1):
  function dispatch_queue (line 195) | def dispatch_queue(loader):
  function dispatch_queue_batch (line 216) | async def dispatch_queue_batch(loader, queue):
  function failed_dispatch (line 273) | def failed_dispatch(loader, queue, error):

FILE: graphene/utils/deduplicator.py
  function deflate (line 4) | def deflate(node, index=None, path=None):

FILE: graphene/utils/deprecated.py
  function warn_deprecation (line 4) | def warn_deprecation(text: str):

FILE: graphene/utils/get_unbound_function.py
  function get_unbound_function (line 1) | def get_unbound_function(func):

FILE: graphene/utils/is_introspection_key.py
  function is_introspection_key (line 1) | def is_introspection_key(key):

FILE: graphene/utils/module_loading.py
  function import_string (line 5) | def import_string(dotted_path, dotted_attributes=None):
  function lazy_import (line 44) | def lazy_import(dotted_path, dotted_attributes=None):

FILE: graphene/utils/orderedtype.py
  class OrderedType (line 5) | class OrderedType:
    method __init__ (line 8) | def __init__(self, _creation_counter=None):
    method gen_counter (line 12) | def gen_counter():
    method reset_counter (line 17) | def reset_counter(self):
    method __eq__ (line 20) | def __eq__(self, other):
    method __lt__ (line 26) | def __lt__(self, other):
    method __gt__ (line 32) | def __gt__(self, other):
    method __hash__ (line 38) | def __hash__(self):

FILE: graphene/utils/props.py
  class _OldClass (line 1) | class _OldClass:
  class _NewClass (line 5) | class _NewClass:
  function props (line 12) | def props(x):

FILE: graphene/utils/resolve_only_args.py
  function resolve_only_args (line 6) | def resolve_only_args(func):

FILE: graphene/utils/str_converters.py
  function to_camel_case (line 6) | def to_camel_case(snake_str):
  function to_snake_case (line 15) | def to_snake_case(name):

FILE: graphene/utils/subclass_with_meta.py
  class SubclassWithMeta_Meta (line 6) | class SubclassWithMeta_Meta(type):
    method __str__ (line 9) | def __str__(cls):
    method __repr__ (line 14) | def __repr__(cls):
  class SubclassWithMeta (line 18) | class SubclassWithMeta(metaclass=SubclassWithMeta_Meta):
    method __init_subclass__ (line 21) | def __init_subclass__(cls, **meta_options):
    method __init_subclass_with_meta__ (line 49) | def __init_subclass_with_meta__(cls, **meta_options):

FILE: graphene/utils/tests/test_crunch.py
  function test_crunch (line 50) | def test_crunch(description, uncrunched, crunched):

FILE: graphene/utils/tests/test_dataloader.py
  class CharacterType (line 20) | class CharacterType(ObjectType):
    method resolve_sibling (line 24) | async def resolve_sibling(character, info):
  class Query (line 30) | class Query(ObjectType):
    method resolve_skywalker_family (line 33) | async def resolve_skywalker_family(_, info):
  class CharacterLoader (line 42) | class CharacterLoader(DataLoader):
    method batch_load_fn (line 43) | async def batch_load_fn(self, character_ids):
  function test_basic_dataloader (line 51) | async def test_basic_dataloader():
  function id_loader (line 83) | def id_loader(**options):
  function test_build_a_simple_data_loader (line 101) | async def test_build_a_simple_data_loader():
  function test_can_build_a_data_loader_from_a_partial (line 114) | async def test_can_build_a_data_loader_from_a_partial():
  function test_supports_loading_multiple_keys_in_one_call (line 130) | async def test_supports_loading_multiple_keys_in_one_call():
  function test_batches_multiple_requests (line 148) | async def test_batches_multiple_requests():
  function test_batches_multiple_requests_with_max_batch_sizes (line 165) | async def test_batches_multiple_requests_with_max_batch_sizes():
  function test_coalesces_identical_requests (line 184) | async def test_coalesces_identical_requests():
  function test_caches_repeated_requests (line 202) | async def test_caches_repeated_requests():
  function test_clears_single_value_in_loader (line 231) | async def test_clears_single_value_in_loader():
  function test_clears_all_values_in_loader (line 252) | async def test_clears_all_values_in_loader():
  function test_allows_priming_the_cache (line 273) | async def test_allows_priming_the_cache():
  function test_does_not_prime_keys_that_already_exist (line 287) | async def test_does_not_prime_keys_that_already_exist():
  function test_resolves_to_error_to_indicate_failure (line 312) | async def test_resolves_to_error_to_indicate_failure():
  function test_can_represent_failures_and_successes_simultaneously (line 332) | async def test_can_represent_failures_and_successes_simultaneously():
  function test_caches_failed_fetches (line 354) | async def test_caches_failed_fetches():
  function test_caches_failed_fetches_2 (line 375) | async def test_caches_failed_fetches_2():
  function test_batches_loads_occuring_within_promises (line 388) | async def test_batches_loads_occuring_within_promises():
  function test_catches_error_if_loader_resolver_fails (line 405) | async def test_catches_error_if_loader_resolver_fails():
  function test_can_call_a_loader_from_a_loader (line 420) | async def test_can_call_a_loader_from_a_loader():
  function test_dataloader_clear_with_missing_key_works (line 447) | async def test_dataloader_clear_with_missing_key_works():

FILE: graphene/utils/tests/test_deduplicator.py
  function test_does_not_modify_object_without_typename_and_id (line 9) | def test_does_not_modify_object_without_typename_and_id():
  function test_does_not_modify_first_instance_of_an_object (line 16) | def test_does_not_modify_first_instance_of_an_object():
  function test_does_not_modify_first_instance_of_an_object_nested (line 34) | def test_does_not_modify_first_instance_of_an_object_nested():
  function test_does_not_modify_input (line 72) | def test_does_not_modify_input():
  function test_example_end_to_end (line 109) | def test_example_end_to_end():

FILE: graphene/utils/tests/test_deprecated.py
  function test_warn_deprecation (line 5) | def test_warn_deprecation(mocker):

FILE: graphene/utils/tests/test_module_loading.py
  function test_import_string (line 8) | def test_import_string():
  function test_import_string_module (line 16) | def test_import_string_module():
  function test_import_string_class (line 23) | def test_import_string_class():
  function test_import_string_attributes (line 33) | def test_import_string_attributes():
  function test_lazy_import (line 62) | def test_lazy_import():

FILE: graphene/utils/tests/test_orderedtype.py
  function test_orderedtype (line 4) | def test_orderedtype():
  function test_orderedtype_eq (line 12) | def test_orderedtype_eq():
  function test_orderedtype_hash (line 20) | def test_orderedtype_hash():
  function test_orderedtype_resetcounter (line 28) | def test_orderedtype_resetcounter():
  function test_orderedtype_non_orderabletypes (line 36) | def test_orderedtype_non_orderabletypes():

FILE: graphene/utils/tests/test_resolve_only_args.py
  function test_resolve_only_args (line 5) | def test_resolve_only_args(mocker):

FILE: graphene/utils/tests/test_str_converters.py
  function test_snake_case (line 5) | def test_snake_case():
  function test_camel_case (line 15) | def test_camel_case():

FILE: graphene/utils/tests/test_trim_docstring.py
  function test_trim_docstring (line 4) | def test_trim_docstring():

FILE: graphene/utils/thenables.py
  function await_and_execute (line 8) | def await_and_execute(obj, on_resolve):
  function maybe_thenable (line 15) | def maybe_thenable(obj, on_resolve):

FILE: graphene/utils/trim_docstring.py
  function trim_docstring (line 4) | def trim_docstring(docstring):

FILE: graphene/validation/depth_limit.py
  function depth_limit_validator (line 53) | def depth_limit_validator(
  function get_fragments (line 84) | def get_fragments(
  function get_queries_and_mutations (line 96) | def get_queries_and_mutations(
  function determine_depth (line 108) | def determine_depth(
  function is_ignored (line 179) | def is_ignored(node: FieldNode, ignore: Optional[List[IgnoreType]] = Non...

FILE: graphene/validation/disable_introspection.py
  class DisableIntrospection (line 8) | class DisableIntrospection(ValidationRule):
    method enter_field (line 9) | def enter_field(self, node: FieldNode, *_args):

FILE: graphene/validation/tests/test_depth_limit_validator.py
  class PetType (line 11) | class PetType(Interface):
    class meta (line 14) | class meta:
  class CatType (line 18) | class CatType(ObjectType):
    class meta (line 19) | class meta:
  class DogType (line 24) | class DogType(ObjectType):
    class meta (line 25) | class meta:
  class AddressType (line 30) | class AddressType(ObjectType):
    class Meta (line 36) | class Meta:
  class HumanType (line 40) | class HumanType(ObjectType):
    class Meta (line 46) | class Meta:
  class Query (line 50) | class Query(ObjectType):
    method resolve_user (line 58) | def resolve_user(root, info, name=None):
  function run_query (line 65) | def run_query(query: str, max_depth: int, ignore=None):
  function test_should_count_depth_without_fragment (line 87) | def test_should_count_depth_without_fragment():
  function test_should_count_with_fragments (line 135) | def test_should_count_with_fragments():
  function test_should_ignore_the_introspection_query (line 195) | def test_should_ignore_the_introspection_query():
  function test_should_catch_very_deep_query (line 201) | def test_should_catch_very_deep_query():
  function test_should_ignore_field (line 224) | def test_should_ignore_field():
  function test_should_raise_invalid_ignore (line 247) | def test_should_raise_invalid_ignore():

FILE: graphene/validation/tests/test_disable_introspection.py
  class Query (line 7) | class Query(ObjectType):
    method resolve_name (line 11) | def resolve_name(root, info):
  function run_query (line 18) | def run_query(query: str):
  function test_disallows_introspection_queries (line 28) | def test_disallows_introspection_queries():
  function test_allows_non_introspection_queries (line 35) | def test_allows_non_introspection_queries():

FILE: setup.py
  class PyTest (line 27) | class PyTest(TestCommand):
    method initialize_options (line 30) | def initialize_options(self):
    method finalize_options (line 34) | def finalize_options(self):
    method run_tests (line 39) | def run_tests(self):
Condensed preview — 189 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (529K chars).
[
  {
    "path": ".coveragerc",
    "chars": 42,
    "preview": "[run]\nomit = graphene/pyutils/*,*/tests/*\n"
  },
  {
    "path": ".editorconfig",
    "chars": 192,
    "preview": "# http://editorconfig.org\n\nroot = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\ntrim_trailing_w"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 805,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: \"\\U0001F41B bug\"\nassignees: ''\n\n---\n\n**"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 28,
    "preview": "blank_issues_enabled: false\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 608,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: \"✨ enhancement\"\nassignees: ''\n\n---\n\n"
  },
  {
    "path": ".github/stale.yml",
    "chars": 826,
    "preview": "# Number of days of inactivity before an issue becomes stale\ndaysUntilStale: false\n# Number of days of inactivity before"
  },
  {
    "path": ".github/workflows/build.yaml",
    "chars": 482,
    "preview": "name: 📦 Build\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checko"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "chars": 560,
    "preview": "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    - "
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 492,
    "preview": "name: 💅 Lint\n\non: [push, pull_request]\n\njobs:\n  build:\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checko"
  },
  {
    "path": ".github/workflows/tests.yml",
    "chars": 1906,
    "preview": "name: 📄 Tests\non:\n  push:\n    branches:\n      - master\n      - '*.x'\n    paths-ignore:\n      - 'docs/**'\n      - '*.md'\n"
  },
  {
    "path": ".gitignore",
    "chars": 1110,
    "preview": "# Created by https://www.gitignore.io\n\n### Python ###\n# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n\n# "
  },
  {
    "path": ".pre-commit-config.yaml",
    "chars": 701,
    "preview": "default_language_version:\n  python: python3.10\n\nrepos:\n-   repo: https://github.com/pre-commit/pre-commit-hooks\n    rev:"
  },
  {
    "path": "LICENSE",
    "chars": 1087,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2015-Present Syrus Akbary\n\nPermission is hereby granted, free of charge, to any per"
  },
  {
    "path": "MANIFEST.in",
    "chars": 125,
    "preview": "global-exclude tests/*\nrecursive-exclude tests *\nrecursive-exclude tests_py35 *\nrecursive-exclude examples *\ninclude LIC"
  },
  {
    "path": "Makefile",
    "chars": 705,
    "preview": ".PHONY: help\nhelp:\n\t@echo \"Please use \\`make <target>' where <target> is one of\"\n\t@grep -E '^\\.PHONY: [a-zA-Z_-]+ .*?## "
  },
  {
    "path": "README.md",
    "chars": 5112,
    "preview": "# ![Graphene Logo](http://graphene-python.org/favicon.png) [Graphene](http://graphene-python.org)  [![PyPI version](http"
  },
  {
    "path": "SECURITY.md",
    "chars": 578,
    "preview": "# Security Policy\n\n## Supported Versions\n\nSupport for security issues is currently provided for Graphene 3.0 and above. "
  },
  {
    "path": "UPGRADE-v1.0.md",
    "chars": 4940,
    "preview": "# 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 arou"
  },
  {
    "path": "UPGRADE-v2.0.md",
    "chars": 8156,
    "preview": "# v2.0 Upgrade Guide\n\n`ObjectType`, `Interface`, `InputObjectType`, `Scalar` and `Enum` implementations\nhave been quite "
  },
  {
    "path": "bin/convert_documentation",
    "chars": 72,
    "preview": "#!/bin/bash\n\npandoc README.md --from markdown --to rst -s -o README.rst\n"
  },
  {
    "path": "docs/Makefile",
    "chars": 7576,
    "preview": "# Makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line.\nSPHINXOPTS    =\nSPHINXBUILD "
  },
  {
    "path": "docs/_static/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/api/index.rst",
    "chars": 1726,
    "preview": "API Reference\n=============\n\nSchema\n------\n\n.. autoclass:: graphene.types.schema.Schema\n    :members:\n\n.. Uncomment sect"
  },
  {
    "path": "docs/conf.py",
    "chars": 12747,
    "preview": "import os\nimport sys\n\nimport sphinx_graphene_theme\n\non_rtd = os.environ.get(\"READTHEDOCS\", None) == \"True\"\n\n# -*- coding"
  },
  {
    "path": "docs/execution/dataloader.rst",
    "chars": 3671,
    "preview": "Dataloader\n==========\n\nDataLoader is a generic utility to be used as part of your application's\ndata fetching layer to p"
  },
  {
    "path": "docs/execution/execute.rst",
    "chars": 3040,
    "preview": ".. _SchemaExecute:\n\nExecuting a query\n=================\n\nFor executing a query against a schema, you can directly call t"
  },
  {
    "path": "docs/execution/fileuploading.rst",
    "chars": 465,
    "preview": "File uploading\n==============\n\nFile uploading is not part of the official GraphQL spec yet and is not natively\nimplement"
  },
  {
    "path": "docs/execution/index.rst",
    "chars": 153,
    "preview": "=========\nExecution\n=========\n\n.. toctree::\n   :maxdepth: 2\n\n   execute\n   middleware\n   dataloader\n   fileuploading\n   "
  },
  {
    "path": "docs/execution/middleware.rst",
    "chars": 1990,
    "preview": "Middleware\n==========\n\nYou can use ``middleware`` to affect the evaluation of fields in your schema.\n\nA middleware is an"
  },
  {
    "path": "docs/execution/queryvalidation.rst",
    "chars": 4033,
    "preview": "Query Validation\n================\nGraphQL uses query validators to check if Query AST is valid and can be executed. Ever"
  },
  {
    "path": "docs/execution/subscriptions.rst",
    "chars": 1106,
    "preview": ".. _SchemaSubscription:\n\nSubscriptions\n=============\n\nTo create a subscription, you can directly call the ``subscribe`` "
  },
  {
    "path": "docs/index.rst",
    "chars": 930,
    "preview": "Graphene\n========\n\nContents:\n\n.. toctree::\n   :maxdepth: 2\n\n   quickstart\n   types/index\n   execution/index\n   relay/ind"
  },
  {
    "path": "docs/quickstart.rst",
    "chars": 4943,
    "preview": "Getting started\n===============\n\nIntroduction\n------------\n\nWhat is GraphQL?\n~~~~~~~~~~~~~~~~\n\nGraphQL is a query langua"
  },
  {
    "path": "docs/relay/connection.rst",
    "chars": 1369,
    "preview": "Connection\n==========\n\nA connection is a vitaminized version of a List that provides ways of\nslicing and paginating thro"
  },
  {
    "path": "docs/relay/index.rst",
    "chars": 684,
    "preview": "Relay\n=====\n\nGraphene has complete support for `Relay`_ and offers some utils to make\nintegration from Python easy.\n\n\n.."
  },
  {
    "path": "docs/relay/mutations.rst",
    "chars": 1678,
    "preview": "Mutations\n=========\n\nMost APIs don’t just allow you to read data, they also allow you to\nwrite.\n\nIn GraphQL, this is don"
  },
  {
    "path": "docs/relay/nodes.rst",
    "chars": 3307,
    "preview": "Nodes\n=====\n\nA ``Node`` is an Interface provided by ``graphene.relay`` that contains\na single field ``id`` (which is a `"
  },
  {
    "path": "docs/requirements.txt",
    "chars": 130,
    "preview": "# Required library\nSphinx==6.1.3\nsphinx-autobuild==2021.3.14\n# Docs template\nhttp://graphene-python.org/sphinx_graphene_"
  },
  {
    "path": "docs/testing/index.rst",
    "chars": 2325,
    "preview": "===================\nTesting in Graphene\n===================\n\n\nAutomated testing is an extremely useful bug-killing tool "
  },
  {
    "path": "docs/types/enums.rst",
    "chars": 2237,
    "preview": "Enums\n=====\n\nAn ``Enum`` is a special ``GraphQL`` type that represents a set of\nsymbolic names (members) bound to unique"
  },
  {
    "path": "docs/types/index.rst",
    "chars": 202,
    "preview": ".. _TypesReference:\n\n===============\nTypes Reference\n===============\n\n.. toctree::\n   :maxdepth: 1\n\n   schema\n   scalars"
  },
  {
    "path": "docs/types/interfaces.rst",
    "chars": 4686,
    "preview": ".. _Interfaces:\n\nInterfaces\n==========\n\nAn *Interface* is an abstract type that defines a certain set of fields that a\nt"
  },
  {
    "path": "docs/types/list-and-nonnull.rst",
    "chars": 1828,
    "preview": "Lists and Non-Null\n==================\n\nObject types, scalars, and enums are the only kinds of types you can\ndefine in Gr"
  },
  {
    "path": "docs/types/mutations.rst",
    "chars": 4275,
    "preview": "Mutations\n=========\n\nA Mutation is a special ObjectType that also defines an Input.\n\nQuick example\n-------------\n\nThis e"
  },
  {
    "path": "docs/types/objecttypes.rst",
    "chars": 14286,
    "preview": ".. _ObjectType:\n\nObjectType\n==========\n\nA Graphene *ObjectType* is the building block used to define the relationship be"
  },
  {
    "path": "docs/types/scalars.rst",
    "chars": 8086,
    "preview": ".. _Scalars:\n\nScalars\n=======\n\nScalar types represent concrete values at the leaves of a query. There are\nseveral built "
  },
  {
    "path": "docs/types/schema.rst",
    "chars": 2684,
    "preview": "Schema\n======\n\nA GraphQL **Schema** defines the types and relationships between **Fields** in your API.\n\nA Schema is cre"
  },
  {
    "path": "docs/types/unions.rst",
    "chars": 1498,
    "preview": "Unions\n======\n\nUnion types are very similar to interfaces, but they don't get\nto specify any common fields between the t"
  },
  {
    "path": "examples/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/complex_example.py",
    "chars": 1461,
    "preview": "import graphene\n\n\nclass GeoInput(graphene.InputObjectType):\n    lat = graphene.Float(required=True)\n    lng = graphene.F"
  },
  {
    "path": "examples/context_example.py",
    "chars": 698,
    "preview": "import graphene\n\n\nclass User(graphene.ObjectType):\n    id = graphene.ID()\n    name = graphene.String()\n\n\nclass Query(gra"
  },
  {
    "path": "examples/simple_example.py",
    "chars": 690,
    "preview": "import graphene\n\n\nclass Patron(graphene.ObjectType):\n    id = graphene.ID()\n    name = graphene.String()\n    age = graph"
  },
  {
    "path": "examples/starwars/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/starwars/data.py",
    "chars": 1881,
    "preview": "human_data = {}\ndroid_data = {}\n\n\ndef setup():\n    from .schema import Human, Droid\n\n    global human_data, droid_data\n "
  },
  {
    "path": "examples/starwars/schema.py",
    "chars": 1197,
    "preview": "import graphene\n\nfrom .data import get_character, get_droid, get_hero, get_human\n\n\nclass Episode(graphene.Enum):\n    NEW"
  },
  {
    "path": "examples/starwars/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/starwars/tests/test_query.py",
    "chars": 6013,
    "preview": "from graphene.test import Client\n\nfrom ..data import setup\nfrom ..schema import schema\n\nsetup()\n\nclient = Client(schema)"
  },
  {
    "path": "examples/starwars/tests/test_schema.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/starwars_relay/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/starwars_relay/data.py",
    "chars": 1593,
    "preview": "data = {}\n\n\ndef setup():\n    global data\n\n    from .schema import Ship, Faction\n\n    xwing = Ship(id=\"1\", name=\"X-Wing\")"
  },
  {
    "path": "examples/starwars_relay/schema.py",
    "chars": 1955,
    "preview": "import graphene\nfrom graphene import relay\n\nfrom .data import create_ship, get_empire, get_faction, get_rebels, get_ship"
  },
  {
    "path": "examples/starwars_relay/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "examples/starwars_relay/tests/test_connections.py",
    "chars": 1337,
    "preview": "from graphene.test import Client\n\nfrom ..data import setup\nfrom ..schema import schema\n\nsetup()\n\nclient = Client(schema)"
  },
  {
    "path": "examples/starwars_relay/tests/test_mutation.py",
    "chars": 1486,
    "preview": "from graphene.test import Client\n\nfrom ..data import setup\nfrom ..schema import schema\n\nsetup()\n\nclient = Client(schema)"
  },
  {
    "path": "examples/starwars_relay/tests/test_objectidentification.py",
    "chars": 4108,
    "preview": "import textwrap\n\nfrom graphene.test import Client\n\nfrom ..data import setup\nfrom ..schema import schema\n\nsetup()\n\nclient"
  },
  {
    "path": "graphene/__init__.py",
    "chars": 1558,
    "preview": "from .pyutils.version import get_version\nfrom .relay import (\n    BaseGlobalIDType,\n    ClientIDMutation,\n    Connection"
  },
  {
    "path": "graphene/pyutils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/pyutils/version.py",
    "chars": 2415,
    "preview": "import datetime\nimport os\nimport subprocess\n\n\ndef get_version(version=None):\n    \"Returns a PEP 440-compliant version nu"
  },
  {
    "path": "graphene/relay/__init__.py",
    "chars": 501,
    "preview": "from .node import Node, is_node, GlobalID\nfrom .mutation import ClientIDMutation\nfrom .connection import Connection, Con"
  },
  {
    "path": "graphene/relay/connection.py",
    "chars": 6539,
    "preview": "import re\nfrom collections.abc import Iterable\nfrom functools import partial\nfrom typing import Type\n\nfrom graphql_relay"
  },
  {
    "path": "graphene/relay/id_type.py",
    "chars": 2247,
    "preview": "from graphql_relay import from_global_id, to_global_id\n\nfrom ..types import ID, UUID\nfrom ..types.base import BaseType\n\n"
  },
  {
    "path": "graphene/relay/mutation.py",
    "chars": 2213,
    "preview": "import re\n\nfrom ..types import Field, InputObjectType, String\nfrom ..types.mutation import Mutation\nfrom ..utils.thenabl"
  },
  {
    "path": "graphene/relay/node.py",
    "chars": 4359,
    "preview": "from functools import partial\nfrom inspect import isclass\n\nfrom ..types import Field, Interface, ObjectType\nfrom ..types"
  },
  {
    "path": "graphene/relay/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/relay/tests/test_connection.py",
    "chars": 9327,
    "preview": "import re\n\nfrom pytest import raises\n\nfrom ...types import Argument, Field, Int, List, NonNull, ObjectType, Schema, Stri"
  },
  {
    "path": "graphene/relay/tests/test_connection_async.py",
    "chars": 2754,
    "preview": "from pytest import mark\n\nfrom graphql_relay.utils import base64\n\nfrom graphene.types import ObjectType, Schema, String\nf"
  },
  {
    "path": "graphene/relay/tests/test_connection_query.py",
    "chars": 7013,
    "preview": "from pytest import mark\n\nfrom graphql_relay.utils import base64\n\nfrom ...types import ObjectType, Schema, String\nfrom .."
  },
  {
    "path": "graphene/relay/tests/test_custom_global_id.py",
    "chars": 10349,
    "preview": "import re\nfrom uuid import uuid4\n\nfrom graphql import graphql_sync\n\nfrom ..id_type import BaseGlobalIDType, SimpleGlobal"
  },
  {
    "path": "graphene/relay/tests/test_global_id.py",
    "chars": 1566,
    "preview": "from graphql_relay import to_global_id\n\nfrom ...types import ID, NonNull, ObjectType, String\nfrom ...types.definitions i"
  },
  {
    "path": "graphene/relay/tests/test_mutation.py",
    "chars": 5750,
    "preview": "from pytest import mark, raises\n\nfrom ...types import (\n    ID,\n    Argument,\n    Field,\n    InputField,\n    InputObject"
  },
  {
    "path": "graphene/relay/tests/test_mutation_async.py",
    "chars": 2262,
    "preview": "from pytest import mark\n\nfrom graphene.types import ID, Field, ObjectType, Schema\nfrom graphene.types.scalars import Str"
  },
  {
    "path": "graphene/relay/tests/test_node.py",
    "chars": 5608,
    "preview": "import re\nfrom textwrap import dedent\n\nfrom graphql_relay import to_global_id\n\nfrom ...types import ObjectType, Schema, "
  },
  {
    "path": "graphene/relay/tests/test_node_custom.py",
    "chars": 6741,
    "preview": "from textwrap import dedent\n\nfrom graphql import graphql_sync\n\nfrom ...types import Interface, ObjectType, Schema\nfrom ."
  },
  {
    "path": "graphene/test/__init__.py",
    "chars": 1286,
    "preview": "from graphql.error import GraphQLError\n\nfrom graphene.types.schema import Schema\n\n\ndef default_format_error(error):\n    "
  },
  {
    "path": "graphene/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/tests/issues/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/tests/issues/test_1293.py",
    "chars": 1066,
    "preview": "# https://github.com/graphql-python/graphene/issues/1293\n\nfrom datetime import datetime, timezone\n\nimport graphene\nfrom "
  },
  {
    "path": "graphene/tests/issues/test_1394.py",
    "chars": 947,
    "preview": "from ...types import ObjectType, Schema, String, NonNull\n\n\nclass Query(ObjectType):\n    hello = String(input=NonNull(Str"
  },
  {
    "path": "graphene/tests/issues/test_1419.py",
    "chars": 1585,
    "preview": "import pytest\n\nfrom ...types.base64 import Base64\nfrom ...types.datetime import Date, DateTime\nfrom ...types.decimal imp"
  },
  {
    "path": "graphene/tests/issues/test_313.py",
    "chars": 1106,
    "preview": "# https://github.com/graphql-python/graphene/issues/313\n\nimport graphene\n\n\nclass Query(graphene.ObjectType):\n    rand = "
  },
  {
    "path": "graphene/tests/issues/test_356.py",
    "chars": 698,
    "preview": "# https://github.com/graphql-python/graphene/issues/356\n\nfrom pytest import raises\n\nimport graphene\nfrom graphene import"
  },
  {
    "path": "graphene/tests/issues/test_425.py",
    "chars": 3101,
    "preview": "# https://github.com/graphql-python/graphene/issues/425\n# Adapted for Graphene 2.0\n\nfrom graphene.types.enum import Enum"
  },
  {
    "path": "graphene/tests/issues/test_490.py",
    "chars": 516,
    "preview": "# https://github.com/graphql-python/graphene/issues/313\n\nimport graphene\n\n\nclass Query(graphene.ObjectType):\n    some_fi"
  },
  {
    "path": "graphene/tests/issues/test_720.py",
    "chars": 1197,
    "preview": "# https://github.com/graphql-python/graphene/issues/720\n# InputObjectTypes overwrite the \"fields\" attribute of the provi"
  },
  {
    "path": "graphene/tests/issues/test_881.py",
    "chars": 663,
    "preview": "import pickle\n\nfrom ...types.enum import Enum\n\n\nclass PickleEnum(Enum):\n    # is defined outside of test because pickle "
  },
  {
    "path": "graphene/tests/issues/test_956.py",
    "chars": 332,
    "preview": "import graphene\n\n\ndef test_issue():\n    options = {\"description\": \"This my enum\", \"deprecation_reason\": \"For the funs\"}\n"
  },
  {
    "path": "graphene/types/__init__.py",
    "chars": 1122,
    "preview": "from graphql import GraphQLResolveInfo as ResolveInfo\n\nfrom .argument import Argument\nfrom .base64 import Base64\nfrom .c"
  },
  {
    "path": "graphene/types/argument.py",
    "chars": 4196,
    "preview": "from itertools import chain\nfrom graphql import Undefined\n\nfrom .dynamic import Dynamic\nfrom .mountedtype import Mounted"
  },
  {
    "path": "graphene/types/base.py",
    "chars": 1386,
    "preview": "from typing import Type, Optional\n\nfrom ..utils.subclass_with_meta import SubclassWithMeta, SubclassWithMeta_Meta\nfrom ."
  },
  {
    "path": "graphene/types/base64.py",
    "chars": 1368,
    "preview": "from binascii import Error as _Error\nfrom base64 import b64decode, b64encode\n\nfrom graphql.error import GraphQLError\nfro"
  },
  {
    "path": "graphene/types/context.py",
    "chars": 791,
    "preview": "class Context:\n    \"\"\"\n    Context can be used to make a convenient container for attributes to provide\n    for executio"
  },
  {
    "path": "graphene/types/datetime.py",
    "chars": 3519,
    "preview": "import datetime\n\nfrom dateutil.parser import isoparse\n\nfrom graphql.error import GraphQLError\nfrom graphql.language impo"
  },
  {
    "path": "graphene/types/decimal.py",
    "chars": 861,
    "preview": "from decimal import Decimal as _Decimal\n\nfrom graphql import Undefined\nfrom graphql.language.ast import StringValueNode,"
  },
  {
    "path": "graphene/types/definitions.py",
    "chars": 1595,
    "preview": "from enum import Enum as PyEnum\n\nfrom graphql import (\n    GraphQLEnumType,\n    GraphQLInputObjectType,\n    GraphQLInter"
  },
  {
    "path": "graphene/types/dynamic.py",
    "chars": 675,
    "preview": "import inspect\nfrom functools import partial\n\nfrom .mountedtype import MountedType\n\n\nclass Dynamic(MountedType):\n    \"\"\""
  },
  {
    "path": "graphene/types/enum.py",
    "chars": 3818,
    "preview": "from enum import Enum as PyEnum\n\nfrom graphene.utils.subclass_with_meta import SubclassWithMeta_Meta\n\nfrom .base import "
  },
  {
    "path": "graphene/types/field.py",
    "chars": 5472,
    "preview": "import inspect\nfrom collections.abc import Mapping\nfrom functools import partial\n\nfrom .argument import Argument, to_arg"
  },
  {
    "path": "graphene/types/generic.py",
    "chars": 1297,
    "preview": "from graphql.language.ast import (\n    BooleanValueNode,\n    FloatValueNode,\n    IntValueNode,\n    ListValueNode,\n    Ob"
  },
  {
    "path": "graphene/types/inputfield.py",
    "chars": 2752,
    "preview": "from graphql import Undefined\n\nfrom .mountedtype import MountedType\nfrom .structures import NonNull\nfrom .utils import g"
  },
  {
    "path": "graphene/types/inputobjecttype.py",
    "chars": 4715,
    "preview": "from typing import TYPE_CHECKING\n\nfrom .base import BaseOptions, BaseType\nfrom .inputfield import InputField\nfrom .unmou"
  },
  {
    "path": "graphene/types/interface.py",
    "chars": 2428,
    "preview": "from typing import TYPE_CHECKING\n\nfrom .base import BaseOptions, BaseType\nfrom .field import Field\nfrom .utils import ya"
  },
  {
    "path": "graphene/types/json.py",
    "chars": 851,
    "preview": "import json\n\nfrom graphql import Undefined\nfrom graphql.language.ast import StringValueNode\n\nfrom .scalars import Scalar"
  },
  {
    "path": "graphene/types/mountedtype.py",
    "chars": 555,
    "preview": "from ..utils.orderedtype import OrderedType\nfrom .unmountedtype import UnmountedType\n\n\nclass MountedType(OrderedType):\n "
  },
  {
    "path": "graphene/types/mutation.py",
    "chars": 5127,
    "preview": "from typing import TYPE_CHECKING\n\nfrom ..utils.deprecated import warn_deprecation\nfrom ..utils.get_unbound_function impo"
  },
  {
    "path": "graphene/types/objecttype.py",
    "chars": 5802,
    "preview": "from typing import TYPE_CHECKING\n\nfrom .base import BaseOptions, BaseType, BaseTypeMeta\nfrom .field import Field\nfrom .i"
  },
  {
    "path": "graphene/types/resolver.py",
    "chars": 696,
    "preview": "def attr_resolver(attname, default_value, root, info, **args):\n    return getattr(root, attname, default_value)\n\n\ndef di"
  },
  {
    "path": "graphene/types/scalars.py",
    "chars": 5194,
    "preview": "from typing import Any\n\nfrom graphql import Undefined\nfrom graphql.language.ast import (\n    BooleanValueNode,\n    Float"
  },
  {
    "path": "graphene/types/schema.py",
    "chars": 20621,
    "preview": "from enum import Enum as PyEnum\nimport inspect\nfrom functools import partial\n\nfrom graphql import (\n    default_type_res"
  },
  {
    "path": "graphene/types/structures.py",
    "chars": 3121,
    "preview": "from .unmountedtype import UnmountedType\nfrom .utils import get_type\n\n\nclass Structure(UnmountedType):\n    \"\"\"\n    A str"
  },
  {
    "path": "graphene/types/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/types/tests/conftest.py",
    "chars": 418,
    "preview": "import pytest\nfrom graphql import Undefined\n\nfrom graphene.types.inputobjecttype import set_input_object_type_default_va"
  },
  {
    "path": "graphene/types/tests/test_argument.py",
    "chars": 2784,
    "preview": "from functools import partial\n\nfrom pytest import raises\n\nfrom ..argument import Argument, to_arguments\nfrom ..field imp"
  },
  {
    "path": "graphene/types/tests/test_base.py",
    "chars": 1688,
    "preview": "from ..base import BaseOptions, BaseType\n\n\nclass CustomOptions(BaseOptions):\n    pass\n\n\nclass CustomType(BaseType):\n    "
  },
  {
    "path": "graphene/types/tests/test_base64.py",
    "chars": 2798,
    "preview": "import base64\n\nfrom graphql import GraphQLError\n\nfrom ..objecttype import ObjectType\nfrom ..scalars import String\nfrom ."
  },
  {
    "path": "graphene/types/tests/test_datetime.py",
    "chars": 7482,
    "preview": "import datetime\n\nfrom graphql import GraphQLError\n\nfrom pytest import fixture\n\nfrom ..datetime import Date, DateTime, Ti"
  },
  {
    "path": "graphene/types/tests/test_decimal.py",
    "chars": 2165,
    "preview": "import decimal\n\nfrom ..decimal import Decimal\nfrom ..objecttype import ObjectType\nfrom ..schema import Schema\n\n\nclass Qu"
  },
  {
    "path": "graphene/types/tests/test_definition.py",
    "chars": 9009,
    "preview": "import copy\n\nfrom ..argument import Argument\nfrom ..definitions import GrapheneGraphQLType\nfrom ..enum import Enum\nfrom "
  },
  {
    "path": "graphene/types/tests/test_dynamic.py",
    "chars": 989,
    "preview": "from functools import partial\n\nfrom ..dynamic import Dynamic\nfrom ..scalars import String\nfrom ..structures import List,"
  },
  {
    "path": "graphene/types/tests/test_enum.py",
    "chars": 13726,
    "preview": "from textwrap import dedent\n\nfrom ..argument import Argument\nfrom ..enum import Enum, PyEnum\nfrom ..field import Field\nf"
  },
  {
    "path": "graphene/types/tests/test_field.py",
    "chars": 4104,
    "preview": "from functools import partial\n\nfrom pytest import raises\n\nfrom ..argument import Argument\nfrom ..field import Field\nfrom"
  },
  {
    "path": "graphene/types/tests/test_generic.py",
    "chars": 2226,
    "preview": "from ..generic import GenericScalar\nfrom ..objecttype import ObjectType\nfrom ..schema import Schema\n\n\nclass Query(Object"
  },
  {
    "path": "graphene/types/tests/test_inputfield.py",
    "chars": 1344,
    "preview": "from functools import partial\n\nfrom pytest import raises\n\nfrom ..inputfield import InputField\nfrom ..structures import N"
  },
  {
    "path": "graphene/types/tests/test_inputobjecttype.py",
    "chars": 4892,
    "preview": "from graphql import Undefined\n\nfrom ..argument import Argument\nfrom ..field import Field\nfrom ..inputfield import InputF"
  },
  {
    "path": "graphene/types/tests/test_interface.py",
    "chars": 5077,
    "preview": "from ..field import Field\nfrom ..interface import Interface\nfrom ..objecttype import ObjectType\nfrom ..scalars import St"
  },
  {
    "path": "graphene/types/tests/test_json.py",
    "chars": 2347,
    "preview": "from ..json import JSONString\nfrom ..objecttype import ObjectType\nfrom ..schema import Schema\n\n\nclass Query(ObjectType):"
  },
  {
    "path": "graphene/types/tests/test_mountedtype.py",
    "chars": 650,
    "preview": "from ..field import Field\nfrom ..scalars import String\n\n\nclass CustomField(Field):\n    def __init__(self, *args, **kwarg"
  },
  {
    "path": "graphene/types/tests/test_mutation.py",
    "chars": 5708,
    "preview": "from pytest import raises\n\nfrom ..argument import Argument\nfrom ..dynamic import Dynamic\nfrom ..mutation import Mutation"
  },
  {
    "path": "graphene/types/tests/test_objecttype.py",
    "chars": 8250,
    "preview": "from pytest import raises\n\nfrom ..field import Field\nfrom ..interface import Interface\nfrom ..objecttype import ObjectTy"
  },
  {
    "path": "graphene/types/tests/test_query.py",
    "chars": 13427,
    "preview": "import json\nfrom functools import partial\n\nfrom graphql import (\n    GraphQLError,\n    GraphQLResolveInfo as ResolveInfo"
  },
  {
    "path": "graphene/types/tests/test_resolver.py",
    "chars": 1384,
    "preview": "from ..resolver import (\n    attr_resolver,\n    dict_resolver,\n    dict_or_attr_resolver,\n    get_default_resolver,\n    "
  },
  {
    "path": "graphene/types/tests/test_scalar.py",
    "chars": 10292,
    "preview": "from ..objecttype import ObjectType, Field\nfrom ..scalars import Scalar, Int, BigInt, Float, String, Boolean\nfrom ..sche"
  },
  {
    "path": "graphene/types/tests/test_scalars_serialization.py",
    "chars": 1767,
    "preview": "from graphql import Undefined\nfrom ..scalars import Boolean, Float, Int, String\n\n\ndef test_serializes_output_int():\n    "
  },
  {
    "path": "graphene/types/tests/test_schema.py",
    "chars": 1621,
    "preview": "from textwrap import dedent\n\nfrom pytest import raises\n\nfrom graphql.type import GraphQLObjectType, GraphQLSchema\n\nfrom "
  },
  {
    "path": "graphene/types/tests/test_structures.py",
    "chars": 3184,
    "preview": "from functools import partial\n\nfrom pytest import raises\n\nfrom ..scalars import String\nfrom ..structures import List, No"
  },
  {
    "path": "graphene/types/tests/test_subscribe_async.py",
    "chars": 2136,
    "preview": "from pytest import mark\n\nfrom graphene import ObjectType, Int, String, Schema, Field\n\n\nclass Query(ObjectType):\n    hell"
  },
  {
    "path": "graphene/types/tests/test_type_map.py",
    "chars": 10417,
    "preview": "from graphql import Undefined\nfrom graphql.type import (\n    GraphQLArgument,\n    GraphQLEnumType,\n    GraphQLEnumValue,"
  },
  {
    "path": "graphene/types/tests/test_union.py",
    "chars": 1453,
    "preview": "from pytest import raises\n\nfrom ..field import Field\nfrom ..objecttype import ObjectType\nfrom ..union import Union\nfrom "
  },
  {
    "path": "graphene/types/tests/test_uuid.py",
    "chars": 2413,
    "preview": "from ..objecttype import ObjectType\nfrom ..schema import Schema\nfrom ..uuid import UUID\nfrom ..structures import NonNull"
  },
  {
    "path": "graphene/types/tests/utils.py",
    "chars": 22,
    "preview": "MyLazyType = object()\n"
  },
  {
    "path": "graphene/types/union.py",
    "chars": 2582,
    "preview": "from typing import TYPE_CHECKING\n\nfrom .base import BaseOptions, BaseType\nfrom .unmountedtype import UnmountedType\n\n# Fo"
  },
  {
    "path": "graphene/types/unmountedtype.py",
    "chars": 2344,
    "preview": "from ..utils.orderedtype import OrderedType\n\n\nclass UnmountedType(OrderedType):\n    \"\"\"\n    This class acts a proxy for "
  },
  {
    "path": "graphene/types/utils.py",
    "chars": 1316,
    "preview": "import inspect\nfrom functools import partial\n\nfrom ..utils.module_loading import import_string\nfrom .mountedtype import "
  },
  {
    "path": "graphene/types/uuid.py",
    "chars": 1021,
    "preview": "from uuid import UUID as _UUID\n\nfrom graphql.error import GraphQLError\nfrom graphql.language.ast import StringValueNode\n"
  },
  {
    "path": "graphene/utils/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/utils/crunch.py",
    "chars": 756,
    "preview": "import json\nfrom collections.abc import Mapping\n\n\ndef to_key(value):\n    return json.dumps(value)\n\n\ndef insert(value, in"
  },
  {
    "path": "graphene/utils/dataloader.py",
    "chars": 9010,
    "preview": "from asyncio import (\n    gather,\n    ensure_future,\n    get_event_loop,\n    iscoroutine,\n    iscoroutinefunction,\n)\nfro"
  },
  {
    "path": "graphene/utils/deduplicator.py",
    "chars": 919,
    "preview": "from collections.abc import Mapping\n\n\ndef deflate(node, index=None, path=None):\n    if index is None:\n        index = {}"
  },
  {
    "path": "graphene/utils/deprecated.py",
    "chars": 119,
    "preview": "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",
    "chars": 121,
    "preview": "def get_unbound_function(func):\n    if not getattr(func, \"__self__\", True):\n        return func.__func__\n    return func"
  },
  {
    "path": "graphene/utils/is_introspection_key.py",
    "chars": 325,
    "preview": "def is_introspection_key(key):\n    # from: https://spec.graphql.org/June2018/#sec-Schema\n    # > All types and directive"
  },
  {
    "path": "graphene/utils/module_loading.py",
    "chars": 1587,
    "preview": "from functools import partial\nfrom importlib import import_module\n\n\ndef import_string(dotted_path, dotted_attributes=Non"
  },
  {
    "path": "graphene/utils/orderedtype.py",
    "chars": 1221,
    "preview": "from functools import total_ordering\n\n\n@total_ordering\nclass OrderedType:\n    creation_counter = 1\n\n    def __init__(sel"
  },
  {
    "path": "graphene/utils/props.py",
    "chars": 229,
    "preview": "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):"
  },
  {
    "path": "graphene/utils/resolve_only_args.py",
    "chars": 261,
    "preview": "from functools import wraps\nfrom typing_extensions import deprecated\n\n\n@deprecated(\"This function is deprecated\")\ndef re"
  },
  {
    "path": "graphene/utils/str_converters.py",
    "chars": 619,
    "preview": "import re\n\n\n# Adapted from this response in Stackoverflow\n# http://stackoverflow.com/a/19053800/1072990\ndef to_camel_cas"
  },
  {
    "path": "graphene/utils/subclass_with_meta.py",
    "chars": 1616,
    "preview": "from inspect import isclass\n\nfrom .props import props\n\n\nclass SubclassWithMeta_Meta(type):\n    _meta = None\n\n    def __s"
  },
  {
    "path": "graphene/utils/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/utils/tests/test_crunch.py",
    "chars": 1758,
    "preview": "from pytest import mark\n\nfrom ..crunch import crunch\n\n\n@mark.parametrize(\n    \"description,uncrunched,crunched\",\n    [\n "
  },
  {
    "path": "graphene/utils/tests/test_dataloader.py",
    "chars": 10662,
    "preview": "from asyncio import gather\nfrom collections import namedtuple\nfrom functools import partial\nfrom unittest.mock import Mo"
  },
  {
    "path": "graphene/utils/tests/test_deduplicator.py",
    "chars": 5052,
    "preview": "import datetime\nimport graphene\nfrom graphene import relay\nfrom graphene.types.resolver import dict_resolver\n\nfrom ..ded"
  },
  {
    "path": "graphene/utils/tests/test_deprecated.py",
    "chars": 267,
    "preview": "from .. import deprecated\nfrom ..deprecated import warn_deprecation\n\n\ndef test_warn_deprecation(mocker):\n    mocker.patc"
  },
  {
    "path": "graphene/utils/tests/test_module_loading.py",
    "chars": 1870,
    "preview": "from pytest import raises\n\nfrom graphene import ObjectType, String\n\nfrom ..module_loading import import_string, lazy_imp"
  },
  {
    "path": "graphene/utils/tests/test_orderedtype.py",
    "chars": 747,
    "preview": "from ..orderedtype import OrderedType\n\n\ndef test_orderedtype():\n    one = OrderedType()\n    two = OrderedType()\n    thre"
  },
  {
    "path": "graphene/utils/tests/test_resolve_only_args.py",
    "chars": 357,
    "preview": "from .. import deprecated\nfrom ..resolve_only_args import resolve_only_args\n\n\ndef test_resolve_only_args(mocker):\n    mo"
  },
  {
    "path": "graphene/utils/tests/test_resolver_from_annotations.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/utils/tests/test_str_converters.py",
    "chars": 847,
    "preview": "# coding: utf-8\nfrom ..str_converters import to_camel_case, to_snake_case\n\n\ndef test_snake_case():\n    assert to_snake_c"
  },
  {
    "path": "graphene/utils/tests/test_trim_docstring.py",
    "chars": 568,
    "preview": "from ..trim_docstring import trim_docstring\n\n\ndef test_trim_docstring():\n    class WellDocumentedObject:\n        \"\"\"\n   "
  },
  {
    "path": "graphene/utils/thenables.py",
    "chars": 667,
    "preview": "\"\"\"\nThis file is used mainly as a bridge for thenable abstractions.\n\"\"\"\n\nfrom inspect import isawaitable\n\n\ndef await_and"
  },
  {
    "path": "graphene/utils/trim_docstring.py",
    "chars": 297,
    "preview": "import inspect\n\n\ndef trim_docstring(docstring):\n    # Cleans up whitespaces from an indented docstring\n    #\n    # See h"
  },
  {
    "path": "graphene/validation/__init__.py",
    "chars": 165,
    "preview": "from .depth_limit import depth_limit_validator\nfrom .disable_introspection import DisableIntrospection\n\n\n__all__ = [\"Dis"
  },
  {
    "path": "graphene/validation/depth_limit.py",
    "chars": 6504,
    "preview": "# This is a Python port of https://github.com/stems/graphql-depth-limit\n# which is licensed under the terms of the MIT l"
  },
  {
    "path": "graphene/validation/disable_introspection.py",
    "chars": 539,
    "preview": "from graphql import GraphQLError\nfrom graphql.language import FieldNode\nfrom graphql.validation import ValidationRule\n\nf"
  },
  {
    "path": "graphene/validation/tests/__init__.py",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "graphene/validation/tests/test_depth_limit_validator.py",
    "chars": 4885,
    "preview": "import re\n\nfrom pytest import raises\nfrom graphql import parse, get_introspection_query, validate\n\nfrom ...types import "
  },
  {
    "path": "graphene/validation/tests/test_disable_introspection.py",
    "chars": 842,
    "preview": "from graphql import parse, validate\n\nfrom ...types import Schema, ObjectType, String\nfrom ..disable_introspection import"
  },
  {
    "path": "mypy.ini",
    "chars": 293,
    "preview": "[mypy]\nignore_missing_imports = True\n\n[mypy-graphene.pyutils.*]\nignore_errors = True\n\n[mypy-graphene.types.scalars]\nigno"
  },
  {
    "path": "setup.cfg",
    "chars": 104,
    "preview": "[coverage:run]\nomit = graphene/pyutils/*,*/tests/*,graphene/types/scalars.py\n\n[bdist_wheel]\nuniversal=1\n"
  },
  {
    "path": "setup.py",
    "chars": 2667,
    "preview": "import ast\nimport codecs\nimport re\nimport sys\n\nfrom setuptools import find_packages, setup\nfrom setuptools.command.test "
  },
  {
    "path": "tox.ini",
    "chars": 474,
    "preview": "[tox]\nenvlist = py3{8,9,10,11,12,13}, mypy, pre-commit\nskipsdist = true\n\n[testenv]\ndeps =\n    .[test]\ncommands =\n    pyt"
  }
]

About this extraction

This page contains the full source code of the graphql-python/graphene GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 189 files (480.1 KB), approximately 117.2k tokens, and a symbol index with 1029 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!