-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Remove watch_* operations in favor of "list_*(watch=True)" #9
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
Conversation
75c10a7
to
2e2b12d
Compare
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.
Some style suggestions, the only one of note is the shadowing of id
.
make_operation_id_map) | ||
|
||
def remove_watch_operations(op, parent): | ||
id = op['operationId'] |
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.
id is a builtin, so this variable assignment is effectively shadowing it. Consider differentiating via a trailing underscore (e.g. id_
) or using a more verbose name (e.g. op_id
).
@@ -16,24 +16,63 @@ def _to_camel_case(s): | |||
return ''.join(_title(y) for y in s.split("_")) | |||
|
|||
|
|||
def iterate_through_operations(spec, func): | |||
def iterate_through_operations(spec, *funcs): |
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.
(No action required)
'iterate' usually implies an iterator, which this is not. Consider renaming to something like 'apply_funcs_to_spec'.
@@ -16,24 +16,63 @@ def _to_camel_case(s): | |||
return ''.join(_title(y) for y in s.split("_")) | |||
|
|||
|
|||
def iterate_through_operations(spec, func): | |||
def iterate_through_operations(spec, *funcs): | |||
for k, v in spec['paths'].iteritems(): | |||
for op in _ops: | |||
if op in v: |
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.
(No action required)
Consider avoiding unnecessary indentation:
for op in _ops:
if not op in v:
continue
...
iterate_through_operations(spec, strip_tags_from_operation_id, | ||
make_operation_id_map) | ||
|
||
def remove_watch_operations(op, parent): |
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.
(No action required)
Consider avoiding the use of complex inline functions (longer than a few lines). They are effectively impossible to unit test because they can't be referenced outside of their scope.
Speaking of testing, consider adding tests for this script.
|
||
def remove_watch_operations(op, parent): | ||
id = op['operationId'] | ||
if not id.startswith("watch"): |
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.
(No action required)
Consider defining watch
as a constant.
for prop in prop_list: | ||
if prop["name"] == property: | ||
return True | ||
return False |
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.
(No action required)
Consider being consistent in returning True/False or True/None (as with remove_watch_operations
).
@marun Thanks for the review. I've applied your comments and also restructured the code to make it more readable. Please take another look. |
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.
a couple of doc/naming nits, otherwise lgtm
@@ -30,24 +39,67 @@ def _to_camel_case(s): | |||
return ''.join(_title(y) for y in s.split("_")) | |||
|
|||
|
|||
def iterate_through_operations(spec, func): | |||
def apply_funcs_to_spec(spec, func, *params): |
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.
nit: Given that this function only applies a single func, consider renaming to appy_func_to_spec
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 missed that. Done.
@@ -30,24 +39,67 @@ def _to_camel_case(s): | |||
return ''.join(_title(y) for y in s.split("_")) | |||
|
|||
|
|||
def iterate_through_operations(spec, func): | |||
def apply_funcs_to_spec(spec, func, *params): | |||
"""Apply fun to each operation in the spec. |
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.
nit: fun -> func
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.
Done
def apply_funcs_to_spec(spec, func, *params): | ||
"""Apply fun to each operation in the spec. | ||
|
||
First two parameters of func will be operation and it's parent, and the |
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.
(No action required)
Consider defining the signature rather than explaining it (e.g. func(operation, parent)
).
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.
is it possible to define a function pointer's signature in python? you do you mean use that syntax in the comment?
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.
Yes, use the syntax in the comment.
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.
Done.
return True | ||
|
||
|
||
def remove_watch_operations(op, parent, operation_ids): |
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.
(No action required)
If/when this method is targeted by a unit test, it may make sense to return messages (e.g. Cannot find...
) as exceptions and allow the calling function more flexibility in how those cases are handled (i.e. script would output to stdout, test would check that the expected exception was returned for a given input).
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.
done.
def strip_tags_from_operation_id(operation, _): | ||
operation_id = operation['operationId'] | ||
for t in operation['tags']: | ||
operation_id = operation_id.replace(_to_camel_case(t), '') |
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.
(No action required)
to_camel_case
is only referenced here, consider inlining.
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.
Would like to keep this one :)
|
||
iterate_through_operations(spec, strip_tags_from_operation_id) | ||
operation_ids = {} | ||
apply_funcs_to_spec(spec, make_operation_id_map, operation_ids) |
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.
(No action required)
make_operation_id_map
is only referenced here, consider inlining. Given that this is a one-liner, it may be appropriate to use lambda.
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.
done.
Is it necessary to include the generated commit in this PR (i.e. does the second commit fix things breakage in the generated code)? If not, consider breaking it the generated commit out into a separate PR that just gets merged. |
In k8s, we always include the generated code commit in the same PR that changes the generating code. That will make sure the state of master after submitting each PR is valid (verify-* scripts will fail if we don't do that and we can't actually submit the PR). Here we do not have any verify script yet, but I still like to keep the master always in sync in regard to generating and generated code. I understand this is a suggestion not required. Can you elaborate more on how this is better? Thanks. |
Ok, makes sense. The code change results in a generated code change, I wasn't clear on that. |
@marun I think I applied all of your comments, please take another look and LGTM the PR if you are satisfied with the changes. Thanks. |
LGTM |
Add tox and travis support
Kubernetes supports two type of watch operations. One is the old deprecated one (watch_resource...) and on is the new one (list_resource...(watch=True)). k8sutil.Watch class support only the new one. It is not hard to support old deprecated ones too, but they are redundant and removing them make client less crowded. This PR removes old deprecated watch operations after it make sure there exists a new watch operation for them.
fixes #8