Skip to content

docgen: Events catalogue misses helpers and generic base classes #216

@khvn26

Description

@khvn26

The docgen events parser (common/core/docgen/events.py) doesn't pick up logger.info(...) / logger.warning(...) / logger.error(...) calls in two common shapes, so the generated catalogue is incomplete.

Shape 1: module-level bound-logger helper

logger = structlog.get_logger(\"gitlab\")

def _get_bound_logger(config):
    return logger.bind(
        organisation__id=config.project.organisation_id,
        project__id=config.project_id,
    )

def do_work(config):
    log = _get_bound_logger(config)
    log.info(\"webhook.registered\", ...)  # ← not picked up

_resolve_bind requires the assignment's RHS to be <known_logger_name>.bind(...) exactly. A call to a module-level helper (_get_bound_logger(config)) has func=ast.Name(\"_get_bound_logger\"), not ast.Attribute(\".bind\"), so the assignment is skipped. The subsequent log.info(...) hits the isinstance(target, ast.Name) branch and logger_scopes.get(\"log\") returns None — silently dropped (no warning because it's not a self.* access).

Workaround: inline log = logger.bind(...) at the top of each emitting function. Loses DRY across functions that share the same bound context.

Shape 2: generic base class providing the accessor

class _BaseView(ListAPIView, Generic[T]):
    def _log_for(self, config): return logger.bind(...)

class BrowseIssues(_BaseView[Issue]):
    def fetch(self, config):
        self._log_for(config).info(\"issues.fetched\", ...)  # ← warns, not picked up

visit_ClassDef only inherits from bases that are ast.Name and present in _module_classes:

for base in node.bases:
    if isinstance(base, ast.Name) and base.id in self._module_classes:
        ...

When the base is subscripted (_BaseView[Issue]), the base is ast.Subscript, so inheritance is skipped and _log_for isn't in the subclass's class_scope. Produces a warning but the event doesn't land in the catalogue.

Real example: api/integrations/gitlab/views/browse_gitlab.py_GitLabListView[GitLabIssue].

Suggested direction

  • Shape 1: track module-level functions whose body is a single return logger.bind(...) the same way _resolve_method_accessor tracks class methods, and resolve their call sites.
  • Shape 2: when a base class is ast.Subscript with value=ast.Name(id=...), treat the inner name as the base for inheritance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions