We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
S
RET
RUF
1 parent d643a59 commit b59fd9eCopy full SHA for b59fd9e
benchmarks/aa_overhead_common.py
@@ -69,6 +69,6 @@ def measure_overhead(measure, title: str):
69
def os_id():
70
if sys.platform.lower() == "darwin":
71
return "macOS"
72
- elif sys.platform.lower() == "win32":
+ if sys.platform.lower() == "win32":
73
return "Windows"
74
return "Linux"
examples/as_app/talk_bot/src/main.py
@@ -20,7 +20,7 @@ def convert_currency(amount, from_currency, to_currency):
20
base_url = "https://api.exchangerate-api.com/v4/latest/"
21
22
# Fetch latest exchange rates
23
- response = requests.get(base_url + from_currency)
+ response = requests.get(base_url + from_currency, timeout=60)
24
data = response.json()
25
26
if "rates" in data:
@@ -30,12 +30,9 @@ def convert_currency(amount, from_currency, to_currency):
30
31
if from_currency in rates and to_currency in rates:
32
conversion_rate = rates[to_currency] / rates[from_currency]
33
- converted_amount = amount * conversion_rate
34
- return converted_amount
35
- else:
36
- raise ValueError("Invalid currency!")
37
38
- raise ValueError("Unable to fetch exchange rates!")
+ return amount * conversion_rate
+ raise ValueError("Invalid currency!")
+ raise ValueError("Unable to fetch exchange rates!")
39
40
41
def currency_talk_bot_process_request(message: talk_bot.TalkBotMessage):
@@ -55,7 +52,7 @@ def currency_talk_bot_process_request(message: talk_bot.TalkBotMessage):
55
52
CURRENCY_BOT.send_message(f"{r.group(2)} {r.group(3)} is equal to {converted_amount} {r.group(4)}", message)
56
53
except Exception as e:
57
54
# In production, it is better to write to log, than in the chat ;)
58
- CURRENCY_BOT.send_message(f"Exception: {str(e)}", message)
+ CURRENCY_BOT.send_message(f"Exception: {e}", message)
59
60
61
@APP.post("/currency_talk_bot")
examples/as_app/talk_bot_multi/src/main.py
@@ -20,21 +20,21 @@
@APP.post("/bot1")
async def bot1(message: Annotated[talk_bot.TalkBotMessage, Depends(talk_bot_app)]):
if message.object_name != "message":
- return
+ return None
r = re.search(r"@bot\sone.*", message.object_content["message"], re.IGNORECASE)
if r is None and re.search(r"@bots!", message.object_content["message"], re.IGNORECASE) is None:
27
BOT1.send_message("I am here, my Lord!", message)
28
return requests.Response()
29
@APP.post("/bot2")
async def bot2(message: Annotated[talk_bot.TalkBotMessage, Depends(talk_bot_app)]):
r = re.search(r"@bot\stwo.*", message.object_content["message"], re.IGNORECASE)
BOT2.send_message("I am here, my Lord!", message)
nc_py_api/_misc.py
@@ -2,10 +2,10 @@
2
3
For internal use, prototypes can change between versions.
4
"""
5
+import secrets
6
from base64 import b64decode
7
from datetime import datetime, timezone
-from random import choice
8
-from string import ascii_lowercase, ascii_uppercase, digits
+from string import ascii_letters, digits
9
from typing import Callable, Union
10
11
from ._exceptions import NextcloudMissingCapabilities
@@ -65,8 +65,8 @@ def check_capabilities(capabilities: Union[str, list[str]], srv_capabilities: di
65
66
def random_string(size: int) -> str:
67
"""Generates a random ASCII string of the given size."""
68
- letters = ascii_lowercase + ascii_uppercase + digits
- return "".join(choice(letters) for _ in range(size))
+ char_string = ascii_letters + digits
+ return "".join(secrets.choice(char_string) for _ in range(size))
def nc_iso_time_to_datetime(iso8601_time: str) -> datetime:
nc_py_api/files/__init__.py
@@ -129,11 +129,11 @@ def __str__(self):
129
if self.info.is_version:
130
return (
131
f"File version: `{self.name}` for FileID={self.file_id}"
132
- f" last modified at {str(self.info.last_modified)} with {self.info.content_length} bytes size."
+ f" last modified at {self.info.last_modified} with {self.info.content_length} bytes size."
133
)
134
135
f"{'Dir' if self.is_dir else 'File'}: `{self.name}` with id={self.file_id}"
136
- f" last modified at {str(self.info.last_modified)} and {self.info.permissions} permissions."
+ f" last modified at {self.info.last_modified} and {self.info.permissions} permissions."
137
138
139
def __eq__(self, other):
nc_py_api/files/files.py
@@ -6,8 +6,6 @@
from io import BytesIO
from json import dumps, loads
from pathlib import Path
-from string import ascii_lowercase, digits
from typing import Optional, Union
12
from urllib.parse import unquote
13
from xml.etree import ElementTree
@@ -16,7 +14,7 @@
16
14
from httpx import Response
17
15
18
from .._exceptions import NextcloudException, NextcloudExceptionNotFound, check_error
19
-from .._misc import clear_from_params_empty, require_capabilities
+from .._misc import clear_from_params_empty, random_string, require_capabilities
from .._session import NcSessionBasic
from . import FsNode, SystemTag
from .sharing import _FilesSharingAPI
@@ -694,8 +692,7 @@ def __download2stream(self, path: str, fp, **kwargs) -> None:
694
692
fp.write(data_chunk)
695
693
696
def __upload_stream(self, path: str, fp, **kwargs) -> FsNode:
697
- _rnd_folder = "".join(choice(digits + ascii_lowercase) for _ in range(64))
698
- _dav_path = self._dav_get_obj_path(self._session.user, _rnd_folder, root_path="/uploads")
+ _dav_path = self._dav_get_obj_path(self._session.user, random_string(64), root_path="/uploads")
699
response = self._session.dav("MKCOL", _dav_path)
700
check_error(response.status_code)
701
try:
nc_py_api/talk_bot.py
@@ -202,7 +202,7 @@ def _sign_send_request(self, method: str, url_suffix: str, data: dict, data_to_s
202
203
def get_bot_secret(callback_url: str) -> typing.Union[bytes, None]:
204
"""Returns the bot's secret from an environment variable or from the application's configuration on the server."""
205
- sha_1 = hashlib.sha1()
+ sha_1 = hashlib.sha1(usedforsecurity=False)
206
string_to_hash = os.environ["APP_ID"] + "_" + callback_url
207
sha_1.update(string_to_hash.encode("UTF-8"))
208
secret_key = sha_1.hexdigest()
nc_py_api/weather_status.py
@@ -67,8 +67,8 @@ def set_location(
) -> bool:
"""Sets the user's location on the Nextcloud server.
- :param latitude: north–south position of a point on the surface of the Earth.
- :param longitude: east–west position of a point on the surface of the Earth.
+ :param latitude: north-south position of a point on the surface of the Earth.
+ :param longitude: east-west position of a point on the surface of the Earth.
:param address: city, index(*optional*) and country, e.g. "Paris, 75007, France"
require_capabilities("weather_status.enabled", self._session.capabilities)
pyproject.toml
@@ -104,8 +104,8 @@ preview = true
104
[tool.ruff]
105
line-length = 120
106
target-version = "py39"
107
-select = ["A", "B", "C", "D", "E", "F", "G", "I", "UP", "SIM", "Q", "W"]
108
-extend-ignore = ["D107", "D105", "D203", "D213", "D401", "I001"]
+select = ["A", "B", "C", "D", "E", "F", "G", "I", "S", "SIM", "Q", "RET", "RUF", "UP" , "W"]
+extend-ignore = ["D107", "D105", "D203", "D213", "D401", "I001", "RUF100"]
109
110
[tool.ruff.per-file-ignores]
111
"nc_py_api/__init__.py" = ["F401"]
@@ -114,8 +114,8 @@ extend-ignore = ["D107", "D105", "D203", "D213", "D401", "I001"]
114
[tool.ruff.extend-per-file-ignores]
115
"benchmarks/**/*.py" = ["D"]
116
"docs/**/*.py" = ["D"]
117
-"examples/**/*.py" = ["D"]
118
-"tests/**/*.py" = ["D", "E402", "UP"]
+"examples/**/*.py" = ["D", "S106"]
+"tests/**/*.py" = ["D", "E402", "S", "UP"]
119
120
[tool.ruff.mccabe]
121
max-complexity = 16
tests/actual_tests/files_test.py
@@ -48,7 +48,7 @@ def test_list_user_root_self_exclude(nc):
48
user_root = nc.files.listdir()
49
user_root_with_self = nc.files.listdir(exclude_self=False)
50
assert len(user_root_with_self) == 1 + len(user_root)
51
- self_res = [i for i in user_root_with_self if not i.user_path][0]
+ self_res = next(i for i in user_root_with_self if not i.user_path)
for i in user_root:
assert self_res != i
assert self_res.has_extra
0 commit comments