From bd4a26f6ac8ac3db1bd7fc8d7a0bcb259e1b671a Mon Sep 17 00:00:00 2001 From: Laurens Valk Date: Tue, 25 Aug 2026 09:54:02 +0200 Subject: [PATCH] pybricks._common.Motor: Fix nested attributes. Now we can use relative paths, which should help when sharing the motor class contents. --- doc/common/conf.py | 1 + doc/common/extensions/nestedmethod.py | 41 +++++++++++++++++++++++ doc/main/pupdevices/motor.rst | 48 +++++++++++++-------------- 3 files changed, 66 insertions(+), 24 deletions(-) create mode 100644 doc/common/extensions/nestedmethod.py diff --git a/doc/common/conf.py b/doc/common/conf.py index 167b60b..69688c4 100644 --- a/doc/common/conf.py +++ b/doc/common/conf.py @@ -62,6 +62,7 @@ extensions = [ "color", "classlink", "docstring_signature", + "nestedmethod", "requirements", "requirements-static", "versionchanged", diff --git a/doc/common/extensions/nestedmethod.py b/doc/common/extensions/nestedmethod.py new file mode 100644 index 0000000..efea056 --- /dev/null +++ b/doc/common/extensions/nestedmethod.py @@ -0,0 +1,41 @@ +"""Provides the ``autonestedmethod`` directive. + +Like ``automethod``, but resolves dotted names such as ``control.limits`` +relative to the class documented by the enclosing ``autoclass`` directive. +Plain ``automethod`` treats everything before the last dot as a module/class +path, so ``control.limits`` would be looked up as an attribute of the current +*module* instead of the current class. Resolving the class here keeps shared +include fragments module-neutral. +""" + +from sphinx.util import logging +from sphinx.util.docutils import SphinxDirective + +logger = logging.getLogger(__name__) + + +class AutoNestedMethodDirective(SphinxDirective): + required_arguments = 1 + has_content = False + + def run(self): + current = self.env.current_document + module = current.autodoc_module or self.env.ref_context.get("py:module") + cls = current.autodoc_class or self.env.ref_context.get("py:class") + + if not module or not cls: + logger.warning( + "autonestedmethod:: %s used outside of an autoclass context", + self.arguments[0], + location=self.get_location(), + ) + return [] + + return self.parse_text_to_nodes( + f".. automethod:: {module}::{cls}.{self.arguments[0]}" + ) + + +def setup(app): + app.add_directive("autonestedmethod", AutoNestedMethodDirective) + return {"parallel_read_safe": True} diff --git a/doc/main/pupdevices/motor.rst b/doc/main/pupdevices/motor.rst index db2a7a0..e276da0 100644 --- a/doc/main/pupdevices/motor.rst +++ b/doc/main/pupdevices/motor.rst @@ -22,71 +22,71 @@ Motors with rotation sensors .. blockimg:: pybricks_blockMotorMeasure_motor_angle - .. automethod:: pybricks.pupdevices.Motor.angle + .. automethod:: angle .. blockimg:: pybricks_blockMotorResetAngle - .. automethod:: pybricks.pupdevices.Motor.reset_angle + .. automethod:: reset_angle .. blockimg:: pybricks_blockMotorMeasure_motor_speed .. blockimg:: pybricks_blockMotorMeasure_motor_get_speed_average - .. automethod:: pybricks.pupdevices.Motor.speed + .. automethod:: speed .. blockimg:: pybricks_blockMotorMeasure_motor_load - .. automethod:: pybricks.pupdevices.Motor.load + .. automethod:: load .. blockimg:: pybricks_blockMotorMeasure_motor_stalled - .. automethod:: pybricks.pupdevices.Motor.stalled + .. automethod:: stalled .. rubric:: Stopping .. blockimg:: pybricks_blockMotorStop_Motor_coast - .. automethod:: pybricks.pupdevices.Motor.stop + .. automethod:: stop .. blockimg:: pybricks_blockMotorStop_Motor_brake - .. automethod:: pybricks.pupdevices.Motor.brake + .. automethod:: brake .. blockimg:: pybricks_blockMotorStop_Motor_hold - .. automethod:: pybricks.pupdevices.Motor.hold + .. automethod:: hold .. rubric:: Running forever .. blockimg:: pybricks_blockMotorRun_run - .. automethod:: pybricks.pupdevices.Motor.run + .. automethod:: run .. blockimg:: pybricks_blockMotorDuty_Motor - .. automethod:: pybricks.pupdevices.Motor.dc + .. automethod:: dc .. rubric:: Running by a fixed amount - .. automethod:: pybricks.pupdevices.Motor.run_time + .. automethod:: run_time .. blockimg:: pybricks_blockMotorRun_run_angle - .. automethod:: pybricks.pupdevices.Motor.run_angle + .. automethod:: run_angle .. blockimg:: pybricks_blockMotorRun_run_target - .. automethod:: pybricks.pupdevices.Motor.run_target + .. automethod:: run_target .. blockimg:: pybricks_blockMotorRun_run_until_stalled - .. automethod:: pybricks.pupdevices.Motor.run_until_stalled + .. automethod:: run_until_stalled .. blockimg:: pybricks_blockMotorTrack - .. automethod:: pybricks.pupdevices.Motor.track_target + .. automethod:: track_target - .. automethod:: pybricks.pupdevices.Motor.done + .. automethod:: done .. _settings: @@ -94,9 +94,9 @@ Motors with rotation sensors .. blockimg:: pybricks_blockMotorConfigure_motor_max_voltage - .. automethod:: pybricks.pupdevices.Motor.settings + .. automethod:: settings - .. automethod:: pybricks.pupdevices.Motor.close + .. automethod:: close .. rubric:: Control settings @@ -108,21 +108,21 @@ Motors with rotation sensors .. blockimg:: pybricks_blockMotorConfigure_motor_max_torque - .. automethod:: pybricks.pupdevices::Motor.control.limits + .. autonestedmethod:: control.limits .. pybricks-requirements:: pybricks-common-control - .. automethod:: pybricks.pupdevices::Motor.control.pid + .. autonestedmethod:: control.pid .. pybricks-requirements:: pybricks-common-control .. blockimg:: pybricks_blockMotorConfigure_motor_target_tolerances - .. automethod:: pybricks.pupdevices::Motor.control.target_tolerances + .. autonestedmethod:: control.target_tolerances .. pybricks-requirements:: pybricks-common-control - .. automethod:: pybricks.pupdevices::Motor.control.stall_tolerances + .. autonestedmethod:: control.stall_tolerances .. pybricks-requirements:: pybricks-common-control @@ -139,11 +139,11 @@ Motors with rotation sensors .. pybricks-requirements:: pybricks-common-control - .. automethod:: pybricks.pupdevices::Motor.model.state + .. autonestedmethod:: model.state .. pybricks-requirements:: pybricks-common-control - .. automethod:: pybricks.pupdevices::Motor.model.settings + .. autonestedmethod:: model.settings Initialization examples -----------------------