Repository: fusion-energy/paramak (language: python)

Issue:
Added patch for Workplane.extrude to permit CQ 2.1/2.2 compatibility
## Proposed changes

Added `patch_workplane()` function that 'monkey patches' CadQuery's `Workplane.extrude` function. All calls have been updated to use the `until` keyword instead of `distance`, but this patch corrects it back to `distance` if the user chooses to use CadQuery 2.1.

## Types of changes

What types of changes does your code introduce to the Paramak?
_Put an `x` in the boxes that apply_

- [x] Bugfix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] Code refactoring
- [ ] Documentation Update (if none of the other choices apply)
- [ ] New tests

## Checklist

_Put an `x` in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your code._

- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] I have added necessary documentation (if appropriate)



Discussion / hints:

Fix patch:
diff --git a/examples/example_parametric_reactors/render_of_random_reactor.py b/examples/example_parametric_reactors/render_of_random_reactor.py
index 2b33d2d7a..84db26462 100644
--- a/examples/example_parametric_reactors/render_of_random_reactor.py
+++ b/examples/example_parametric_reactors/render_of_random_reactor.py
@@ -66,7 +66,7 @@ def create_reactor_renders(
     )
 
     # sets the position of the camera using a matrix
-    cam = 2 ** -0.5
+    cam = 2**-0.5
     camera_pose = np.array(
         [[1, 0, 0, 0], [0, cam, -cam, -350], [0, cam, cam, 350], [0, 0, 0, 1]]
     )
diff --git a/examples/example_parametric_reactors/render_of_random_reactors.py b/examples/example_parametric_reactors/render_of_random_reactors.py
index dc09a8971..988e56c8c 100644
--- a/examples/example_parametric_reactors/render_of_random_reactors.py
+++ b/examples/example_parametric_reactors/render_of_random_reactors.py
@@ -83,7 +83,7 @@ def create_reactor_renders(
     )
 
     # sets the position of the camera using a matrix
-    cam = 2 ** -0.5
+    cam = 2**-0.5
     camera_pose = np.array(
         [[1, 0, 0, 0], [0, cam, -cam, -650], [0, cam, cam, 650], [0, 0, 0, 1]]
     )
diff --git a/paramak/parametric_components/blanket_fp.py b/paramak/parametric_components/blanket_fp.py
index 46b17021f..5a8210e5d 100644
--- a/paramak/parametric_components/blanket_fp.py
+++ b/paramak/parametric_components/blanket_fp.py
@@ -242,7 +242,7 @@ def create_offset_points(self, thetas, offset):
             ny = -val_R_derivative
 
             # normalise normal vector
-            normal_vector_norm = (nx ** 2 + ny ** 2) ** 0.5
+            normal_vector_norm = (nx**2 + ny**2) ** 0.5
             nx /= normal_vector_norm
             ny /= normal_vector_norm
 
diff --git a/paramak/parametric_components/toroidal_field_coil_coat_hanger.py b/paramak/parametric_components/toroidal_field_coil_coat_hanger.py
index 5aa9fa9e5..afdc61793 100644
--- a/paramak/parametric_components/toroidal_field_coil_coat_hanger.py
+++ b/paramak/parametric_components/toroidal_field_coil_coat_hanger.py
@@ -5,7 +5,9 @@
 import numpy as np
 
 from paramak import ExtrudeStraightShape
-from paramak.utils import calculate_wedge_cut, rotate
+from paramak.utils import calculate_wedge_cut, rotate, patch_workplane
+
+patch_workplane()
 
 
 class ToroidalFieldCoilCoatHanger(ExtrudeStraightShape):
@@ -222,7 +224,7 @@ def create_solid(self):
 
         self.wire = wire
 
-        solid = wire.extrude(distance=-self.distance / 2.0, both=True)
+        solid = wire.extrude(until=-self.distance / 2.0, both=True)
 
         solid = self.rotate_solid(solid)
 
@@ -233,7 +235,7 @@ def create_solid(self):
             inner_leg_solid = cq.Workplane(self.workplane)
             inner_leg_solid = inner_leg_solid.polyline(self.inner_leg_connection_points)
             inner_leg_solid = inner_leg_solid.close().extrude(
-                distance=-self.distance / 2.0, both=True
+                until=-self.distance / 2.0, both=True
             )
 
             inner_leg_solid = self.rotate_solid(inner_leg_solid)
diff --git a/paramak/parametric_components/toroidal_field_coil_rectangle.py b/paramak/parametric_components/toroidal_field_coil_rectangle.py
index fd0c778b5..c2b6659f6 100644
--- a/paramak/parametric_components/toroidal_field_coil_rectangle.py
+++ b/paramak/parametric_components/toroidal_field_coil_rectangle.py
@@ -4,7 +4,9 @@
 import numpy as np
 
 from paramak import ExtrudeStraightShape
-from paramak.utils import calculate_wedge_cut
+from paramak.utils import calculate_wedge_cut, patch_workplane
+
+patch_workplane()
 
 
 class ToroidalFieldCoilRectangle(ExtrudeStraightShape):
@@ -129,7 +131,7 @@ def create_solid(self):
 
         self.wire = wire
 
-        solid = wire.extrude(distance=-self.distance / 2.0, both=True)
+        solid = wire.extrude(until=-self.distance / 2.0, both=True)
 
         solid = self.rotate_solid(solid)
 
@@ -140,7 +142,7 @@ def create_solid(self):
             inner_leg_solid = cq.Workplane(self.workplane)
             inner_leg_solid = inner_leg_solid.polyline(self.inner_leg_connection_points)
             inner_leg_solid = inner_leg_solid.close().extrude(
-                distance=-self.distance / 2.0, both=True
+                until=-self.distance / 2.0, both=True
             )
 
             inner_leg_solid = self.rotate_solid(inner_leg_solid)
diff --git a/paramak/parametric_components/toroidal_field_coil_round_corners.py b/paramak/parametric_components/toroidal_field_coil_round_corners.py
index 5d80b6679..be8ebb741 100644
--- a/paramak/parametric_components/toroidal_field_coil_round_corners.py
+++ b/paramak/parametric_components/toroidal_field_coil_round_corners.py
@@ -4,7 +4,9 @@
 import numpy as np
 
 from paramak.parametric_shapes.extruded_mixed_shape import ExtrudeMixedShape
-from paramak.utils import calculate_wedge_cut
+from paramak.utils import calculate_wedge_cut, patch_workplane
+
+patch_workplane()
 
 
 class ToroidalFieldCoilRectangleRoundCorners(ExtrudeMixedShape):
@@ -98,7 +100,7 @@ def _find_radii(self):
             self._outter_curve_radius = (
                 1 + (self._thickness / self._base_length)
             ) * self._thickness
-            self._inner_curve_radius = (self._thickness ** 2) / self._base_length
+            self._inner_curve_radius = (self._thickness**2) / self._base_length
 
         self._analyse_attributes[2] = self._inner_curve_radius
         self._analyse_attributes[3] = self._outter_curve_radius
@@ -243,11 +245,11 @@ def find_points(self):
 
         def shift_long(radius):
             """radius is the radius of curvature"""
-            return (2 ** 0.5) * 0.5 * radius
+            return (2**0.5) * 0.5 * radius
 
         def shift_short(radius):
             """radius is the radius of curvature"""
-            return (2 - (2 ** 0.5)) * 0.5 * radius
+            return (2 - (2**0.5)) * 0.5 * radius
 
         point11 = (point2[0] - inner_curve_radius, point2[1])
         point12 = (
@@ -362,7 +364,7 @@ def create_solid(self):
             .consolidateWires()
         )
 
-        solid = wire.extrude(distance=-self._distance / 2, both=True)
+        solid = wire.extrude(until=-self._distance / 2, both=True)
         solid = self.rotate_solid(solid)
 
         cutting_wedge = calculate_wedge_cut(self)
@@ -375,7 +377,7 @@ def create_solid(self):
             inner_leg_solid = (
                 inner_leg_solid.polyline(self._inner_leg_connection_points)
                 .close()
-                .extrude(distance=-self._distance / 2, both=True)
+                .extrude(until=-self._distance / 2, both=True)
             )
 
             inner_leg_solid = self.rotate_solid(inner_leg_solid)
diff --git a/paramak/parametric_shapes/extruded_circle_shape.py b/paramak/parametric_shapes/extruded_circle_shape.py
index a2943baa7..f9dca5eaf 100644
--- a/paramak/parametric_shapes/extruded_circle_shape.py
+++ b/paramak/parametric_shapes/extruded_circle_shape.py
@@ -3,7 +3,9 @@
 from cadquery import Workplane
 
 from paramak import Shape
-from paramak.utils import calculate_wedge_cut
+from paramak.utils import calculate_wedge_cut, patch_workplane
+
+patch_workplane()
 
 
 class ExtrudeCircleShape(Shape):
@@ -102,7 +104,7 @@ def create_solid(self):
 
         self.wire = wire
 
-        solid = wire.extrude(distance=extrusion_distance, both=self.extrude_both)
+        solid = wire.extrude(until=extrusion_distance, both=self.extrude_both)
 
         solid = self.rotate_solid(solid)
         cutting_wedge = calculate_wedge_cut(self)
diff --git a/paramak/parametric_shapes/extruded_mixed_shape.py b/paramak/parametric_shapes/extruded_mixed_shape.py
index cd2fd59ee..d768845ba 100644
--- a/paramak/parametric_shapes/extruded_mixed_shape.py
+++ b/paramak/parametric_shapes/extruded_mixed_shape.py
@@ -1,7 +1,9 @@
 from typing import Optional, Tuple
 
 from paramak import Shape
-from paramak.utils import calculate_wedge_cut
+from paramak.utils import calculate_wedge_cut, patch_workplane
+
+patch_workplane()
 
 
 class ExtrudeMixedShape(Shape):
@@ -83,7 +85,7 @@ def create_solid(self):
 
         self.wire = wire
 
-        solid = wire.extrude(distance=extrusion_distance, both=self.extrude_both)
+        solid = wire.extrude(until=extrusion_distance, both=self.extrude_both)
 
         # filleting rectangular port cutter edges
         # must be done before azimuthal placement
diff --git a/paramak/utils.py b/paramak/utils.py
index 2155b797e..bc94042bf 100644
--- a/paramak/utils.py
+++ b/paramak/utils.py
@@ -356,7 +356,7 @@ def add_thickness(
             nx *= -1
             ny *= -1
         # normalize normal vector
-        normal_vector_norm = (nx ** 2 + ny ** 2) ** 0.5
+        normal_vector_norm = (nx**2 + ny**2) ** 0.5
         nx /= normal_vector_norm
         ny /= normal_vector_norm
         # calculate outer points
@@ -801,3 +801,20 @@ def filter(self, object_list):
                 new_obj_list.append(obj)
         print("length(new_obj_list)", len(new_obj_list))
         return new_obj_list
+
+
+def patch_workplane():
+    """Going from CadQuery 2.1 to 2.2, the 'distance' arg to extrude was renamed 'until'.
+    This patch ensures that either version works fine using 'until'.
+    """
+    from cadquery import Workplane
+
+    if "distance" in Workplane.extrude.__code__.co_varnames:
+        extrude_func = Workplane.extrude
+
+        def extrude(*args, **kwargs):
+            if "until" in kwargs.keys():
+                kwargs["distance"] = kwargs.pop("until")
+            return extrude_func(*args, **kwargs)
+
+        Workplane.extrude = extrude


Test patch:
diff --git a/tests/test_parametric_components/test_CuttingWedge.py b/tests/test_parametric_components/test_CuttingWedge.py
index ef086a345..6b1ce814b 100644
--- a/tests/test_parametric_components/test_CuttingWedge.py
+++ b/tests/test_parametric_components/test_CuttingWedge.py
@@ -24,5 +24,5 @@ def test_volume_of_for_5_random_dimentions(self):
                 azimuth_placement_angle=azimuth_placement_angle,
             )
             angle_fraction = 360 / rotation_angle
-            correct_volume = (math.pi * radius ** 2 * height) / angle_fraction
+            correct_volume = (math.pi * radius**2 * height) / angle_fraction
             assert test_shape.volume() == pytest.approx(correct_volume)
diff --git a/tests/test_parametric_components/test_capsule_vacuum_vessel.py b/tests/test_parametric_components/test_capsule_vacuum_vessel.py
index ac4891083..9c73c8322 100644
--- a/tests/test_parametric_components/test_capsule_vacuum_vessel.py
+++ b/tests/test_parametric_components/test_capsule_vacuum_vessel.py
@@ -97,11 +97,11 @@ def volume(outer_start_point, radius, thickness, angle):
     point9 = test_shape.points[8]
     point10 = test_shape.points[9]
 
-    outer_volume_cylinder = float(math.pi * (radius ** 2) * (point4[1] - point3[1]))
+    outer_volume_cylinder = float(math.pi * (radius**2) * (point4[1] - point3[1]))
     inner_volume_cylinder = float(
         math.pi * ((radius - thickness) ** 2) * (point9[1] - point10[1])
     )
-    outer_volume_sphere = float((4 / 3) * math.pi * (radius ** 3))
+    outer_volume_sphere = float((4 / 3) * math.pi * (radius**3))
     inner_volume_sphere = float((4 / 3) * math.pi * ((radius - thickness) ** 3))
     outer_volume = outer_volume_sphere + outer_volume_cylinder
     inner_volume = inner_volume_cylinder + inner_volume_sphere
diff --git a/tests/test_parametric_components/test_center_column_shield_cylinder.py b/tests/test_parametric_components/test_center_column_shield_cylinder.py
index fd787ecc6..48807a8b8 100644
--- a/tests/test_parametric_components/test_center_column_shield_cylinder.py
+++ b/tests/test_parametric_components/test_center_column_shield_cylinder.py
@@ -64,7 +64,7 @@ def test_absolute_volume(self):
         relative volume is correct"""
 
         assert self.test_shape.volume() == pytest.approx(
-            ((math.pi * (200 ** 2)) - (math.pi * (100 ** 2))) * 600
+            ((math.pi * (200**2)) - (math.pi * (100**2))) * 600
         )
 
     def test_absolute_area(self):
@@ -73,13 +73,13 @@ def test_absolute_area(self):
 
         assert len(self.test_shape.areas) == 4
         assert self.test_shape.area == pytest.approx(
-            (((math.pi * (200 ** 2)) - (math.pi * (100 ** 2))) * 2)
+            (((math.pi * (200**2)) - (math.pi * (100**2))) * 2)
             + (math.pi * (2 * 200) * 600)
             + (math.pi * (2 * 100) * 600)
         )
         assert (
             self.test_shape.areas.count(
-                pytest.approx((math.pi * (200 ** 2)) - (math.pi * (100 ** 2)))
+                pytest.approx((math.pi * (200**2)) - (math.pi * (100**2)))
             )
             == 2
         )
diff --git a/tests/test_parametric_components/test_coolant_channel_ring_straight.py b/tests/test_parametric_components/test_coolant_channel_ring_straight.py
index dd316f5e3..7ab9ce202 100644
--- a/tests/test_parametric_components/test_coolant_channel_ring_straight.py
+++ b/tests/test_parametric_components/test_coolant_channel_ring_straight.py
@@ -33,10 +33,10 @@ def test_faces(self):
         self.test_shape.rotation_axis = "Z"
 
         assert self.test_shape.area == pytest.approx(
-            (((math.pi * (10 ** 2)) * 2) + (math.pi * (10 * 2) * 100)) * 8
+            (((math.pi * (10**2)) * 2) + (math.pi * (10 * 2) * 100)) * 8
         )
         assert len(self.test_shape.areas) == 24
-        assert self.test_shape.areas.count(pytest.approx(math.pi * (10 ** 2))) == 16
+        assert self.test_shape.areas.count(pytest.approx(math.pi * (10**2))) == 16
         assert self.test_shape.areas.count(pytest.approx(math.pi * (10 * 2) * 100)) == 8
 
     def test_volume(self):
@@ -45,7 +45,7 @@ def test_volume(self):
         self.test_shape.workplane = "XY"
         self.test_shape.rotation_axis = "Z"
 
-        assert self.test_shape.volume() == pytest.approx(math.pi * (10 ** 2) * 100 * 8)
+        assert self.test_shape.volume() == pytest.approx(math.pi * (10**2) * 100 * 8)
 
     def test_start_angle(self):
         """Checks that the coolant channels are placed at the correct azimuthal placement
diff --git a/tests/test_parametric_components/test_port_cutter_circular.py b/tests/test_parametric_components/test_port_cutter_circular.py
index 5baa0f9c6..fbb297cf8 100644
--- a/tests/test_parametric_components/test_port_cutter_circular.py
+++ b/tests/test_parametric_components/test_port_cutter_circular.py
@@ -40,10 +40,10 @@ def test_relative_volume(self):
     def test_absolute_volume(self):
         """Creates a PortCutterCircular shape and checks that its volume is correct."""
 
-        assert self.test_shape.volume() == pytest.approx(math.pi * (20 ** 2) * 300)
+        assert self.test_shape.volume() == pytest.approx(math.pi * (20**2) * 300)
 
         self.test_shape.extrusion_start_offset = 20
         self.test_shape.azimuth_placement_angle = [0, 90, 180, 270]
         self.test_shape.radius = 10
 
-        assert self.test_shape.volume() == pytest.approx(math.pi * (10 ** 2) * 300 * 4)
+        assert self.test_shape.volume() == pytest.approx(math.pi * (10**2) * 300 * 4)
diff --git a/tests/test_parametric_components/test_toroidal_field_coil_coat_hanger.py b/tests/test_parametric_components/test_toroidal_field_coil_coat_hanger.py
index f36223b2c..4a2fc962a 100644
--- a/tests/test_parametric_components/test_toroidal_field_coil_coat_hanger.py
+++ b/tests/test_parametric_components/test_toroidal_field_coil_coat_hanger.py
@@ -214,8 +214,8 @@ def test_absolute_area(self):
             + ((50 * 30) * 4)
             + ((400 * 30) * 4)
             + ((500 * 30) * 2)
-            + ((((50 ** 2 + 50 ** 2) ** 0.5) * 30) * 2)
-            + ((((100 ** 2 + 250 ** 2) ** 0.5) * 30) * 4)
+            + ((((50**2 + 50**2) ** 0.5) * 30) * 2)
+            + ((((100**2 + 250**2) ** 0.5) * 30) * 4)
             + ((50 * 1000) * 2)
             + ((1000 * 30) * 2),
             rel=0.1,
@@ -227,7 +227,7 @@ def test_absolute_area(self):
         assert self.test_shape.areas.count(pytest.approx(500 * 30)) == 2
         assert (
             self.test_shape.areas.count(
-                pytest.approx(((100 ** 2 + 250 ** 2) ** 0.5) * 30)
+                pytest.approx(((100**2 + 250**2) ** 0.5) * 30)
             )
             == 4
         )
@@ -248,8 +248,8 @@ def test_absolute_area(self):
             + ((50 * 30) * 2)
             + ((400 * 30) * 4)
             + ((500 * 30) * 2)
-            + ((((50 ** 2 + 50 ** 2) ** 0.5) * 30) * 2)
-            + ((((100 ** 2 + 250 ** 2) ** 0.5) * 30) * 4),
+            + ((((50**2 + 50**2) ** 0.5) * 30) * 2)
+            + ((((100**2 + 250**2) ** 0.5) * 30) * 4),
             rel=0.1,
         )
 
diff --git a/tests/test_parametric_components/test_toroidal_field_coil_rectangle_round_corner.py b/tests/test_parametric_components/test_toroidal_field_coil_rectangle_round_corner.py
index f89a397bb..1e6d7e780 100644
--- a/tests/test_parametric_components/test_toroidal_field_coil_rectangle_round_corner.py
+++ b/tests/test_parametric_components/test_toroidal_field_coil_rectangle_round_corner.py
@@ -53,7 +53,7 @@ def surface_area(
     # The surface area of the face in XZ plane is divisible into 5 segments
     base_segment_area = thickness * (base - inner_rad)
     vertical_segment_area = thickness * (height - (inner_rad * 2))
-    corner_area = (pi / 4) * (outter_rad ** 2 - inner_rad ** 2)
+    corner_area = (pi / 4) * (outter_rad**2 - inner_rad**2)
 
     # XZ plane face area
     total_face_area = base_segment_area * 2 + vertical_segment_area + corner_area * 2
diff --git a/tests/test_parametric_shapes/test_extrude_circle_shape.py b/tests/test_parametric_shapes/test_extrude_circle_shape.py
index 245d8da9b..9446356ce 100644
--- a/tests/test_parametric_shapes/test_extrude_circle_shape.py
+++ b/tests/test_parametric_shapes/test_extrude_circle_shape.py
@@ -22,7 +22,7 @@ def test_absolute_shape_volume(self):
         """Creates an ExtrudeCircleShape and checks that its volume is correct."""
 
         assert self.test_shape.solid is not None
-        assert self.test_shape.volume() == pytest.approx(math.pi * (10 ** 2) * 30)
+        assert self.test_shape.volume() == pytest.approx(math.pi * (10**2) * 30)
 
     def test_relative_shape_volume(self):
         """Creates two ExtrudeCircleShapes and checks that their relative
@@ -37,10 +37,10 @@ def test_absolute_shape_areas(self):
         are correct."""
 
         assert self.test_shape.area == pytest.approx(
-            (math.pi * (10 ** 2) * 2) + (math.pi * (2 * 10) * 30)
+            (math.pi * (10**2) * 2) + (math.pi * (2 * 10) * 30)
         )
         assert len(self.test_shape.areas) == 3
-        assert self.test_shape.areas.count(pytest.approx(math.pi * (10 ** 2))) == 2
+        assert self.test_shape.areas.count(pytest.approx(math.pi * (10**2))) == 2
         assert self.test_shape.areas.count(pytest.approx(math.pi * (2 * 10) * 30)) == 1
 
     def test_cut_volume(self):
@@ -52,7 +52,7 @@ def test_cut_volume(self):
         )
 
         assert shape_with_cut.volume() == pytest.approx(
-            (math.pi * (20 ** 2) * 40) - (math.pi * (10 ** 2) * 30)
+            (math.pi * (20**2) * 40) - (math.pi * (10**2) * 30)
         )
 
     def test_intersect_volume(self):
@@ -68,7 +68,7 @@ def test_intersect_volume(self):
             intersect=[self.test_shape, intersect_shape],
         )
 
-        assert intersected_shape.volume() == pytest.approx(math.pi * 5 ** 2 * 30)
+        assert intersected_shape.volume() == pytest.approx(math.pi * 5**2 * 30)
 
     def test_rotation_angle(self):
         """Creates an ExtrudeCircleShape with a rotation_angle < 360 and checks
diff --git a/tests/test_parametric_shapes/test_rotate_circle_shape.py b/tests/test_parametric_shapes/test_rotate_circle_shape.py
index 3b11803ad..79432040a 100644
--- a/tests/test_parametric_shapes/test_rotate_circle_shape.py
+++ b/tests/test_parametric_shapes/test_rotate_circle_shape.py
@@ -27,7 +27,7 @@ def test_absolute_shape_volume(self):
         # )
         self.test_shape.rotation_angle = 270
         assert self.test_shape.volume() == pytest.approx(
-            2 * math.pi * 60 * math.pi * (10 ** 2) * 0.75
+            2 * math.pi * 60 * math.pi * (10**2) * 0.75
         )
 
     def test_absolute_shape_areas(self):
@@ -43,11 +43,11 @@ def test_absolute_shape_areas(self):
 
         self.test_shape.rotation_angle = 180
         assert self.test_shape.area == pytest.approx(
-            ((math.pi * (10 ** 2)) * 2) + (math.pi * (10 * 2) * math.pi * (60 * 2) / 2),
+            ((math.pi * (10**2)) * 2) + (math.pi * (10 * 2) * math.pi * (60 * 2) / 2),
             rel=0.01,
         )
         assert len(self.test_shape.areas) == 3
-        assert self.test_shape.areas.count(pytest.approx(math.pi * (10 ** 2))) == 2
+        assert self.test_shape.areas.count(pytest.approx(math.pi * (10**2))) == 2
         assert (
             self.test_shape.areas.count(
                 pytest.approx(math.pi * (10 * 2) * math.pi * (60 * 2) / 2, rel=0.01)
@@ -62,12 +62,12 @@ def test_relative_shape_volume_azimuth_placement_angle(self):
 
         self.test_shape.rotation_angle = 10
         assert self.test_shape.volume() == pytest.approx(
-            (math.pi * 10 ** 2) * ((2 * math.pi * 60) / 36)
+            (math.pi * 10**2) * ((2 * math.pi * 60) / 36)
         )
 
         self.test_shape.azimuth_placement_angle = [0, 90, 180, 270]
         assert self.test_shape.volume() == pytest.approx(
-            (math.pi * 10 ** 2) * ((2 * math.pi * 60) / 36) * 4
+            (math.pi * 10**2) * ((2 * math.pi * 60) / 36) * 4
         )
 
     def test_cut_volume(self):
diff --git a/tests/test_parametric_shapes/test_rotate_straight_shape.py b/tests/test_parametric_shapes/test_rotate_straight_shape.py
index 5ffe75900..8e95612f1 100644
--- a/tests/test_parametric_shapes/test_rotate_straight_shape.py
+++ b/tests/test_parametric_shapes/test_rotate_straight_shape.py
@@ -36,7 +36,7 @@ def test_absolute_shape_volume(self):
         """Creates a RotateStraightShape and checks that its volume is correct."""
 
         assert self.test_shape.solid is not None
-        assert self.test_shape.volume() == pytest.approx(math.pi * (20 ** 2) * 20)
+        assert self.test_shape.volume() == pytest.approx(math.pi * (20**2) * 20)
 
     def test_relative_shape_volume(self):
         """Creates two RotateStraightShapes and checks that their relative volumes
@@ -72,18 +72,18 @@ def test_absolute_shape_areas(self):
         are correct."""
 
         assert self.test_shape.area == pytest.approx(
-            (math.pi * (20 ** 2) * 2) + (math.pi * (20 * 2) * 20)
+            (math.pi * (20**2) * 2) + (math.pi * (20 * 2) * 20)
         )
         assert len(self.test_shape.areas) == 3
-        assert self.test_shape.areas.count(pytest.approx(math.pi * (20 ** 2))) == 2
+        assert self.test_shape.areas.count(pytest.approx(math.pi * (20**2))) == 2
         assert self.test_shape.areas.count(pytest.approx(math.pi * (20 * 2) * 20)) == 1
 
         self.test_shape.rotation_angle = 180
         assert self.test_shape.area == pytest.approx(
-            ((math.pi * (20 ** 2) / 2) * 2) + (20 * 40) + (math.pi * (20 * 2) * 20 / 2)
+            ((math.pi * (20**2) / 2) * 2) + (20 * 40) + (math.pi * (20 * 2) * 20 / 2)
         )
         assert len(self.test_shape.areas) == 4
-        assert self.test_shape.areas.count(pytest.approx(math.pi * (20 ** 2) / 2)) == 2
+        assert self.test_shape.areas.count(pytest.approx(math.pi * (20**2) / 2)) == 2
         assert self.test_shape.areas.count(pytest.approx(20 * 40)) == 1
         assert (
             self.test_shape.areas.count(pytest.approx((math.pi * (20 * 2) * 20) / 2))
@@ -95,14 +95,14 @@ def test_absolute_shape_areas(self):
         )
 
         assert test_shape.area == pytest.approx(
-            (((math.pi * (70 ** 2)) - (math.pi * (50 ** 2))) * 2)
+            (((math.pi * (70**2)) - (math.pi * (50**2))) * 2)
             + (math.pi * (50 * 2) * 50)
             + (math.pi * (70 * 2) * 50)
         )
         assert len(test_shape.areas) == 4
         assert (
             test_shape.areas.count(
-                pytest.approx((math.pi * (70 ** 2)) - (math.pi * (50 ** 2)))
+                pytest.approx((math.pi * (70**2)) - (math.pi * (50**2)))
             )
             == 2
         )
@@ -112,7 +112,7 @@ def test_absolute_shape_areas(self):
         test_shape.rotation_angle = 180
         assert test_shape.area == pytest.approx(
             (20 * 50 * 2)
-            + ((((math.pi * (70 ** 2)) / 2) - ((math.pi * (50 ** 2)) / 2)) * 2)
+            + ((((math.pi * (70**2)) / 2) - ((math.pi * (50**2)) / 2)) * 2)
             + ((math.pi * (50 * 2) * 50) / 2)
             + ((math.pi * (70 * 2) * 50) / 2)
         )
@@ -120,7 +120,7 @@ def test_absolute_shape_areas(self):
         assert test_shape.areas.count(pytest.approx(20 * 50)) == 2
         assert (
             test_shape.areas.count(
-                pytest.approx(((math.pi * (70 ** 2)) / 2) - ((math.pi * (50 ** 2)) / 2))
+                pytest.approx(((math.pi * (70**2)) / 2) - ((math.pi * (50**2)) / 2))
             )
             == 2
         )
@@ -214,7 +214,7 @@ def test_cut_volume(self):
         )
 
         assert shape_with_cut.volume() == pytest.approx(
-            (math.pi * (25 ** 2) * 30) - (math.pi * (20 ** 2) * 20)
+            (math.pi * (25**2) * 30) - (math.pi * (20**2) * 20)
         )
 
     def test_multiple_cut_volume(self):
@@ -239,9 +239,9 @@ def test_multiple_cut_volume(self):
         )
 
         assert main_shape_with_cuts.volume() == pytest.approx(
-            (math.pi * (200 ** 2) * 200)
-            - ((math.pi * (40 ** 2) * 200) - (math.pi * (20 ** 2) * 200))
-            - ((math.pi * (140 ** 2) * 200) - (math.pi * (120 ** 2) * 200))
+            (math.pi * (200**2) * 200)
+            - ((math.pi * (40**2) * 200) - (math.pi * (20**2) * 200))
+            - ((math.pi * (140**2) * 200) - (math.pi * (120**2) * 200))
         )
 
     def test_hash_value(self):
diff --git a/tests/test_parametric_shapes/test_sweep_circle_shape.py b/tests/test_parametric_shapes/test_sweep_circle_shape.py
index efa007a1d..2e9bb83e5 100644
--- a/tests/test_parametric_shapes/test_sweep_circle_shape.py
+++ b/tests/test_parametric_shapes/test_sweep_circle_shape.py
@@ -54,7 +54,7 @@ def test_absolute_shape_volume(self):
 
         self.test_shape.path_points = [(50, 0), (50, 50), (50, 100)]
         assert self.test_shape.solid is not None
-        assert self.test_shape.volume() == pytest.approx(math.pi * 10 ** 2 * 100)
+        assert self.test_shape.volume() == pytest.approx(math.pi * 10**2 * 100)
 
     def test_relative_shape_volume_radius(self):
         """Creates two SweepCircleShapes and checks that their relative volume
@@ -91,7 +91,7 @@ def test_force_cross_section(self):
         self.test_shape.force_cross_section = True
 
         assert (
-            self.test_shape.areas.count(pytest.approx(math.pi * (10 ** 2), rel=0.01))
+            self.test_shape.areas.count(pytest.approx(math.pi * (10**2), rel=0.01))
             == 2
         )
 
@@ -101,7 +101,7 @@ def test_force_cross_section(self):
         self.test_shape.cut = cutting_shape
 
         assert (
-            self.test_shape.areas.count(pytest.approx(math.pi * (10 ** 2), rel=0.01))
+            self.test_shape.areas.count(pytest.approx(math.pi * (10**2), rel=0.01))
             == 2
         )
 
@@ -111,7 +111,7 @@ def test_force_cross_section(self):
         self.test_shape.cut = cutting_shape
 
         assert (
-            self.test_shape.areas.count(pytest.approx(math.pi * (10 ** 2), rel=0.01))
+            self.test_shape.areas.count(pytest.approx(math.pi * (10**2), rel=0.01))
             == 2
         )