Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: 3YOURMIND/django-deprecate-fields
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: master
Choose a base ref
...
head repository: ottertune/django-deprecate-fields
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: master
Choose a head ref
Can’t automatically merge. Don’t worry, you can still create the pull request.
  • 2 commits
  • 1 file changed
  • 1 contributor

Commits on Aug 31, 2021

  1. Copy the full SHA
    193b46a View commit details
  2. Copy the full SHA
    d89dc3f View commit details
Showing with 36 additions and 39 deletions.
  1. +36 −39 django_deprecate_fields/deprecate_field.py
75 changes: 36 additions & 39 deletions django_deprecate_fields/deprecate_field.py
Original file line number Diff line number Diff line change
@@ -4,45 +4,42 @@

logger = logging.getLogger(__file__)


class DeprecatedField(object):
def __deprecate_warn_get_name(self, obj):
"""
Descriptor class for deprecated fields. Do not use directly, use the
deprecate_field function instead.
Try to find this field's name in the model class
"""

def __init__(self, val):
self.val = val

def _get_name(self, obj):
"""
Try to find this field's name in the model class
"""
for k, v in type(obj).__dict__.items():
if v is self:
return k
return "<unknown>"

def __get__(self, obj, type=None):
msg = "accessing deprecated field %s.%s" % (
obj.__class__.__name__,
self._get_name(obj),
)
warnings.warn(msg, DeprecationWarning, stacklevel=2)
logger.warning(msg)
if not callable(self.val):
return self.val
return self.val()

def __set__(self, obj, val):
msg = "writing to deprecated field %s.%s" % (
obj.__class__.__name__,
self._get_name(obj),
)
warnings.warn(msg, DeprecationWarning, stacklevel=2)
logger.warning(msg)
self.val = val

for k, v in type(obj).__dict__.items():
if v is self:
return k
return "<unknown>"

def __deprecate_warn_and_return_substitute__get__(self, obj, type=None):
msg = "accessing deprecated field %s.%s" % (
obj.__class__.__name__,
self._get_name(obj),
)
warnings.warn(msg, DeprecationWarning, stacklevel=2)
logger.warning(msg)
if not callable(self.__patched_return_value):
return self.__patched_return_value
return self.__patched_return_value()

def __deprecate_warn__set__(self, obj, val):
msg = "writing to deprecated field %s.%s" % (
obj.__class__.__name__,
self._get_name(obj),
)
warnings.warn(msg, DeprecationWarning, stacklevel=2)
logger.warning(msg)
self.__patched_return_value = val

def monkey_patch_deprecated_methods(field_instance, return_replacement):
field_instance.__patched_return_value = return_replacement
field_instance._get_name = __deprecate_warn_get_name
field_instance.__get__ = __deprecate_warn_and_return_substitute__get__
field_instance.__original_set = field.instance.__set__
field_instance.__set__ = __deprecate_warn__set__
return field_instance

def deprecate_field(field_instance, return_instead=None):
"""
@@ -57,8 +54,8 @@ def deprecate_field(field_instance, return_instead=None):
:param return_instead: A value or function that
the field will pretend to have
"""
field_instance.null = True
if not set(sys.argv) & {"makemigrations", "migrate", "showmigrations"}:
return DeprecatedField(return_instead)
monkey_patch_deprecated_methods(field_instance)

field_instance.null = True
return field_instance