From 8c52b887672f3153e31e78db4ab9e24c3081db74 Mon Sep 17 00:00:00 2001 From: ed Date: Thu, 30 Nov 2023 17:33:07 +0000 Subject: [PATCH] make linters happier --- bin/dbtool.py | 5 +++-- bin/partyfuse.py | 26 ++++++++++++++------------ bin/u2c.py | 11 ++++++----- bin/unforget.py | 2 +- copyparty/__init__.py | 2 +- copyparty/__main__.py | 17 +++++++++++------ copyparty/authsrv.py | 5 ++++- copyparty/broker_mp.py | 4 ++-- copyparty/ftpd.py | 6 +++--- copyparty/httpcli.py | 10 +++++++--- copyparty/ico.py | 18 ++---------------- copyparty/mtag.py | 3 ++- copyparty/th_srv.py | 3 ++- copyparty/up2k.py | 8 ++++---- copyparty/util.py | 28 +++++++++++++++++++--------- pyproject.toml | 4 ++++ tests/ptrav.py | 8 ++++---- tests/run.py | 2 +- tests/test_dxml.py | 4 ++-- tests/test_httpcli.py | 9 ++++----- tests/test_vfs.py | 7 +++---- tests/util.py | 34 +++++++++++++++++----------------- 22 files changed, 116 insertions(+), 100 deletions(-) diff --git a/bin/dbtool.py b/bin/dbtool.py index 11979dfa..ff92fca3 100755 --- a/bin/dbtool.py +++ b/bin/dbtool.py @@ -207,7 +207,7 @@ def examples(): def main(): - global NC, BY_PATH + global NC, BY_PATH # pylint: disable=global-statement os.system("") print() @@ -282,7 +282,8 @@ def main(): if ver == "corrupt": 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" die(m) diff --git a/bin/partyfuse.py b/bin/partyfuse.py index 365067e1..6a616e9b 100755 --- a/bin/partyfuse.py +++ b/bin/partyfuse.py @@ -53,7 +53,13 @@ from urllib.parse import unquote_to_bytes as unquote WINDOWS = sys.platform == "win32" MACOS = platform.system() == "Darwin" 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( @@ -65,6 +71,13 @@ print( ) +def null_log(msg): + pass + + +info = log = dbg = null_log + + try: from fuse import FUSE, FuseOSError, Operations except: @@ -84,13 +97,6 @@ except: 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): try: 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="") -def null_log(msg): - pass - - def hexler(binary): return binary.replace("\r", "\\r").replace("\n", "\\n") return " ".join(["{}\033[36m{:02x}\033[0m".format(b, ord(b)) for b in binary]) diff --git a/bin/u2c.py b/bin/u2c.py index 72020cee..a166d786 100755 --- a/bin/u2c.py +++ b/bin/u2c.py @@ -105,8 +105,8 @@ class File(object): # set by handshake self.recheck = False # duplicate; redo handshake after all files done self.ucids = [] # type: list[str] # chunks which need to be uploaded - self.wark = None # type: str - self.url = None # type: str + self.wark = "" # type: str + self.url = "" # type: str self.nhs = 0 # set by upload @@ -223,6 +223,7 @@ class MTHash(object): def hash_at(self, nch): f = self.f + assert f ofs = ofs0 = nch * self.csz hashobj = hashlib.sha512() chunk_sz = chunk_rem = min(self.csz, self.sz - ofs) @@ -463,7 +464,7 @@ def quotep(btxt): if not PY2: quot1 = quot1.encode("ascii") - return quot1.replace(b" ", b"+") + return quot1.replace(b" ", b"+") # type: ignore # from copyparty/util.py @@ -500,7 +501,7 @@ def up2k_chunksize(filesize): # mostly from copyparty/up2k.py 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`""" 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("-a", metavar="PASSWORD", help="password or $filepath") 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("--version", action="store_true", help="show version and exit") diff --git a/bin/unforget.py b/bin/unforget.py index e3b1b395..bda10dc6 100755 --- a/bin/unforget.py +++ b/bin/unforget.py @@ -66,7 +66,7 @@ def main(): ofs = ln.find("{") j = json.loads(ln[ofs:]) except: - pass + continue w = j["wark"] if db.execute("select w from up where w = ?", (w,)).fetchone(): diff --git a/copyparty/__init__.py b/copyparty/__init__.py index 9a067f80..2830fbba 100644 --- a/copyparty/__init__.py +++ b/copyparty/__init__.py @@ -23,7 +23,7 @@ if not PY2: unicode: Callable[[Any], str] = str else: sys.dont_write_bytecode = True - unicode = unicode # noqa: F821 # pylint: disable=undefined-variable,self-assigning-variable + unicode = unicode # type: ignore WINDOWS: Any = ( [int(x) for x in platform.version().split(".")] diff --git a/copyparty/__main__.py b/copyparty/__main__.py index 857d8082..f50434e1 100755 --- a/copyparty/__main__.py +++ b/copyparty/__main__.py @@ -143,9 +143,11 @@ def warn(msg: str) -> None: 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 + E = EE # pylint: disable=redefined-outer-name + def get_unixdir() -> str: paths: list[tuple[Callable[..., Any], str]] = [ (os.environ.get, "XDG_CONFIG_HOME"), @@ -246,7 +248,7 @@ def get_srvname() -> str: return ret -def get_fk_salt(cert_path) -> str: +def get_fk_salt() -> str: fp = os.path.join(E.cfg, "fk-salt.txt") try: with open(fp, "rb") as f: @@ -320,6 +322,7 @@ def configure_ssl_ver(al: argparse.Namespace) -> None: # oh man i love openssl # check this out # hold my beer + assert ssl ptn = re.compile(r"^OP_NO_(TLS|SSL)v") sslver = terse_sslver(al.ssl_ver).split(",") 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: + assert ssl ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) if al.ssl_ver: ctx.options &= ~al.ssl_flags_en @@ -432,9 +436,9 @@ def disable_quickedit() -> None: if PY2: wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) - k32.GetStdHandle.errcheck = ecb - k32.GetConsoleMode.errcheck = ecb - k32.SetConsoleMode.errcheck = ecb + k32.GetStdHandle.errcheck = ecb # type: ignore + k32.GetConsoleMode.errcheck = ecb # type: ignore + k32.SetConsoleMode.errcheck = ecb # type: ignore k32.GetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.LPDWORD) k32.SetConsoleMode.argtypes = (wintypes.HANDLE, wintypes.DWORD) @@ -1253,7 +1257,7 @@ def run_argparse( 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() # alpine peaks at 5 threads for some reason, @@ -1269,6 +1273,7 @@ def run_argparse( add_network(ap) add_tls(ap, cert_path) add_cert(ap, cert_path) + add_auth(ap) add_qr(ap, tty) add_zeroconf(ap) add_zc_mdns(ap) diff --git a/copyparty/authsrv.py b/copyparty/authsrv.py index 726a529d..620902aa 100644 --- a/copyparty/authsrv.py +++ b/copyparty/authsrv.py @@ -957,6 +957,7 @@ class AuthSrv(object): err = "" try: self._l(ln, 5, "volume access config:") + assert vp sk, sv = ln.split(":") if re.sub("[rwmdgGha]", "", sk) or not sk: err = "invalid accs permissions list; " @@ -974,6 +975,7 @@ class AuthSrv(object): err = "" try: self._l(ln, 6, "volume-specific config:") + assert vp zd = split_cfg_ln(ln) fstr = "" 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]) continue + assert vfs # type: ignore zv = vfs.add(mount[dst], dst) zv.axs = daxs[dst] zv.flags = mflags[dst] zv.dbv = None - assert vfs + assert vfs # type: ignore vfs.all_vols = {} vfs.all_aps = [] vfs.all_vps = [] diff --git a/copyparty/broker_mp.py b/copyparty/broker_mp.py index 371cfa67..848b07ee 100644 --- a/copyparty/broker_mp.py +++ b/copyparty/broker_mp.py @@ -46,8 +46,8 @@ class BrokerMp(object): self.num_workers = self.args.j or CORES self.log("broker", "booting {} subprocesses".format(self.num_workers)) for n in range(1, self.num_workers + 1): - q_pend: queue.Queue[tuple[int, str, list[Any]]] = mp.Queue(1) - q_yield: queue.Queue[tuple[int, str, list[Any]]] = mp.Queue(64) + 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) # type: ignore proc = MProcess(q_pend, q_yield, MpWorker, (q_pend, q_yield, self.args, n)) Daemon(self.collector, "mp-sink-{}".format(n), (proc,)) diff --git a/copyparty/ftpd.py b/copyparty/ftpd.py index 118d2b88..3538be94 100644 --- a/copyparty/ftpd.py +++ b/copyparty/ftpd.py @@ -15,7 +15,7 @@ from pyftpdlib.handlers import FTPHandler from pyftpdlib.ioloop import IOLoop from pyftpdlib.servers import FTPServer -from .__init__ import ANYWIN, PY2, TYPE_CHECKING, E +from .__init__ import PY2, TYPE_CHECKING from .authsrv import VFS from .bos import bos from .util import ( @@ -88,8 +88,8 @@ class FtpAuth(DummyAuthorizer): bans[ip] = bonk try: # only possible if multiprocessing disabled - self.hub.broker.httpsrv.bans[ip] = bonk - self.hub.broker.httpsrv.nban += 1 + self.hub.broker.httpsrv.bans[ip] = bonk # type: ignore + self.hub.broker.httpsrv.nban += 1 # type: ignore except: pass diff --git a/copyparty/httpcli.py b/copyparty/httpcli.py index cc56a8b4..7444f500 100644 --- a/copyparty/httpcli.py +++ b/copyparty/httpcli.py @@ -81,7 +81,7 @@ from .util import ( sendfile_py, undot, unescape_cookie, - unquote, + unquote, # type: ignore unquotep, vjoin, vol_san, @@ -888,7 +888,11 @@ class HttpCli(object): return self.tx_ico(self.vpath.split("/")[-1], exact=True) if self.vpath.startswith(".cpr/ssdp"): - return self.conn.hsrv.ssdp.reply(self) + if self.conn.hsrv.ssdp: + 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.args.mpmc == ".": @@ -3309,7 +3313,7 @@ class HttpCli(object): def setck(self) -> bool: 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) self.out_headerlist.append(("Set-Cookie", ck)) self.reply(b"o7\n") diff --git a/copyparty/ico.py b/copyparty/ico.py index a2ba0b0e..57da0928 100644 --- a/copyparty/ico.py +++ b/copyparty/ico.py @@ -8,7 +8,7 @@ import re from .__init__ import PY2 from .th_srv import HAVE_PIL, HAVE_PILF -from .util import BytesIO +from .util import BytesIO # type: ignore class Ico(object): @@ -22,7 +22,7 @@ class Ico(object): ext = bext.decode("utf-8") zb = hashlib.sha1(bext).digest()[2:4] 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) 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) 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 = """\ diff --git a/copyparty/mtag.py b/copyparty/mtag.py index d9971343..c71e45d6 100644 --- a/copyparty/mtag.py +++ b/copyparty/mtag.py @@ -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: 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 diff --git a/copyparty/th_srv.py b/copyparty/th_srv.py index 233de259..129e3251 100644 --- a/copyparty/th_srv.py +++ b/copyparty/th_srv.py @@ -18,7 +18,7 @@ from .bos import bos from .mtag import HAVE_FFMPEG, HAVE_FFPROBE, ffprobe from .util import ( FFMPEG_URL, - BytesIO, + BytesIO, # type: ignore Cooldown, Daemon, Pebkac, @@ -411,6 +411,7 @@ class ThumbSrv(object): if c == crops[-1]: raise + assert img # type: ignore img.write_to_file(tpath, Q=40) def conv_ffmpeg(self, abspath: str, tpath: str, fmt: str, vn: VFS) -> None: diff --git a/copyparty/up2k.py b/copyparty/up2k.py index 5d37b962..efd8c98d 100644 --- a/copyparty/up2k.py +++ b/copyparty/up2k.py @@ -1285,8 +1285,8 @@ class Up2k(object): db.t = time.time() if not self.args.no_dhash: - db.c.execute("delete from dh where d = ?", (drd,)) - db.c.execute("insert into dh values (?,?)", (drd, dhash)) + db.c.execute("delete from dh where d = ?", (drd,)) # type: ignore + db.c.execute("insert into dh values (?,?)", (drd, dhash)) # type: ignore if self.stop: return -1 @@ -1305,7 +1305,7 @@ class Up2k(object): if n: t = "forgetting {} shadowed autoindexed files in [{}] > [{}]" 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 ?||'%')" db.c.execute(q, (sh_erd, sh_erd + "/")) @@ -2204,7 +2204,7 @@ class Up2k(object): t = "native sqlite3 backup failed; using fallback method:\n" self.log(t + min_ex()) finally: - c2.close() + c2.close() # type: ignore db = cur.connection cur.close() diff --git a/copyparty/util.py b/copyparty/util.py index e4c8964c..5e39c31f 100644 --- a/copyparty/util.py +++ b/copyparty/util.py @@ -115,6 +115,11 @@ if True: # pylint: disable=using-constant-test import typing from typing import Any, Generator, Optional, Pattern, Protocol, Union + try: + from typing import LiteralString + except: + pass + class RootLogger(Protocol): def __call__(self, src: str, msg: str, c: Union[int, str] = 0) -> None: return None @@ -144,15 +149,15 @@ if not PY2: from urllib.parse import quote_from_bytes as quote from urllib.parse import unquote_to_bytes as unquote else: - from StringIO import StringIO as BytesIO - from urllib import quote # pylint: disable=no-name-in-module - from urllib import unquote # pylint: disable=no-name-in-module + from StringIO import StringIO as BytesIO # type: ignore + from urllib import quote # type: ignore # pylint: disable=no-name-in-module + from urllib import unquote # type: ignore # pylint: disable=no-name-in-module try: struct.unpack(b">i", b"idgi") - spack = struct.pack - sunpack = struct.unpack + spack = struct.pack # type: ignore + sunpack = struct.unpack # type: ignore except: def spack(fmt: bytes, *a: Any) -> bytes: @@ -378,6 +383,7 @@ def py_desc() -> str: def _sqlite_ver() -> str: + assert sqlite3 # type: ignore try: co = sqlite3.connect(":memory:") 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(".")] -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 words0 = [x for x in oth.split(",") if x] words1 = [x for x in oth[1:].split(",") if x] @@ -1987,10 +1993,10 @@ else: # moonrunes become \x3f with bytestrings, # losing mojibake support is worth def _not_actually_mbcs_enc(txt: str) -> bytes: - return txt + return txt # type: ignore def _not_actually_mbcs_dec(txt: bytes) -> str: - return txt + return txt # type: ignore fsenc = afsenc = sfsenc = _not_actually_mbcs_enc 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]]: try: # some fuses misbehave + assert ctypes if ANYWIN: bfree = ctypes.c_ulonglong(0) ctypes.windll.kernel32.GetDiskFreeSpaceExW( # type: ignore @@ -2451,6 +2458,7 @@ def getalive(pids: list[int], pgid: int) -> list[int]: alive.append(pid) else: # windows doesn't have pgroups; assume + assert psutil psutil.Process(pid) alive.append(pid) except: @@ -2468,6 +2476,7 @@ def killtree(root: int) -> None: pgid = 0 if HAVE_PSUTIL: + assert psutil pids = [root] parent = psutil.Process(root) for child in parent.children(recursive=True): @@ -2864,7 +2873,7 @@ def loadpy(ap: str, hot: bool) -> Any: if PY2: mod = __import__(mname) if hot: - reload(mod) + reload(mod) # type: ignore else: import importlib @@ -3007,6 +3016,7 @@ def termsize() -> tuple[int, int]: def hidedir(dp) -> None: if ANYWIN: try: + assert ctypes k32 = ctypes.WinDLL("kernel32") attrs = k32.GetFileAttributesW(dp) if attrs >= 0: diff --git a/pyproject.toml b/pyproject.toml index ae71bad1..8c1a1020 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,6 +100,10 @@ include_trailing_comma = true [tool.bandit] skips = ["B104", "B110", "B112"] +[tool.ruff] +line-length = 120 +ignore = ["E402", "E722"] + # ===================================================================== [tool.pylint.MAIN] diff --git a/tests/ptrav.py b/tests/ptrav.py index a7c7a260..bce8aec8 100644 --- a/tests/ptrav.py +++ b/tests/ptrav.py @@ -1,16 +1,16 @@ #!/usr/bin/env python3 +import itertools import re import sys import time -import itertools - -from . import util as tu -from .util import Cfg from copyparty.authsrv import AuthSrv from copyparty.httpcli import HttpCli +from . import util as tu +from .util import Cfg + atlas = ["%", "25", "2e", "2f", ".", "/"] diff --git a/tests/run.py b/tests/run.py index 8b6daecc..6d4bf9c9 100755 --- a/tests/run.py +++ b/tests/run.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 -import sys import runpy +import sys host = sys.argv[1] sys.argv = sys.argv[:1] + sys.argv[2:] diff --git a/tests/test_dxml.py b/tests/test_dxml.py index e3f67704..960a837d 100644 --- a/tests/test_dxml.py +++ b/tests/test_dxml.py @@ -4,9 +4,9 @@ from __future__ import print_function, unicode_literals import re import unittest - 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:") diff --git a/tests/test_httpcli.py b/tests/test_httpcli.py index 22b5ce0a..3de1b1d3 100644 --- a/tests/test_httpcli.py +++ b/tests/test_httpcli.py @@ -4,18 +4,17 @@ from __future__ import print_function, unicode_literals import io import os -import time -import shutil import pprint +import shutil import tarfile import tempfile +import time import unittest -from tests import util as tu -from tests.util import Cfg, eprint - from copyparty.authsrv import AuthSrv from copyparty.httpcli import HttpCli +from tests import util as tu +from tests.util import Cfg, eprint def hdr(query): diff --git a/tests/test_vfs.py b/tests/test_vfs.py index bd26f8dd..b79cc178 100644 --- a/tests/test_vfs.py +++ b/tests/test_vfs.py @@ -2,19 +2,18 @@ # coding: utf-8 from __future__ import print_function, unicode_literals -import os import json +import os import shutil import tempfile import unittest from textwrap import dedent +from copyparty import util +from copyparty.authsrv import VFS, AuthSrv from tests import util as tu from tests.util import Cfg -from copyparty.authsrv import AuthSrv, VFS -from copyparty import util - class TestVFS(unittest.TestCase): def setUp(self): diff --git a/tests/util.py b/tests/util.py index d3f7ae91..e2c01e10 100644 --- a/tests/util.py +++ b/tests/util.py @@ -3,23 +3,23 @@ from __future__ import print_function, unicode_literals import os -import re -import sys -import time -import shutil -import jinja2 -import threading -import tempfile import platform +import re +import shutil import subprocess as sp +import sys +import tempfile +import threading +import time from argparse import Namespace +import jinja2 WINDOWS = platform.system() == "Windows" ANYWIN = WINDOWS or sys.platform in ["msys"] 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") @@ -43,7 +43,7 @@ if MACOS: from copyparty.__init__ import E from copyparty.__main__ import init_E -from copyparty.util import Unrecv, FHC, Garda +from copyparty.util import FHC, Garda, Unrecv init_E(E) @@ -83,8 +83,8 @@ def get_ramdisk(): for _ in range(10): try: _, _ = chkcmd(["diskutil", "eraseVolume", "HFS+", "cptd", devname]) - with open("/Volumes/cptd/.metadata_never_index", "w") as f: - f.write("orz") + with open("/Volumes/cptd/.metadata_never_index", "wb") as f: + f.write(b"orz") try: shutil.rmtree("/Volumes/cptd/.fseventsd") @@ -99,10 +99,10 @@ def get_ramdisk(): raise Exception("ramdisk creation failed") ret = os.path.join(tempfile.gettempdir(), "copyparty-test") - try: + if not os.path.isdir(ret): os.mkdir(ret) - finally: - return subdir(ret) + + return subdir(ret) class Cfg(Namespace): @@ -156,10 +156,10 @@ class Cfg(Namespace): class NullBroker(object): - def say(*args): + def say(self, *args): pass - def ask(*args): + def ask(self, *args): pass @@ -209,7 +209,7 @@ class VHttpSrv(object): class VHttpConn(object): def __init__(self, args, asrv, log, 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.args = args self.asrv = asrv