Skip to content

Commit

Permalink
fix(Python): Avoid generating recursive types
Browse files Browse the repository at this point in the history
  • Loading branch information
nokome committed Jun 20, 2021
1 parent 261280a commit eceb36a
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 20 deletions.
37 changes: 19 additions & 18 deletions python/stencila/schema/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# in the `schema` directory and run `npm run build:python` to regenerate it.
"""Python classes for schema types."""

# List is imported as Array to avoid conflict with the schema's List type
from typing import Any, Dict, List as Array, Optional, Union
from enum import Enum

Expand Down Expand Up @@ -236,7 +237,7 @@ class CodeChunk(CodeBlock):
label: Optional[str] = None
"""A short label for the CodeChunk."""

outputs: Optional[Array["Node"]] = None
outputs: Optional[Array["Any"]] = None
"""Outputs from executing the chunk."""

reads: Optional[Array[str]] = None
Expand All @@ -262,7 +263,7 @@ def __init__(
imports: Optional[Array[Union["SoftwareSourceCode", "SoftwareApplication", str]]] = None,
label: Optional[str] = None,
meta: Optional[Dict[str, Any]] = None,
outputs: Optional[Array["Node"]] = None,
outputs: Optional[Array["Any"]] = None,
programmingLanguage: Optional[str] = None,
reads: Optional[Array[str]] = None,
uses: Optional[Array[Union["Variable", str]]] = None
Expand Down Expand Up @@ -327,7 +328,7 @@ class CodeExpression(CodeFragment):
errors: Optional[Array["CodeError"]] = None
"""Errors when compiling or executing the chunk."""

output: Optional["Node"] = None
output: Optional["Any"] = None
"""The value of the expression when it was last evaluated."""


Expand All @@ -338,7 +339,7 @@ def __init__(
format: Optional[str] = None,
id: Optional[str] = None,
meta: Optional[Dict[str, Any]] = None,
output: Optional["Node"] = None,
output: Optional["Any"] = None,
programmingLanguage: Optional[str] = None
) -> None:
super().__init__(
Expand Down Expand Up @@ -1432,7 +1433,7 @@ class DatatableColumn(Thing):
name: str # type: ignore
"""The name of the item."""

values: Array["Node"]
values: Array["Any"]
"""The data values of the column."""

validator: Optional["ArrayValidator"] = None
Expand All @@ -1442,7 +1443,7 @@ class DatatableColumn(Thing):
def __init__(
self,
name: str,
values: Array["Node"],
values: Array["Any"],
alternateNames: Optional[Array[str]] = None,
description: Optional[Union[Array["BlockContent"], Array["InlineContent"], str]] = None,
id: Optional[str] = None,
Expand Down Expand Up @@ -1586,15 +1587,15 @@ def __init__(
class ConstantValidator(Validator):
"""A validator specifying a constant value that a node must have."""

value: Optional["Node"] = None
value: Optional["Any"] = None
"""The value that the node must have."""


def __init__(
self,
id: Optional[str] = None,
meta: Optional[Dict[str, Any]] = None,
value: Optional["Node"] = None
value: Optional["Any"] = None
) -> None:
super().__init__(
id=id,
Expand All @@ -1607,15 +1608,15 @@ def __init__(
class EnumValidator(Validator):
"""A schema specifying that a node must be one of several values."""

values: Optional[Array["Node"]] = None
values: Optional[Array["Any"]] = None
"""A node is valid if it is equal to any of these values."""


def __init__(
self,
id: Optional[str] = None,
meta: Optional[Dict[str, Any]] = None,
values: Optional[Array["Node"]] = None
values: Optional[Array["Any"]] = None
) -> None:
super().__init__(
id=id,
Expand Down Expand Up @@ -2085,7 +2086,7 @@ class ListItem(Thing):
isChecked: Optional[bool] = None
"""A flag to indicate if this list item is checked."""

item: Optional["Node"] = None
item: Optional["Any"] = None
"""The item represented by this list item."""

position: Optional[int] = None
Expand All @@ -2101,7 +2102,7 @@ def __init__(
identifiers: Optional[Array[Union["PropertyValue", str]]] = None,
images: Optional[Array[Union["ImageObject", str]]] = None,
isChecked: Optional[bool] = None,
item: Optional["Node"] = None,
item: Optional["Any"] = None,
meta: Optional[Dict[str, Any]] = None,
name: Optional[str] = None,
position: Optional[int] = None,
Expand Down Expand Up @@ -2467,7 +2468,7 @@ class Variable(Entity):
validator: Optional["ValidatorTypes"] = None
"""The validator that the value is validated against."""

value: Optional["Node"] = None
value: Optional["Any"] = None
"""The value of the variable."""


Expand All @@ -2478,7 +2479,7 @@ def __init__(
isReadonly: Optional[bool] = None,
meta: Optional[Dict[str, Any]] = None,
validator: Optional["ValidatorTypes"] = None,
value: Optional["Node"] = None
value: Optional["Any"] = None
) -> None:
super().__init__(
id=id,
Expand All @@ -2497,7 +2498,7 @@ def __init__(
class Parameter(Variable):
"""A parameter that can be set and used in evaluated code."""

default: Optional["Node"] = None
default: Optional["Any"] = None
"""The default value of the parameter."""

isExtensible: Optional[bool] = None
Expand All @@ -2513,15 +2514,15 @@ class Parameter(Variable):
def __init__(
self,
name: str,
default: Optional["Node"] = None,
default: Optional["Any"] = None,
id: Optional[str] = None,
isExtensible: Optional[bool] = None,
isReadonly: Optional[bool] = None,
isRequired: Optional[bool] = None,
isVariadic: Optional[bool] = None,
meta: Optional[Dict[str, Any]] = None,
validator: Optional["ValidatorTypes"] = None,
value: Optional["Node"] = None
value: Optional["Any"] = None
) -> None:
super().__init__(
name=name,
Expand Down Expand Up @@ -4414,7 +4415,7 @@ class CitationIntentEnumeration(Enum):
"""
Union type for all schema nodes, including primitives and entities
"""
Node = Union["Entity", "ArrayValidator", "Article", "AudioObject", "BooleanValidator", "Brand", "CitationIntentEnumeration", "Cite", "CiteGroup", "Claim", "Code", "CodeBlock", "CodeChunk", "CodeError", "CodeExpression", "CodeFragment", "Collection", "Comment", "ConstantValidator", "ContactPoint", "CreativeWork", "Datatable", "DatatableColumn", "Date", "DefinedTerm", "Delete", "Emphasis", "EnumValidator", "Enumeration", "Figure", "Function", "Grant", "Heading", "ImageObject", "Include", "IntegerValidator", "Link", "List", "ListItem", "Mark", "Math", "MathBlock", "MathFragment", "MediaObject", "MonetaryGrant", "NontextualAnnotation", "Note", "NumberValidator", "Organization", "Paragraph", "Parameter", "Periodical", "Person", "PostalAddress", "Product", "PropertyValue", "PublicationIssue", "PublicationVolume", "Quote", "QuoteBlock", "Review", "SoftwareApplication", "SoftwareEnvironment", "SoftwareSession", "SoftwareSourceCode", "StringValidator", "Strong", "Subscript", "Superscript", "Table", "TableCell", "TableRow", "ThematicBreak", "Thing", "TupleValidator", "Validator", "Variable", "VideoObject", "VolumeMount", None, bool, int, float, str, Dict[str, Any], Array["Node"]]
Node = Union["Entity", "ArrayValidator", "Article", "AudioObject", "BooleanValidator", "Brand", "CitationIntentEnumeration", "Cite", "CiteGroup", "Claim", "Code", "CodeBlock", "CodeChunk", "CodeError", "CodeExpression", "CodeFragment", "Collection", "Comment", "ConstantValidator", "ContactPoint", "CreativeWork", "Datatable", "DatatableColumn", "Date", "DefinedTerm", "Delete", "Emphasis", "EnumValidator", "Enumeration", "Figure", "Function", "Grant", "Heading", "ImageObject", "Include", "IntegerValidator", "Link", "List", "ListItem", "Mark", "Math", "MathBlock", "MathFragment", "MediaObject", "MonetaryGrant", "NontextualAnnotation", "Note", "NumberValidator", "Organization", "Paragraph", "Parameter", "Periodical", "Person", "PostalAddress", "Product", "PropertyValue", "PublicationIssue", "PublicationVolume", "Quote", "QuoteBlock", "Review", "SoftwareApplication", "SoftwareEnvironment", "SoftwareSession", "SoftwareSourceCode", "StringValidator", "Strong", "Subscript", "Superscript", "Table", "TableCell", "TableRow", "ThematicBreak", "Thing", "TupleValidator", "Validator", "Variable", "VideoObject", "VolumeMount", None, bool, int, float, str, Dict[str, Any], Array["Any"]]


"""
Expand Down
12 changes: 10 additions & 2 deletions ts/bindings/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ async function build(): Promise<void> {
)}
"""Python classes for schema types."""
# List is imported as Array to avoid conflict with the schema's List type
from typing import Any, Dict, List as Array, Optional, Union
from enum import Enum
Expand Down Expand Up @@ -212,12 +213,19 @@ export function unionGenerator(schema: JsonSchema): string {
}

/**
* Convert a schema definition to a Python type
* Convert a schema definition to a Python type.
*
* To avoid cyclic type definitions in MyPy, the type `Node` is converted
* to a Python `Any`. See https://github.com/python/mypy/issues/731
*/
function schemaToType(schema: JsonSchema): string {
const { type, anyOf, allOf, $ref } = schema

if ($ref !== undefined) return `"${$ref.replace('.schema.json', '')}"`
if ($ref !== undefined) {
const title = $ref.replace('.schema.json', '')
return `"${title === 'Node' ? 'Any' : title}"`
}

if (anyOf !== undefined) return anyOfToType(anyOf)
if (allOf !== undefined) return allOfToType(allOf)
if (schema.enum !== undefined) return enumToType(schema['@id'], schema.enum)
Expand Down

0 comments on commit eceb36a

Please sign in to comment.