• 
      

    Add support for light-weight feature checks.

    Review Request #8031 — Created March 4, 2016 and submitted

    Information

    Djblets
    release-0.10.x

    Reviewers

    Feature checks (aka feature switches/toggles) are a way to allow new
    features to be built and tested in a codebase without exposing them to
    every user.
    
    This introduces support for light-weight feature checks. There are three
    parts: Features, Feature Checkers, and the Feature Registry.
    
    The Feature class is used to define a feature. It just requires a
    feature ID and an optional name, summary, and stability level. It may
    also contain functions for handling initialization and shutdown (for
    when the feature is registered and unregistered, respectively). Once
    instantiated, the feature is registered and ready to check.
    
    Feature checkers determine whether a feature should be enabled, based on
    the severity level and any other custom criteria. When an application
    checks if a feature should be enabled, it can pass any criteria it
    wants (user, request, etc.), and if the checker understands it, it can
    consider it. This gives applications a lot of control of how features
    and their checkers are to be used, without imposing major requirements
    on them like other frameworks.
    
    The feature registry contains all the features that have been
    instantiated, and can be used to look up or list features dynamically.
    
    There are template tags available as well for limiting bits of a
    template based on whether a feature is enabled.
    
    Documentation is provided covering how features work, and how to write
    both features and feature checkers.

    Unit tests pass.

    Checked the docs for errors and bad code references.

    Description From Last Updated

    'FeatureNotFoundError' imported but unused

    reviewbotreviewbot

    redefinition of unused 'test_is_enabled_with_unavailable' from line 91

    reviewbotreviewbot

    'settings' imported but unused

    reviewbotreviewbot

    'Site' imported but unused

    reviewbotreviewbot

    'ImproperlyConfigured' imported but unused

    reviewbotreviewbot

    'set_feature_checker' imported but unused

    reviewbotreviewbot

    'SiteConfigFeatureChecker' imported but unused

    reviewbotreviewbot

    'SettingsFeatureChecker' imported but unused

    reviewbotreviewbot

    'BaseFeatureChecker' imported but unused

    reviewbotreviewbot

    'get_feature_checker' imported but unused

    reviewbotreviewbot

    'FeatureNotFoundError' imported but unused

    reviewbotreviewbot

    'SiteConfiguration' imported but unused

    reviewbotreviewbot

    local variable 't' is assigned to but never used

    reviewbotreviewbot

    local variable 't' is assigned to but never used

    reviewbotreviewbot

    local variable 'feature' is assigned to but never used

    reviewbotreviewbot

    local variable 'feature' is assigned to but never used

    reviewbotreviewbot

    local variable 'feature' is assigned to but never used

    reviewbotreviewbot

    local variable 'feature' is assigned to but never used

    reviewbotreviewbot

    local variable 't' is assigned to but never used

    reviewbotreviewbot

    local variable 't' is assigned to but never used

    reviewbotreviewbot

    local variable 'feature' is assigned to but never used

    reviewbotreviewbot

    local variable 'feature' is assigned to but never used

    reviewbotreviewbot

    local variable 'feature' is assigned to but never used

    reviewbotreviewbot

    local variable 'feature' is assigned to but never used

    reviewbotreviewbot

    'cache' imported but unused

    reviewbotreviewbot

    Can we log the original exception?

    daviddavid

    Missing closing paren.

    brenniebrennie

    I think we should initialize the feature before registering it.

    daviddavid

    This should be djblets.features.feature.Feature

    brenniebrennie

    Docstrings in this file?

    daviddavid

    'Site' imported but unused

    reviewbotreviewbot

    Too many blank lines.

    daviddavid

    Too many blank lines.

    daviddavid

    typo: "registerd"

    daviddavid

    I don't suppose it's possible to extract the docs for these from the code?

    daviddavid

    Can you add a period here?

    daviddavid

    Can you add a period here?

    daviddavid

    undefined name 'feature_id'

    reviewbotreviewbot

    'set_feature_checker' imported but unused

    reviewbotreviewbot

    'get_feature_checker' imported but unused

    reviewbotreviewbot
    reviewbot
    1. Tool: PEP8 Style Checker
      Processed Files:
          djblets/features/tests/test_feature.py
          djblets/features/tests/test_checkers.py
          djblets/features/feature.py
          djblets/features/errors.py
          djblets/registries/registry.py
          djblets/features/tests/test_template_tags.py
          djblets/features/tests/test_registry.py
          djblets/features/templatetags/features.py
          djblets/features/registry.py
          djblets/siteconfig/models.py
          djblets/features/__init__.py
          djblets/features/level.py
          djblets/features/checkers.py
      
      Ignored Files:
          docs/djblets/guides/features/intro.rst
          docs/djblets/guides/features/index.rst
          docs/djblets/guides/index.rst
          docs/djblets/guides/features/writing-feature-checkers.rst
          docs/djblets/guides/features/writing-features.rst
          docs/djblets/coderef/index.rst
          djblets/features/templatetags/__init__.py
          djblets/features/tests/__init__.py
      
      
      
      Tool: Pyflakes
      Processed Files:
          djblets/features/tests/test_feature.py
          djblets/features/tests/test_checkers.py
          djblets/features/feature.py
          djblets/features/errors.py
          djblets/registries/registry.py
          djblets/features/tests/test_template_tags.py
          djblets/features/tests/test_registry.py
          djblets/features/templatetags/features.py
          djblets/features/registry.py
          djblets/siteconfig/models.py
          djblets/features/__init__.py
          djblets/features/level.py
          djblets/features/checkers.py
      
      Ignored Files:
          docs/djblets/guides/features/intro.rst
          docs/djblets/guides/features/index.rst
          docs/djblets/guides/index.rst
          docs/djblets/guides/features/writing-feature-checkers.rst
          docs/djblets/guides/features/writing-features.rst
          docs/djblets/coderef/index.rst
          djblets/features/templatetags/__init__.py
          djblets/features/tests/__init__.py
      
      
    2. Show all issues
       'FeatureNotFoundError' imported but unused
      
    3. djblets/features/tests/test_feature.py (Diff revision 1)
       
       
      Show all issues
       redefinition of unused 'test_is_enabled_with_unavailable' from line 91
      
    4. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'settings' imported but unused
      
    5. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'Site' imported but unused
      
    6. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'ImproperlyConfigured' imported but unused
      
    7. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'set_feature_checker' imported but unused
      
    8. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'SiteConfigFeatureChecker' imported but unused
      
    9. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'SettingsFeatureChecker' imported but unused
      
    10. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'BaseFeatureChecker' imported but unused
      
    11. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'get_feature_checker' imported but unused
      
    12. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'FeatureNotFoundError' imported but unused
      
    13. djblets/features/tests/test_registry.py (Diff revision 1)
       
       
      Show all issues
       'SiteConfiguration' imported but unused
      
    14. Show all issues
       local variable 't' is assigned to but never used
      
    15. Show all issues
       local variable 't' is assigned to but never used
      
    16. Show all issues
       local variable 'feature' is assigned to but never used
      
    17. Show all issues
       local variable 'feature' is assigned to but never used
      
    18. Show all issues
       local variable 'feature' is assigned to but never used
      
    19. Show all issues
       local variable 'feature' is assigned to but never used
      
    20. Show all issues
       local variable 't' is assigned to but never used
      
    21. Show all issues
       local variable 't' is assigned to but never used
      
    22. Show all issues
       local variable 'feature' is assigned to but never used
      
    23. Show all issues
       local variable 'feature' is assigned to but never used
      
    24. Show all issues
       local variable 'feature' is assigned to but never used
      
    25. Show all issues
       local variable 'feature' is assigned to but never used
      
    26. djblets/siteconfig/models.py (Diff revision 1)
       
       
      Show all issues
       'cache' imported but unused
      
    27. 
        
    chipx86
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          djblets/features/tests/test_feature.py
          djblets/features/tests/test_checkers.py
          djblets/features/feature.py
          djblets/features/errors.py
          djblets/registries/registry.py
          djblets/features/tests/test_template_tags.py
          djblets/features/tests/test_registry.py
          djblets/features/templatetags/features.py
          djblets/features/registry.py
          djblets/siteconfig/models.py
          djblets/features/__init__.py
          djblets/features/level.py
          djblets/features/checkers.py
      
      Ignored Files:
          docs/djblets/guides/features/intro.rst
          docs/djblets/guides/features/index.rst
          docs/djblets/guides/index.rst
          docs/djblets/guides/features/writing-feature-checkers.rst
          docs/djblets/guides/features/writing-features.rst
          docs/djblets/coderef/index.rst
          djblets/features/templatetags/__init__.py
          djblets/features/tests/__init__.py
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          djblets/features/tests/test_feature.py
          djblets/features/tests/test_checkers.py
          djblets/features/feature.py
          djblets/features/errors.py
          djblets/registries/registry.py
          djblets/features/tests/test_template_tags.py
          djblets/features/tests/test_registry.py
          djblets/features/templatetags/features.py
          djblets/features/registry.py
          djblets/siteconfig/models.py
          djblets/features/__init__.py
          djblets/features/level.py
          djblets/features/checkers.py
      
      Ignored Files:
          docs/djblets/guides/features/intro.rst
          docs/djblets/guides/features/index.rst
          docs/djblets/guides/index.rst
          docs/djblets/guides/features/writing-feature-checkers.rst
          docs/djblets/guides/features/writing-features.rst
          docs/djblets/coderef/index.rst
          djblets/features/templatetags/__init__.py
          djblets/features/tests/__init__.py
      
      
    2. djblets/features/tests/test_registry.py (Diff revision 2)
       
       
      Show all issues
       'Site' imported but unused
      
    3. 
        
    david
    1. Would you mind adding some utilities (either a method decorator or a context manager) to make it possible to set whether or not a feature is enabled when unit testing?

      1. Good idea. Will do!

    2. djblets/features/checkers.py (Diff revision 2)
       
       
       
       
      Show all issues

      Can we log the original exception?

    3. djblets/features/registry.py (Diff revision 2)
       
       
       
       
      Show all issues

      I think we should initialize the feature before registering it.

    4. Show all issues

      Docstrings in this file?

    5. djblets/features/tests/test_checkers.py (Diff revision 2)
       
       

      :)

    6. docs/djblets/guides/features/intro.rst (Diff revision 2)
       
       
       
      Show all issues

      Too many blank lines.

    7. docs/djblets/guides/features/intro.rst (Diff revision 2)
       
       
       
      Show all issues

      Too many blank lines.

    8. Show all issues

      typo: "registerd"

    9. docs/djblets/guides/features/writing-features.rst (Diff revision 2)
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
      Show all issues

      I don't suppose it's possible to extract the docs for these from the code?

      1. Kind of is, but the presentation isn't quite right for this guide, and ends up not linking to the right place anymore (wants to link to itself).

    10. Show all issues

      Can you add a period here?

    11. Show all issues

      Can you add a period here?

    12. 
        
    brennie
    1. 
        
    2. djblets/features/registry.py (Diff revision 2)
       
       
      Show all issues

      Missing closing paren.

    3. djblets/features/registry.py (Diff revision 2)
       
       
      Show all issues

      This should be djblets.features.feature.Feature

    4. 
        
    chipx86
    reviewbot
    1. Tool: PEP8 Style Checker
      Processed Files:
          djblets/features/tests/test_feature.py
          djblets/features/tests/test_checkers.py
          djblets/features/feature.py
          djblets/features/errors.py
          djblets/registries/registry.py
          djblets/features/tests/test_template_tags.py
          djblets/features/tests/test_registry.py
          djblets/features/templatetags/features.py
          djblets/features/registry.py
          djblets/siteconfig/models.py
          djblets/features/__init__.py
          djblets/features/tests/test_testing.py
          djblets/features/level.py
          djblets/features/checkers.py
          djblets/features/testing.py
      
      Ignored Files:
          docs/djblets/guides/features/intro.rst
          docs/djblets/guides/features/index.rst
          docs/djblets/guides/index.rst
          docs/djblets/guides/features/testing.rst
          docs/djblets/guides/features/writing-feature-checkers.rst
          docs/djblets/guides/features/writing-features.rst
          docs/djblets/coderef/index.rst
          djblets/features/templatetags/__init__.py
          djblets/features/tests/__init__.py
      
      
      
      Tool: Pyflakes
      Processed Files:
          djblets/features/tests/test_feature.py
          djblets/features/tests/test_checkers.py
          djblets/features/feature.py
          djblets/features/errors.py
          djblets/registries/registry.py
          djblets/features/tests/test_template_tags.py
          djblets/features/tests/test_registry.py
          djblets/features/templatetags/features.py
          djblets/features/registry.py
          djblets/siteconfig/models.py
          djblets/features/__init__.py
          djblets/features/tests/test_testing.py
          djblets/features/level.py
          djblets/features/checkers.py
          djblets/features/testing.py
      
      Ignored Files:
          docs/djblets/guides/features/intro.rst
          docs/djblets/guides/features/index.rst
          docs/djblets/guides/index.rst
          docs/djblets/guides/features/testing.rst
          docs/djblets/guides/features/writing-feature-checkers.rst
          docs/djblets/guides/features/writing-features.rst
          docs/djblets/coderef/index.rst
          djblets/features/templatetags/__init__.py
          djblets/features/tests/__init__.py
      
      
    2. Show all issues
       undefined name 'feature_id'
      
    3. djblets/features/testing.py (Diff revision 3)
       
       
      Show all issues
       'set_feature_checker' imported but unused
      
    4. djblets/features/testing.py (Diff revision 3)
       
       
      Show all issues
       'get_feature_checker' imported but unused
      
    5. 
        
    chipx86
    reviewbot
    1. Tool: Pyflakes
      Processed Files:
          djblets/features/tests/test_feature.py
          djblets/features/tests/test_checkers.py
          djblets/features/feature.py
          djblets/features/errors.py
          djblets/registries/registry.py
          djblets/features/tests/test_template_tags.py
          djblets/features/tests/test_registry.py
          djblets/features/templatetags/features.py
          djblets/features/registry.py
          djblets/siteconfig/models.py
          djblets/features/__init__.py
          djblets/features/tests/test_testing.py
          djblets/features/level.py
          djblets/features/checkers.py
          djblets/features/testing.py
      
      Ignored Files:
          docs/djblets/guides/features/intro.rst
          docs/djblets/guides/features/index.rst
          docs/djblets/guides/index.rst
          docs/djblets/guides/features/testing.rst
          docs/djblets/guides/features/writing-feature-checkers.rst
          docs/djblets/guides/features/writing-features.rst
          docs/djblets/coderef/index.rst
          djblets/features/templatetags/__init__.py
          djblets/features/tests/__init__.py
      
      
      
      Tool: PEP8 Style Checker
      Processed Files:
          djblets/features/tests/test_feature.py
          djblets/features/tests/test_checkers.py
          djblets/features/feature.py
          djblets/features/errors.py
          djblets/registries/registry.py
          djblets/features/tests/test_template_tags.py
          djblets/features/tests/test_registry.py
          djblets/features/templatetags/features.py
          djblets/features/registry.py
          djblets/siteconfig/models.py
          djblets/features/__init__.py
          djblets/features/tests/test_testing.py
          djblets/features/level.py
          djblets/features/checkers.py
          djblets/features/testing.py
      
      Ignored Files:
          docs/djblets/guides/features/intro.rst
          docs/djblets/guides/features/index.rst
          docs/djblets/guides/index.rst
          docs/djblets/guides/features/testing.rst
          docs/djblets/guides/features/writing-feature-checkers.rst
          docs/djblets/guides/features/writing-features.rst
          docs/djblets/coderef/index.rst
          djblets/features/templatetags/__init__.py
          djblets/features/tests/__init__.py
      
      
    2. 
        
    david
    1. Ship It!
    2. 
        
    chipx86
    Review request changed
    Status:
    Completed
    Change Summary:
    Pushed to release-0.10.x (9e2737e)