Skip to content

fix: pyoaev crashes on Python 3.14: 'object has no attribute __annotations__' in RESTObject._create_managers #346

Closed

Description

Summary

pyoaev crashes at startup on Python 3.14. Any collector/injector that
instantiates a RESTObject (e.g. collector.create() during setup) raises:

AttributeError: 'Collector' object has no attribute '__annotations__'. Did you mean: '__annotate_func__'?

This makes the current OpenAEV-Platform/collectors images (whose Dockerfile was
bumped to python:3.14-alpine) fail to start entirely.

Stack trace

File ".../pyoaev/daemons/collector_daemon.py", line 90, in _setup
    self.api.collector.create(config, collector_icon)
File ".../pyoaev/mixins.py", line 218, in create
    return self._obj_cls(self, server_data)
File ".../pyoaev/base.py", line 54, in __init__
    self._create_managers()
File ".../pyoaev/base.py", line 160, in _create_managers
    for attr, annotation in sorted(self.__annotations__.items()):
File ".../pyoaev/base.py", line 90, in __getattr__
    raise AttributeError(message)
AttributeError: 'Collector' object has no attribute '__annotations__'

Root cause

RESTObject._create_managers() reads self.__annotations__ directly. Under
Python 3.14 (PEP 649 / PEP 749, deferred annotations), __annotations__ is no
longer guaranteed to be a plain attribute resolvable this way — and RESTObject
also overrides __getattr__, so the missing attribute raises instead of
returning an empty dict.

Suggested fix

Use inspect.get_annotations() (or walk the MRO collecting
cls.__dict__.get("__annotations__", {})) instead of self.__annotations__:

import inspect
annotations = {}
for klass in type(self).__mro__:
    annotations.update(inspect.get_annotations(klass))
for attr, annotation in sorted(annotations.items()):
    ...

Impact / context

Found while testing OpenAEV-Platform/collectors#590 (Splunk ES collector fix).
The collector image built on 3.14 does not start; I validated that PR on a 3.13
build. Until this is fixed in pyoaev, collector Dockerfiles should stay on 3.13.

Environment

  • Python 3.14 (python:3.14-alpine)
  • pyoaev from OpenAEV-Platform/client-python (current main)

Activity

  1. changed the title [-]pyoaev crashes on Python 3.14: 'object has no attribute __annotations__' in RESTObject._create_managers[/-] [+]fix: pyoaev crashes on Python 3.14: 'object has no attribute __annotations__' in RESTObject._create_managers[/+] on Sep 11, 2026
  2. Megafredo commented on Sep 17, 2026

    @Megafredo
    Member

    Hey Sébastien MIGUEL (@Seb-MIGUEL), thanks for reporting this !

    However, I believe the issue has already been fixed on the client-python side. The change was made last week in this commit 128029a, specifically to correctly handle annotations in light of the changes introduced in Python 3.14.
    Issue reference: #337

    The chosen solution relies on typing.get_type_hints(), which is also the recommended approach in the Python documentation for resolving type annotations: https://docs.python.org/3/library/typing.html#typing.get_type_hints .

    Consequently, it seems to me that the behavior described in the issue corresponds to a version of client-python that does not yet include this fix. Could you check if the version of the client-python being used is up to date?

    For reference, this fix was specifically related to standardizing the collectors in this PR: OpenAEV-Platform/collectors#562

  3. Seb-MIGUEL commented on Sep 17, 2026

    @Seb-MIGUEL
    ContributorAuthor

    Thanks Frédéric BASLER (@Megafredo), you're right that the code fix landed on main with 128029a (#337), and I confirm it works: I reproduced on Python 3.14.7 with pyoaev==3.260904.0 (crash, same stack trace as above) and with pyoaev==3.260917.1 (OK). So on the client-python side this is a duplicate of #337 and can be closed.

    The gap is on the release / pin side, which is why the collector images fail:

    • When I opened this issue (Sept 11), the latest PyPI release was 3.260904.0, tagged Sept 4, i.e. before the fix (the tag is one commit behind 128029a). The first release containing the fix is 3.260917.0, published this morning.
    • In OpenAEV-Platform/collectors main (including today's 3.260917.1 release commit), every collector's pyproject.toml still pins pyoaev = "3.260904.0" (netwitness even 3.260805.0), while the Dockerfiles use python:3.14-alpine and requires-python = ">=3.14". A default docker build therefore installs the broken version on 3.14 and the container crashes at startup.
    • The GitHub Actions test workflow clones client-python main as a path dependency, so tests run against the fixed code. That explains why the tests are green while the images are not.
    • Side note: CircleCI passes --build-arg PYOAEV_GIT_BRANCH_OVERRIDE=main on main, but the Dockerfiles declare ARG PYOAEV_GIT_REF_OVERRIDE. The names don't match, so the override is a no-op and even the main images are built with the PyPI pin.

    Proposed follow-up on the collectors repo (happy to open the PR):

    1. Bump pyoaev to 3.260917.1 in all collectors' pyproject.toml.
    2. Align the CircleCI build-arg name with the Dockerfile ARG (or vice versa).

    Fine with me to close this one as a duplicate of #337 once the collectors follow-up is tracked.

  4. Megafredo commented on Sep 17, 2026

    @Megafredo
    Member

    Thanks Sébastien MIGUEL (@Seb-MIGUEL) !

    Yes, you're absolutely right! Thanks for the details, and good catch regarding the environment variable and the pyproject.toml files! <3
    We'll fix the issues. It would be great if you could create the corresponding issues. We'll handle the fixes as soon as possible!

    Thanks again for reporting this and for the verification!

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

    bugType: something isn't working (fix:).

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions