Skip to content

Conversation

@feltech
Copy link
Member

@feltech feltech commented Oct 1, 2025

Closes #80. Add support for versioning of traits and specifications, whilst retaining backward compatibility and adding deprecation warnings for old-style usage.

Implements the design discussed in OpenAssetIO/OpenAssetIO-MediaCreation#90

  • Updated the YAML schema to move trait/specification definitions under a version number, implemented as a dict of "<version number>": <definition>. This is the only breaking change.
  • Trait view classes have a _vX suffix, where X is a version number (e.g. LocatableContentTrait_v1)
  • Similarly, Specification view classes have a _vX suffix.
  • Trait IDs have a .vX suffix, except for the first version, which has no suffix for backward compatibility.
  • Trait/specification view classes are available with no _vX suffix, which are just an alias to _v1, but with deprecation warnings.
  • Entire traits/specifications can be flagged as deprecated with a deprecated=true at the top-level of their YAML definition (i.e. above the versions).
  • Deprecation uses the warnings module for Python and [[deprecated]] for C++, and @deprecated in docstrings.

See commits for more details.

Part of OpenAssetIO#80. The .editorconfig setting were only applied to `.yml` and
not `.yaml`, yet our tests use `.yaml`.

Signed-off-by: David Feltell <[email protected]>
Part of OpenAssetIO#80. The main OpenAssetIO project updated to Clang-Tidy 19 in
OpenAssetIO/OpenAssetIO#1390. The TraitGen C++ tests run the generated
code through `clang-tidy`, which failed for v19, specifically the
`modernize-use-auto` check.

So tweak the C++ code template to satisfy the failing check, allowing
us to use a common Clang-Tidy version across projects.

Signed-off-by: David Feltell <[email protected]>
Part of OpenAssetIO#80. The `unique_name_parts` field is not, in general, a tuple
of a single element. In order to allow for arbitrary length tuples, we
must suffix an ellipsis.

Signed-off-by: David Feltell <[email protected]>
@feltech feltech self-assigned this Oct 1, 2025
@feltech feltech requested a review from a team as a code owner October 1, 2025 17:51
@feltech feltech force-pushed the work/88-traitVersioning branch from 69b8b40 to 7280d76 Compare October 1, 2025 17:54
@feltech feltech requested a review from hutchinson October 1, 2025 17:55
@feltech feltech force-pushed the work/88-traitVersioning branch from 7280d76 to 7d76d22 Compare October 1, 2025 18:09
Copy link

@hutchinson hutchinson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work, i've limited experience with the innards of the code but nothing has jumped out as alarming!

Closes OpenAssetIO#80.

Update the schema to support a dictionary of "versions" for traits and
specifications, where each version contains a full trait/specification
definition.

Add a "deprecated" tag to the schema, allowing traits and specifications
to be flagged as due for complete removal (i.e. all versions).

Use string keys for the version, rather than integer keys, to provide
maximum scope for future extension (e.g. tagged, semver). Note: this
decision was not called out in the original design.

Add a `.v1` suffix to trait IDs and an `_v1` suffix to trait and
specification class names (where `1` is the version string).

Do not add a version suffix to the ID for the first version of a trait,
to maintain backward compatibility.

Add trait classes that match the previous scheme, i.e. with no `_v1`
suffix, which alias the first version of a trait, to maintain backward
compatibility. Use inheritance to ensure maximum compatibility, rather
than duplicating the class.

Similarly to traits, add unversioned Specification view classes for
backward compatibility.

Non-versioned view classes are only for backward compatibility - going
forward, hosts/managers should be explicit and use the version-suffixed
classes.

So mark non-versioned view classes as deprecated in their docstrings.

For Python, add a `DeprecationWarning` using the `warnings` module when
an unversioned view class is first constructed. Use the class name in
the warning text, so a separate warning will be generated for each
non-migrated class.

For C++, add `[[deprecated]]` annotation to non-versioned view classes.

Add deprecation docstrings and warnings for traits and specifications
flagged with `deprecated: true`. Flag warnings at runtime in Python
using the `warnings` module and C++ at compile time using the
`[[deprecated]]` annotation.

Update log output from command-line script to add version numbers.

Since we're now using the `to_python_*_name` filters multiple times for
the same input (in particular, class names), any names modified to be
valid Python identifiers duplicate the same "Conforming" warning logs
several times. So de-duplicate by keeping a cache of warnings that have
already been logged.

Add version specifiers to `TraitDeclaration`, `TraitReference` and
`SpecificationDeclaration` for use in constructing IDs and class names.

Add a CTest target for testing C++ deprecation warnings. Suppress at the
compiler warning level, other than for the explicit deprecation warning
test. Unfortunately, testing multiple raw string matches in build output
via CTest is rather involved, but can be made to work.

Signed-off-by: David Feltell <[email protected]>
@feltech feltech force-pushed the work/88-traitVersioning branch from 7d76d22 to aa5abef Compare October 13, 2025 07:49
@feltech feltech merged commit 9f0667f into OpenAssetIO:main Oct 13, 2025
14 checks passed
@feltech feltech deleted the work/88-traitVersioning branch October 13, 2025 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Versioning generation behaviour.

2 participants