Skip to content

Commit f0c266f

Browse files
authored
Merge pull request OpenAssetIO#1345 from feltech/work/856-managementPolicySingular
Singular managementPolicy overload
2 parents d003ee9 + 1c82a32 commit f0c266f

File tree

8 files changed

+9577
-9201
lines changed

8 files changed

+9577
-9201
lines changed

RELEASE_NOTES.md

+10-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
Release Notes
22
=============
33

4+
v1.0.0-beta.x.x
5+
---------------
6+
7+
### Improvements
8+
9+
- Added singular overload of `managementPolicy` for convenience.
10+
[#856](https://github.com/OpenAssetIO/OpenAssetIO/issues/856)
11+
12+
413
v1.0.0-beta.2.2
514
---------------
615

@@ -16,7 +25,7 @@ _The addition of a new virtual method,
1625
Notably, this includes `TraitsData`, which when printed now displays all the
1726
properties contained within the traits, rather than simply a list of trait
1827
ids.
19-
28+
2029
Note: Due to this, some runtime string output may have slightly changed, and
2130
tests may need to be adjusted.
2231
[#1307](https://github.com/OpenAssetIO/OpenAssetIO/issues/1307)

doc/doxygen/src/Examples.dox

+6-6
Original file line numberDiff line numberDiff line change
@@ -303,8 +303,8 @@
303303
* # the correct trait set to query. Using the standard definition
304304
* # ensures consistent behaviour across managers/hosts. We request
305305
* # the manager's policy for read access to this entity type.
306-
* [policy] = manager.managementPolicy(
307-
* [TextFileSpecification.kTraitSet], PolicyAccess.kRead, context)
306+
* policy = manager.managementPolicy(
307+
* TextFileSpecification.kTraitSet, PolicyAccess.kRead, context)
308308
*
309309
* # We can now check which traits were imbued in the policy, the
310310
* # absence of a trait means it is unsupported.
@@ -353,8 +353,8 @@
353353
* # The first step is to see if the manager wants to manage text files.
354354
* # Note that this time we request the manager's policy for write
355355
* # access.
356-
* [policy] = manager.managementPolicy(
357-
* [TextFileSpecification.kTraitSet], PolicyAccess.kWrite, context)
356+
* policy = manager.managementPolicy(
357+
* TextFileSpecification.kTraitSet, PolicyAccess.kWrite, context)
358358
*
359359
* if not ManagedTrait.isImbuedTo(policy):
360360
* # The manager doesn't care about this type of asset
@@ -363,8 +363,8 @@
363363
* # Managers may want to dictate to the host some of the data to be
364364
* # published, e.g. tell us where to put files. So we ask the manager
365365
* # which traits, if any, it is interested in "driving" itself.
366-
* [manager_driven_policy] = manager.managementPolicy(
367-
* [TextFileSpecification.kTraitSet], PolicyAccess.kManagerDriven, context)
366+
* manager_driven_policy = manager.managementPolicy(
367+
* TextFileSpecification.kTraitSet, PolicyAccess.kManagerDriven, context)
368368
*
369369
* # Choose some defaults in case the manager cannot drive these values.
370370
* save_path = os.path.join(os.path.expanduser('~'), 'greeting.txt')

resources/abi/libopenassetio.so.1.0.0.xml

+9,486-9,190
Large diffs are not rendered by default.

src/openassetio-core/include/openassetio/hostApi/Manager.hpp

+23
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,29 @@ class OPENASSETIO_CORE_EXPORT Manager final {
443443
access::PolicyAccess policyAccess,
444444
const ContextConstPtr& context);
445445

446+
/**
447+
* Management Policy queries allow a host to ask a Manager how they
448+
* would like to interact with different kinds of entity.
449+
*
450+
* This includes the policy for a given trait set, as well as the
451+
* per-trait policy, with the context for the policy determined by
452+
* the @p policyAccess.
453+
*
454+
* See the @ref managementPolicy(const trait::TraitSets&,<!--
455+
* -->access::PolicyAccess, const ContextConstPtr&) "batch overload"
456+
* documentation for more details.
457+
*
458+
* @param traitSet The entity @ref trait "traits" to query.
459+
*
460+
* @param policyAccess Intended operation type to perform on entities.
461+
*
462+
* @param context The calling context.
463+
*
464+
* @return Policy for the @p traitSet.
465+
*/
466+
[[nodiscard]] trait::TraitsDataPtr managementPolicy(const trait::TraitSet& traitSet,
467+
access::PolicyAccess policyAccess,
468+
const ContextConstPtr& context);
446469
/**
447470
* @}
448471
*/

src/openassetio-core/src/hostApi/ManagerConveniences.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,12 @@ namespace hostApi {
2020
// alternate, often friendlier signatures wrapping the core batch-first
2121
// callback-based member functions found in `Manager.cpp`
2222

23+
trait::TraitsDataPtr Manager::managementPolicy(const trait::TraitSet &traitSet,
24+
access::PolicyAccess policyAccess,
25+
const ContextConstPtr &context) {
26+
return managementPolicy(trait::TraitSets{traitSet}, policyAccess, context).at(0);
27+
}
28+
2329
/******************************************
2430
* entityExists
2531
******************************************/

src/openassetio-python/cmodule/src/hostApi/ManagerBinding.cpp

+10-2
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,17 @@ void registerManager(const py::module& mod) {
9090
.def("initialize", &Manager::initialize, py::arg("managerSettings"),
9191
py::call_guard<py::gil_scoped_release>{})
9292
.def("flushCaches", &Manager::flushCaches, py::call_guard<py::gil_scoped_release>{})
93-
.def("managementPolicy", &Manager::managementPolicy, py::arg("traitSets"),
94-
py::arg("policyAccess"), py::arg("context").none(false),
93+
.def("managementPolicy",
94+
py::overload_cast<const trait::TraitSet&, access::PolicyAccess, const ContextConstPtr&>(
95+
&Manager::managementPolicy),
96+
py::arg("traitSet"), py::arg("policyAccess"), py::arg("context").none(false),
9597
py::call_guard<py::gil_scoped_release>{})
98+
.def(
99+
"managementPolicy",
100+
py::overload_cast<const trait::TraitSets&, access::PolicyAccess, const ContextConstPtr&>(
101+
&Manager::managementPolicy),
102+
py::arg("traitSets"), py::arg("policyAccess"), py::arg("context").none(false),
103+
py::call_guard<py::gil_scoped_release>{})
96104
.def("createContext", &Manager::createContext, py::call_guard<py::gil_scoped_release>{})
97105
.def("createChildContext", &Manager::createChildContext,
98106
py::arg("parentContext").none(false), py::call_guard<py::gil_scoped_release>{})

src/openassetio-python/tests/cmodule/gil/test_manager_gil.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from openassetio import access
2626
from openassetio.hostApi import Manager
2727
from openassetio.managerApi import ManagerStateBase
28+
from openassetio.trait import TraitsData
2829

2930

3031
class Test_Manager_gil:
@@ -226,7 +227,10 @@ def test_initialize(self, a_threaded_manager):
226227
def test_isEntityReferenceString(self, a_threaded_manager):
227228
a_threaded_manager.isEntityReferenceString("")
228229

229-
def test_managementPolicy(self, a_threaded_manager, a_context):
230+
def test_managementPolicy(self, mock_manager_interface, a_threaded_manager, a_context):
231+
mock_manager_interface.mock.managementPolicy.return_value = [TraitsData()]
232+
233+
a_threaded_manager.managementPolicy(set(), access.PolicyAccess.kRead, a_context)
230234
a_threaded_manager.managementPolicy([], access.PolicyAccess.kRead, a_context)
231235

232236
def test_preflight(self, a_threaded_manager, an_entity_reference, a_traits_data, a_context):

src/openassetio-python/tests/package/hostApi/test_manager.py

+31-1
Original file line numberDiff line numberDiff line change
@@ -2409,7 +2409,7 @@ def test_method_defined_in_cpp(self, method_introspector):
24092409
assert not method_introspector.is_defined_in_python(Manager.managementPolicy)
24102410
assert method_introspector.is_implemented_once(Manager, "managementPolicy")
24112411

2412-
def test_wraps_the_corresponding_method_of_the_held_interface(
2412+
def test_batch_overload_wraps_the_corresponding_method_of_the_held_interface(
24132413
self, manager, mock_manager_interface, a_host_session, some_entity_trait_sets, a_context
24142414
):
24152415
data1 = TraitsData()
@@ -2429,6 +2429,36 @@ def test_wraps_the_corresponding_method_of_the_held_interface(
24292429
some_entity_trait_sets, access.PolicyAccess.kWrite, a_context, a_host_session
24302430
)
24312431

2432+
def test_singular_overload_wraps_the_corresponding_method_of_the_held_interface(
2433+
self, manager, mock_manager_interface, a_host_session, an_entity_trait_set, a_context
2434+
):
2435+
expected = TraitsData()
2436+
expected.setTraitProperty("t1", "p1", 1)
2437+
method = mock_manager_interface.mock.managementPolicy
2438+
method.return_value = [expected]
2439+
2440+
actual = manager.managementPolicy(
2441+
an_entity_trait_set, access.PolicyAccess.kWrite, a_context
2442+
)
2443+
2444+
assert actual == expected
2445+
method.assert_called_once_with(
2446+
[an_entity_trait_set], access.PolicyAccess.kWrite, a_context, a_host_session
2447+
)
2448+
2449+
def test_when_plugin_gives_no_result_then_singular_overload_raises(
2450+
self, manager, mock_manager_interface, an_entity_trait_set, a_context
2451+
):
2452+
"""
2453+
This is a truly exceptional exception, we're just checking that
2454+
we don't get a segfault. The message isn't important.
2455+
"""
2456+
method = mock_manager_interface.mock.managementPolicy
2457+
method.return_value = []
2458+
2459+
with pytest.raises(IndexError):
2460+
manager.managementPolicy(an_entity_trait_set, access.PolicyAccess.kWrite, a_context)
2461+
24322462

24332463
class Test_Manager_preflight(BatchFirstMethodTest):
24342464
@pytest.fixture(autouse=True)

0 commit comments

Comments
 (0)