-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow update #14
Allow update #14
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The tests look okay - and I made some comments for the first part of the change. I'm honestly having trouble following the logic of the changes - if you could put more comments and description this would be helpful.
child = self.attType[0] | ||
|
||
# It's either a nested structure | ||
if is_struct(child): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could get hairy if we have multiple levels of nesting. Can you implement this possibly with recursion? Once we've grabbed a child (and we know it's a struct) does it not work to call the function again for that struct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a test for nested Structs.
Recursion is not needed as .load(value)
will construct nested structs for us.
# It's either a nested structure | ||
if is_struct(child): | ||
|
||
# If we have a list of values, generate them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The logic down here would change I think too. There aren't enough comments here to help me understand what is going on. (e.g., can we do like I did with case 1, case 2, etc.
Struct.add() is now only supports updating a list or dict. Use .set() for setting a new value on an attribute.
@PhilippHomann checking in - are you going to remove the last commit? |
Which commit do you mean? Why do you want it to be removed? |
We discussed removing set: #14 (comment). |
This reverts commit 3349754.
Reverted the last commit. Sorry for the delay! |
if isinstance(value, list): | ||
values = [] | ||
for v in value: | ||
if not is_struct(type(value)): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to still see a comment above this line (89) explaining what this block is going to cover.
# Transform value to Struct if not already | ||
if not is_struct(valueType): | ||
value = attr.attType().load(value) | ||
if attr.attType in [StrStruct, IntStruct]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adding an int/string to another? is this the behavior we want?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know.
In another comment (#14 (comment)) you noticed that replacing the value might not be the thing we want.
So maybe we should only allow dict and list as type for value?!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking is that add should explicitly be for things you can add/append to (like list or dict). If someone wants to change a value entirely they can just use set. I can see the argument for wanting add for an int (to add a number to an existing one) but I'd say we should wait until someone actually speaks up about that use case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But imho we should have a Struct.set()
then.
Because for now one have to use Struct.attrs["name"].set("value")
to change the value of an attribute.
But you asked me to revert the commit which added Struct.set()
So I don't understand what we're up to..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we already have .set() on lines 75/84?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed but only in StructAttr
not in Struct
.
So Struct.attrs["name"].set("value")
is the only way to change a value of an attribute.
Don't know if this the way one should set a value when we have a Struct.add("name", "value")
to append to a list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh I see. I think Struct.add with name and value would make sense to append to a list, do you think not? Let's discuss what you think would be most intuitive!
if attr.attType in [StrStruct, IntStruct]: | ||
if attr.value is not None: | ||
value = attr.value + value | ||
elif attr.attType == list or isinstance(attr.attType, list): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to check attType and the instance type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed because for attributes with attType=[IntStruct]
the isinstance()
check is True
and for attributes with attType=list
or attType=dict
as used in opencontainers/image/v1/config.py.
# Load values from dict or list of dicts | ||
# list may also already contain Structs | ||
if valueType == dict: | ||
value = attr.attType[0]().load(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you see common functoinality between here and checking types and the above logic for set()?
else: | ||
raise ValueError("dict expected for {}, got {}: {}".format(name, valueType, value)) | ||
else: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be some warning message here about an unknown type?
@@ -314,25 +352,28 @@ def load(self, content, validate=True): | |||
given a dictionary load into its respective object | |||
if validate is True, we require it to be completely valid. | |||
""" | |||
if not isinstance(content, dict): | |||
bot.exit("Please provide a dictionary or list to load.") | |||
if Struct in type(content).__bases__: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add comments above this line to explain the logic here?
@@ -383,6 +424,12 @@ def validate(self): | |||
return False | |||
return True | |||
|
|||
def get(self, name, default=None): | |||
r = self.attrs[name].value |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If name isn't in self.attrs won't this error?
Co-authored-by: Vanessasaurus <814322+vsoch@users.noreply.github.com>
Changed my mind on using oci-python. |
Will do, thanks! |
* adding support to update an existing value currently, if we take a structure and run "add" to update an attribute, it completely replaces any content there (e.g., a dict or list). But with add we would actually want it to update - if the user wants to replace they can use set. Signed-off-by: vsoch <vsoch@users.noreply.github.com> * Allow update (#14) * Add test for updating structs * Improve .add() to allow updating * Add .get() to Struct to receive value * Remove type hint to remain compatible * Add test to deeply nested structs * Really add value instead of replacing if type is int or str * Add Struct.set() Struct.add() is now only supports updating a list or dict. Use .set() for setting a new value on an attribute. * Revert "Add Struct.set()" This reverts commit 3349754. * Commit as suggested by @vsoch Co-authored-by: Vanessasaurus <814322+vsoch@users.noreply.github.com> Co-authored-by: Vanessasaurus <814322+vsoch@users.noreply.github.com> * run black and update docstrings Signed-off-by: vsoch <vsoch@users.noreply.github.com> * pin black Signed-off-by: vsoch <vsoch@users.noreply.github.com> Co-authored-by: vsoch <vsoch@users.noreply.github.com> Co-authored-by: PhilippHomann <3265572+PhilippHomann@users.noreply.github.com>
Follow-up of #13