Support Classes with No fields
Closed this issue · 4 comments
xaellison commented
This works
from pydantic import BaseModel
class WrapperClass(BaseModel):
field: int
erd.create(WrapperClass)
but this does not
from pydantic import BaseModel
class EmptyClass(BaseModel):
pass
erd.create(EmptyClass)
stack trace
StopIteration Traceback (most recent call last)
File ~/.pyenv/versions/3.8.11/envs/default/lib/python3.8/site-packages/IPython/core/formatters.py:344, in BaseFormatter.__call__(self, obj)
342 method = get_real_method(obj, self.print_method)
343 if method is not None:
--> 344 return method()
345 return None
346 else:
File ~/.pyenv/versions/3.8.11/envs/default/lib/python3.8/site-packages/erdantic/core.py:712, in EntityRelationshipDiagram._repr_png_(self)
710 def _repr_png_(self) -> bytes:
711 """IPython special method to display object as a PNG image."""
--> 712 graph = self.to_graphviz()
713 return graph.draw(prog="dot", format="png")
File ~/.pyenv/versions/3.8.11/envs/default/lib/python3.8/site-packages/erdantic/core.py:644, in EntityRelationshipDiagram.to_graphviz(self, graph_attr, node_attr, edge_attr)
640 g.edge_attr.update(edge_attr or {})
641 for full_name, model_info in self.models.items():
642 g.add_node(
643 full_name,
--> 644 label=model_info.to_dot_label(),
645 tooltip=model_info.description.replace("\n", "
"),
646 )
647 for edge in self.edges.values():
648 g.add_edge(
649 edge.source_model_full_name,
650 edge.target_model_full_name,
(...)
654 arrowtail=edge.source_dot_arrow_shape(),
655 )
File ~/.pyenv/versions/3.8.11/envs/default/lib/python3.8/site-packages/erdantic/core.py:302, in ModelInfo.to_dot_label(self)
294 """Returns the DOT language "HTML-like" syntax specification of a table for this data
295 model. It is used as the `label` attribute of data model's node in the graph's DOT
296 representation.
(...)
299 str: DOT language for table
300 """
301 # Get number of columns dynamically from first row
--> 302 num_cols = next(iter(self.fields.values())).to_dot_row().count("<td")
303 # Concatenate DOT of all rows together
304 rows = "\n".join(field_info.to_dot_row() for field_info in self.fields.values()) + "\n"
StopIteration:
jayqi commented
Hi @xaellison, can you explain a little more about your use case here?
I'm not sure about whether drawing a class with no fields makes sense, but at least there's room for either a better error message or more graceful handling of the error.
xaellison commented
Hey @jayqi, thanks for the reply. I'm collaborating on a project that has some placeholder class definitions with no fields - we're going to implement them later.
I don't particularly care about being able to render an empty class. It'd be great if it did not error out, though.
- Would it be possible to treat it like a primitive type like an int that shows up as a field but doesn't point anywhere?
- Could we populate a fake field in if there are no real ones?
jayqi commented
Should be fixed in v1.0.3.
xaellison commented
great thank you!