From eb07351489e809640a7116f9303e8497b312654a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Roland=20H=C3=A4der?= Date: Fri, 9 Jun 2023 02:50:37 +0200 Subject: [PATCH] Fixed some issues found by pylint: - added pylint.rc file (all checks are enabled) - '!= None' should be 'is not None' - '== None' should be 'is None' - '!= type' should be 'not isinstance(var, type)' - fixed some 'unused variable' - fixed 'duplicate definition' - fixed 'invalid name' - fixed f"foo" with no {var} in it - renamed more variables --- api.py | 58 +++-- fba/blacklist.py | 4 +- fba/blocks.py | 44 ++-- fba/boot.py | 4 +- fba/cache.py | 10 +- fba/commands.py | 32 +-- fba/config.py | 2 +- fba/fba.py | 190 +++++++------- fba/federation/lemmy.py | 8 +- fba/federation/mastodon.py | 38 +-- fba/federation/misskey.py | 22 +- fba/federation/peertube.py | 8 +- fba/federation/pleroma.py | 22 +- fba/instances.py | 64 ++--- fba/network.py | 42 +-- pylint.rc | 513 +++++++++++++++++++++++++++++++++++++ 16 files changed, 793 insertions(+), 268 deletions(-) create mode 100644 pylint.rc diff --git a/api.py b/api.py index d292349..3add50d 100644 --- a/api.py +++ b/api.py @@ -27,7 +27,8 @@ import requests import re import validators -from fba import * +from fba import config +from fba import fba router = fastapi.FastAPI(docs_url=config.get("base_url") + "/docs", redoc_url=config.get("base_url") + "/redoc") templates = Jinja2Templates(directory="templates") @@ -47,27 +48,27 @@ def info(): @router.get(config.get("base_url") + "/api/top.json", response_class=JSONResponse) def top(blocked: int = None, blockers: int = None, reference: int = None, software: int = None, originator: int = None, error_code: int = None): - if blocked != None: + if blocked is not None: if blocked > 500: raise HTTPException(status_code=400, detail="Too many results") fba.cursor.execute("SELECT blocked, COUNT(blocked) FROM blocks WHERE block_level = 'reject' GROUP BY blocked ORDER BY COUNT(blocked) DESC LIMIT ?", [blocked]) - elif blockers != None: + elif blockers is not None: if blockers > 500: raise HTTPException(status_code=400, detail="Too many results") fba.cursor.execute("SELECT blocker, COUNT(blocker) FROM blocks WHERE block_level = 'reject' GROUP BY blocker ORDER BY COUNT(blocker) DESC LIMIT ?", [blockers]) - elif reference != None: + elif reference is not None: if reference > 500: raise HTTPException(status_code=400, detail="Too many results") fba.cursor.execute("SELECT origin, COUNT(domain) FROM instances WHERE software IS NOT NULL GROUP BY origin ORDER BY COUNT(domain) DESC LIMIT ?", [reference]) - elif software != None: + elif software is not None: if software > 500: raise HTTPException(status_code=400, detail="Too many results") fba.cursor.execute("SELECT software, COUNT(domain) FROM instances WHERE software IS NOT NULL GROUP BY software ORDER BY COUNT(domain) DESC, software ASC LIMIT ?", [software]) - elif originator != None: + elif originator is not None: if originator > 500: raise HTTPException(status_code=400, detail="Too many results") fba.cursor.execute("SELECT originator, COUNT(domain) FROM instances WHERE originator IS NOT NULL GROUP BY originator ORDER BY COUNT(domain) DESC, originator ASC LIMIT ?", [originator]) - elif error_code != None: + elif error_code is not None: if error_code > 500: raise HTTPException(status_code=400, detail="Too many results") fba.cursor.execute("SELECT last_status_code, COUNT(domain) AS cnt FROM instances WHERE last_status_code IS NOT NULL AND last_status_code != '200' GROUP BY last_status_code ORDER BY cnt DESC LIMIT ?", [error_code]) @@ -88,20 +89,20 @@ def top(blocked: int = None, blockers: int = None, reference: int = None, softwa @router.get(config.get("base_url") + "/api/index.json", response_class=JSONResponse) def blocked(domain: str = None, reason: str = None, reverse: str = None): - if domain == None and reason == None and reverse == None: + if domain is None and reason is None and reverse is None: raise HTTPException(status_code=400, detail="No filter specified") - if reason != None: + if reason is not None: reason = re.sub("(%|_)", "", reason) if len(reason) < 3: raise HTTPException(status_code=400, detail="Keyword is shorter than three characters") - if domain != None: + if domain is not None: wildchar = "*." + ".".join(domain.split(".")[-domain.count("."):]) punycode = domain.encode('idna').decode('utf-8') fba.cursor.execute("SELECT blocker, blocked, block_level, reason, first_seen, last_seen FROM blocks WHERE blocked = ? OR blocked = ? OR blocked = ? OR blocked = ? OR blocked = ? OR blocked = ? ORDER BY first_seen ASC", (domain, "*." + domain, wildchar, fba.get_hash(domain), punycode, "*." + punycode)) - elif reverse != None: + elif reverse is not None: fba.cursor.execute("SELECT blocker, blocked, block_level, reason, first_seen, last_seen FROM blocks WHERE blocker = ? ORDER BY first_seen ASC", [reverse]) else: fba.cursor.execute("SELECT blocker, blocked, block_level, reason, first_seen, last_seen FROM blocks WHERE reason like ? AND reason != '' ORDER BY first_seen ASC", ["%" + reason + "%"]) @@ -110,7 +111,7 @@ def blocked(domain: str = None, reason: str = None, reverse: str = None): result = {} for blocker, blocked, block_level, reason, first_seen, last_seen in blocklist: - if reason != None and reason != "": + if reason is not None and reason != "": reason = reason.replace(",", " ").replace(" ", " ") entry = { @@ -153,23 +154,23 @@ def mutual(domains: list[str] = Query()): return JSONResponse(status_code=200, content={}) @router.get(config.get("base_url") + "/scoreboard") -def index(request: Request, blockers: int = None, blocked: int = None, reference: int = None, software: int = None, originator: int = None, error_code: int = None): - if blockers != None and blockers > 0: +def scoreboard(request: Request, blockers: int = None, blocked: int = None, reference: int = None, software: int = None, originator: int = None, error_code: int = None): + if blockers is not None and blockers > 0: response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/top.json?blockers={blockers}") - elif blocked != None and blocked > 0: + elif blocked is not None and blocked > 0: response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/top.json?blocked={blocked}") - elif reference != None and reference > 0: + elif reference is not None and reference > 0: response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/top.json?reference={reference}") - elif software != None and software > 0: + elif software is not None and software > 0: response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/top.json?software={software}") - elif originator != None and originator > 0: + elif originator is not None and originator > 0: response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/top.json?originator={originator}") - elif error_code != None and error_code > 0: + elif error_code is not None and error_code > 0: response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/top.json?error_code={error_code}") else: raise HTTPException(status_code=400, detail="No filter specified") - if response == None: + if response is None: raise HTTPException(status_code=500, detail="Could not determine scores") elif not response.ok: raise HTTPException(status_code=response.status_code, detail=response.text) @@ -202,7 +203,7 @@ def index(request: Request): }) @router.get(config.get("base_url") + "/top") -def index(request: Request, domain: str = None, reason: str = None, reverse: str = None): +def top(request: Request, domain: str = None, reason: str = None, reverse: str = None): if domain == "" or reason == "" or reverse == "": raise HTTPException(status_code=500, detail="Insufficient parameter provided") @@ -214,20 +215,20 @@ def index(request: Request, domain: str = None, reason: str = None, reverse: str info = response.json() response = None - if domain != None: + if domain is not None: if not validators.domain(domain): raise HTTPException(status_code=500, detail="Invalid domain") response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/index.json?domain={domain}") - elif reason != None: + elif reason is not None: response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/index.json?reason={reason}") - elif reverse != None: + elif reverse is not None: if not validators.domain(reverse): raise HTTPException(status_code=500, detail="Invalid domain") response = requests.get(f"http://{config.get('host')}:{config.get('port')}{config.get('base_url')}/api/index.json?reverse={reverse}") - if response != None: + if response is not None: if not response.ok: raise HTTPException(status_code=response.status_code, detail=response.text) blocklist = response.json() @@ -247,7 +248,7 @@ def index(request: Request, domain: str = None, reason: str = None, reverse: str @router.get(config.get("base_url") + "/rss") def rss(request: Request, domain: str = None): - if domain != None: + if domain is not None: wildchar = "*." + ".".join(domain.split(".")[-domain.count("."):]) punycode = domain.encode('idna').decode('utf-8') fba.cursor.execute("SELECT blocker, blocked, block_level, reason, first_seen, last_seen FROM blocks WHERE blocked = ? OR blocked = ? OR blocked = ? OR blocked = ? OR blocked = ? OR blocked = ? ORDER BY first_seen DESC LIMIT 50", @@ -260,7 +261,7 @@ def rss(request: Request, domain: str = None): blocklist = [] for blocker, blocked, block_level, reason, first_seen, last_seen in result: first_seen = utils.format_datetime(datetime.fromtimestamp(first_seen)) - if reason == None or reason == '': + if reason is None or reason == '': reason = "No reason provided." else: reason = "Provided reason: '" + reason + "'" @@ -270,7 +271,8 @@ def rss(request: Request, domain: str = None): "blocked" : blocked, "block_level": block_level, "reason" : reason, - "first_seen" : first_seen + "first_seen" : first_seen, + "last_seen" : last_seen, }) return templates.TemplateResponse("rss.xml", { diff --git a/fba/blacklist.py b/fba/blacklist.py index d78cde8..f71f735 100644 --- a/fba/blacklist.py +++ b/fba/blacklist.py @@ -34,10 +34,10 @@ blacklist = [ def is_blacklisted(domain: str) -> bool: # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") blacklisted = False for peer in blacklist: diff --git a/fba/blocks.py b/fba/blocks.py index dac50f2..50ceec8 100644 --- a/fba/blocks.py +++ b/fba/blocks.py @@ -23,17 +23,17 @@ from fba import fba def update_reason(reason: str, blocker: str, blocked: str, block_level: str): # DEBUG: print(f"DEBUG: reason='{reason}',blocker={blocker},blocked={blocked},block_level={block_level} - CALLED!") - if type(reason) != str and reason != None: + if not isinstance(reason, str) and reason is not None: raise ValueError(f"Parameter reason[]='{type(reason)}' is not 'str'") - elif type(blocker) != str: + elif not isinstance(blocker, str): raise ValueError(f"Parameter blocker[]='{type(blocker)}' is not 'str'") elif blocker == "": raise ValueError("Parameter 'blocker' is empty") - elif type(blocked) != str: + elif not isinstance(blocked, str): raise ValueError(f"Parameter blocked[]='{type(blocked)}' is not 'str'") elif blocked == "": raise ValueError("Parameter 'blocked' is empty") - elif type(block_level) != str: + elif not isinstance(block_level, str): raise ValueError(f"Parameter block_level[]='{type(block_level)}' is not 'str'") elif block_level == "": raise ValueError("Parameter 'block_level' is empty") @@ -56,23 +56,23 @@ def update_reason(reason: str, blocker: str, blocked: str, block_level: str): # DEBUG: print(f"DEBUG: Did not update any rows: blocker='{blocker}',blocked='{blocked}',block_level='{block_level}',reason='{reason}' - EXIT!") return - except BaseException as e: - print(f"ERROR: failed SQL query: reason='{reason}',blocker='{blocker}',blocked='{blocked}',block_level='{block_level}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: failed SQL query: reason='{reason}',blocker='{blocker}',blocked='{blocked}',block_level='{block_level}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print("DEBUG: EXIT!") def update_last_seen(blocker: str, blocked: str, block_level: str): # DEBUG: print("DEBUG: Updating last_seen for:", blocker, blocked, block_level) - if type(blocker) != str: + if not isinstance(blocker, str): raise ValueError(f"Parameter blocker[]='{type(blocker)}' is not 'str'") elif blocker == "": raise ValueError("Parameter 'blocker' is empty") - elif type(blocked) != str: + elif not isinstance(blocked, str): raise ValueError(f"Parameter blocked[]='{type(blocked)}' is not 'str'") elif blocked == "": raise ValueError("Parameter 'blocked' is empty") - elif type(block_level) != str: + elif not isinstance(block_level, str): raise ValueError(f"Parameter block_level[]='{type(block_level)}' is not 'str'") elif block_level == "": raise ValueError("Parameter 'block_level' is empty") @@ -93,23 +93,23 @@ def update_last_seen(blocker: str, blocked: str, block_level: str): # DEBUG: print(f"DEBUG: Did not update any rows: blocker='{blocker}',blocked='{blocked}',block_level='{block_level}' - EXIT!") return - except BaseException as e: - print(f"ERROR: failed SQL query: blocker='{blocker}',blocked='{blocked}',block_level='{block_level}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: failed SQL query: blocker='{blocker}',blocked='{blocked}',block_level='{block_level}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print("DEBUG: EXIT!") def is_instance_blocked(blocker: str, blocked: str, block_level: str) -> bool: # DEBUG: print(f"DEBUG: blocker={blocker},blocked={blocked},block_level={block_level} - CALLED!") - if type(blocker) != str: + if not isinstance(blocker, str): raise ValueError(f"Parameter blocker[]={type(blocker)} is not of type 'str'") elif blocker == "": raise ValueError("Parameter 'blocker' is empty") - elif type(blocked) != str: + elif not isinstance(blocked, str): raise ValueError(f"Parameter blocked[]={type(blocked)} is not of type 'str'") elif blocked == "": raise ValueError("Parameter 'blocked' is empty") - elif type(block_level) != str: + elif not isinstance(block_level, str): raise ValueError(f"Parameter block_level[]={type(block_level)} is not of type 'str'") elif block_level == "": raise ValueError("Parameter 'block_level' is empty") @@ -123,23 +123,23 @@ def is_instance_blocked(blocker: str, blocked: str, block_level: str) -> bool: ), ) - is_blocked = fba.cursor.fetchone() != None + is_blocked = fba.cursor.fetchone() is not None # DEBUG: print(f"DEBUG: is_blocked='{is_blocked}' - EXIT!") return is_blocked def add_instance(blocker: str, blocked: str, reason: str, block_level: str): # DEBUG: print("DEBUG: blocker,blocked,reason,block_level:", blocker, blocked, reason, block_level) - if type(blocker) != str: + if not isinstance(blocker, str): raise ValueError(f"Parameter blocker[]={type(blocker)} is not 'str'") elif blocker == "": - raise ValueError(f"Parameter 'blocker' is empty") + raise ValueError("Parameter 'blocker' is empty") elif not validators.domain(blocker.split("/")[0]): raise ValueError(f"Bad blocker='{blocker}'") - elif type(blocked) != str: + elif not isinstance(blocked, str): raise ValueError(f"Parameter blocked[]={type(blocked)} is not 'str'") elif blocked == "": - raise ValueError(f"Parameter 'blocked' is empty") + raise ValueError("Parameter 'blocked' is empty") elif not validators.domain(blocked.split("/")[0]): raise ValueError(f"Bad blocked='{blocked}'") elif blacklist.is_blacklisted(blocker): @@ -147,7 +147,7 @@ def add_instance(blocker: str, blocked: str, reason: str, block_level: str): elif blacklist.is_blacklisted(blocked): raise Exception(f"blocked='{blocked}' is blacklisted but function invoked") - if reason != None: + if reason is not None: # Maybe needs cleaning reason = fba.tidyup_reason(reason) @@ -164,8 +164,8 @@ def add_instance(blocker: str, blocked: str, reason: str, block_level: str): time.time() ), ) - except BaseException as e: - print(f"ERROR: failed SQL query: blocker='{blocker}',blocked='{blocked}',reason='{reason}',block_level='{block_level}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: failed SQL query: blocker='{blocker}',blocked='{blocked}',reason='{reason}',block_level='{block_level}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print("DEBUG: EXIT!") diff --git a/fba/boot.py b/fba/boot.py index e66690b..fcdef23 100644 --- a/fba/boot.py +++ b/fba/boot.py @@ -123,13 +123,13 @@ def run_command(): # DEBUG: print(f"DEBUG: args[{type(args)}]={args}") status = args.command(args) # DEBUG: print("DEBUG: status={status} - EXIT!") - return status if type(status) == int else 0 + return status if isinstance(status, int) else 0 def shutdown(): print("DEBUG: Closing database connection ...") fba.connection.close() - if LOCK != None: + if LOCK is not None: print("DEBUG: Releasing lock ...") LOCK.close() print(f"DEBUG: Deleting lockfile='{lockfile}' ...") diff --git a/fba/cache.py b/fba/cache.py index 22c2b00..71ca822 100644 --- a/fba/cache.py +++ b/fba/cache.py @@ -24,7 +24,7 @@ def key_exists(key: str) -> bool: def set_all(key: str, rows: list, value: any): # DEBUG: print(f"DEBUG: key='{key}',rows()={len(rows)},value[]={type(value)} - CALLED!") - if type(key) != str: + if not isinstance(key, str): raise ValueError("Parameter key[]='{type(key)}' is not 'str'") elif not key_exists(key): # DEBUG: print(f"DEBUG: Cache for key='{key}' not initialized.") @@ -41,9 +41,9 @@ def set_all(key: str, rows: list, value: any): # DEBUG: print("DEBUG: EXIT!") def set_sub_key(key: str, sub: str, value: any): - if type(key) != str: + if not isinstance(key, str): raise ValueError("Parameter key[]='{type(key)}' is not 'str'") - elif type(sub) != str: + elif not isinstance(sub, str): raise ValueError("Parameter sub[]='{type(sub)}' is not 'str'") elif not key_exists(key): print(f"WARNING: Bad method call, key='{key}' is not initialized yet.") @@ -52,9 +52,9 @@ def set_sub_key(key: str, sub: str, value: any): _cache[key][sub] = value def sub_key_exists(key: str, sub: str) -> bool: - if type(key) != str: + if not isinstance(key, str): raise ValueError("Parameter key[]='{type(key)}' is not 'str'") - elif type(sub) != str: + elif not isinstance(sub, str): raise ValueError("Parameter sub[]='{type(sub)}' is not 'str'") elif not key_exists(key): print(f"WARNING: Bad method call, key='{key}' is not initialized yet.") diff --git a/fba/commands.py b/fba/commands.py index dedaf0a..65ddb03 100644 --- a/fba/commands.py +++ b/fba/commands.py @@ -74,7 +74,7 @@ def fetch_bkali(args: argparse.Namespace): for entry in fetched["data"]["nodeinfo"]: # DEBUG: print(f"DEBUG: entry['{type(entry)}']='{entry}'") if not "domain" in entry: - print(f"WARNING: entry does not contain 'domain' - SKIPPED!") + print(f"WARNING: entry()={len(entry)} does not contain 'domain' - SKIPPED!") continue elif not validators.domain(entry["domain"]): print(f"WARNING: domain='{entry['domain']}' is not a valid domain - SKIPPED!") @@ -89,8 +89,8 @@ def fetch_bkali(args: argparse.Namespace): # DEBUG: print(f"DEBUG: Adding domain='{entry['domain']}' ...") domains.append(entry["domain"]) - except BaseException as e: - print(f"ERROR: Cannot fetch graphql,exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: Cannot fetch graphql,exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print(f"DEBUG: domains()={len(domains)}") @@ -106,7 +106,7 @@ def fetch_bkali(args: argparse.Namespace): def fetch_blocks(args: argparse.Namespace): # DEBUG: print(f"DEBUG: args[]={type(args)} - CALLED!") - if args.domain != None and args.domain != "": + if args.domain is not None and args.domain != "": # DEBUG: print(f"DEBUG: args.domain='{args.domain}' - checking ...") if not validators.domain(args.domain): print(f"WARNING: domain='{args.domain}' is not valid.") @@ -120,7 +120,7 @@ def fetch_blocks(args: argparse.Namespace): boot.acquire_lock() - if args.domain != None and args.domain != "": + if args.domain is not None and args.domain != "": # Re-check single domain fba.cursor.execute( "SELECT domain, software, origin, nodeinfo_url FROM instances WHERE software IN ('pleroma', 'mastodon', 'friendica', 'misskey', 'bookwyrm', 'takahe') AND domain = ?", [args.domain] @@ -177,7 +177,7 @@ def fetch_blocks(args: argparse.Namespace): blocked, reason = block.values() # DEBUG: print(f"DEBUG: blocked='{blocked}',reason='{reason}' - BEFORE!") blocked = fba.tidyup_domain(blocked) - reason = fba.tidyup_reason(reason) if reason != None and reason != "" else None + reason = fba.tidyup_reason(reason) if reason is not None and reason != "" else None # DEBUG: print(f"DEBUG: blocked='{blocked}',reason='{reason}' - AFTER!") if blocked == "": @@ -194,7 +194,7 @@ def fetch_blocks(args: argparse.Namespace): searchres = fba.cursor.fetchone() - if searchres == None: + if searchres is None: print(f"WARNING: Cannot deobsfucate blocked='{blocked}' - SKIPPED!") continue @@ -209,7 +209,7 @@ def fetch_blocks(args: argparse.Namespace): searchres = fba.cursor.fetchone() - if searchres == None: + if searchres is None: print(f"WARNING: Cannot deobsfucate blocked='{blocked}' - SKIPPED!") continue @@ -243,8 +243,8 @@ def fetch_blocks(args: argparse.Namespace): # DEBUG: print("DEBUG: Committing changes ...") fba.connection.commit() - except Exception as e: - print(f"ERROR: blocker='{blocker}',software='{software}',exception[{type(e)}]:'{str(e)}'") + except Exception as exception: + print(f"ERROR: blocker='{blocker}',software='{software}',exception[{type(exception)}]:'{str(exception)}'") else: print("WARNING: Unknown software:", blocker, software) @@ -277,8 +277,8 @@ def fetch_cs(args: argparse.Namespace): # DEBUG: print(f"DEBUG: blocked[]={type(blocked)}") domains["reject"] = domains["reject"] + fba.find_domains(blocked) - except BaseException as e: - print(f"ERROR: Cannot fetch from meta.chaos.social,exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: Cannot fetch from meta.chaos.social,exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print(f"DEBUG: domains()={len(domains)}") @@ -335,8 +335,8 @@ def fetch_fba_rss(args: argparse.Namespace): # DEBUG: print(f"DEBUG: Adding domain='{domain}'") domains.append(domain) - except BaseException as e: - print(f"ERROR: Cannot fetch feed='{feed}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: Cannot fetch feed='{feed}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print(f"DEBUG: domains()={len(domains)}") @@ -388,8 +388,8 @@ def fetch_fbabot_atom(args: argparse.Namespace): # DEBUG: print(f"DEBUG: Adding domain='{domain}',domains()={len(domains)}") domains.append(domain) - except BaseException as e: - print(f"ERROR: Cannot fetch feed='{feed}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: Cannot fetch feed='{feed}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print(f"DEBUG: domains({len(domains)})={domains}") diff --git a/fba/config.py b/fba/config.py index b488ef2..f682106 100644 --- a/fba/config.py +++ b/fba/config.py @@ -21,7 +21,7 @@ with open("config.json") as f: def get(key: str) -> any: # DEBUG: print(f"DEBUG: key[{type(key)}]={key} - CALLED!") - if type(key) != str: + if not isinstance(key, str): raise ValueError(f"Parameter key[]='{type(key)}' is not 'str'") elif key == "": raise ValueError("Parameter 'key' is empty") diff --git a/fba/fba.py b/fba/fba.py index 122b2f6..49b1044 100644 --- a/fba/fba.py +++ b/fba/fba.py @@ -82,26 +82,26 @@ patterns = [ def is_primitive(var: any) -> bool: # DEBUG: print(f"DEBUG: var[]='{type(var)}' - CALLED!") - return type(var) in {int, str, float, bool} or var == None + return type(var) in {int, str, float, bool} or var is None def fetch_instances(domain: str, origin: str, software: str, script: str, path: str = None): # DEBUG: print(f"DEBUG: domain='{domain}',origin='{origin}',software='{software}',path='{path}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(origin) != str and origin != None: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(origin, str) and origin is not None: raise ValueError(f"Parameter origin[]={type(origin)} is not 'str'") - elif software == None: + elif software is None: print(f"DEBUG: software for domain='{domain}' is not set, determining ...") software = determine_software(domain, path) print(f"DEBUG: Determined software='{software}' for domain='{domain}'") - elif type(software) != str: + elif not isinstance(software, str): raise ValueError(f"Parameter software[]={type(software)} is not 'str'") - elif type(script) != str: + elif not isinstance(script, str): raise ValueError(f"Parameter script[]={type(script)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") if not instances.is_registered(domain): # DEBUG: print("DEBUG: Adding new domain:", domain, origin) @@ -119,7 +119,7 @@ def fetch_instances(domain: str, origin: str, software: str, script: str, path: print(f"INFO: Checking {len(peerlist)} instances from {domain} ...") for instance in peerlist: - if instance == None: + if instance is None: # Skip "None" types as tidup() cannot parse them continue @@ -142,8 +142,8 @@ def fetch_instances(domain: str, origin: str, software: str, script: str, path: if not instances.is_registered(instance): # DEBUG: print("DEBUG: Adding new instance:", instance, domain) instances.add(instance, domain, script) - except BaseException as e: - print(f"ERROR: instance='{instance}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: instance='{instance}',exception[{type(exception)}]:'{str(exception)}'") continue # DEBUG: print("DEBUG: EXIT!") @@ -153,7 +153,7 @@ def add_peers(rows: dict) -> list: peers = list() for key in ["linked", "allowed", "blocked"]: # DEBUG: print(f"DEBUG: Checking key='{key}'") - if key in rows and rows[key] != None: + if key in rows and rows[key] is not None: # DEBUG: print(f"DEBUG: Adding {len(rows[key])} peer(s) to peers list ...") for peer in rows[key]: # DEBUG: print(f"DEBUG: peer='{peer}' - BEFORE!") @@ -196,7 +196,6 @@ def remove_version(software: str) -> str: # DEBUG: print(f"DEBUG: Was not able to find common seperator, returning untouched software='{software}'") return software - matches = None match = None # DEBUG: print(f"DEBUG: Checking {len(patterns)} patterns ...") for pattern in patterns: @@ -204,11 +203,12 @@ def remove_version(software: str) -> str: match = pattern.match(version) # DEBUG: print(f"DEBUG: match[]={type(match)}") - if type(match) is re.Match: + if isinstance(match, re.Match): + # DEBUG: print(f"DEBUG: version='{version}' is matching pattern='{pattern}'") break # DEBUG: print(f"DEBUG: version[{type(version)}]='{version}',match='{match}'") - if type(match) is not re.Match: + if not isinstance(match, re.Match): print(f"WARNING: version='{version}' does not match regex, leaving software='{software}' untouched.") return software @@ -226,11 +226,12 @@ def remove_version(software: str) -> str: def strip_powered_by(software: str) -> str: # DEBUG: print(f"DEBUG: software='{software}' - CALLED!") - if software == "": - print(f"ERROR: Bad method call, 'software' is empty") - raise Exception("Parameter 'software' is empty") + if not isinstance(software, str): + raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'") + elif software == "": + raise ValueError("Parameter 'software' is empty") elif not "powered by" in software: - print(f"WARNING: Cannot find 'powered by' in '{software}'!") + print(f"WARNING: Cannot find 'powered by' in software='{software}'!") return software start = software.find("powered by ") @@ -246,9 +247,10 @@ def strip_powered_by(software: str) -> str: def strip_hosted_on(software: str) -> str: # DEBUG: print(f"DEBUG: software='{software}' - CALLED!") - if software == "": - print(f"ERROR: Bad method call, 'software' is empty") - raise Exception("Parameter 'software' is empty") + if not isinstance(software, str): + raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'") + elif software == "": + raise ValueError("Parameter 'software' is empty") elif not "hosted on" in software: print(f"WARNING: Cannot find 'hosted on' in '{software}'!") return software @@ -256,7 +258,7 @@ def strip_hosted_on(software: str) -> str: end = software.find("hosted on ") # DEBUG: print(f"DEBUG: end[{type(end)}]='{end}'") - software = software[0, start].strip() + software = software[0, end].strip() # DEBUG: print(f"DEBUG: software='{software}'") software = strip_until(software, " - ") @@ -266,12 +268,14 @@ def strip_hosted_on(software: str) -> str: def strip_until(software: str, until: str) -> str: # DEBUG: print(f"DEBUG: software='{software}',until='{until}' - CALLED!") - if software == "": - print(f"ERROR: Bad method call, 'software' is empty") - raise Exception("Parameter 'software' is empty") + if not isinstance(software, str): + raise ValueError(f"Parameter software[]='{type(software)}' is not 'str'") + elif software == "": + raise ValueError("Parameter 'software' is empty") + elif not isinstance(until, str): + raise ValueError(f"Parameter until[]='{type(until)}' is not 'str'") elif until == "": - print(f"ERROR: Bad method call, 'until' is empty") - raise Exception("Parameter 'until' is empty") + raise ValueError("Parameter 'until' is empty") elif not until in software: print(f"WARNING: Cannot find '{until}' in '{software}'!") return software @@ -287,10 +291,10 @@ def strip_until(software: str, until: str) -> str: return software def remove_pending_error(domain: str): - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") try: # Prevent updating any pending errors, nodeinfo was found @@ -302,19 +306,19 @@ def remove_pending_error(domain: str): # DEBUG: print("DEBUG: EXIT!") def get_hash(domain: str) -> str: - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") return hashlib.sha256(domain.encode("utf-8")).hexdigest() def log_error(domain: str, response: requests.models.Response): # DEBUG: print("DEBUG: domain,response[]:", domain, type(response)) - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") try: # DEBUG: print("DEBUG: BEFORE response[]:", type(response)) @@ -322,7 +326,7 @@ def log_error(domain: str, response: requests.models.Response): response = str(response) # DEBUG: print("DEBUG: AFTER response[]:", type(response)) - if type(response) is str: + if isinstance(response, str): cursor.execute("INSERT INTO error_log (domain, error_code, error_message, created) VALUES (?, 999, ?, ?)",[ domain, response, @@ -339,19 +343,19 @@ def log_error(domain: str, response: requests.models.Response): # Cleanup old entries # DEBUG: print(f"DEBUG: Purging old records (distance: {config.get('error_log_cleanup')})") cursor.execute("DELETE FROM error_log WHERE created < ?", [time.time() - config.get("error_log_cleanup")]) - except BaseException as e: - print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print("DEBUG: EXIT!") def fetch_peers(domain: str, software: str) -> list: # DEBUG: print(f"DEBUG: domain({len(domain)})={domain},software={software} - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(software) != str and software != None: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(software, str) and software is not None: raise ValueError(f"software[]={type(software)} is not 'str'") if software == "misskey": @@ -395,9 +399,9 @@ def fetch_peers(domain: str, software: str) -> list: # DEBUG: print("DEBUG: Querying API was successful:", domain, len(data)) peers = data - except BaseException as e: - print("WARNING: Some error during get():", domain, e) - instances.update_last_error(domain, e) + except BaseException as exception: + print("WARNING: Some error during get():", domain, exception) + instances.update_last_error(domain, exception) # DEBUG: print(f"DEBUG: Adding '{len(peers)}' for domain='{domain}'") instances.set("total_peers", domain, len(peers)) @@ -410,11 +414,11 @@ def fetch_peers(domain: str, software: str) -> list: def fetch_nodeinfo(domain: str, path: str = None) -> list: # DEBUG: print(f"DEBUG: domain='{domain}',path={path} - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(path) != str and path != None: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(path, str) and path is not None: raise ValueError(f"Parameter path[]={type(path)} is not 'str'") # DEBUG: print(f"DEBUG: Fetching nodeinfo from domain='{domain}' ...") @@ -436,7 +440,7 @@ def fetch_nodeinfo(domain: str, path: str = None) -> list: data = {} for request in request_paths: - if path != None and path != "" and path != f"https://{domain}{path}": + if path is not None and path != "" and path != f"https://{domain}{path}": # DEBUG: print(f"DEBUG: path='{path}' does not match request='{request}' - SKIPPED!") continue @@ -459,9 +463,9 @@ def fetch_nodeinfo(domain: str, path: str = None) -> list: instances.update_last_error(domain, response) continue - except BaseException as e: + except BaseException as exception: # DEBUG: print("DEBUG: Cannot fetch API request:", request) - instances.update_last_error(domain, e) + instances.update_last_error(domain, exception) pass # DEBUG: print(f"DEBUG: data()={len(data)} - EXIT!") @@ -469,10 +473,10 @@ def fetch_nodeinfo(domain: str, path: str = None) -> list: def fetch_wellknown_nodeinfo(domain: str) -> list: # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print("DEBUG: Fetching .well-known info for domain:", domain) data = {} @@ -505,9 +509,9 @@ def fetch_wellknown_nodeinfo(domain: str) -> list: else: print("WARNING: nodeinfo does not contain 'links':", domain) - except BaseException as e: + except BaseException as exception: print("WARNING: Failed fetching .well-known info:", domain) - instances.update_last_error(domain, e) + instances.update_last_error(domain, exception) pass # DEBUG: print("DEBUG: Returning data[]:", type(data)) @@ -515,14 +519,14 @@ def fetch_wellknown_nodeinfo(domain: str) -> list: def fetch_generator_from_path(domain: str, path: str = "/") -> str: # DEBUG: print(f"DEBUG: domain({len(domain)})={domain},path={path} - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(path) != str: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(path, str): raise ValueError(f"path[]={type(path)} is not 'str'") elif path == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'path' is empty") # DEBUG: print(f"DEBUG: domain='{domain}',path='{path}' - CALLED!") software = None @@ -554,30 +558,30 @@ def fetch_generator_from_path(domain: str, path: str = "/") -> str: instances.set("detection_mode", domain, "SITE_NAME") remove_pending_error(domain) - except BaseException as e: - # DEBUG: print(f"DEBUG: Cannot fetch / from '{domain}':", e) - instances.update_last_error(domain, e) + except BaseException as exception: + # DEBUG: print(f"DEBUG: Cannot fetch / from '{domain}':", exception) + instances.update_last_error(domain, exception) pass # DEBUG: print(f"DEBUG: software[]={type(software)}") - if type(software) is str and software == "": + if isinstance(software, str) and software == "": # DEBUG: print(f"DEBUG: Corrected empty string to None for software of domain='{domain}'") software = None - elif type(software) is str and ("." in software or " " in software): + elif isinstance(software, str) and ("." in software or " " in software): # DEBUG: print(f"DEBUG: software='{software}' may contain a version number, domain='{domain}', removing it ...") software = remove_version(software) # DEBUG: print(f"DEBUG: software[]={type(software)}") - if type(software) is str and " powered by " in software: + if isinstance(software, str) and " powered by " in software: # DEBUG: print(f"DEBUG: software='{software}' has 'powered by' in it") software = remove_version(strip_powered_by(software)) - elif type(software) is str and " hosted on " in software: + elif isinstance(software, str) and " hosted on " in software: # DEBUG: print(f"DEBUG: software='{software}' has 'hosted on' in it") software = remove_version(strip_hosted_on(software)) - elif type(software) is str and " by " in software: + elif isinstance(software, str) and " by " in software: # DEBUG: print(f"DEBUG: software='{software}' has ' by ' in it") software = strip_until(software, " by ") - elif type(software) is str and " see " in software: + elif isinstance(software, str) and " see " in software: # DEBUG: print(f"DEBUG: software='{software}' has ' see ' in it") software = strip_until(software, " see ") @@ -586,11 +590,11 @@ def fetch_generator_from_path(domain: str, path: str = "/") -> str: def determine_software(domain: str, path: str = None) -> str: # DEBUG: print(f"DEBUG: domain({len(domain)})={domain},path={path} - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(path) != str and path != None: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(path, str) and path is not None: raise ValueError(f"Parameter path[]={type(path)} is not 'str'") # DEBUG: print("DEBUG: Determining software for domain,path:", domain, path) @@ -641,10 +645,10 @@ def determine_software(domain: str, path: str = None) -> str: elif "powered by" in software: # DEBUG: print(f"DEBUG: software='{software}' has 'powered by' in it") software = strip_powered_by(software) - elif type(software) is str and " by " in software: + elif isinstance(software, str) and " by " in software: # DEBUG: print(f"DEBUG: software='{software}' has ' by ' in it") software = strip_until(software, " by ") - elif type(software) is str and " see " in software: + elif isinstance(software, str) and " see " in software: # DEBUG: print(f"DEBUG: software='{software}' has ' see ' in it") software = strip_until(software, " see ") @@ -662,7 +666,7 @@ def determine_software(domain: str, path: str = None) -> str: software = remove_version(software) # DEBUG: print(f"DEBUG: software[]={type(software)}") - if type(software) is str and "powered by" in software: + if isinstance(software, str) and "powered by" in software: # DEBUG: print(f"DEBUG: software='{software}' has 'powered by' in it") software = remove_version(strip_powered_by(software)) @@ -671,7 +675,7 @@ def determine_software(domain: str, path: str = None) -> str: def tidyup_reason(reason: str) -> str: # DEBUG: print(f"DEBUG: reason='{reason}' - CALLED!") - if type(reason) != str: + if not isinstance(reason, str): raise ValueError(f"Parameter reason[]={type(reason)} is not 'str'") # Strip string @@ -685,7 +689,7 @@ def tidyup_reason(reason: str) -> str: def tidyup_domain(domain: str) -> str: # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") # All lower-case and strip spaces out + last dot @@ -729,24 +733,24 @@ def json_from_response(response: requests.models.Response) -> list: # DEBUG: print(f"DEBUG: data[]={type(data)} - EXIT!") return data -def has_key(keys: list, search: str, value: any) -> bool: - # DEBUG: print(f"DEBUG: keys()={len(keys)},search='{search}',value[]='{type(value)}' - CALLED!") - if type(keys) != list: - raise ValueError(f"Parameter keys[]='{type(keys)}' is not 'list'") - elif type(search) != str: - raise ValueError(f"Parameter search[]='{type(search)}' is not 'str'") - elif search == "": - raise ValueError("Parameter 'search' is empty") +def has_key(lists: list, key: str, value: any) -> bool: + # DEBUG: print(f"DEBUG: lists()={len(lists)},key='{key}',value[]='{type(value)}' - CALLED!") + if not isinstance(lists, list): + raise ValueError(f"Parameter lists[]='{type(lists)}' is not 'list'") + elif not isinstance(key, str): + raise ValueError(f"Parameter key[]='{type(key)}' is not 'str'") + elif key == "": + raise ValueError("Parameter 'key' is empty") has = False - # DEBUG: print(f"DEBUG: Checking keys()={len(keys)} ...") - for key in keys: - # DEBUG: print(f"DEBUG: key['{type(key)}']={key}") - if type(key) != dict: - raise ValueError(f"key[]='{type(key)}' is not 'dict'") - elif not search in key: - raise KeyError(f"Cannot find search='{search}'") - elif key[search] == value: + # DEBUG: print(f"DEBUG: Checking lists()={len(lists)} ...") + for row in lists: + # DEBUG: print(f"DEBUG: row['{type(row)}']={row}") + if not isinstance(row, dict): + raise ValueError(f"row[]='{type(row)}' is not 'dict'") + elif not key in row: + raise KeyError(f"Cannot find key='{key}'") + elif row[key] == value: has = True break @@ -807,10 +811,14 @@ def find_domains(tag: bs4.element.Tag) -> list: def fetch_url(url: str, headers: dict, timeout: list) -> requests.models.Response: # DEBUG: print(f"DEBUG: url='{url}',headers()={len(headers)},timeout={timeout} - CALLED!") - if type(url) != str: + if not isinstance(url, str): raise ValueError(f"Parameter url[]='{type(url)}' is not 'str'") elif url == "": raise ValueError("Parameter 'url' is empty") + elif not isinstance(headers, dict): + raise ValueError(f"Parameter headers[]='{type(headers)}' is not 'dict'") + elif not isinstance(timeout, list): + raise ValueError(f"Parameter timeout[]='{type(timeout)}' is not 'list'") # DEBUG: print(f"DEBUG: Parsing url='{url}'") components = urlparse(url) diff --git a/fba/federation/lemmy.py b/fba/federation/lemmy.py index cc6d132..7e3c513 100644 --- a/fba/federation/lemmy.py +++ b/fba/federation/lemmy.py @@ -21,10 +21,10 @@ from fba import network def fetch_peers(domain: str) -> list: # DEBUG: print(f"DEBUG: domain({len(domain)})={domain},software='lemmy' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") peers = list() try: @@ -47,8 +47,8 @@ def fetch_peers(domain: str) -> list: print("WARNING: JSON response does not contain 'federated_instances':", domain) instances.update_last_error(domain, response) - except BaseException as e: - print(f"WARNING: Exception during fetching JSON: domain='{domain}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"WARNING: Exception during fetching JSON: domain='{domain}',exception[{type(exception)}]:'{str(exception)}'") # DEBUG: print(f"DEBUG: Adding '{len(peers)}' for domain='{domain}'") instances.set("total_peers", domain, len(peers)) diff --git a/fba/federation/mastodon.py b/fba/federation/mastodon.py index d00fa7c..abbe8b8 100644 --- a/fba/federation/mastodon.py +++ b/fba/federation/mastodon.py @@ -53,10 +53,10 @@ language_mapping = { def fetch_blocks_from_about(domain: str) -> dict: # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print("DEBUG: Fetching mastodon blocks from domain:", domain) blocklist = { @@ -71,9 +71,9 @@ def fetch_blocks_from_about(domain: str) -> dict: network.fetch_response(domain, "/about/more", fba.headers, (config.get("connection_timeout"), config.get("read_timeout"))).text, "html.parser", ) - except BaseException as e: - print("ERROR: Cannot fetch from domain:", domain, e) - instances.update_last_error(domain, e) + except BaseException as exception: + print("ERROR: Cannot fetch from domain:", domain, exception) + instances.update_last_error(domain, exception) return {} for header in doc.find_all("h3"): @@ -108,18 +108,18 @@ def fetch_blocks_from_about(domain: str) -> dict: def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): # DEBUG: print(f"DEBUG: domain='{domain}',origin='{origin}',nodeinfo_url='{nodeinfo_url}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(origin) != str and origin != None: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(origin, str) and origin is not None: raise ValueError(f"Parameter origin[]={type(origin)} is not 'str'") elif origin == "": - raise ValueError(f"Parameter 'origin' is empty") - elif type(nodeinfo_url) != str: + raise ValueError("Parameter 'origin' is empty") + elif not isinstance(nodeinfo_url, str): raise ValueError(f"Parameter nodeinfo_url[]={type(nodeinfo_url)} is not 'str'") elif nodeinfo_url == "": - raise ValueError(f"Parameter 'nodeinfo_url' is empty") + raise ValueError("Parameter 'nodeinfo_url' is empty") try: # json endpoint for newer mastodongs @@ -142,8 +142,8 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): csrf = meta.find("meta", attrs={"name": "csrf-token"})["content"] # DEBUG: print("DEBUG: Adding CSRF token:", domain, csrf) reqheaders = {**fba.api_headers, **{"X-CSRF-Token": csrf}} - except BaseException as e: - # DEBUG: print("DEBUG: No CSRF token found, using normal headers:", domain, e) + except BaseException as exception: + # DEBUG: print("DEBUG: No CSRF token found, using normal headers:", domain, exception) reqheaders = fba.api_headers # DEBUG: print("DEBUG: Querying API domain_blocks:", domain) @@ -173,8 +173,8 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): else: print("WARNING: Unknown severity:", block['severity'], block['domain']) - except BaseException as e: - # DEBUG: print(f"DEBUG: Failed, trying mastodon-specific fetches: domain='{domain}',exception[{type(e)}]={str(e)}") + except BaseException as exception: + # DEBUG: print(f"DEBUG: Failed, trying mastodon-specific fetches: domain='{domain}',exception[{type(exception)}]={str(exception)}") json = fetch_blocks_from_about(domain) print(f"INFO: Checking {len(json.items())} entries from domain='{domain}',software='mastodon' ...") @@ -193,7 +193,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): blocked, blocked_hash, reason = block.values() # DEBUG: print(f"DEBUG: blocked='{blocked}',blocked_hash='{blocked_hash}',reason='{reason}':") blocked = fba.tidyup_domain(blocked) - reason = fba.tidyup_reason(reason) if reason != None and reason != "" else None + reason = fba.tidyup_reason(reason) if reason is not None and reason != "" else None # DEBUG: print(f"DEBUG: blocked='{blocked}',reason='{reason}' - AFTER!") if blocked == "": @@ -209,7 +209,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): ) searchres = fba.cursor.fetchone() - if searchres == None: + if searchres is None: print(f"WARNING: Cannot deobsfucate blocked='{blocked}',blocked_hash='{blocked_hash}' - SKIPPED!") continue @@ -256,7 +256,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): # DEBUG: print("DEBUG: Committing changes ...") fba.connection.commit() - except Exception as e: - print(f"ERROR: domain='{domain}',software='mastodon',exception[{type(e)}]:'{str(e)}'") + except Exception as exception: + print(f"ERROR: domain='{domain}',software='mastodon',exception[{type(exception)}]:'{str(exception)}'") # DEBUG: print("DEBUG: EXIT!") diff --git a/fba/federation/misskey.py b/fba/federation/misskey.py index cb75a96..0a6ee12 100644 --- a/fba/federation/misskey.py +++ b/fba/federation/misskey.py @@ -24,10 +24,10 @@ from fba import network def fetch_peers(domain: str) -> list: # DEBUG: print(f"DEBUG: domain({len(domain)})={domain} - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print(f"DEBUG: domain='{domain}' is misskey, sending API POST request ...") peers = list() @@ -81,7 +81,7 @@ def fetch_peers(domain: str) -> list: if not "host" in row: print(f"WARNING: row()={len(row)} does not contain key 'host': {row},domain='{domain}'") continue - elif type(row["host"]) != str: + elif not isinstance(row["host"], str): print(f"WARNING: row[host][]={type(row['host'])} is not 'str'") continue elif blacklist.is_blacklisted(row["host"]): @@ -110,10 +110,10 @@ def fetch_peers(domain: str) -> list: def fetch_blocks(domain: str) -> dict: # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print("DEBUG: Fetching misskey blocks from domain:", domain) blocklist = { @@ -180,9 +180,9 @@ def fetch_blocks(domain: str) -> dict: # DEBUG: print(f"DEBUG: API is no more returning new instances, aborting loop!") break - except BaseException as e: - print("WARNING: Caught error, exiting loop:", domain, e) - instances.update_last_error(domain, e) + except BaseException as exception: + print("WARNING: Caught error, exiting loop:", domain, exception) + instances.update_last_error(domain, exception) offset = 0 break @@ -237,9 +237,9 @@ def fetch_blocks(domain: str) -> dict: # DEBUG: print(f"DEBUG: API is no more returning new instances, aborting loop!") break - except BaseException as e: - print("ERROR: Exception during POST:", domain, e) - instances.update_last_error(domain, e) + except BaseException as exception: + print("ERROR: Exception during POST:", domain, exception) + instances.update_last_error(domain, exception) offset = 0 break diff --git a/fba/federation/peertube.py b/fba/federation/peertube.py index 13adea4..4c9c782 100644 --- a/fba/federation/peertube.py +++ b/fba/federation/peertube.py @@ -21,10 +21,10 @@ from fba import network def fetch_peers(domain: str) -> list: # DEBUG: print(f"DEBUG: domain({len(domain)})={domain},software='peertube' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print(f"DEBUG: domain='{domain}' is a PeerTube, fetching JSON ...") peers = list() @@ -56,8 +56,8 @@ def fetch_peers(domain: str) -> list: # Continue with next row start = start + 100 - except BaseException as e: - print(f"WARNING: Exception during fetching JSON: domain='{domain}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"WARNING: Exception during fetching JSON: domain='{domain}',exception[{type(exception)}]:'{str(exception)}'") # DEBUG: print(f"DEBUG: Adding '{len(peers)}' for domain='{domain}'") instances.set("total_peers", domain, len(peers)) diff --git a/fba/federation/pleroma.py b/fba/federation/pleroma.py index 06b7a4d..4c5d726 100644 --- a/fba/federation/pleroma.py +++ b/fba/federation/pleroma.py @@ -24,18 +24,18 @@ from fba import instances def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): # DEBUG: print(f"DEBUG: domain='{domain}',origin='{origin}',nodeinfo_url='{nodeinfo_url}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(origin) != str and origin != None: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(origin, str) and origin is not None: raise ValueError(f"Parameter origin[]={type(origin)} is not 'str'") elif origin == "": - raise ValueError(f"Parameter 'origin' is empty") - elif type(nodeinfo_url) != str: + raise ValueError("Parameter 'origin' is empty") + elif not isinstance(nodeinfo_url, str): raise ValueError(f"Parameter nodeinfo_url[]={type(nodeinfo_url)} is not 'str'") elif nodeinfo_url == "": - raise ValueError(f"Parameter 'nodeinfo_url' is empty") + raise ValueError("Parameter 'nodeinfo_url' is empty") try: # Blocks @@ -94,7 +94,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): searchres = fba.cursor.fetchone() # DEBUG: print("DEBUG: searchres[]:", type(searchres)) - if searchres == None: + if searchres is None: print(f"WARNING: Cannot deobsfucate blocked='{blocked}' - SKIPPED!") continue @@ -152,7 +152,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): for blocked, reason in info.items(): # DEBUG: print(f"DEBUG: blocked='{blocked}',reason='{reason}' - BEFORE!") blocked = fba.tidyup_domain(blocked) - reason = fba.tidyup_reason(reason) if reason != None and reason != "" else None + reason = fba.tidyup_reason(reason) if reason is not None and reason != "" else None # DEBUG: print(f"DEBUG: blocked='{blocked}',reason='{reason}' - AFTER!") if blocked == "": @@ -171,7 +171,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): ) searchres = fba.cursor.fetchone() - if searchres == None: + if searchres is None: print(f"WARNING: Cannot deobsfucate blocked='{blocked}' - SKIPPED!") continue @@ -194,7 +194,7 @@ def fetch_blocks(domain: str, origin: str, nodeinfo_url: str): entry["reason"] = reason["reason"] fba.connection.commit() - except Exception as e: - print(f"ERROR: domain='{domain}',software='pleroma',exception[{type(e)}]:'{str(e)}'") + except Exception as exception: + print(f"ERROR: domain='{domain}',software='pleroma',exception[{type(exception)}]:'{str(exception)}'") # DEBUG: print("DEBUG: EXIT!") diff --git a/fba/instances.py b/fba/instances.py index 76a1a80..e002fb3 100644 --- a/fba/instances.py +++ b/fba/instances.py @@ -51,14 +51,14 @@ _pending = { def set(key: str, domain: str, value: any): # DEBUG: print(f"DEBUG: key='{key}',domain='{domain}',value[]='{type(value)}' - CALLED!") - if type(key) != str: + if not isinstance(key, str): raise ValueError("Parameter key[]='{type(key)}' is not 'str'") elif key == "": - raise ValueError(f"Parameter 'key' cannot be empty") - elif type(domain) != str: - raise ValueError("Parameter domain[]='{type(domain)}' is not 'str'") + raise ValueError("Parameter 'key' is empty") + elif not isinstance(domain, str): + raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' cannot be empty") + raise ValueError("Parameter 'domain' is empty") elif not key in _pending: raise ValueError(f"key='{key}' not found in _pending") elif not fba.is_primitive(value): @@ -71,10 +71,10 @@ def set(key: str, domain: str, value: any): def has_pending_instance_data(domain: str) -> bool: # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") has_pending = False for key in _pending: @@ -88,10 +88,10 @@ def has_pending_instance_data(domain: str) -> bool: def update_data(domain: str): # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") elif not has_pending_instance_data(domain): raise Exception(f"Domain '{domain}' has no pending instance data, but function invoked") @@ -135,18 +135,18 @@ def update_data(domain: str): except: pass - except BaseException as e: - print(f"ERROR: failed SQL query: domain='{domain}',sql_string='{sql_string}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: failed SQL query: domain='{domain}',sql_string='{sql_string}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # DEBUG: print("DEBUG: EXIT!") def update_last_instance_fetch(domain: str): # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print("DEBUG: Updating last_instance_fetch for domain:", domain) set("last_instance_fetch", domain, time.time()) @@ -158,10 +158,10 @@ def update_last_instance_fetch(domain: str): # DEBUG: print("DEBUG: EXIT!") def update_last_blocked(domain: str): - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print("DEBUG: Updating last_blocked for domain", domain) set("last_blocked", domain, time.time()) @@ -174,16 +174,18 @@ def update_last_blocked(domain: str): def add(domain: str, origin: str, originator: str, path: str = None): # DEBUG: print(f"DEBUG: domain='{domain}',origin='{origin}',originator='{originator}',path='{path}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(origin) != str and origin != None: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(origin, str) and origin is not None: raise ValueError(f"origin[]={type(origin)} is not 'str'") - elif type(originator) != str: + elif origin == "": + raise ValueError("Parameter 'origin' is empty") + elif not isinstance(originator, str): raise ValueError(f"originator[]={type(originator)} is not 'str'") elif originator == "": - raise ValueError(f"originator cannot be empty") + raise ValueError("Parameter 'originator' is empty") elif not validators.domain(domain.split("/")[0]): raise ValueError(f"Bad domain name='{domain}'") elif origin is not None and not validators.domain(origin.split("/")[0]): @@ -230,8 +232,8 @@ def add(domain: str, origin: str, originator: str, path: str = None): update_last_error(domain, fba.pending_errors[domain]) fba.remove_pending_error(domain) - except BaseException as e: - print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) else: # DEBUG: print("DEBUG: Updating nodeinfo for domain:", domain) @@ -241,10 +243,10 @@ def add(domain: str, origin: str, originator: str, path: str = None): def update_last_nodeinfo(domain: str): # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print("DEBUG: Updating last_nodeinfo for domain:", domain) set("last_nodeinfo", domain, time.time()) @@ -258,17 +260,17 @@ def update_last_nodeinfo(domain: str): def update_last_error(domain: str, response: requests.models.Response): # DEBUG: print("DEBUG: domain,response[]:", domain, type(response)) - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print("DEBUG: BEFORE response[]:", type(response)) if isinstance(response, BaseException) or isinstance(response, json.decoder.JSONDecodeError): response = f"{type}:str(response)" # DEBUG: print("DEBUG: AFTER response[]:", type(response)) - if type(response) is str: + if isinstance(response, str): # DEBUG: print(f"DEBUG: Setting last_error_details='{response}'"); set("last_status_code" , domain, 999) set("last_error_details", domain, response) @@ -287,10 +289,10 @@ def update_last_error(domain: str, response: requests.models.Response): def is_registered(domain: str) -> bool: # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") if not cache.key_exists("is_registered"): @@ -300,8 +302,8 @@ def is_registered(domain: str) -> bool: # Check Set all cache.set_all("is_registered", fba.cursor.fetchall(), True) - except BaseException as e: - print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"ERROR: failed SQL query: domain='{domain}',exception[{type(exception)}]:'{str(exception)}'") sys.exit(255) # Is cache found? diff --git a/fba/network.py b/fba/network.py index a60e0e8..8d64144 100644 --- a/fba/network.py +++ b/fba/network.py @@ -23,15 +23,15 @@ from fba import instances def post_json_api(domain: str, path: str, parameter: str, extra_headers: dict = {}) -> dict: # DEBUG: print(f"DEBUG: domain='{domain}',path='{path}',parameter='{parameter}',extra_headers()={len(extra_headers)} - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") - elif type(path) != str: + raise ValueError("Parameter 'domain' is empty") + elif not isinstance(path, str): raise ValueError(f"path[]={type(path)} is not 'str'") elif path == "": raise ValueError("Parameter 'path' cannot be empty") - elif type(parameter) != str: + elif not isinstance(parameter, str): raise ValueError(f"parameter[]={type(parameter)} is not 'str'") # DEBUG: print("DEBUG: Sending POST to domain,path,parameter:", domain, path, parameter, extra_headers) @@ -50,22 +50,22 @@ def post_json_api(domain: str, path: str, parameter: str, extra_headers: dict = print(f"WARNING: Cannot query JSON API: domain='{domain}',path='{path}',parameter()={len(parameter)},response.status_code='{response.status_code}',data[]='{type(data)}'") instances.update_last_error(domain, response) - except BaseException as e: - print(f"WARNING: Some error during post(): domain='{domain}',path='{path}',parameter()={len(parameter)},exception[{type(e)}]:'{str(e)}'") + except BaseException as exception: + print(f"WARNING: Some error during post(): domain='{domain}',path='{path}',parameter()={len(parameter)},exception[{type(exception)}]:'{str(exception)}'") # DEBUG: print(f"DEBUG: Returning data({len(data)})=[]:{type(data)}") return data def send_bot_post(instance: str, blocklist: dict): # DEBUG: print(f"DEBUG: instance={instance},blocklist()={len(blocklist)} - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") elif domain == "": raise ValueError("Parameter 'domain' is empty") - elif type(blocklist) != dict: + elif not isinstance(blocklist, dict): raise ValueError(f"Parameter blocklist[]='{type(blocklist)}' is not 'dict'") - message = instance + " has blocked the following instances:\n\n" + message = f"{instance} has blocked the following instances:\n\n" truncated = False if len(blocklist) > 20: @@ -75,7 +75,7 @@ def send_bot_post(instance: str, blocklist: dict): # DEBUG: print(f"DEBUG: blocklist()={len(blocklist)}") for block in blocklist: # DEBUG: print(f"DEBUG: block['{type(block)}']={block}") - if block["reason"] == None or block["reason"] == '': + if block["reason"] is None or block["reason"] == '': message = message + block["blocked"] + " with unspecified reason\n" else: if len(block["reason"]) > 420: @@ -103,10 +103,10 @@ def send_bot_post(instance: str, blocklist: dict): def fetch_friendica_blocks(domain: str) -> dict: # DEBUG: print(f"DEBUG: domain='{domain}' - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]={type(domain)} is not 'str'") elif domain == "": - raise ValueError(f"Parameter 'domain' is empty") + raise ValueError("Parameter 'domain' is empty") # DEBUG: print("DEBUG: Fetching friendica blocks from domain:", domain) blocked = list() @@ -116,9 +116,9 @@ def fetch_friendica_blocks(domain: str) -> dict: fetch_response(domain, "/friendica", headers, (config.get("connection_timeout"), config.get("read_timeout"))).text, "html.parser", ) - except BaseException as e: - print("WARNING: Failed to fetch /friendica from domain:", domain, e) - instances.update_last_error(domain, e) + except BaseException as exception: + print("WARNING: Failed to fetch /friendica from domain:", domain, exception) + instances.update_last_error(domain, exception) return {} blocklist = doc.find(id="about_blocklist") @@ -152,11 +152,11 @@ def fetch_friendica_blocks(domain: str) -> dict: def fetch_response(domain: str, path: str, headers: dict, timeout: list) -> requests.models.Response: # DEBUG: print(f"DEBUG: domain='{domain}',path='{path}',headers()={len(headers)},timeout={timeout} - CALLED!") - if type(domain) != str: + if not isinstance(domain, str): raise ValueError(f"Parameter domain[]='{type(domain)}' is not 'str'") elif domain == "": raise ValueError("Parameter 'domain' is empty") - elif type(path) != str: + elif not isinstance(path, str): raise ValueError(f"Parameter path[]='{type(path)}' is not 'str'") elif path == "": raise ValueError("Parameter 'path' is empty") @@ -168,10 +168,10 @@ def fetch_response(domain: str, path: str, headers: dict, timeout: list) -> requ headers=headers, timeout=timeout ); - except requests.exceptions.ConnectionError as e: - # DEBUG: print(f"DEBUG: Fetching '{path}' from '{domain}' failed. exception[{type(e)}]='{str(e)}'") - instances.update_last_error(domain, e) - raise e + except requests.exceptions.ConnectionError as exception: + # DEBUG: print(f"DEBUG: Fetching '{path}' from '{domain}' failed. exception[{type(exception)}]='{str(exception)}'") + instances.update_last_error(domain, exception) + raise exception # DEBUG: print(f"DEBUG: response[]='{type(response)}' - EXXIT!") return response diff --git a/pylint.rc b/pylint.rc new file mode 100644 index 0000000..9b2f850 --- /dev/null +++ b/pylint.rc @@ -0,0 +1,513 @@ +[MASTER] + +# A comma-separated list of package or module names from where C extensions may +# be loaded. Extensions are loading into the active Python interpreter and may +# run arbitrary code. +extension-pkg-whitelist= + +# Specify a score threshold to be exceeded before program exits with error. +fail-under=10.0 + +# Add files or directories to the blacklist. They should be base names, not +# paths. +ignore=CVS + +# Add files or directories matching the regex patterns to the blacklist. The +# regex matches against base names, not paths. +ignore-patterns= + +# Python code to execute, usually for sys.path manipulation such as +# pygtk.require(). +#init-hook= + +# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the +# number of processors available to use. +jobs=1 + +# Control the amount of potential inferred values when inferring a single +# object. This can help the performance when dealing with large functions or +# complex, nested conditions. +limit-inference-results=100 + +# List of plugins (as comma separated values of python module names) to load, +# usually to register additional checkers. +load-plugins= + +# Pickle collected data for later comparisons. +persistent=yes + +# When enabled, pylint would attempt to guess common misconfiguration and emit +# user-friendly hints instead of false-positive error messages. +suggestion-mode=yes + +# Allow loading of arbitrary C extensions. Extensions are imported into the +# active Python interpreter and may run arbitrary code. +unsafe-load-any-extension=no + + +[MESSAGES CONTROL] + +# Only show warnings with the listed confidence levels. Leave empty to show +# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. +confidence= + +# Disable the message, report, category or checker with the given id(s). You +# can either give multiple identifiers separated by comma (,) or put this +# option multiple times (only on the command line, not in the configuration +# file where it should appear only once). You can also use "--disable=all" to +# disable everything first and then reenable specific checks. For example, if +# you want to run only the similarities checker, you can use "--disable=all +# --enable=similarities". If you want to run only the classes checker, but have +# no Warning level messages displayed, use "--disable=all --enable=classes +# --disable=W". +disable=anomalous-backslash-in-string + +# Enable the message, report, category or checker with the given id(s). You can +# either give multiple identifier separated by comma (,) or put this option +# multiple time (only on the command line, not in the configuration file where +# it should appear only once). See also the "--disable" option for examples. +enable=c-extension-no-member + + +[REPORTS] + +# Python expression which should return a score less than or equal to 10. You +# have access to the variables 'error', 'warning', 'refactor', and 'convention' +# which contain the number of messages in each category, as well as 'statement' +# which is the total number of statements analyzed. This score is used by the +# global evaluation report (RP0004). +evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) + +# Template used to display messages. This is a python new-style format string +# used to format the message information. See doc for all details. +#msg-template= + +# Set the output format. Available formats are text, parseable, colorized, json +# and msvs (visual studio). You can also give a reporter class, e.g. +# mypackage.mymodule.MyReporterClass. +output-format=text + +# Tells whether to display a full report or only the messages. +reports=yes + +# Activate the evaluation score. +score=yes + + +[REFACTORING] + +# Maximum number of nested blocks for function / method body +max-nested-blocks=5 + +# Complete name of functions that never returns. When checking for +# inconsistent-return-statements if a never returning function is called then +# it will be considered as an explicit return statement and no message will be +# printed. +never-returning-functions=sys.exit + + +[FORMAT] + +# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. +expected-line-ending-format= + +# Regexp for a line that is allowed to be longer than the limit. +ignore-long-lines=^\s*(# )??$ + +# Number of spaces of indent required inside a hanging or continued line. +indent-after-paren=4 + +# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 +# tab). +indent-string=' ' + +# Maximum number of characters on a single line. +max-line-length=100 + +# Maximum number of lines in a module. +max-module-lines=1000 + +# Allow the body of a class to be on the same line as the declaration if body +# contains single statement. +single-line-class-stmt=no + +# Allow the body of an if to be on the same line as the test if there is no +# else. +single-line-if-stmt=no + + +[BASIC] + +# Naming style matching correct argument names. +argument-naming-style=snake_case + +# Regular expression matching correct argument names. Overrides argument- +# naming-style. +#argument-rgx= + +# Naming style matching correct attribute names. +attr-naming-style=snake_case + +# Regular expression matching correct attribute names. Overrides attr-naming- +# style. +#attr-rgx= + +# Bad variable names which should always be refused, separated by a comma. +bad-names=foo, + bar, + baz, + toto, + tutu, + tata + +# Bad variable names regexes, separated by a comma. If names match any regex, +# they will always be refused +bad-names-rgxs= + +# Naming style matching correct class attribute names. +class-attribute-naming-style=any + +# Regular expression matching correct class attribute names. Overrides class- +# attribute-naming-style. +#class-attribute-rgx= + +# Naming style matching correct class names. +class-naming-style=PascalCase + +# Regular expression matching correct class names. Overrides class-naming- +# style. +#class-rgx= + +# Naming style matching correct constant names. +const-naming-style=UPPER_CASE + +# Regular expression matching correct constant names. Overrides const-naming- +# style. +#const-rgx= + +# Minimum line length for functions/classes that require docstrings, shorter +# ones are exempt. +docstring-min-length=-1 + +# Naming style matching correct function names. +function-naming-style=snake_case + +# Regular expression matching correct function names. Overrides function- +# naming-style. +#function-rgx= + +# Good variable names which should always be accepted, separated by a comma. +good-names=i, + j, + k, + ex, + Run, + _ + +# Good variable names regexes, separated by a comma. If names match any regex, +# they will always be accepted +good-names-rgxs= + +# Include a hint for the correct naming format with invalid-name. +include-naming-hint=no + +# Naming style matching correct inline iteration names. +inlinevar-naming-style=any + +# Regular expression matching correct inline iteration names. Overrides +# inlinevar-naming-style. +#inlinevar-rgx= + +# Naming style matching correct method names. +method-naming-style=snake_case + +# Regular expression matching correct method names. Overrides method-naming- +# style. +#method-rgx= + +# Naming style matching correct module names. +module-naming-style=snake_case + +# Regular expression matching correct module names. Overrides module-naming- +# style. +#module-rgx= + +# Colon-delimited sets of names that determine each other's naming style when +# the name regexes allow several styles. +name-group= + +# Regular expression which should only match function or class names that do +# not require a docstring. +no-docstring-rgx=^_ + +# List of decorators that produce properties, such as abc.abstractproperty. Add +# to this list to register other decorators that produce valid properties. +# These decorators are taken in consideration only for invalid-name. +property-classes=abc.abstractproperty + +# Naming style matching correct variable names. +variable-naming-style=snake_case + +# Regular expression matching correct variable names. Overrides variable- +# naming-style. +#variable-rgx= + + +[SIMILARITIES] + +# Ignore comments when computing similarities. +ignore-comments=yes + +# Ignore docstrings when computing similarities. +ignore-docstrings=yes + +# Ignore imports when computing similarities. +ignore-imports=no + +# Minimum lines number of a similarity. +min-similarity-lines=4 + + +[MISCELLANEOUS] + +# List of note tags to take in consideration, separated by a comma. +notes=FIXME, + XXX, + TODO + +# Regular expression of note tags to take in consideration. +#notes-rgx= + + +[SPELLING] + +# Limits count of emitted suggestions for spelling mistakes. +max-spelling-suggestions=4 + +# Spelling dictionary name. Available dictionaries: none. To make it work, +# install the python-enchant package. +spelling-dict= + +# List of comma separated words that should not be checked. +spelling-ignore-words= + +# A path to a file that contains the private dictionary; one word per line. +spelling-private-dict-file= + +# Tells whether to store unknown words to the private dictionary (see the +# --spelling-private-dict-file option) instead of raising a message. +spelling-store-unknown-words=no + + +[VARIABLES] + +# List of additional names supposed to be defined in builtins. Remember that +# you should avoid defining new builtins when possible. +additional-builtins= + +# Tells whether unused global variables should be treated as a violation. +allow-global-unused-variables=yes + +# List of strings which can identify a callback function by name. A callback +# name must start or end with one of those strings. +callbacks=cb_, + _cb + +# A regular expression matching the name of dummy variables (i.e. expected to +# not be used). +dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ + +# Argument names that match this expression will be ignored. Default to name +# with leading underscore. +ignored-argument-names=_.*|^ignored_|^unused_ + +# Tells whether we should check for unused import in __init__ files. +init-import=no + +# List of qualified module names which can have objects that can redefine +# builtins. +redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io + + +[STRING] + +# This flag controls whether inconsistent-quotes generates a warning when the +# character used as a quote delimiter is used inconsistently within a module. +check-quote-consistency=no + +# This flag controls whether the implicit-str-concat should generate a warning +# on implicit string concatenation in sequences defined over several lines. +check-str-concat-over-line-jumps=no + + +[TYPECHECK] + +# List of decorators that produce context managers, such as +# contextlib.contextmanager. Add to this list to register other decorators that +# produce valid context managers. +contextmanager-decorators=contextlib.contextmanager + +# List of members which are set dynamically and missed by pylint inference +# system, and so shouldn't trigger E1101 when accessed. Python regular +# expressions are accepted. +generated-members= + +# Tells whether missing members accessed in mixin class should be ignored. A +# mixin class is detected if its name ends with "mixin" (case insensitive). +ignore-mixin-members=yes + +# Tells whether to warn about missing members when the owner of the attribute +# is inferred to be None. +ignore-none=yes + +# This flag controls whether pylint should warn about no-member and similar +# checks whenever an opaque object is returned when inferring. The inference +# can return multiple potential results while evaluating a Python object, but +# some branches might not be evaluated, which results in partial inference. In +# that case, it might be useful to still emit no-member and other checks for +# the rest of the inferred objects. +ignore-on-opaque-inference=yes + +# List of class names for which member attributes should not be checked (useful +# for classes with dynamically set attributes). This supports the use of +# qualified names. +ignored-classes=optparse.Values,thread._local,_thread._local + +# List of module names for which member attributes should not be checked +# (useful for modules/projects where namespaces are manipulated during runtime +# and thus existing member attributes cannot be deduced by static analysis). It +# supports qualified module names, as well as Unix pattern matching. +ignored-modules= + +# Show a hint with possible names when a member name was not found. The aspect +# of finding the hint is based on edit distance. +missing-member-hint=yes + +# The minimum edit distance a name should have in order to be considered a +# similar match for a missing member name. +missing-member-hint-distance=1 + +# The total number of similar names that should be taken in consideration when +# showing a hint for a missing member. +missing-member-max-choices=1 + +# List of decorators that change the signature of a decorated function. +signature-mutators= + + +[LOGGING] + +# The type of string formatting that logging methods do. `old` means using % +# formatting, `new` is for `{}` formatting. +logging-format-style=old + +# Logging modules to check that the string format arguments are in logging +# function parameter format. +logging-modules=logging + + +[CLASSES] + +# Warn about protected attribute access inside special methods +check-protected-access-in-special-methods=no + +# List of method names used to declare (i.e. assign) instance attributes. +defining-attr-methods=__init__, + __new__, + setUp, + __post_init__ + +# List of member names, which should be excluded from the protected access +# warning. +exclude-protected=_asdict, + _fields, + _replace, + _source, + _make + +# List of valid names for the first argument in a class method. +valid-classmethod-first-arg=cls + +# List of valid names for the first argument in a metaclass class method. +valid-metaclass-classmethod-first-arg=cls + + +[DESIGN] + +# Maximum number of arguments for function / method. +max-args=5 + +# Maximum number of attributes for a class (see R0902). +max-attributes=7 + +# Maximum number of boolean expressions in an if statement (see R0916). +max-bool-expr=5 + +# Maximum number of branch for function / method body. +max-branches=12 + +# Maximum number of locals for function / method body. +max-locals=15 + +# Maximum number of parents for a class (see R0901). +max-parents=7 + +# Maximum number of public methods for a class (see R0904). +max-public-methods=20 + +# Maximum number of return / yield for function / method body. +max-returns=6 + +# Maximum number of statements in function / method body. +max-statements=50 + +# Minimum number of public methods for a class (see R0903). +min-public-methods=2 + + +[IMPORTS] + +# List of modules that can be imported at any level, not just the top level +# one. +allow-any-import-level= + +# Allow wildcard imports from modules that define __all__. +allow-wildcard-with-all=no + +# Analyse import fallback blocks. This can be used to support both Python 2 and +# 3 compatible code, which means that the block might have code that exists +# only in one or another interpreter, leading to false positives when analysed. +analyse-fallback-blocks=no + +# Deprecated modules which should not be used, separated by a comma. +deprecated-modules=optparse,tkinter.tix + +# Create a graph of external dependencies in the given file (report RP0402 must +# not be disabled). +ext-import-graph= + +# Create a graph of every (i.e. internal and external) dependencies in the +# given file (report RP0402 must not be disabled). +import-graph= + +# Create a graph of internal dependencies in the given file (report RP0402 must +# not be disabled). +int-import-graph= + +# Force import order to recognize a module as part of the standard +# compatibility libraries. +known-standard-library= + +# Force import order to recognize a module as part of a third party library. +known-third-party=enchant + +# Couples of modules and preferred modules, separated by a comma. +preferred-modules= + + +[EXCEPTIONS] + +# Exceptions that will emit a warning when being caught. Defaults to +# "BaseException, Exception". +overgeneral-exceptions=BaseException, + Exception -- 2.39.5