Skip to content

Commit

Permalink
v2.0.0: Deprecate waffle namespace classes
Browse files Browse the repository at this point in the history
We now expose the old namespace classes as LegacyWaffle*. This causes a
breaking change of import path.
  • Loading branch information
regisb committed Jan 8, 2021
1 parent bc642c6 commit 03bb0ba
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 33 deletions.
29 changes: 28 additions & 1 deletion CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,34 @@ Change Log

.. There should always be an "Unreleased" section for changes pending release.
[2.0.0] - 2020-11-05
~~~~~~~~~~~~~~~~~~~~

* BREAKING CHANGE: The ``WaffleFlagNamespace`` and ``WaffleSwitchNamespace`` classes have been removed. You can either rename to ``LegacyWaffleFlagNamespace`` and ``LegacyWaffleSwitchNamespace``, which are deprecated, or you can move to the newer waffle classes that no longer use these Namespace classes (see below).
* BREAKING CHANGE: The ``WaffleFlag`` and ``WaffleSwitch`` classes exposed in ``toggles`` no longer use the Namespace classes and are now the classes which were previously only available in ``toggles.__future__``.

* If you were importing from ``edx_toggles.toggles.__future__`` before, then you simply need to import from ``edx_toggles.toggles``. Importing from ``__future__`` will continue to work but will trigger a deprecation warning.
* If you were importing from ``edx_toggles.toggles``, then you either need to:

* Migrate your legacy namespaced classes to the new-style classes (see the new behaviour below), or
* Import ``LegacyWaffleFlag`` instead of ``WaffleFlag`` and ``LegacyWaffleSwitch`` instead of ``WaffleSwitch``. Note that these classes will be removed soon, so it's preferable to migrate to the new classes already.

* The new Waffle classes introduce the following changes:

* They no longer use Namespace classes like ``WaffleSwitchNamespace`` or ``WaffleFlagNamespace``.
* The ``WaffleSwitchNamespace._namespaced_name`` and ``WaffleFlagNamespace._namespaced_name`` methods are replaced by the ``WaffleSwitch.name`` and ``WaffleFlag.name`` attributes.
* The ``WaffleSwitchNamespace.is_enabled`` method is replaced by the ``WaffleSwitch.is_enabled`` method.
* The ``WaffleSwitchNamespace.set_request_cache_with_short_name`` method has no replacement because an alternative solution should be found. You could (but really shouldn't) use the ``WaffleSwitch._cached_switches`` property.
* The ``WaffleSwitch.switch_name`` attribute is deprecated: switches should only ever be referred to using their fully namespaced names.
* The ``WaffleSwitch.switch_name`` attribute no longer exists. Switches should only ever be referred to using their fully namespaced names. If you need the non-namespaced name, it must be parsed from the namespaced name.
* The ``WaffleFlagNamespace.is_flag_active`` method is replaced by ``WaffleFlag.is_enabled``.
* The ``WaffleFlagNamespace._monitor_value`` method is replaced by ``WaffleFlag.set_monitor_value``.
* The ``WaffleFlagNamespace._cached_flags`` attribute is replaced by the ``WaffleFlag.cached_flags`` method.
* The ``WaffleFlag`` and ``WaffleSwitch`` ``module_name`` constructor argument is now mandatory.
* The ``WaffleFlag.flag_name`` attribute is deprecated.
* The ``WaffleFlag.flag_name`` attribute no longer exists. Flags should only ever be referred to using their fully namespaced names. If you need the non-namespaced name, it must be parsed from the namespaced name.
* The ``WaffleFlag.waffle_namespace`` attribute no longer exists, since there is no longer a separate namespace object.

[1.2.2] - 2020-12-22
~~~~~~~~~~~~~~~~~~~~

Expand All @@ -25,7 +53,6 @@ More improvements to monitoring of legacy waffle class imports.

* Improve monitoring of legacy Waffle class imports. We should watch for "edx_toggles.toggles.internal.waffle.legacy.WaffleSwitch" custom attributes.


[1.2.0] - 2020-11-05
~~~~~~~~~~~~~~~~~~~~

Expand Down
2 changes: 1 addition & 1 deletion edx_toggles/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
Library and utilities for feature toggles.
"""

__version__ = '1.2.2'
__version__ = '2.0.0'

default_app_config = 'edx_toggles.apps.TogglesConfig' # pylint: disable=invalid-name
4 changes: 1 addition & 3 deletions edx_toggles/tests/test_testutils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@
from django.test.client import RequestFactory
from edx_django_utils.cache import RequestCache

# TODO import from edx_toggles.toggles once we remove the legacy classes from the exposed API
from edx_toggles.toggles.internal.waffle.flag import WaffleFlag
from edx_toggles.toggles.internal.waffle.switch import WaffleSwitch
from edx_toggles.toggles import WaffleFlag, WaffleSwitch
from edx_toggles.toggles.testutils import override_waffle_flag, override_waffle_switch


Expand Down
4 changes: 1 addition & 3 deletions edx_toggles/tests/test_waffle.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@

from django.test import TestCase

from edx_toggles.toggles import NonNamespacedWaffleFlag, NonNamespacedWaffleSwitch, WaffleFlag, WaffleSwitch
from edx_toggles.toggles.internal.waffle.base import BaseWaffle
# TODO import from edx_toggles.toggles once we remove the legacy classes from the exposed API
from edx_toggles.toggles.internal.waffle.flag import NonNamespacedWaffleFlag, WaffleFlag
from edx_toggles.toggles.internal.waffle.switch import NonNamespacedWaffleSwitch, WaffleSwitch


class NaiveWaffle(BaseWaffle):
Expand Down
19 changes: 13 additions & 6 deletions edx_toggles/toggles/__future__.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
"""
Expose new-style waffle classes. In the future, these imports will be moved to edx_toggles.toggles. Applications that
want to migrate to the new-style API can do so right now by importing from this module.
This module had been created to expose new-style waffle classes. These are now available from edx_toggles.toggles.
"""
# pylint: disable=unused-import
from .internal.setting_toggle import SettingDictToggle, SettingToggle
from .internal.waffle.flag import NonNamespacedWaffleFlag, WaffleFlag
from .internal.waffle.switch import NonNamespacedWaffleSwitch, WaffleSwitch
import warnings

from . import * # pylint: disable=unused-import,wildcard-import

warnings.warn(
(
"Importing from edx_toggles.toggles.__future__ is now deprecated."
" You should import from edx_toggles.toggles instead."
),
DeprecationWarning,
stacklevel=2,
)
26 changes: 15 additions & 11 deletions edx_toggles/toggles/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,31 @@
Expose public feature toggle API.
"""
from .internal.setting_toggle import SettingDictToggle, SettingToggle
from .internal.waffle.legacy import WaffleFlag, WaffleFlagNamespace, WaffleSwitch, WaffleSwitchNamespace
from .internal.waffle.flag import NonNamespacedWaffleFlag, WaffleFlag
from .internal.waffle.legacy import WaffleFlag as _LegacyWaffleFlag
from .internal.waffle.legacy import WaffleFlagNamespace as _LegacyWaffleFlagNamespace
from .internal.waffle.legacy import WaffleSwitch as _LegacyWaffleSwitch
from .internal.waffle.legacy import WaffleSwitchNamespace as _LegacyWaffleSwitchNamespace
from .internal.waffle.switch import NonNamespacedWaffleSwitch, WaffleSwitch


# Create waffle aliases for forward compatibility
# We create new classes instead of using `LegacyClass = Class` statements
# We create new classes instead of simply importing the legacy classes
# for better monitoring of legacy class usage.
class LegacyWaffleFlag(WaffleFlag):
class LegacyWaffleFlag(_LegacyWaffleFlag):
def _get_legacy_custom_attribute_name(self):
return 'deprecated_compatible_legacy_waffle_class'
return "deprecated_compatible_legacy_waffle_class"


class LegacyWaffleFlagNamespace(WaffleFlagNamespace):
class LegacyWaffleFlagNamespace(_LegacyWaffleFlagNamespace):
def _get_legacy_custom_attribute_name(self):
return 'deprecated_compatible_legacy_waffle_class'
return "deprecated_compatible_legacy_waffle_class"


class LegacyWaffleSwitch(WaffleSwitch):
class LegacyWaffleSwitch(_LegacyWaffleSwitch):
def _get_legacy_custom_attribute_name(self):
return 'deprecated_compatible_legacy_waffle_class'
return "deprecated_compatible_legacy_waffle_class"


class LegacyWaffleSwitchNamespace(WaffleSwitchNamespace):
class LegacyWaffleSwitchNamespace(_LegacyWaffleSwitchNamespace):
def _get_legacy_custom_attribute_name(self):
return 'deprecated_compatible_legacy_waffle_class'
return "deprecated_compatible_legacy_waffle_class"
16 changes: 8 additions & 8 deletions edx_toggles/toggles/internal/waffle/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,24 @@
To upgrade your code, use the following guidelines. Where previously you had::
from edx_toggles.toggles import WaffleSwitch, WaffleSwitchNamespace
SOME_NAMESPACE = WaffleSwitchNamespace("some_namespace")
SOME_SWITCH = WaffleSwitch(SOME_NAMESPACE, "some_switch", module_name=__name__)
from edx_toggles.toggles import LegacyWaffleSwitch, LegacyWaffleSwitchNamespace
SOME_NAMESPACE = LegacyWaffleSwitchNamespace("some_namespace")
SOME_SWITCH = LegacyWaffleSwitch(SOME_NAMESPACE, "some_switch", module_name=__name__)
You should now write::
from edx_toggles.toggles.__future__ import WaffleSwitch
from edx_toggles.toggles import WaffleSwitch
SOME_SWITCH = WaffleSwitch("some_namespace.some_switch", module_name=__name__)
And similarly for waffle flags, replace::
from edx_toggles.toggles import WaffleFlag, WaffleFlagNamespace
SOME_NAMESPACE = WaffleFlagNamespace("some_namespace", log_prefix="some_namespace")
SOME_FLAG = WaffleFlag(SOME_NAMESPACE, "some_flag", module_name=__name__)
from edx_toggles.toggles import LegacyWaffleFlag, LegacyWaffleFlagNamespace
SOME_NAMESPACE = LegacyWaffleFlagNamespace("some_namespace", log_prefix="some_namespace")
SOME_FLAG = LegacyWaffleFlag(SOME_NAMESPACE, "some_flag", module_name=__name__)
by::
from edx_toggles.toggles.__future__ import WaffleFlag
from edx_toggles.toggles import WaffleFlag
SOME_FLAG = WaffleFlag("some_namespace.some_flag", module_name=__name__, log_prefix="some_namespace")
"""
from abc import ABC
Expand Down

0 comments on commit 03bb0ba

Please sign in to comment.