make linters happier

This commit is contained in:
ed 2023-11-30 17:33:07 +00:00
parent c9fd26255b
commit 8c52b88767
22 changed files with 116 additions and 100 deletions

View file

@ -207,7 +207,7 @@ def examples():
def main(): def main():
global NC, BY_PATH global NC, BY_PATH # pylint: disable=global-statement
os.system("") os.system("")
print() print()
@ -282,7 +282,8 @@ def main():
if ver == "corrupt": if ver == "corrupt":
die("{} database appears to be corrupt, sorry") die("{} database appears to be corrupt, sorry")
if ver < DB_VER1 or ver > DB_VER2: iver = int(ver)
if iver < DB_VER1 or iver > DB_VER2:
m = f"{n} db is version {ver}, this tool only supports versions between {DB_VER1} and {DB_VER2}, please upgrade it with copyparty first" m = f"{n} db is version {ver}, this tool only supports versions between {DB_VER1} and {DB_VER2}, please upgrade it with copyparty first"
die(m) die(m)

View file

@ -53,7 +53,13 @@ from urllib.parse import unquote_to_bytes as unquote
WINDOWS = sys.platform == "win32" WINDOWS = sys.platform == "win32"
MACOS = platform.system() == "Darwin" MACOS = platform.system() == "Darwin"
UTC = timezone.utc UTC = timezone.utc
info = log = dbg = None
def print(*args, **kwargs):
try:
builtins.print(*list(args), **kwargs)
except:
builtins.print(termsafe(" ".join(str(x) for x in args)), **kwargs)
print( print(
@ -65,6 +71,13 @@ print(
) )
def null_log(msg):
pass
info = log = dbg = null_log
try: try:
from fuse import FUSE, FuseOSError, Operations from fuse import FUSE, FuseOSError, Operations
except: except:
@ -84,13 +97,6 @@ except:
raise raise
def print(*args, **kwargs):
try:
builtins.print(*list(args), **kwargs)
except:
builtins.print(termsafe(" ".join(str(x) for x in args)), **kwargs)
def termsafe(txt): def termsafe(txt):
try: try:
return txt.encode(sys.stdout.encoding, "backslashreplace").decode( return txt.encode(sys.stdout.encoding, "backslashreplace").decode(
@ -119,10 +125,6 @@ def fancy_log(msg):
print("{:10.6f} {} {}\n".format(time.time() % 900, rice_tid(), msg), end="") print("{:10.6f} {} {}\n".format(time.time() % 900, rice_tid(), msg), end="")
def null_log(msg):
pass
def hexler(binary): def hexler(binary):
return binary.replace("\r", "\\r").replace("\n", "\\n") return binary.replace("\r", "\\r").replace("\n", "\\n")
return " ".join(["{}\033[36m{:02x}\033[0m".format(b, ord(b)) for b in binary]) return " ".join(["{}\033[36m{:02x}\033[0m".format(b, ord(b)) for b in binary])

View file

@ -105,8 +105,8 @@ class File(object):
# set by handshake # set by handshake
self.recheck = False # duplicate; redo handshake after all files done self.recheck = False # duplicate; redo handshake after all files done
self.ucids = [] # type: list[str] # chunks which need to be uploaded self.ucids = [] # type: list[str] # chunks which need to be uploaded
self.wark = None # type: str self.wark = "" # type: str
self.url = None # type: str self.url = "" # type: str
self.nhs = 0 self.nhs = 0
# set by upload # set by upload
@ -223,6 +223,7 @@ class MTHash(object):
def hash_at(self, nch): def hash_at(self, nch):
f = self.f f = self.f
assert f
ofs = ofs0 = nch * self.csz ofs = ofs0 = nch * self.csz
hashobj = hashlib.sha512() hashobj = hashlib.sha512()
chunk_sz = chunk_rem = min(self.csz, self.sz - ofs) chunk_sz = chunk_rem = min(self.csz, self.sz - ofs)
@ -463,7 +464,7 @@ def quotep(btxt):
if not PY2: if not PY2:
quot1 = quot1.encode("ascii") quot1 = quot1.encode("ascii")
return quot1.replace(b" ", b"+") return quot1.replace(b" ", b"+") # type: ignore
# from copyparty/util.py # from copyparty/util.py
@ -500,7 +501,7 @@ def up2k_chunksize(filesize):
# mostly from copyparty/up2k.py # mostly from copyparty/up2k.py
def get_hashlist(file, pcb, mth): def get_hashlist(file, pcb, mth):
# type: (File, any, any) -> None # type: (File, Any, Any) -> None
"""generates the up2k hashlist from file contents, inserts it into `file`""" """generates the up2k hashlist from file contents, inserts it into `file`"""
chunk_sz = up2k_chunksize(file.size) chunk_sz = up2k_chunksize(file.size)
@ -1116,7 +1117,7 @@ source file/folder selection uses rsync syntax, meaning that:
ap.add_argument("-v", action="store_true", help="verbose") ap.add_argument("-v", action="store_true", help="verbose")
ap.add_argument("-a", metavar="PASSWORD", help="password or $filepath") ap.add_argument("-a", metavar="PASSWORD", help="password or $filepath")
ap.add_argument("-s", action="store_true", help="file-search (disables upload)") ap.add_argument("-s", action="store_true", help="file-search (disables upload)")
ap.add_argument("-x", type=unicode, metavar="REGEX", default="", help="skip file if filesystem-abspath matches REGEX, example: '.*/\.hist/.*'") ap.add_argument("-x", type=unicode, metavar="REGEX", default="", help="skip file if filesystem-abspath matches REGEX, example: '.*/\\.hist/.*'")
ap.add_argument("--ok", action="store_true", help="continue even if some local files are inaccessible") ap.add_argument("--ok", action="store_true", help="continue even if some local files are inaccessible")
ap.add_argument("--version", action="store_true", help="show version and exit") ap.add_argument("--version", action="store_true", help="show version and exit")

View file

@ -66,7 +66,7 @@ def main():
ofs = ln.find("{") ofs = ln.find("{")
j = json.loads(ln[ofs:]) j = json.loads(ln[ofs:])
except: except:
pass continue
w = j["wark"] w = j["wark"]
if db.execute("select w from up where w = ?", (w,)).fetchone(): if db.execute("select w from up where w = ?", (w,)).fetchone():

View file

@ -23,7 +23,7 @@ if not PY2:
unicode: Callable[[Any], str] = str unicode: Callable[[Any], str] = str
else: else:
sys.dont_write_bytecode = True sys.dont_write_bytecode = True
unicode = unicode # noqa: F821 # pylint: disable=undefined-variable,self-assigning-variable unicode = unicode # type: ignore
WINDOWS: Any = ( WINDOWS: Any = (
[int(x) for x in platform.version().split(".")] [int(x) for x in platform.version().split(".")]

View file

@ -143,9 +143,11 @@ def warn(msg: str) -> None:
lprint("\033[1mwarning:\033[0;33m {}\033[0m\n".format(msg)) lprint("\033[1mwarning:\033[0;33m {}\033[0m\n".format(msg))
def init_E(E: EnvParams) -> None: def init_E(EE: EnvParams) -> None:
# __init__ runs 18 times when oxidized; do expensive stuff here # __init__ runs 18 times when oxidized; do expensive stuff here
E = EE # pylint: disable=redefined-outer-name
def get_unixdir() -> str: def get_unixdir() -> str:
paths: list[tuple[Callable[..., Any], str]] = [ paths: list[tuple[Callable[..., Any], str]] = [
(os.environ.get, "XDG_CONFIG_HOME"), (os.environ.get, "XDG_CONFIG_HOME"),
@ -246,7 +248,7 @@ def get_srvname() -> str:
return ret return ret
def get_fk_salt(cert_path) -> str: def get_fk_salt() -> str:
fp = os.path.join(E.cfg, "fk-salt.txt") fp = os.path.join(E.cfg, "fk-salt.txt")
try: try:
with open(fp, "rb") as f: with open(fp, "rb") as f:
@ -320,6 +322,7 @@ def configure_ssl_ver(al: argparse.Namespace) -> None:
# oh man i love openssl # oh man i love openssl
# check this out # check this out
# hold my beer # hold my beer
assert ssl
ptn = re.compile(r"^OP_NO_(TLS|SSL)v") ptn = re.compile(r"^OP_NO_(TLS|SSL)v")
sslver = terse_sslver(al.ssl_ver).split(",") sslver = terse_sslver(al.ssl_ver).split(",")
flags = [k for k in ssl.__dict__ if ptn.match(k)] flags = [k for k in ssl.__dict__ if ptn.match(k)]
@ -353,6 +356,7 @@ def configure_ssl_ver(al: argparse.Namespace) -> None:
def configure_ssl_ciphers(al: argparse.Namespace) -> None: def configure_ssl_ciphers(al: argparse.Namespace) -> None:
assert ssl
ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
if al.ssl_ver: if al.ssl_ver:
ctx.options &= ~al.ssl_flags_en ctx.options &= ~al.ssl_flags_en
@ -432,9 +436,9 @@ def disable_quickedit() -> None:
if PY2: if PY2:
wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD)
k32.GetStdHandle.errcheck = ecb k32.GetStdHandle.errcheck = ecb # type: ignore
k32.GetConsoleMode.errcheck = ecb k32.GetConsoleMode.errcheck = ecb # type: ignore
k32.SetConsoleMode.errcheck = ecb k32.SetConsoleMode.errcheck = ecb # type: ignore
k32.GetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.LPDWORD) k32.GetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.LPDWORD)
k32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD) k32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD)
@ -1253,7 +1257,7 @@ def run_argparse(
cert_path = os.path.join(E.cfg, "cert.pem") cert_path = os.path.join(E.cfg, "cert.pem")
fk_salt = get_fk_salt(cert_path) fk_salt = get_fk_salt()
ah_salt = get_ah_salt() ah_salt = get_ah_salt()
# alpine peaks at 5 threads for some reason, # alpine peaks at 5 threads for some reason,
@ -1269,6 +1273,7 @@ def run_argparse(
add_network(ap) add_network(ap)
add_tls(ap, cert_path) add_tls(ap, cert_path)
add_cert(ap, cert_path) add_cert(ap, cert_path)
add_auth(ap)
add_qr(ap, tty) add_qr(ap, tty)
add_zeroconf(ap) add_zeroconf(ap)
add_zc_mdns(ap) add_zc_mdns(ap)

View file

@ -957,6 +957,7 @@ class AuthSrv(object):
err = "" err = ""
try: try:
self._l(ln, 5, "volume access config:") self._l(ln, 5, "volume access config:")
assert vp
sk, sv = ln.split(":") sk, sv = ln.split(":")
if re.sub("[rwmdgGha]", "", sk) or not sk: if re.sub("[rwmdgGha]", "", sk) or not sk:
err = "invalid accs permissions list; " err = "invalid accs permissions list; "
@ -974,6 +975,7 @@ class AuthSrv(object):
err = "" err = ""
try: try:
self._l(ln, 6, "volume-specific config:") self._l(ln, 6, "volume-specific config:")
assert vp
zd = split_cfg_ln(ln) zd = split_cfg_ln(ln)
fstr = "" fstr = ""
for sk, sv in zd.items(): for sk, sv in zd.items():
@ -1184,12 +1186,13 @@ class AuthSrv(object):
vfs = VFS(self.log_func, mount[dst], dst, daxs[dst], mflags[dst]) vfs = VFS(self.log_func, mount[dst], dst, daxs[dst], mflags[dst])
continue continue
assert vfs # type: ignore
zv = vfs.add(mount[dst], dst) zv = vfs.add(mount[dst], dst)
zv.axs = daxs[dst] zv.axs = daxs[dst]
zv.flags = mflags[dst] zv.flags = mflags[dst]
zv.dbv = None zv.dbv = None
assert vfs assert vfs # type: ignore
vfs.all_vols = {} vfs.all_vols = {}
vfs.all_aps = [] vfs.all_aps = []
vfs.all_vps = [] vfs.all_vps = []

View file

@ -46,8 +46,8 @@ class BrokerMp(object):
self.num_workers = self.args.j or CORES self.num_workers = self.args.j or CORES
self.log("broker", "booting {} subprocesses".format(self.num_workers)) self.log("broker", "booting {} subprocesses".format(self.num_workers))
for n in range(1, self.num_workers + 1): for n in range(1, self.num_workers + 1):
q_pend: queue.Queue[tuple[int, str, list[Any]]] = mp.Queue(1) q_pend: queue.Queue[tuple[int, str, list[Any]]] = mp.Queue(1) # type: ignore
q_yield: queue.Queue[tuple[int, str, list[Any]]] = mp.Queue(64) q_yield: queue.Queue[tuple[int, str, list[Any]]] = mp.Queue(64) # type: ignore
proc = MProcess(q_pend, q_yield, MpWorker, (q_pend, q_yield, self.args, n)) proc = MProcess(q_pend, q_yield, MpWorker, (q_pend, q_yield, self.args, n))
Daemon(self.collector, "mp-sink-{}".format(n), (proc,)) Daemon(self.collector, "mp-sink-{}".format(n), (proc,))

View file

@ -15,7 +15,7 @@ from pyftpdlib.handlers import FTPHandler
from pyftpdlib.ioloop import IOLoop from pyftpdlib.ioloop import IOLoop
from pyftpdlib.servers import FTPServer from pyftpdlib.servers import FTPServer
from .__init__ import ANYWIN, PY2, TYPE_CHECKING, E from .__init__ import PY2, TYPE_CHECKING
from .authsrv import VFS from .authsrv import VFS
from .bos import bos from .bos import bos
from .util import ( from .util import (
@ -88,8 +88,8 @@ class FtpAuth(DummyAuthorizer):
bans[ip] = bonk bans[ip] = bonk
try: try:
# only possible if multiprocessing disabled # only possible if multiprocessing disabled
self.hub.broker.httpsrv.bans[ip] = bonk self.hub.broker.httpsrv.bans[ip] = bonk # type: ignore
self.hub.broker.httpsrv.nban += 1 self.hub.broker.httpsrv.nban += 1 # type: ignore
except: except:
pass pass

View file

@ -81,7 +81,7 @@ from .util import (
sendfile_py, sendfile_py,
undot, undot,
unescape_cookie, unescape_cookie,
unquote, unquote, # type: ignore
unquotep, unquotep,
vjoin, vjoin,
vol_san, vol_san,
@ -888,7 +888,11 @@ class HttpCli(object):
return self.tx_ico(self.vpath.split("/")[-1], exact=True) return self.tx_ico(self.vpath.split("/")[-1], exact=True)
if self.vpath.startswith(".cpr/ssdp"): if self.vpath.startswith(".cpr/ssdp"):
if self.conn.hsrv.ssdp:
return self.conn.hsrv.ssdp.reply(self) return self.conn.hsrv.ssdp.reply(self)
else:
self.reply(b"ssdp is disabled in server config", 404)
return False
if self.vpath.startswith(".cpr/dd/") and self.args.mpmc: if self.vpath.startswith(".cpr/dd/") and self.args.mpmc:
if self.args.mpmc == ".": if self.args.mpmc == ".":
@ -3309,7 +3313,7 @@ class HttpCli(object):
def setck(self) -> bool: def setck(self) -> bool:
k, v = self.uparam["setck"].split("=", 1) k, v = self.uparam["setck"].split("=", 1)
t = None if v == "" else 86400 * 299 t = 0 if v == "" else 86400 * 299
ck = gencookie(k, v, self.args.R, False, t) ck = gencookie(k, v, self.args.R, False, t)
self.out_headerlist.append(("Set-Cookie", ck)) self.out_headerlist.append(("Set-Cookie", ck))
self.reply(b"o7\n") self.reply(b"o7\n")

View file

@ -8,7 +8,7 @@ import re
from .__init__ import PY2 from .__init__ import PY2
from .th_srv import HAVE_PIL, HAVE_PILF from .th_srv import HAVE_PIL, HAVE_PILF
from .util import BytesIO from .util import BytesIO # type: ignore
class Ico(object): class Ico(object):
@ -22,7 +22,7 @@ class Ico(object):
ext = bext.decode("utf-8") ext = bext.decode("utf-8")
zb = hashlib.sha1(bext).digest()[2:4] zb = hashlib.sha1(bext).digest()[2:4]
if PY2: if PY2:
zb = [ord(x) for x in zb] zb = [ord(x) for x in zb] # type: ignore
c1 = colorsys.hsv_to_rgb(zb[0] / 256.0, 1, 0.3) c1 = colorsys.hsv_to_rgb(zb[0] / 256.0, 1, 0.3)
c2 = colorsys.hsv_to_rgb(zb[0] / 256.0, 0.8 if HAVE_PILF else 1, 1) c2 = colorsys.hsv_to_rgb(zb[0] / 256.0, 0.8 if HAVE_PILF else 1, 1)
@ -91,20 +91,6 @@ class Ico(object):
img.save(buf, format="PNG", compress_level=1) img.save(buf, format="PNG", compress_level=1)
return "image/png", buf.getvalue() return "image/png", buf.getvalue()
elif False:
# 48s, too slow
import pyvips
h = int(192 * h / w)
w = 192
img = pyvips.Image.text(
ext, width=w, height=h, dpi=192, align=pyvips.Align.CENTRE
)
img = img.ifthenelse(ci[3:], ci[:3], blend=True)
# i = i.resize(3, kernel=pyvips.Kernel.NEAREST)
buf = img.write_to_buffer(".png[compression=1]")
return "image/png", buf
svg = """\ svg = """\
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1" viewBox="0 0 100 {}" xmlns="http://www.w3.org/2000/svg"><g> <svg version="1.1" viewBox="0 0 100 {}" xmlns="http://www.w3.org/2000/svg"><g>

View file

@ -261,7 +261,8 @@ def parse_ffprobe(txt: str) -> tuple[dict[str, tuple[int, Any]], dict[str, list[
if ".resw" in ret and ".resh" in ret: if ".resw" in ret and ".resh" in ret:
ret["res"] = "{}x{}".format(ret[".resw"], ret[".resh"]) ret["res"] = "{}x{}".format(ret[".resw"], ret[".resh"])
zd = {k: (0, v) for k, v in ret.items()} zero = int("0")
zd = {k: (zero, v) for k, v in ret.items()}
return zd, md return zd, md

View file

@ -18,7 +18,7 @@ from .bos import bos
from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, ffprobe from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, ffprobe
from .util import ( from .util import (
FFMPEG_URL, FFMPEG_URL,
BytesIO, BytesIO, # type: ignore
Cooldown, Cooldown,
Daemon, Daemon,
Pebkac, Pebkac,
@ -411,6 +411,7 @@ class ThumbSrv(object):
if c == crops[-1]: if c == crops[-1]:
raise raise
assert img # type: ignore
img.write_to_file(tpath, Q=40) img.write_to_file(tpath, Q=40)
def conv_ffmpeg(self, abspath: str, tpath: str, fmt: str, vn: VFS) -> None: def conv_ffmpeg(self, abspath: str, tpath: str, fmt: str, vn: VFS) -> None:

View file

@ -1285,8 +1285,8 @@ class Up2k(object):
db.t = time.time() db.t = time.time()
if not self.args.no_dhash: if not self.args.no_dhash:
db.c.execute("delete from dh where d = ?", (drd,)) db.c.execute("delete from dh where d = ?", (drd,)) # type: ignore
db.c.execute("insert into dh values (?,?)", (drd, dhash)) db.c.execute("insert into dh values (?,?)", (drd, dhash)) # type: ignore
if self.stop: if self.stop:
return -1 return -1
@ -1305,7 +1305,7 @@ class Up2k(object):
if n: if n:
t = "forgetting {} shadowed autoindexed files in [{}] > [{}]" t = "forgetting {} shadowed autoindexed files in [{}] > [{}]"
self.log(t.format(n, top, sh_rd)) self.log(t.format(n, top, sh_rd))
assert sh_erd assert sh_erd # type: ignore
q = "delete from dh where (d = ? or d like ?||'%')" q = "delete from dh where (d = ? or d like ?||'%')"
db.c.execute(q, (sh_erd, sh_erd + "/")) db.c.execute(q, (sh_erd, sh_erd + "/"))
@ -2204,7 +2204,7 @@ class Up2k(object):
t = "native sqlite3 backup failed; using fallback method:\n" t = "native sqlite3 backup failed; using fallback method:\n"
self.log(t + min_ex()) self.log(t + min_ex())
finally: finally:
c2.close() c2.close() # type: ignore
db = cur.connection db = cur.connection
cur.close() cur.close()

View file

@ -115,6 +115,11 @@ if True: # pylint: disable=using-constant-test
import typing import typing
from typing import Any, Generator, Optional, Pattern, Protocol, Union from typing import Any, Generator, Optional, Pattern, Protocol, Union
try:
from typing import LiteralString
except:
pass
class RootLogger(Protocol): class RootLogger(Protocol):
def __call__(self, src: str, msg: str, c: Union[int, str] = 0) -> None: def __call__(self, src: str, msg: str, c: Union[int, str] = 0) -> None:
return None return None
@ -144,15 +149,15 @@ if not PY2:
from urllib.parse import quote_from_bytes as quote from urllib.parse import quote_from_bytes as quote
from urllib.parse import unquote_to_bytes as unquote from urllib.parse import unquote_to_bytes as unquote
else: else:
from StringIO import StringIO as BytesIO from StringIO import StringIO as BytesIO # type: ignore
from urllib import quote # pylint: disable=no-name-in-module from urllib import quote # type: ignore # pylint: disable=no-name-in-module
from urllib import unquote # pylint: disable=no-name-in-module from urllib import unquote # type: ignore # pylint: disable=no-name-in-module
try: try:
struct.unpack(b">i", b"idgi") struct.unpack(b">i", b"idgi")
spack = struct.pack spack = struct.pack # type: ignore
sunpack = struct.unpack sunpack = struct.unpack # type: ignore
except: except:
def spack(fmt: bytes, *a: Any) -> bytes: def spack(fmt: bytes, *a: Any) -> bytes:
@ -378,6 +383,7 @@ def py_desc() -> str:
def _sqlite_ver() -> str: def _sqlite_ver() -> str:
assert sqlite3 # type: ignore
try: try:
co = sqlite3.connect(":memory:") co = sqlite3.connect(":memory:")
cur = co.cursor() cur = co.cursor()
@ -1817,7 +1823,7 @@ def exclude_dotfiles(filepaths: list[str]) -> list[str]:
return [x for x in filepaths if not x.split("/")[-1].startswith(".")] return [x for x in filepaths if not x.split("/")[-1].startswith(".")]
def odfusion(base: ODict[str, bool], oth: str) -> ODict[str, bool]: def odfusion(base: Union[ODict[str, bool], ODict["LiteralString", bool]], oth: str) -> ODict[str, bool]:
# merge an "ordered set" (just a dict really) with another list of keys # merge an "ordered set" (just a dict really) with another list of keys
words0 = [x for x in oth.split(",") if x] words0 = [x for x in oth.split(",") if x]
words1 = [x for x in oth[1:].split(",") if x] words1 = [x for x in oth[1:].split(",") if x]
@ -1987,10 +1993,10 @@ else:
# moonrunes become \x3f with bytestrings, # moonrunes become \x3f with bytestrings,
# losing mojibake support is worth # losing mojibake support is worth
def _not_actually_mbcs_enc(txt: str) -> bytes: def _not_actually_mbcs_enc(txt: str) -> bytes:
return txt return txt # type: ignore
def _not_actually_mbcs_dec(txt: bytes) -> str: def _not_actually_mbcs_dec(txt: bytes) -> str:
return txt return txt # type: ignore
fsenc = afsenc = sfsenc = _not_actually_mbcs_enc fsenc = afsenc = sfsenc = _not_actually_mbcs_enc
fsdec = _not_actually_mbcs_dec fsdec = _not_actually_mbcs_dec
@ -2049,6 +2055,7 @@ def atomic_move(usrc: str, udst: str) -> None:
def get_df(abspath: str) -> tuple[Optional[int], Optional[int]]: def get_df(abspath: str) -> tuple[Optional[int], Optional[int]]:
try: try:
# some fuses misbehave # some fuses misbehave
assert ctypes
if ANYWIN: if ANYWIN:
bfree = ctypes.c_ulonglong(0) bfree = ctypes.c_ulonglong(0)
ctypes.windll.kernel32.GetDiskFreeSpaceExW( # type: ignore ctypes.windll.kernel32.GetDiskFreeSpaceExW( # type: ignore
@ -2451,6 +2458,7 @@ def getalive(pids: list[int], pgid: int) -> list[int]:
alive.append(pid) alive.append(pid)
else: else:
# windows doesn't have pgroups; assume # windows doesn't have pgroups; assume
assert psutil
psutil.Process(pid) psutil.Process(pid)
alive.append(pid) alive.append(pid)
except: except:
@ -2468,6 +2476,7 @@ def killtree(root: int) -> None:
pgid = 0 pgid = 0
if HAVE_PSUTIL: if HAVE_PSUTIL:
assert psutil
pids = [root] pids = [root]
parent = psutil.Process(root) parent = psutil.Process(root)
for child in parent.children(recursive=True): for child in parent.children(recursive=True):
@ -2864,7 +2873,7 @@ def loadpy(ap: str, hot: bool) -> Any:
if PY2: if PY2:
mod = __import__(mname) mod = __import__(mname)
if hot: if hot:
reload(mod) reload(mod) # type: ignore
else: else:
import importlib import importlib
@ -3007,6 +3016,7 @@ def termsize() -> tuple[int, int]:
def hidedir(dp) -> None: def hidedir(dp) -> None:
if ANYWIN: if ANYWIN:
try: try:
assert ctypes
k32 = ctypes.WinDLL("kernel32") k32 = ctypes.WinDLL("kernel32")
attrs = k32.GetFileAttributesW(dp) attrs = k32.GetFileAttributesW(dp)
if attrs >= 0: if attrs >= 0:

View file

@ -100,6 +100,10 @@ include_trailing_comma = true
[tool.bandit] [tool.bandit]
skips = ["B104", "B110", "B112"] skips = ["B104", "B110", "B112"]
[tool.ruff]
line-length = 120
ignore = ["E402", "E722"]
# ===================================================================== # =====================================================================
[tool.pylint.MAIN] [tool.pylint.MAIN]

View file

@ -1,16 +1,16 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import itertools
import re import re
import sys import sys
import time import time
import itertools
from . import util as tu
from .util import Cfg
from copyparty.authsrv import AuthSrv from copyparty.authsrv import AuthSrv
from copyparty.httpcli import HttpCli from copyparty.httpcli import HttpCli
from . import util as tu
from .util import Cfg
atlas = ["%", "25", "2e", "2f", ".", "/"] atlas = ["%", "25", "2e", "2f", ".", "/"]

View file

@ -1,7 +1,7 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import sys
import runpy import runpy
import sys
host = sys.argv[1] host = sys.argv[1]
sys.argv = sys.argv[:1] + sys.argv[2:] sys.argv = sys.argv[:1] + sys.argv[2:]

View file

@ -4,9 +4,9 @@ from __future__ import print_function, unicode_literals
import re import re
import unittest import unittest
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
from copyparty.dxml import parse_xml, BadXML, mkenod, mktnod
from copyparty.dxml import BadXML, mkenod, mktnod, parse_xml
ET.register_namespace("D", "DAV:") ET.register_namespace("D", "DAV:")

View file

@ -4,18 +4,17 @@ from __future__ import print_function, unicode_literals
import io import io
import os import os
import time
import shutil
import pprint import pprint
import shutil
import tarfile import tarfile
import tempfile import tempfile
import time
import unittest import unittest
from tests import util as tu
from tests.util import Cfg, eprint
from copyparty.authsrv import AuthSrv from copyparty.authsrv import AuthSrv
from copyparty.httpcli import HttpCli from copyparty.httpcli import HttpCli
from tests import util as tu
from tests.util import Cfg, eprint
def hdr(query): def hdr(query):

View file

@ -2,19 +2,18 @@
# coding: utf-8 # coding: utf-8
from __future__ import print_function, unicode_literals from __future__ import print_function, unicode_literals
import os
import json import json
import os
import shutil import shutil
import tempfile import tempfile
import unittest import unittest
from textwrap import dedent from textwrap import dedent
from copyparty import util
from copyparty.authsrv import VFS, AuthSrv
from tests import util as tu from tests import util as tu
from tests.util import Cfg from tests.util import Cfg
from copyparty.authsrv import AuthSrv, VFS
from copyparty import util
class TestVFS(unittest.TestCase): class TestVFS(unittest.TestCase):
def setUp(self): def setUp(self):

View file

@ -3,23 +3,23 @@
from __future__ import print_function, unicode_literals from __future__ import print_function, unicode_literals
import os import os
import re
import sys
import time
import shutil
import jinja2
import threading
import tempfile
import platform import platform
import re
import shutil
import subprocess as sp import subprocess as sp
import sys
import tempfile
import threading
import time
from argparse import Namespace from argparse import Namespace
import jinja2
WINDOWS = platform.system() == "Windows" WINDOWS = platform.system() == "Windows"
ANYWIN = WINDOWS or sys.platform in ["msys"] ANYWIN = WINDOWS or sys.platform in ["msys"]
MACOS = platform.system() == "Darwin" MACOS = platform.system() == "Darwin"
J2_ENV = jinja2.Environment(loader=jinja2.BaseLoader) J2_ENV = jinja2.Environment(loader=jinja2.BaseLoader) # type: ignore
J2_FILES = J2_ENV.from_string("{{ files|join('\n') }}\nJ2EOT") J2_FILES = J2_ENV.from_string("{{ files|join('\n') }}\nJ2EOT")
@ -43,7 +43,7 @@ if MACOS:
from copyparty.__init__ import E from copyparty.__init__ import E
from copyparty.__main__ import init_E from copyparty.__main__ import init_E
from copyparty.util import Unrecv, FHC, Garda from copyparty.util import FHC, Garda, Unrecv
init_E(E) init_E(E)
@ -83,8 +83,8 @@ def get_ramdisk():
for _ in range(10): for _ in range(10):
try: try:
_, _ = chkcmd(["diskutil", "eraseVolume", "HFS+", "cptd", devname]) _, _ = chkcmd(["diskutil", "eraseVolume", "HFS+", "cptd", devname])
with open("/Volumes/cptd/.metadata_never_index", "w") as f: with open("/Volumes/cptd/.metadata_never_index", "wb") as f:
f.write("orz") f.write(b"orz")
try: try:
shutil.rmtree("/Volumes/cptd/.fseventsd") shutil.rmtree("/Volumes/cptd/.fseventsd")
@ -99,9 +99,9 @@ def get_ramdisk():
raise Exception("ramdisk creation failed") raise Exception("ramdisk creation failed")
ret = os.path.join(tempfile.gettempdir(), "copyparty-test") ret = os.path.join(tempfile.gettempdir(), "copyparty-test")
try: if not os.path.isdir(ret):
os.mkdir(ret) os.mkdir(ret)
finally:
return subdir(ret) return subdir(ret)
@ -156,10 +156,10 @@ class Cfg(Namespace):
class NullBroker(object): class NullBroker(object):
def say(*args): def say(self, *args):
pass pass
def ask(*args): def ask(self, *args):
pass pass
@ -209,7 +209,7 @@ class VHttpSrv(object):
class VHttpConn(object): class VHttpConn(object):
def __init__(self, args, asrv, log, buf): def __init__(self, args, asrv, log, buf):
self.s = VSock(buf) self.s = VSock(buf)
self.sr = Unrecv(self.s, None) self.sr = Unrecv(self.s, None) # type: ignore
self.addr = ("127.0.0.1", "42069") self.addr = ("127.0.0.1", "42069")
self.args = args self.args = args
self.asrv = asrv self.asrv = asrv