Skip to content
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

Merged
merged 9 commits into from
Aug 10, 2021
Merged

Allow update #14

merged 9 commits into from
Aug 10, 2021

Conversation

PhilippHomann
Copy link
Contributor

Follow-up of #13

Copy link
Owner

@vsoch vsoch left a 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.

opencontainers/struct.py Show resolved Hide resolved
opencontainers/struct.py Show resolved Hide resolved
opencontainers/struct.py Show resolved Hide resolved
child = self.attType[0]

# It's either a nested structure
if is_struct(child):
Copy link
Owner

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?

Copy link
Contributor Author

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
Copy link
Owner

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.

opencontainers/struct.py Outdated Show resolved Hide resolved
@vsoch
Copy link
Owner

vsoch commented Jul 24, 2021

@PhilippHomann checking in - are you going to remove the last commit?

@PhilippHomann
Copy link
Contributor Author

Which commit do you mean? Why do you want it to be removed?

@vsoch
Copy link
Owner

vsoch commented Jul 28, 2021

We discussed removing set: #14 (comment).

This reverts commit 3349754.
@PhilippHomann
Copy link
Contributor Author

PhilippHomann commented Jul 30, 2021

Reverted the last commit. Sorry for the delay!

opencontainers/struct.py Outdated Show resolved Hide resolved
if isinstance(value, list):
values = []
for v in value:
if not is_struct(type(value)):
Copy link
Owner

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]:
Copy link
Owner

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?

Copy link
Contributor Author

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?!

Copy link
Owner

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.

Copy link
Contributor Author

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..

Copy link
Owner

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?

Copy link
Contributor Author

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.

Copy link
Owner

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):
Copy link
Owner

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?

Copy link
Contributor Author

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)
Copy link
Owner

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
Copy link
Owner

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__:
Copy link
Owner

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
Copy link
Owner

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>
@PhilippHomann
Copy link
Contributor Author

Changed my mind on using oci-python.
As I don't need these changes anymore, I'm closing the PR.
Feel free to adapt to my changes.

@vsoch
Copy link
Owner

vsoch commented Aug 10, 2021

Will do, thanks!

@vsoch vsoch reopened this Aug 10, 2021
@vsoch vsoch merged commit ab24c49 into vsoch:allow-update Aug 10, 2021
vsoch added a commit that referenced this pull request Feb 12, 2022
* 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>
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.

None yet

2 participants