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

deprecation: add fine-grained deprecation on models #874

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions leapp/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,26 @@ def __init__(self, init_method='from_initialization', **kwargs):
for field in defined_fields: # noqa; pylint: disable=consider-using-dict-items
getattr(defined_fields[field], init_method)(kwargs, field, self)

# The instance is prepared (fields are recursively populated). Modify the instance so that if we are accessing
# a deprecated field we will be triggering deprecation warnings
if hasattr(self, '_deprecated_nodes'):
# depr_path is of the form ['field1', 'field2', 'field3', ..]. Traverse the path to obtain
# x = self.field1.field2...field{N-1}. Add field{N} to x's _deprecation_attributes which
# will be checked when accessing its attributes using __getattribute__
for depr_path in self._deprecated_nodes:
root = self
depr_path = list(depr_path)

while len(depr_path) > 1:
current_field = depr_path.pop(0)
root = getattr(root, current_field)

# Path has length 1
if getattr(root, '_deprecated_attributes', None) is None:
root._deprecated_attributes = []

root._deprecated_attributes.append(depr_path[0])

topic = None
"""
`topic` has to be set to a subclass of :py:class:`leapp.topics.Topic`
Expand All @@ -113,6 +133,24 @@ def create(cls, data):
"""
return cls(init_method='to_model', **data)

def __getattribute__(self, name):
try:
depr_attribs = super().__getattribute__('_deprecated_attributes')
if name in depr_attribs:
raise NotImplementedError('Register a Deprecation warning here.')
return super().__getattribute__(name)
except AttributeError: # There are no _deprecated_attributes, access the fields normally
return super().__getattribute__(name)

def __setattr__(self, name, value):
try:
depr_attribs = super().__getattribute__('_deprecated_attributes')
if name in depr_attribs:
raise NotImplementedError('Register a Deprecation warning here.')
return super().__setattr__(name, value)
except AttributeError:
return super().__setattr__(name, value)

def dump(self):
"""
Dumps the data in the dictionary form that is safe to serialize to JSON.
Expand Down
Loading