Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for exporting Signature objects as JSON #289

Merged
merged 1 commit into from
Oct 2, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions papyri/signature.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from dataclasses import dataclass
from typing import Optional, List
from .common_ast import Node

import json

@dataclass
class ParameterNode(Node):
Expand Down Expand Up @@ -58,10 +58,17 @@ def to_node(self):

parameters = []
for param in self.parameters.values():
if param.annotation is inspect._empty:
annotation = None
elif isinstance(param.annotation, str):
annotation = param.annotation
else:
# TODO: Keep the original annotation object somewhere
annotation = inspect.formatannotation(param.annotation)
parameters.append(
ParameterNode(
param.name,
None if param.annotation is inspect._empty else param.annotation,
annotation,
param.kind.name,
None if param.default else str(param.default),
)
Expand Down Expand Up @@ -92,6 +99,11 @@ def param_default(self, param):
def annotations(self):
return self.target_item.__annotations__

@property
def return_annotation(self) -> Optional[str]:
return_annotation = self._sig.return_annotation
return None if return_annotation is inspect._empty else inspect.formatannotation(return_annotation)

@property
def is_public(self) -> bool:
return not self.target_item.__name__.startswith("_")
Expand Down Expand Up @@ -124,5 +136,26 @@ def keyword_only_parameter_count(self):
else:
return None

def to_dict(self) -> dict:
"""
Output self as JSON (Python dict), using the same format as Griffe
"""
json_data = self.to_node().to_dict()

# Use human-readable names for parameter kinds
for param in json_data['parameters']:
param['kind'] = getattr(inspect._ParameterKind, param['kind']).description


json_data["returns"] = self.return_annotation

return json_data

def to_json(self) -> bytes:
"""
Output self as JSON, using the same format as Griffe
"""
return json.dumps(self.to_dict(), indent=2, sort_keys=True).encode()

def __str__(self):
return str(self._sig)