Closed
Description
I was going through the codebase and was trying to understand it. I landed up at:
python/kubernetes/utils/create_from_yaml.py
Lines 142 to 178 in 6d64cf6
I think we can refactor this function by breaking down it into a couple of nested functions to reduce cognitive complexity and maybe distribute responsibilities.
Furthermore, I have this suggestion and would love to contribute if such a change is acceptable.
upper_followed_by_lower_re = re.compile('(.)([A-Z][a-z]+)')
lower_or_num_followed_by_upper_re = re.compile('([a-z0-9])([A-Z])')
def create_from_yaml_single_item(
k8s_client, yml_object, verbose=False, **kwargs):
def get_version_and_group(_api_version):
_group, _, _version = _api_version.partition("/")
if _version == "":
_version = group
_group = "core"
return _version, _group
def clean_group(_group):
# Take care for the case e.g. api_type is "apiextensions.k8s.io"
# Only replace the last instance
_group = "".join(_group.rsplit(".k8s.io", 1))
# convert group name from DNS subdomain format to
# python class name convention
return "".join(word.capitalize() for word in _group.split('.'))
def clean_kind(_kind):
# Replace CamelCased action_type into snake_case
_kind = upper_followed_by_lower_re.sub(r'\1_\2', _kind)
return lower_or_num_followed_by_upper_re.sub(r'\1_\2', _kind).lower()
def get_response(_yml_obj, _k8s_api, _kind, **_kwargs):
def get_namespaced_response(__yml_obj, __k8s_api, __kind, **__kwargs):
__namespace = __yml_obj["metadata"]["namespace"]
__kwargs['namespace'] = __namespace
return getattr(__k8s_api, "create_namespaced_{0}".format(_kind_))(
body=__yml_obj, **__kwargs)
def get_non_namespaced_response(__yml_obj, __k8s_apis, __kind, **__kwargs):
__kwargs.pop('namespace', None)
return getattr(__k8s_api, "create_{0}".format(__kind))(
body=__yml_obj, **__kwargs)
# Expect the user to create namespaced objects more often
if hasattr(_k8s_api, "create_namespaced_{0}"._format(kind)):
# Decide which namespace we are going to put the object in,
# if any
return get_namespaced_response(_yml_obj, _k8s_api, _kind, **_kwargs)
return get_non_namespaced_response(_yml_obj, _k8s_api, _kind, **_kwargs)
def display_message(_kind, _resp, *, _verbose):
if _verbose:
_msg = "{0} created.".format(_kind)
if hasattr(resp, 'status'):
_msg += " status='{0}'".format(str(_resp.status))
print(_msg)
version, group = get_version_and_group(yml_object['apiVersion'])
group = clean_group(group)
fcn_to_call = "{0}{1}Api".format(group, version.capitalize())
k8s_api = getattr(client, fcn_to_call)(k8s_client)
kind = clean_kind(yml_object['kind'])
resp = get_response(yml_object, k8s_api, kind, **kwargs)
display_message(kind, resp, _verbose=verbose)
return resp
Regarding the code:
- Prefixed
_
in nested function variables so that they are there are lesser chances of facing scoping issues. - Move the regular expression pattern to the top of the module as it can hopefully reduce execution time.
I believe a couple of other functions too can be broken down but just wanted to confirm if this is acceptable.
Metadata
Metadata
Assignees
Labels
No labels