2025-12-01
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
from typing import Any
|
||||
|
||||
from .location import SourceLocation
|
||||
|
||||
__all__ = ["Source", "is_source"]
|
||||
|
||||
|
||||
class Source:
|
||||
"""A representation of source input to GraphQL."""
|
||||
|
||||
# allow custom attributes and weak references (not used internally)
|
||||
__slots__ = "__weakref__", "__dict__", "body", "name", "location_offset"
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
body: str,
|
||||
name: str = "GraphQL request",
|
||||
location_offset: SourceLocation = SourceLocation(1, 1),
|
||||
) -> None:
|
||||
"""Initialize source input.
|
||||
|
||||
The ``name`` and ``location_offset`` parameters are optional, but they are
|
||||
useful for clients who store GraphQL documents in source files. For example,
|
||||
if the GraphQL input starts at line 40 in a file named ``Foo.graphql``, it might
|
||||
be useful for ``name`` to be ``"Foo.graphql"`` and location to be ``(40, 0)``.
|
||||
|
||||
The ``line`` and ``column`` attributes in ``location_offset`` are 1-indexed.
|
||||
"""
|
||||
self.body = body
|
||||
self.name = name
|
||||
if not isinstance(location_offset, SourceLocation):
|
||||
location_offset = SourceLocation._make(location_offset)
|
||||
if location_offset.line <= 0:
|
||||
raise ValueError(
|
||||
"line in location_offset is 1-indexed and must be positive."
|
||||
)
|
||||
if location_offset.column <= 0:
|
||||
raise ValueError(
|
||||
"column in location_offset is 1-indexed and must be positive."
|
||||
)
|
||||
self.location_offset = location_offset
|
||||
|
||||
def get_location(self, position: int) -> SourceLocation:
|
||||
lines = self.body[:position].splitlines()
|
||||
if lines:
|
||||
line = len(lines)
|
||||
column = len(lines[-1]) + 1
|
||||
else:
|
||||
line = 1
|
||||
column = 1
|
||||
return SourceLocation(line, column)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return f"<{self.__class__.__name__} name={self.name!r}>"
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
return (isinstance(other, Source) and other.body == self.body) or (
|
||||
isinstance(other, str) and other == self.body
|
||||
)
|
||||
|
||||
def __ne__(self, other: Any) -> bool:
|
||||
return not self == other
|
||||
|
||||
|
||||
def is_source(source: Any) -> bool:
|
||||
"""Test if the given value is a Source object.
|
||||
|
||||
For internal use only.
|
||||
"""
|
||||
return isinstance(source, Source)
|
||||
Reference in New Issue
Block a user