Skip to content
Merged
Show file tree
Hide file tree
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
10 changes: 10 additions & 0 deletions schema_salad/avro/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class Schema:
"""Base class for all Schema classes."""

def __init__(self, atype: str, other_props: Optional[PropsType] = None) -> None:
"""Avro Schema initializer."""
# Ensure valid ctor args
if not isinstance(atype, str):
raise SchemaParseException(
Expand All @@ -123,9 +124,11 @@ def props(self) -> PropsType:

# utility functions to manipulate properties dict
def get_prop(self, key: str) -> Optional[PropType]:
"""Retrieve a property from the Schema."""
return self._props.get(key)

def set_prop(self, key: str, value: Optional[PropType]) -> None:
"""Set a Schema property."""
self._props[key] = value


Expand Down Expand Up @@ -173,6 +176,7 @@ def validate(val: Optional[str], name: str) -> None:

@property
def fullname(self) -> Optional[str]:
"""Retrieve the computed full name."""
return self._full

def get_space(self) -> Optional[str]:
Expand All @@ -189,10 +193,12 @@ class Names:
"""Track name set and default namespace during parsing."""

def __init__(self, default_namespace: Optional[str] = None) -> None:
"""Create a namespace tracker."""
self.names: dict[str, NamedSchema] = {}
self.default_namespace = default_namespace

def has_name(self, name_attr: str, space_attr: Optional[str]) -> bool:
"""Test if the given namespace is stored."""
test = Name(name_attr, space_attr, self.default_namespace).fullname
return test in self.names

Expand Down Expand Up @@ -324,13 +330,16 @@ def __init__(
# read-only properties
@property
def default(self) -> Optional[Any]:
"""Return the default value, if any."""
return self.get_prop("default")

# utility functions to manipulate properties dict
def get_prop(self, key: str) -> Optional[PropType]:
"""Retrieve a property from the Field."""
return self._props.get(key)

def set_prop(self, key: str, value: Optional[PropType]) -> None:
"""Set a Field property."""
self._props[key] = value


Expand All @@ -341,6 +350,7 @@ class PrimitiveSchema(Schema):
"""Valid primitive types are in PRIMITIVE_TYPES."""

def __init__(self, atype: str, other_props: Optional[PropsType] = None) -> None:
"""Create a PrimitiveSchema."""
# Ensure valid ctor args
if atype not in PRIMITIVE_TYPES:
raise AvroException(f"{atype} is not a valid primitive type.")
Expand Down
5 changes: 3 additions & 2 deletions schema_salad/cpp_codegen.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
C++17 code generator for a given Schema Salad definition.

Currently only supports emiting YAML from the C++ objects, not yet parsing
Currently only supports emitting YAML from the C++ objects, not yet parsing
YAML into C++ objects.

The generated code requires the libyaml-cpp library & headers
Expand Down Expand Up @@ -489,7 +489,7 @@ def writeDefinition(self, target: IO[str], ind: str, common_namespace: str) -> N

# !TODO way to many functions, most of these shouldn't exists
def isPrimitiveType(v: Any) -> bool:
"""Check if v is a primitve type."""
"""Check if v is a primitive type."""
if not isinstance(v, str):
return False
return v in ["null", "boolean", "int", "long", "float", "double", "string"]
Expand Down Expand Up @@ -714,6 +714,7 @@ def convertTypeToCpp(self, type_declaration: Union[list[Any], dict[str, Any], st
return f"std::variant<{type_declaration}>"

def epilogue(self, root_loader: Optional[TypeDef]) -> None:
"""Trigger to generate the epilouge code."""
# find common namespace

common_namespace = os.path.commonprefix(
Expand Down
1 change: 1 addition & 0 deletions schema_salad/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def as_warning(self) -> "SchemaSaladException":
return self

def with_sourceline(self, sl: Optional[SourceLine]) -> "SchemaSaladException":
"""Use the provided SourceLine to set the causal location."""
if sl and sl.file():
self.file = sl.file()
self.start = sl.start()
Expand Down
9 changes: 5 additions & 4 deletions schema_salad/java_codegen.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def _ensure_directory_and_write(path: Path, contents: str) -> None:
f.write(contents)


def doc_to_doc_string(doc: Optional[str], indent_level: int = 0) -> str:
def _doc_to_doc_string(doc: Optional[str], indent_level: int = 0) -> str:
lead = " " + " " * indent_level + "* " * indent_level
if doc:
doc_str = f"{lead}<BLOCKQUOTE>\n"
Expand Down Expand Up @@ -185,9 +185,9 @@ def begin_class(
if not abstract:
implemented_by = "This interface is implemented by {{@link {}Impl}}<BR>"
interface_doc_str += implemented_by.format(cls)
interface_doc_str += doc_to_doc_string(doc)
interface_doc_str += _doc_to_doc_string(doc)
class_doc_str = f"* Auto-generated class implementation for <I>{classname}</I><BR>"
class_doc_str += doc_to_doc_string(doc)
class_doc_str += _doc_to_doc_string(doc)
target = self.main_src_dir / f"{cls}.java"
with open(target, "w") as f:
_logger.info("Writing file: %s", target)
Expand Down Expand Up @@ -683,7 +683,7 @@ def declare_field(
{field_doc_str}
*/
""".format(
fieldname=fieldname, field_doc_str=doc_to_doc_string(doc, indent_level=1)
fieldname=fieldname, field_doc_str=_doc_to_doc_string(doc, indent_level=1)
)
target = self.main_src_dir / f"{self.current_class}.java"
with open(target, "a") as f:
Expand Down Expand Up @@ -850,6 +850,7 @@ def idmap_loader(
)

def typedsl_loader(self, inner: TypeDef, ref_scope: Union[int, None]) -> TypeDef:
"""Construct the TypeDef for the given DSL loader."""
instance_type = inner.instance_type or "Object"
return self.declare_type(
TypeDef(
Expand Down
3 changes: 2 additions & 1 deletion schema_salad/ref_resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def add_namespaces(self, ns: dict[str, str]) -> None:
self.vocab.update(ns)

def add_schemas(self, ns: Union[list[str], str], base_url: str) -> None:
"""Fetch exernal schemas and add them to the graph."""
"""Fetch external schemas and add them to the graph."""
if self.skip_schemas:
return
for sch in aslist(ns):
Expand Down Expand Up @@ -1102,6 +1102,7 @@ def validate_link(
return link

def getid(self, d: Any) -> Optional[str]:
"""Use our identifiers to extract the first match from the document."""
if isinstance(d, MutableMapping):
for i in self.identifiers:
if i in d:
Expand Down
2 changes: 1 addition & 1 deletion schema_salad/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ def extend_and_specialize(items: list[dict[str, Any]], loader: Loader) -> list[d
# because we have unit tests that rely on the order that
# fields are written. Codegen output changes as well.
# We are relying on the insertion order preserving
# property of python dicts (i.e. relyig on Py3.5+).
# property of Python dicts (i.e. relying on Py3.5+).

# First pass adding the exfields.
for sn_exfield, exfield in sns_exfields.items():
Expand Down
16 changes: 15 additions & 1 deletion schema_salad/sourceline.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import ruamel.yaml
from ruamel.yaml.comments import CommentedBase, CommentedMap, CommentedSeq

lineno_re = re.compile("^(.*?:[0-9]+:[0-9]+: )(( *)(.*))")
lineno_re = re.compile(r"^(.*?:[0-9]+:[0-9]+: )(( *)(.*))")


def _add_lc_filename(r: ruamel.yaml.comments.CommentedBase, source: AnyStr) -> None:
Expand All @@ -32,6 +32,7 @@ def add_lc_filename(r: ruamel.yaml.comments.CommentedBase, source: str) -> None:


def reflow_all(text: str, maxline: Optional[int] = None) -> str:
"""Reflow text respecting a common prefix with line & col info."""
if maxline is None:
maxline = int(os.environ.get("COLUMNS", "100"))
maxno = 0
Expand Down Expand Up @@ -59,6 +60,7 @@ def reflow_all(text: str, maxline: Optional[int] = None) -> str:


def reflow(text: str, maxline: int, shift: Optional[str] = "") -> str:
"""Reflow a single line of text."""
maxline = max(maxline, 20)
if len(text) > maxline:
sp = text.rfind(" ", 0, maxline)
Expand Down Expand Up @@ -120,6 +122,7 @@ def strip_duplicated_lineno(text: str) -> str:


def strip_dup_lineno(text: str, maxline: Optional[int] = None) -> str:
"""Strip duplicated line numbers."""
if maxline is None:
maxline = int(os.environ.get("COLUMNS", "100"))
pre: Optional[str] = None
Expand Down Expand Up @@ -163,6 +166,16 @@ def cmap(
lc: Optional[list[int]] = None,
fn: Optional[str] = None,
) -> Union[int, float, str, CommentedMap, CommentedSeq, None]:
"""
Apply line+column & filename data through to the provided data.

:param d: Target datastructure: number and strings will be passed through
unchanged. Non-Commented container types with be transformed into
the relevant Commented container types.
:param lc: Line & Column information to be applied.
:param fn: The Filename to store.
:returns: The (transformed) datastructure.
"""
if lc is None:
lc = [0, 0, 0, 0]
if fn is None:
Expand Down Expand Up @@ -241,6 +254,7 @@ def __exit__(
raise self.makeError(str(exc_value)) from exc_value

def file(self) -> Optional[str]:
"""Return the embedded filename."""
if hasattr(self.item, "lc") and hasattr(self.item.lc, "filename"):
return str(self.item.lc.filename)
return None
Expand Down
2 changes: 0 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,6 @@
},
install_requires=install_requires,
extras_require=extras_require,
test_suite="tests",
tests_require=["pytest<9"],
entry_points={
"console_scripts": [
"schema-salad-tool=schema_salad.main:main",
Expand Down
Loading