class MyValidator(pyblish.Validator):
def process(self, context, instance):
"""Unified processing method with dependency injection"""
# Plain dictionary for data
instance.data["key"] = value
if "key" in instance.data:
print("Yes, it's got key")
# Modify or add depending on whether it exists
with instance.data.item("group") as g:
g["key"] = value
API Changes
Thought I’d summarise and bring up to discussion some proposed api changes about to happen and what they will mean for developers of plug-ins.
Unified processing method
This is perhaps the one thing that keeps me up the most at night, the duplication involved in having both process_context
and process_instance
.
def process_context(self, context):
"""duplication in function-name, signature and sibling function"""
See here for details.
Plain dictionary
The data property has all the features of a plain dictionary, except delegated to individual functions such as set_data
and has_data
. I’d like to see these merged into being a plain dictionary.
# Old
instance.set_data("key", "value") # old
instance.data("notexists", default="exists")
for key, value in instance.data().iteritems():
pass
# New
instance.data["key"] = "value"
instance.data.get("notexists", default="exists")
for key, value in instance.data.iteritems():
pass
Besides cosmetic changes, the following behaviour can also be simplified.
# Before
if not instance.has_data("mydata"):
instance.set_data("mydata", {})
mydata = instance.data("mydata")
mydata["key"] = "value"
# After
try:
mydata = instance["mydata"]
except:
mydata = {}
instance["mydata"] = mydata
mydata["key"] = "value
Which also paves the road for multiprocessing. Notice how the first method queries the existence before attempting to write. In this member is accessed by two separate threads, there is no telling which one starts writing first, and which one is told the member already exist.
See here for more.
Modify on add
Based on the fact that the above is still quite complicated, and still a common thing to do, I’m also considering implementing this sort of behaviour.
with instance.data.item("group") as g:
g["key"] = value
It does exactly like what the above does, but in 2 lines as opposed to 6, and is thread-safe.
Backwards compatibility
The big question here is of course:
Will this break our plug-ins??
And no, there’s no need for that.
Each of the above changes can be implemented to the side of existing behaviour and that’s the plan. We could have a think about whether we would like to have access to some form of transition mechanism.
import pyblish.api as pyblish
pyblish.set_api(1) # Old API
pyblish.set_api(2) # New API
In which the old API would provide the new API, but remain backwards compatible, and the new API would discard the old functionality altogether. The old API would remain default until Pyblish hits 2.0, but users could choose to adopt it before hand if they wanted to.