Skip to content

Commit

Permalink
Merge pull request #560 from jdegenstein/groupby_str_repr
Browse files Browse the repository at this point in the history
Better GroupBy dunder str/repr/ipython methods
  • Loading branch information
gumyr authored Feb 22, 2024
2 parents 72827ff + 1c61a13 commit 1717698
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/build123d/topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
from typing_extensions import Self, Literal

from anytree import NodeMixin, PreOrderIter, RenderTree
from IPython.lib.pretty import pretty
from scipy.spatial import ConvexHull
from vtkmodules.vtkCommonDataModel import vtkPolyData
from vtkmodules.vtkFiltersCore import vtkPolyDataNormals, vtkTriangleFilter
Expand Down Expand Up @@ -3750,6 +3751,23 @@ def __len__(self):
def __getitem__(self, key: int):
return self.groups[key]

def __str__(self):
return pretty(self)

def __repr__(self):
return repr(ShapeList(self))

def _repr_pretty_(self, p, cycle = False):
if cycle:
p.text('(...)')
else:
with p.group(1, '[', ']'):
for idx, item in enumerate(self):
if idx:
p.text(',')
p.breakable()
p.pretty(item)

def group(self, key: K):
"""Select group by key"""
for k, i in self.key_to_group_index:
Expand Down
52 changes: 52 additions & 0 deletions tests/test_direct_api.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# system modules
import copy
import io
import json
import math
import os
Expand All @@ -9,6 +10,7 @@
from typing import Optional
import unittest
from random import uniform
from IPython.lib import pretty

from OCP.BRepBuilderAPI import BRepBuilderAPI_MakeEdge
from OCP.gp import (
Expand Down Expand Up @@ -2853,6 +2855,21 @@ def test_manifold(self):
class TestShapeList(DirectApiTestCase):
"""Test ShapeList functionality"""

def assertDunderStrEqual(self, actual: str, expected_lines: list[str]):
actual_lines = actual.splitlines()
self.assertEqual(len(actual_lines), len(expected_lines))
for actual_line, expected_line in zip(actual_lines, expected_lines):
start, end = re.split(r"at 0x[0-9a-f]+", expected_line, 2, re.I)
self.assertTrue(actual_line.startswith(start))
self.assertTrue(actual_line.endswith(end))

def assertDunderReprEqual(self, actual: str, expected: str):
splitter = r"at 0x[0-9a-f]+"
actual_split_list = re.split(splitter, actual, 0, re.I)
expected_split_list = re.split(splitter, expected, 0, re.I)
for actual_split, expected_split in zip(actual_split_list, expected_split_list):
self.assertEqual(actual_split, expected_split)

def test_sort_by(self):
faces = Solid.make_box(1, 2, 3).faces() < SortBy.AREA
self.assertAlmostEqual(faces[-1].area, 2, 5)
Expand Down Expand Up @@ -2963,6 +2980,41 @@ def test_group_by_retrieve_groups(self):
with self.assertRaises(KeyError):
result.group("C")

def test_group_by_str_repr(self):
nonagon = RegularPolygon(5,9)

expected = [
"[[<build123d.topology.Edge at 0x1277f6e1cd0>],",
" [<build123d.topology.Edge at 0x1277f6e1c10>,",
" <build123d.topology.Edge at 0x1277fd8a090>],",
" [<build123d.topology.Edge at 0x1277f75d690>,",
" <build123d.topology.Edge at 0x127760d9310>],",
" [<build123d.topology.Edge at 0x12777261f90>,",
" <build123d.topology.Edge at 0x1277f6bd2d0>],",
" [<build123d.topology.Edge at 0x1276fbb0590>,",
" <build123d.topology.Edge at 0x1277fec6d90>]]",
]

self.assertDunderStrEqual(str(nonagon.edges().group_by(Axis.X)), expected)

expected_repr = (
"[[<build123d.topology.Edge object at 0x000001277FEC6D90>],"
" [<build123d.topology.Edge object at 0x000001277F6BCC10>,"
" <build123d.topology.Edge object at 0x000001277EC3D5D0>],"
" [<build123d.topology.Edge object at 0x000001277F6BEA90>,"
" <build123d.topology.Edge object at 0x000001276FCB2310>],"
" [<build123d.topology.Edge object at 0x000001277F6D10D0>,"
" <build123d.topology.Edge object at 0x000001276FBAAD10>],"
" [<build123d.topology.Edge object at 0x000001277FC86F90>,"
" <build123d.topology.Edge object at 0x000001277F6E1CD0>]]"
)
self.assertDunderReprEqual(repr(nonagon.edges().group_by(Axis.X)),expected_repr)

f = io.StringIO()
p = pretty.PrettyPrinter(f)
nonagon.edges().group_by(Axis.X)._repr_pretty_(p, cycle=True)
self.assertEqual(f.getvalue(), "(...)")

def test_distance(self):
with BuildPart() as box:
Box(1, 2, 3)
Expand Down

0 comments on commit 1717698

Please sign in to comment.