Skip to content

test_every_method_attribute_has_docstring never checks overridden properties #124

Description

@mwcraig

ImageAPITest.test_every_method_attribute_has_docstring is meant to check that every method and attribute in the protocol has a docstring on the backend under test. It does not check properties. An overridden image_labels or catalog_labels with no docstring passes silently.

Cause

The test looks each name up on the instance:

for method in all_methods_and_attributes:
    attr = getattr(self.image, method)
    if not attr.__doc__:
        method_attrs_no_docs.append(method)

For a method that returns a bound method, whose __doc__ is the function's docstring. For a property it returns the property's value. image_labels and catalog_labels return a tuple, so the test inspects tuple.__doc__, which is always truthy.

Reproduction

from astro_image_display_api.image_viewer_logic import ImageViewerLogic

class NoDoc(ImageViewerLogic):
    @property
    def image_labels(self):
        return tuple(self._images)

    def save(self, filename, overwrite=False, **kwargs):
        pass

n = NoDoc()
type(getattr(n, "image_labels"))   # tuple, __doc__ is truthy  -> passes the test
NoDoc.image_labels.__doc__         # None                      -> should have failed
n.save.__doc__                     # None                      -> correctly caught

So the undocumented save override is caught and the undocumented image_labels override is not.

Possible fix, and the trade-off

Looking the name up on the class, getattr(type(self.image), method), gives the property object, whose __doc__ is the getter's docstring. That handles both methods and properties.

The catch is backends that provide image_labels or catalog_labels as a plain instance attribute set in __init__. The protocol declares them as properties, but the runtime isinstance check only requires the name to exist, so such backends pass today. A class-level lookup would raise AttributeError for them. Options include:

  • look up on the class first and fall back to the instance when the class has no such attribute, skipping the docstring requirement for plain data attributes;
  • or decide that these two must be properties and let the class-level lookup enforce it.

Context

Found while reviewing #123, which narrows the wording in the backend guide to match what the test does today: #123 (comment). docs_from_image_viewer_logic_if_missing already handles properties correctly, so only the test is affected. Note that #105 reports a second copy of this test under tests/; any fix should cover both copies, or land after that duplicate is removed.

— Written by Claude at @mwcraig's direction.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions