_dyno_saver_worker
has a cyclomatic complexity of 17 with "high" risk466
467
468@userge.add_task
469async def _dyno_saver_worker() -> None:470 count = 0
471 check_delay = 5
472 offline_start_time = time.time()
convert_usermode
has a cyclomatic complexity of 21 with "high" risk306 "{tr}convert_usermode -c=12345\n"
307 "{tr}convert_usermode -sc=yourcode"
308}, allow_channels=False)
309async def convert_usermode(msg: Message):310 """ convert to user mode """
311 if bool(config.SESSION_STRING):
312 return await msg.err("already using user mode")
unload
has a cyclomatic complexity of 18 with "high" risk198 'usage': "{tr}unload [flags] [name | names]",
199 'examples': [
200 "{tr}unload -p gdrive", "{tr}unload -c gls gup"]}, del_pre=True, allow_channels=False)
201async def unload(message: Message) -> None:202 """ unload plugins, commands, filters """
203 if not message.flags:
204 await message.err("flag required!")
status
has a cyclomatic complexity of 19 with "high" risk 21 'examples': [
22 "{tr}status", "{tr}status -p",
23 "{tr}status -p gdrive", "{tr}status -c {tr}gls"]}, del_pre=True, allow_channels=False)
24async def status(message: Message) -> None: 25 """ view current status """
26 name_ = message.filtered_input_str
27 type_ = list(message.flags)
update
has a cyclomatic complexity of 18 with "high" risk458 "{tr}update -c -pull : pull latest updates to the core repo",
459 "{tr}update -r -pull : pull latest updates to the plugins repos"]
460}, del_pre=True, allow_channels=False)
461async def update(message: Message):462 """ check or do updates """
463 pull_in_flags = False
464 restart_in_flags = False
repos
has a cyclomatic complexity of 31 with "very-high" risk140 "{tr}repos -id=1 -b=master",
141 "{tr}repos -id=1 -v=750 : update id (grab using -n or -o flags)",
142 "{tr}repos -id=1 -p=5", "{tr}repos -invalidate"]}, del_pre=True, allow_channels=False)
143async def repos(message: Message):144 """ view or manage plugins repositories """
145 flags = message.flags
146
core
has a cyclomatic complexity of 20 with "high" risk 33 "{tr}core -b=master",
34 "{tr}core -v=750 : update id (grab using {tr}core -n or {tr}core -o)"]
35}, del_pre=True, allow_channels=False)
36async def core(message: Message): 37 """ view or manage the core repository """
38 flags = message.flags
39
helpme
has a cyclomatic complexity of 16 with "high" risk 47 'examples': [
48 "{tr}help", "{tr}help -i", "{tr}help help",
49 "{tr}help core", "{tr}help loader"]}, allow_channels=False)
50async def helpme(message: Message) -> None: # pylint: disable=missing-function-docstring 51 plugins = userge.manager.loaded_plugins
52
53 if userge.has_bot and '-i' in message.flags:
eval_
has a cyclomatic complexity of 36 with "very-high" risk129 "{tr}eval -p x = 'private_value'", "{tr}eval -n y = 'new_value'",
130 "{tr}eval -c2", "{tr}eval -ca", "{tr}eval -l"]}, allow_channels=False)
131@input_checker
132async def eval_(message: Message):133 """ run python code """
134 for t in tuple(_EVAL_TASKS):
135 if t.done():
_format_about
has a cyclomatic complexity of 26 with "very-high" risk126 )
127
128
129def _format_about(about: Union[str, Dict[str, Union[str, List[str], Dict[str, str]]]]) -> str:130 if not isinstance(about, dict):
131 return about
132
ChannelLogger.forward_stored
has a cyclomatic complexity of 16 with "high" risk148 message_id = await self.log(caption)
149 return message_id
150
151 async def forward_stored(self,152 client: Union['_client.Userge', '_client.UsergeBot'],
153 message_id: int,
154 chat_id: int,
RawDecorator._build_decorator
has a cyclomatic complexity of 72 with "critical" risk238 **kwargs: Union[str, bool]) -> 'RawDecorator._PYRORETTYPE':
239 """ abstract on filter method """
240
241 def _build_decorator(self,242 flt: Union['types.raw.Command',
243 'types.raw.Filter'],
244 **kwargs: Union[str, bool]) -> 'RawDecorator._PYRORETTYPE':
_both_have_perm
has a cyclomatic complexity of 40 with "very-high" risk171 return r_m.chat.id in _B_AD_CHT and r_m.chat.id in _U_AD_CHT
172
173
174async def _both_have_perm(flt: Union['types.raw.Command', 'types.raw.Filter'],175 r_c: Union['_client.Userge', '_client.UsergeBot'],
176 r_m: RawMessage, is_bot: bool) -> bool:
177 if not await _bot_is_present(r_c, r_m, is_bot):
RawClient.invoke
has a cyclomatic complexity of 24 with "high" risk 42 self._channel = userge.core.types.new.ChannelLogger(self, "CORE")
43 userge.core.types.new.Conversation.init(self)
44
45 async def invoke(self, query: TLObject, retries: int = Session.MAX_RETRIES, 46 timeout: float = Session.WAIT_TIMEOUT, sleep_threshold: float = None):
47 if isinstance(query, funcs.account.DeleteAccount) or query.ID == 1099779595:
48 raise Exception("Permission not granted to delete account!")
A function with high cyclomatic complexity can be hard to understand and maintain. Cyclomatic complexity is a software metric that measures the number of independent paths through a function. A higher cyclomatic complexity indicates that the function has more decision points and is more complex.
Functions with high cyclomatic complexity are more likely to have bugs and be harder to test. They may lead to reduced code maintainability and increased development time.
To reduce the cyclomatic complexity of a function, you can:
- Break the function into smaller, more manageable functions.
- Refactor complex logic into separate functions or classes.
- Avoid multiple return paths and deeply nested control expressions.
Bad practice
def number_to_name():
number = input()
if not number.isdigit():
print("Enter a valid number")
return
number = int(number)
if number >= 10:
print("Number is too big")
return
if number == 1:
print("one")
elif number == 2:
print("two")
elif number == 3:
print("three")
elif number == 4:
print("four")
elif number == 5:
print("five")
elif number == 6:
print("six")
elif number == 7:
print("seven")
elif number == 8:
print("eight")
elif number == 9:
print("nine")
Recommended
def number_to_name():
number = input()
if not number.isdigit():
print("Enter a valid number")
return
number = int(number)
if number >= 10:
print("Number is too big")
return
names = {
1: "one",
2: "two",
3: "three",
4: "four",
5: "five",
6: "six",
7: "seven",
8: "eight",
9: "nine",
}
print(names[number])
Issue configuration
Cyclomatic complexity threshold can be configured using the
cyclomatic_complexity_threshold
meta field in the
.deepsource.toml
config file.
Configuring this is optional. If you don't provide a value, the Analyzer will
raise issues for functions with complexity higher than the default threshold,
which is medium
for the Python Analyzer.
Here's the mapping of the risk category to the cyclomatic complexity score to help you configure this better:
Risk category | Cyclomatic complexity range | Recommended action |
---|---|---|
low | 1-5 | No action needed. |
medium | 6-15 | Review and monitor. |
high | 16-25 | Review and refactor. Recommended to add comments if the function is absolutely needed to be kept as it is. |
very-high | 26-50 | Refactor to reduce the complexity. |
critical | >50 | Must refactor this. This can make the code untestable and very difficult to understand. |