Policy support backend

Review Request #970 — Created Aug. 17, 2009 and discarded

Information

Review Board SVN (deprecated)

Reviewers

This patch includes policy support for ReviewBoard. It includes the expression parser, a simple admin interface and a single action as a proof of concept.

This is a fully extensible parser, that already has a few operators to serve as an example and more operators can be used in the future.
The parser is based on a technique described in the book Beautiful Code, and has the advantage of being fast and creating a syntactic tree that can be evaluated under different contexts, and the disadvantage of having poor error messages for syntactic errors. This can be improved in latter versions using heuristics.

Actions should be checked through the helper function policy.applier.applies, conviniently imported under the name `policy_checks` in the example. That function was caching syntactic trees, but I couldn't get the cache invalidated, so I removed it.

I still don't know wether we should be using a reference to a string in the Policy class or a hardcoded string for action names, but in order to simplify the development I opted for the latter. More actions will have to be mapped for this patch to be considered complete, and those will come in future updates to this review.

Also, there should be enough semantic in the operators themselves that an builder is feasible for a limited number of expressions. Also, the manual should be automatically generated, so should a syntax helper on the side of the screen.

The parser was tested a lot. The rest was tested only in Safari.
chipx86
  1. In general, this change looks awesome, but there's a lot of code style changes I'd like to see made. Also, a lot of doc blocks could use some revising.
  2. /trunk/reviewboard/admin/views.py (Diff revision 1)
     
     
     
     
    Should be in the list alphabetically.
  3. /trunk/reviewboard/admin/views.py (Diff revision 1)
     
     
     
     
     
    Should continue to be two blank lines here.
  4. /trunk/reviewboard/policy/admin.py (Diff revision 1)
     
     
     
     
    Two blank lines.
  5. /trunk/reviewboard/policy/admin.py (Diff revision 1)
     
     
     
     
     
     
     
    This can be in the class itself.
  6. /trunk/reviewboard/policy/admin.py (Diff revision 1)
     
     
     
     
    No blank line here.
  7. /trunk/reviewboard/policy/applier.py (Diff revision 1)
     
     
    Should remove this line.
  8. /trunk/reviewboard/policy/applier.py (Diff revision 1)
     
     
     
     
    Two blank lines here.
  9. /trunk/reviewboard/policy/applier.py (Diff revision 1)
     
     
    Can you add a doc block explaining this?
  10. /trunk/reviewboard/policy/applier.py (Diff revision 1)
     
     
     
    Can combine these lines.
  11. /trunk/reviewboard/policy/applier.py (Diff revision 1)
     
     
     
    Blank line here.
  12. /trunk/reviewboard/policy/applier.py (Diff revision 1)
     
     
     
    Remove these lines.
  13. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Should be alphabetical.
  14. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Two blank lines here.
  15. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
     
     
     
    You should be able to make this simply inherit from Exception. It should handle taking a string automatically as part of Exception.
  16. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Two blank lines here.
  17. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    I'd prefer a bit of cleanup with the comment. The "Nothing too fancy here" isn't really helpful from a user's point of view.
    
    The comment about the literal strings can just be a standard # comment before the tokenizer.
  18. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    I think you can just simply return self.tokenizer.finditer(self.origin)
  19. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Blank line here.
  20. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
     
     
     
     
     
    Much of this doc block is about the implementation and background of the class, rather than how it's used. The doc block should be more about the purpose of the class and how to use it. The rest should go in standard comments.
  21. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Blank line here.
  22. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Blank line here.
  23. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Instead of using \ to join multi-line conditionals, put the whole thing in parens.
  24. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    No need for the \, since it's already in parens.
    
    Align the % (token, ...) with the string.
  25. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    What's this symbol? Should probably be a constant instead.
  26. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    "If fails" should probably be something like "If the token is not an operator, then it's a variable and will be returned." 
  27. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Same here. Use Variable.name.
  28. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Blank line between these.
  29. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Blank line here.
  30. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Shouldn't be a blank line here.
  31. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    For readability, I'd prefer: if ' ' not in op_name
  32. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Can you put the comment on the next line?
  33. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Parameters should be aligned.
  34. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Blank line here.
  35. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    "or a variable"
  36. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Blank line should be removed.
  37. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    No need for the comma after "constructs"
  38. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    "its" instead of "it's"
  39. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    This sentence doesn't make much sense to me. Also, maybe this is a regional difference, but it should be "it" instead of "he". Same with other comments in this file.
  40. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Would be nice to use _(..) for all strings in this file.
  41. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    No space after """. Same with other doc blocks.
    
    Also, "first," not "fist". Same in right().
    
    I'm not really sure what the comment means though. Can you reword it?
  42. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    No r before """
  43. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    "... of Django's own Variable for templates."
  44. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    No blank line here.
  45. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Blank line here.
  46. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Blank line here.
  47. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Can you put the comment on its own line? Also, comments should be in sentence casing.
  48. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Same here.
  49. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Blank line here.
  50. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Same about the comment. Also the same throughout the rest of this code.
  51. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
    Can combine these.
  52. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Can you add a doc block?
  53. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Two blank lines.
  54. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Two blank lines.
  55. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Two blank lines.
  56. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    its, not it's
  57. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    What is 70 for? Should probably use a constant.
  58. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
     
     
    Two blank lines.
  59. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Needs a doc block
  60. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Need a doc block.
  61. /trunk/reviewboard/policy/expression.py (Diff revision 1)
     
     
    Should be "expression" or "create_expression" or something.
  62. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
     
     
    No blank line here.
  63. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
     
     
    Two blank lines here.
  64. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
    "reviewboard" should be "Review Board"
  65. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
     
    Seems like part of the second sentence here is missing.
  66. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
    Should be unindented one indentation level.
  67. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
    The "default" parameter should be aligned with the other parameters.
  68. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
     
    Same with the first parameter here.
  69. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
    Can you add a TODO here and file a bug to get both the docs written and a link to the docs from this help text?
  70. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
     
    No need for the \, and the second line of params should align with the error string.
  71. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
    Should be localized using _(..)
  72. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
     
    Should remove these two lines.
  73. /trunk/reviewboard/policy/rules.py (Diff revision 1)
     
     
     
    These imports should be absolute. reviewboard.policy.expression. You can run into interesting problems otherwise if importing the same module using two separate relative paths.
  74. /trunk/reviewboard/policy/rules.py (Diff revision 1)
     
     
     
     
    Two blank lines here.
  75. /trunk/reviewboard/policy/rules.py (Diff revision 1)
     
     
     
     
    Two blank lines here.
  76. /trunk/reviewboard/policy/rules.py (Diff revision 1)
     
     
    This would be fine for a # comment, but not a doc block. Can you add a doc block explaining what this class does?
  77. /trunk/reviewboard/policy/rules.py (Diff revision 1)
     
     
     
     
    Two blank lines here.
  78. /trunk/reviewboard/policy/rules.py (Diff revision 1)
     
     
     
    Remove these lines.
  79. /trunk/reviewboard/policy/tests.py (Diff revision 1)
     
     
     
    If we don't have unit tests yet, we shouldn't add this file.
  80. /trunk/reviewboard/reviews/models.py (Diff revision 1)
     
     
    Not a huge fan of this. It makes it harder to grep for usage of functions and stuff.
    
    Maybe rename applies to policy_applies in applier.py.
  81. 
      
edufelipe
  1. 
      
  2. /trunk/reviewboard/policy/models.py (Diff revision 1)
     
     
    Don't you think it's too soon to file a bug about this?
  3. /trunk/reviewboard/policy/rules.py (Diff revision 1)
     
     
     
    Yeah, I complained about that on the other review and made that mistake here. Sorry.
  4.