Constraints Reference
44 constraints are available, all mechanically checked via Python AST analysis. No runtime execution needed.
List constraints flat in your profiles (constraints/profiles.yaml). They are auto-classified into required (blocking) or advisory based on the field type.
Complexity & Size
Constraint
Description
max_cyclomatic_complexity
Max McCabe complexity per function
max_cognitive_complexity
Max SonarSource cognitive complexity per function (penalizes nesting)
max_lines_per_function
Max lines in any single function
max_total_lines
Max total lines in the file
max_time_complexity
Max estimated time complexity: O(1), O(log n), O(n), O(n log n), O(n^2), O(n^3), O(2^n)
max_parameters
Max parameters per function (excluding self/cls)
max_nested_depth
Max nesting depth of control flow structures
max_return_statements
Max return statements per function
max_local_variables
Max local variables per function (excludes parameters)
Correctness
Constraint
Description
no_bare_except
Disallow except: without specifying an exception type
no_try_except_pass
Disallow except: pass or except SomeError: pass
no_return_in_finally
Disallow return/break/continue inside finally blocks
no_unreachable_code
Disallow statements after return, raise, break, or continue
no_duplicate_dict_keys
Disallow duplicate constant keys in dict literals
no_loop_variable_closure
Disallow closures capturing loop variables without default args
no_mutable_defaults
Disallow mutable literals as default arguments (def f(x=[]))
no_mutable_call_in_defaults
Disallow function calls as defaults (def f(ts=datetime.now()))
no_shadowing_builtins
Disallow names that shadow Python builtins
no_open_without_context_manager
Disallow open() without with statement
Security
Constraint
Description
no_eval
Disallow eval()
no_exec
Disallow exec()
no_unsafe_deserialization
Disallow pickle.load(), marshal.load(), etc.
no_unsafe_yaml
Disallow yaml.load() without Loader=SafeLoader
no_shell_true
Disallow subprocess.run(cmd, shell=True)
no_hardcoded_secrets
Disallow string literals in password/secret/token variables
no_requests_without_timeout
Disallow requests.get() etc. without timeout
Style & Documentation
Constraint
Description
require_docstrings
Require docstrings on all functions and classes
require_type_annotations
Require type annotations on all parameters and return values
no_print_statements
Disallow print() calls
no_star_imports
Disallow from module import *
no_global_state
Disallow module-level mutable variable assignments
no_debugger_statements
Disallow pdb/ipdb/breakpoint()
no_nested_imports
Disallow import statements inside functions
no_magic_numbers
Disallow numeric literals other than -1, 0, 1, 2 inside functions
max_string_literal_repeats
Max times the same string literal can appear
allowed_imports
Whitelist of allowed import module names
Class & Module Metrics
Constraint
Description
max_methods_per_class
Max methods per class (SRP proxy)
max_fields_per_class
Max instance attributes per class
max_class_lines
Max total lines in any single class body
max_weighted_methods_per_class
Max sum of cyclomatic complexity across all methods in a class (WMC)
max_efferent_coupling
Max distinct imported modules
min_maintainability_index
Min Radon maintainability index (0-100, higher = better)
Python Idioms
Constraint
Description
enforce_naming_conventions
PEP 8: snake_case functions/methods, CapWords classes
no_single_char_names
Ban single-char variable names (loop/comprehension vars exempt)
no_unnecessary_else_after_return
Flag else after if body ending in return/raise/break/continue
no_len_as_condition
Flag len(x) > 0, len(x) == 0, len(x) != 0 patterns
Quick-copy profiles
Minimal
profiles :
minimal :
max_cyclomatic_complexity : 15
Recommended
profiles :
recommended :
max_cyclomatic_complexity : 10
max_cognitive_complexity : 15
max_lines_per_function : 50
max_parameters : 5
max_nested_depth : 4
no_bare_except : true
no_unreachable_code : true
no_mutable_defaults : true
no_eval : true
no_exec : true
require_docstrings : true # advisory
no_print_statements : true # advisory
no_debugger_statements : true # advisory
no_magic_numbers : true
max_methods_per_class : 20
max_fields_per_class : 10
max_class_lines : 200
max_efferent_coupling : 15
enforce_naming_conventions : true
no_unnecessary_else_after_return : true
Strict
profiles :
strict :
max_cyclomatic_complexity : 5
max_cognitive_complexity : 8
max_lines_per_function : 30
max_parameters : 3
max_nested_depth : 3
max_return_statements : 4
max_local_variables : 5 # advisory
max_time_complexity : "O(n)"
no_bare_except : true
no_try_except_pass : true
no_return_in_finally : true
no_unreachable_code : true
no_duplicate_dict_keys : true
no_loop_variable_closure : true
no_mutable_defaults : true
no_mutable_call_in_defaults : true
no_shadowing_builtins : true
no_open_without_context_manager : true
no_eval : true
no_exec : true
no_unsafe_deserialization : true
no_unsafe_yaml : true
no_shell_true : true
no_hardcoded_secrets : true
no_requests_without_timeout : true
require_docstrings : true # advisory
require_type_annotations : true # advisory
no_print_statements : true # advisory
no_star_imports : true # advisory
no_global_state : true # advisory
no_debugger_statements : true # advisory
no_nested_imports : true # advisory
max_methods_per_class : 10
max_fields_per_class : 7
max_class_lines : 100
max_weighted_methods_per_class : 50
max_efferent_coupling : 10
min_maintainability_index : 20.0
enforce_naming_conventions : true
no_single_char_names : true
no_unnecessary_else_after_return : true
no_len_as_condition : true