@esteele Jenkins CI reporting about code analysis
See the full report here: https://jenkins.plone.org/job/package-plone.app.contentrules/63/violations
```
plone/app/contentrules/handlers.py:80:12: P002 found "hasattr", consider replacing it
plone/app/contentrules/handlers.py:82:12: P002 found "hasattr", consider replacing it
plone/app/contentrules/handlers.py:89:8: P002 found "hasattr", consider replacing it
plone/app/contentrules/handlers.py:92:8: P002 found "hasattr", consider replacing it
plone/app/contentrules/actions/copy.py:85:45: C812 missing trailing comma
plone/app/contentrules/actions/copy.py:86:18: C812 missing trailing comma
plone/app/contentrules/actions/copy.py:126:56: C812 missing trailing comma
plone/app/contentrules/actions/logger.py:22:60: C812 missing trailing comma
plone/app/contentrules/actions/logger.py:50:10: C812 missing trailing comma
plone/app/contentrules/actions/logger.py:94:18: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:39:22: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:45:57: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:47:23: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:53:67: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:55:22: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:59:80: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:64:22: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:102:5: C901 'MailActionExecutor.__call__' is too complex (13)
plone/app/contentrules/actions/mail.py:106:74: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:129:78: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:152:19: C812 missing trailing comma
plone/app/contentrules/actions/mail.py:165:19: T000 Todo note found.
plone/app/contentrules/actions/mail.py:176:78: C812 missing trailing comma
plone/app/contentrules/actions/move.py:54:52: C812 missing trailing comma
plone/app/contentrules/actions/move.py:91:18: C812 missing trailing comma
plone/app/contentrules/actions/move.py:144:56: C812 missing trailing comma
plone/app/contentrules/browser/assignments.py:24:5: C901 'ManageAssignments.__call__' is too complex (14)
plone/app/contentrules/browser/assignments.py:154:54: C812 missing trailing comma
plone/app/contentrules/browser/controlpanel.py:83:18: C812 missing trailing comma
plone/app/contentrules/browser/elements.py:29:5: C901 'ManageElements.__call__' is too complex (12)
plone/app/contentrules/browser/elements.py:77:45: C812 missing trailing comma
plone/app/contentrules/conditions/fileextension.py:31:22: C812 missing trailing comma
plone/app/contentrules/conditions/fileextension.py:49:50: C812 missing trailing comma
plone/app/contentrules/conditions/fileextension.py:90:78: C812 missing trailing comma
plone/app/contentrules/conditions/fileextension.py:113:78: C812 missing trailing comma
plone/app/contentrules/conditions/group.py:27:77: C812 missing trailing comma
plone/app/contentrules/conditions/group.py:45:60: C812 missing trailing comma
plone/app/contentrules/conditions/group.py:84:70: C812 missing trailing comma
plone/app/contentrules/conditions/group.py:105:70: C812 missing trailing comma
plone/app/contentrules/conditions/portaltype.py:33:72: C812 missing trailing comma
plone/app/contentrules/conditions/portaltype.py:34:10: C812 missing trailing comma
plone/app/contentrules/conditions/portaltype.py:60:50: C812 missing trailing comma
plone/app/contentrules/conditions/portaltype.py:79:16: P002 found "hasattr", consider replacing it
plone/app/contentrules/conditions/portaltype.py:98:34: C812 missing trailing comma
plone/app/contentrules/conditions/portaltype.py:119:26: C812 missing trailing comma
plone/app/contentrules/conditions/role.py:28:76: C812 missing trailing comma
plone/app/contentrules/conditions/role.py:46:59: C812 missing trailing comma
plone/app/contentrules/conditions/role.py:84:51: C812 missing trailing comma
plone/app/contentrules/conditions/role.py:105:51: C812 missing trailing comma
plone/app/contentrules/conditions/wfstate.py:28:63: C812 missing trailing comma
plone/app/contentrules/conditions/wfstate.py:29:10: C812 missing trailing comma
plone/app/contentrules/conditions/wfstate.py:46:59: C812 missing trailing comma
plone/app/contentrules/conditions/wftransition.py:28:68: C812 missing trailing comma
plone/app/contentrules/conditions/wftransition.py:29:10: C812 missing trailing comma
plone/app/contentrules/exportimport/rules.py:30:1: I004 isort found an unexpected blank line in imports
plone/app/contentrules/exportimport/rules.py:138:11: T000 Todo note found.
plone/app/contentrules/exportimport/rules.py:201:5: C901 'RulesXMLAdapter._initRules' is too complex (21)
plone/app/contentrules/tests/test_action_delete.py:12:1: F401 'plone.app.testing.login' imported but unused
plone/app/contentrules/tests/test_action_delete.py:12:1: I001 isort found an import in the wrong position
plone/app/contentrules/tests/test_action_delete.py:13:1: F401 'plone.app.testing.TEST_USER_ID' imported but unused
plone/app/contentrules/tests/test_action_delete.py:13:1: I001 isort found an import in the wrong position
plone/app/contentrules/tests/test_action_delete.py:14:1: F401 'plone.app.testing.TEST_USER_NAME' imported but unused
plone/app/contentrules/tests/test_action_delete.py:14:1: I001 isort found an import in the wrong position
plone/app/contentrules/tests/test_action_delete.py:15:1: F401 'plone.app.testing.setRoles' imported but unused
plone/app/contentrules/tests/test_action_delete.py:15:1: I001 isort found an import in the wrong position
plone/app/contentrules/tests/test_action_logger.py:6:1: F401 'plone.app.testing.TEST_USER_ID' imported but unused
plone/app/contentrules/tests/test_action_mail.py:50:11: T000 Todo note found.
plone/app/contentrules/tests/test_action_mail.py:95:14: C812 missing trailing comma
plone/app/contentrules/tests/test_action_mail.py:250:73: C812 missing trailing comma
plone/app/contentrules/tests/test_action_workflow.py:70:14: C812 missing trailing comma
plone/app/contentrules/tests/test_action_workflow.py:89:14: C812 missing trailing comma
plone/app/contentrules/tests/test_browser.py:2:80: E501 line too long (84 > 79 characters)
plone/app/contentrules/tests/test_cascading_rule.py:3:80: E501 line too long (84 > 79 characters)
plone/app/contentrules/tests/test_condition_wftransition.py:68:18: C812 missing trailing comma
plone/app/contentrules/tests/test_condition_wftransition.py:83:18: C812 missing trailing comma
plone/app/contentrules/tests/test_condition_wftransition.py:98:18: C812 missing trailing comma
plone/app/contentrules/tests/test_configuration.py:90:80: E501 line too long (85 > 79 characters)
plone/app/contentrules/tests/test_events.py:8:11: T000 Todo note found.
plone/app/contentrules/tests/test_events.py:12:11: T000 Todo note found.
plone/app/contentrules/tests/test_rule_assignment_mapping.py:7:1: F401 'plone.app.contentrules.tests.base.ContentRulesTestCase' imported but unused
plone/app/contentrules/tests/test_traversal.py:4:1: I001 isort found an import in the wrong position
plone/app/contentrules/tests/test_traversal.py:5:1: I001 isort found an import in the wrong position
```
Follow [these instructions](https://github.com/plone/jenkins.plone.org/blob/master/docs/source/run-qa-on-package.rst) to reproduce it locally.


pls revert

I was having so much fun 👎