Skip to content

Make most properties use conventional syntax to fix static typing #273

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 22, 2025
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
63 changes: 27 additions & 36 deletions pymunk/arbiter.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,17 @@ def __init__(self, _arbiter: ffi.CData, space: "Space") -> None:
self._arbiter = _arbiter
self._space = space

def _get_contact_point_set(self) -> ContactPointSet:
@property
def contact_point_set(self) -> ContactPointSet:
"""Contact point sets make getting contact information from the
Arbiter simpler.

Return `ContactPointSet`"""
_set = lib.cpArbiterGetContactPointSet(self._arbiter)
return ContactPointSet._from_cp(_set)

def _set_contact_point_set(self, point_set: ContactPointSet) -> None:
@contact_point_set.setter
def contact_point_set(self, point_set: ContactPointSet) -> None:
# This has to be done by fetching a new Chipmunk point set, update it
# according to whats passed in and the pass that back to chipmunk due
# to the fact that ContactPointSet doesnt contain a reference to the
Expand All @@ -63,15 +69,6 @@ def _set_contact_point_set(self, point_set: ContactPointSet) -> None:

lib.cpArbiterSetContactPointSet(self._arbiter, ffi.addressof(_set))

contact_point_set = property(
_get_contact_point_set,
_set_contact_point_set,
doc="""Contact point sets make getting contact information from the
Arbiter simpler.

Return `ContactPointSet`""",
)

@property
def shapes(self) -> Tuple["Shape", "Shape"]:
"""Get the shapes in the order that they were defined in the
Expand All @@ -87,46 +84,40 @@ def shapes(self) -> Tuple["Shape", "Shape"]:
assert b is not None
return a, b

def _get_restitution(self) -> float:
return lib.cpArbiterGetRestitution(self._arbiter)

def _set_restitution(self, restitution: float) -> None:
lib.cpArbiterSetRestitution(self._arbiter, restitution)

restitution = property(
_get_restitution,
_set_restitution,
doc="""The calculated restitution (elasticity) for this collision
@property
def restitution(self) -> float:
"""The calculated restitution (elasticity) for this collision
pair.

Setting the value in a pre_solve() callback will override the value
calculated by the space. The default calculation multiplies the
elasticity of the two shapes together.
""",
)
"""
return lib.cpArbiterGetRestitution(self._arbiter)

def _get_friction(self) -> float:
return lib.cpArbiterGetFriction(self._arbiter)
@restitution.setter
def restitution(self, restitution: float) -> None:
lib.cpArbiterSetRestitution(self._arbiter, restitution)

def _set_friction(self, friction: float) -> None:
lib.cpArbiterSetFriction(self._arbiter, friction)
@property
def friction(self) -> float:
"""The calculated friction for this collision pair.

friction = property(
_get_friction,
_set_friction,
doc="""The calculated friction for this collision pair.

Setting the value in a pre_solve() callback will override the value
calculated by the space. The default calculation multiplies the
friction of the two shapes together.
""",
)
"""
return lib.cpArbiterGetFriction(self._arbiter)

@friction.setter
def friction(self, friction: float) -> None:
lib.cpArbiterSetFriction(self._arbiter, friction)

def _get_surface_velocity(self) -> Vec2d:
v = lib.cpArbiterGetSurfaceVelocity(self._arbiter)
return Vec2d(v.x, v.y)

def _set_surface_velocity(self, velocity: Vec2d) -> None:
def _set_surface_velocity(self, velocity: Tuple[float, float]) -> None:
lib.cpArbiterSetSurfaceVelocity(self._arbiter, velocity)

surface_velocity = property(
Expand Down
122 changes: 53 additions & 69 deletions pymunk/body.py
Original file line number Diff line number Diff line change
Expand Up @@ -252,30 +252,28 @@ def __repr__(self) -> str:
else:
return "Body(Body.STATIC)"

def _set_mass(self, mass: float) -> None:
lib.cpBodySetMass(self._body, mass)

def _get_mass(self) -> float:
@property
def mass(self) -> float:
"""Mass of the body."""
return lib.cpBodyGetMass(self._body)

mass = property(_get_mass, _set_mass, doc="""Mass of the body.""")
@mass.setter
def mass(self, mass: float) -> None:
lib.cpBodySetMass(self._body, mass)

def _set_moment(self, moment: float) -> None:
lib.cpBodySetMoment(self._body, moment)
@property
def moment(self) -> float:
"""Moment of inertia (MoI or sometimes just moment) of the body.

def _get_moment(self) -> float:
The moment is like the rotational mass of a body.
"""
return lib.cpBodyGetMoment(self._body)

moment = property(
_get_moment,
_set_moment,
doc="""Moment of inertia (MoI or sometimes just moment) of the body.

The moment is like the rotational mass of a body.
""",
)
@moment.setter
def moment(self, moment: float) -> None:
lib.cpBodySetMoment(self._body, moment)

def _set_position(self, pos: Union[Vec2d, Tuple[float, float]]) -> None:
def _set_position(self, pos: Tuple[float, float]) -> None:
assert len(pos) == 2
lib.cpBodySetPosition(self._body, pos)

Expand Down Expand Up @@ -344,16 +342,9 @@ def _get_force(self) -> Vec2d:
force applied manually from the apply force functions.""",
)

def _set_angle(self, angle: float) -> None:
lib.cpBodySetAngle(self._body, angle)

def _get_angle(self) -> float:
return lib.cpBodyGetAngle(self._body)

angle = property(
_get_angle,
_set_angle,
doc="""Rotation of the body in radians.
@property
def angle(self) -> float:
"""Rotation of the body in radians.

When changing the rotation you may also want to call
:py:func:`Space.reindex_shapes_for_body` to update the collision
Expand All @@ -365,43 +356,39 @@ def _get_angle(self) -> float:
If you get small/no changes to the angle when for example a
ball is "rolling" down a slope it might be because the Circle shape
attached to the body or the slope shape does not have any friction
set.""",
)
set."""
return lib.cpBodyGetAngle(self._body)

def _set_angular_velocity(self, w: float) -> None:
lib.cpBodySetAngularVelocity(self._body, w)
@angle.setter
def angle(self, angle: float) -> None:
lib.cpBodySetAngle(self._body, angle)

def _get_angular_velocity(self) -> float:
@property
def angular_velocity(self) -> float:
"""The angular velocity of the body in radians per second."""
return lib.cpBodyGetAngularVelocity(self._body)

angular_velocity = property(
_get_angular_velocity,
_set_angular_velocity,
doc="""The angular velocity of the body in radians per second.""",
)
@angular_velocity.setter
def angular_velocity(self, w: float) -> None:
lib.cpBodySetAngularVelocity(self._body, w)

def _set_torque(self, t: float) -> None:
lib.cpBodySetTorque(self._body, t)
@property
def torque(self) -> float:
"""The torque applied to the body.

def _get_torque(self) -> float:
This value is reset for every time step."""
return lib.cpBodyGetTorque(self._body)

torque = property(
_get_torque,
_set_torque,
doc="""The torque applied to the body.

This value is reset for every time step.""",
)
@torque.setter
def torque(self, t: float) -> None:
lib.cpBodySetTorque(self._body, t)

def _get_rotation_vector(self) -> Vec2d:
@property
def rotation_vector(self) -> Vec2d:
"""The rotation vector for the body."""
v = lib.cpBodyGetRotation(self._body)
return Vec2d(v.x, v.y)

rotation_vector = property(
_get_rotation_vector, doc="""The rotation vector for the body."""
)

@property
def space(self) -> Optional["Space"]:
"""Get the :py:class:`Space` that the body has been added to (or
Expand Down Expand Up @@ -609,7 +596,20 @@ def is_sleeping(self) -> bool:
"""Returns true if the body is sleeping."""
return bool(lib.cpBodyIsSleeping(self._body))

def _set_type(self, body_type: _BodyType) -> None:
@property
def body_type(self) -> _BodyType:
"""The type of a body (:py:const:`Body.DYNAMIC`,
:py:const:`Body.KINEMATIC` or :py:const:`Body.STATIC`).

When changing an body to a dynamic body, the mass and moment of
inertia are recalculated from the shapes added to the body. Custom
calculated moments of inertia are not preserved when changing types.
This function cannot be called directly in a collision callback.
"""
return lib.cpBodyGetType(self._body)

@body_type.setter
def body_type(self, body_type: _BodyType) -> None:
if body_type != Body.DYNAMIC:
for c in self.constraints:
assert (c.a != self and c.b.body_type == Body.DYNAMIC) or (
Expand All @@ -618,22 +618,6 @@ def _set_type(self, body_type: _BodyType) -> None:

lib.cpBodySetType(self._body, body_type)

def _get_type(self) -> _BodyType:
return lib.cpBodyGetType(self._body)

body_type = property(
_get_type,
_set_type,
doc="""The type of a body (:py:const:`Body.DYNAMIC`,
:py:const:`Body.KINEMATIC` or :py:const:`Body.STATIC`).

When changing an body to a dynamic body, the mass and moment of
inertia are recalculated from the shapes added to the body. Custom
calculated moments of inertia are not preserved when changing types.
This function cannot be called directly in a collision callback.
""",
)

def each_arbiter(
self,
func: Callable[..., None], # TODO: Fix me once PEP 612 is ready
Expand Down
4 changes: 2 additions & 2 deletions pymunk/collision_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def data(self) -> Dict[Any, Any]:
"""
return self._data

def _set_begin(self, func: Callable[[Arbiter, "Space", Any], bool]) -> None:
def _set_begin(self, func: _CollisionCallbackBool) -> None:
self._begin = func
self._handler.beginFunc = lib.ext_cpCollisionBeginFunc

Expand All @@ -98,7 +98,7 @@ def _set_pre_solve(self, func: _CollisionCallbackBool) -> None:
self._pre_solve = func
self._handler.preSolveFunc = lib.ext_cpCollisionPreSolveFunc

def _get_pre_solve(self) -> Optional[Callable[[Arbiter, "Space", Any], bool]]:
def _get_pre_solve(self) -> Optional[_CollisionCallbackBool]:
return self._pre_solve

pre_solve = property(
Expand Down
Loading
Loading