From 10f9ebe162d2dccda637b98297fec9ead8c970b7 Mon Sep 17 00:00:00 2001 From: Iwan Aucamp Date: Tue, 20 Jun 2023 21:39:59 +0200 Subject: [PATCH] fix: typing errors from dmypy (#2451) Fix various typing errors that are reported when running with `dmypy`, the mypy daemon. Also add a task for running `dmypy` to the Taskfile that can be selected as the default mypy variant by setting the `MYPY_VARIANT` environment variable to `dmypy`. --- Taskfile.yml | 10 +++++++++- docs/conf.py | 1 + rdflib/events.py | 9 +++++++-- rdflib/plugins/parsers/notation3.py | 2 +- rdflib/plugins/sparql/parserutils.py | 4 ++-- rdflib/plugins/stores/memory.py | 4 +++- rdflib/store.py | 2 +- rdflib/tools/csv2rdf.py | 14 ++++++++------ test/jsonld/test_compaction.py | 8 +++++--- test/test_graph/test_graph_context.py | 5 ++++- test/test_sparql/test_prefixed_name.py | 5 +++-- test/utils/sparql_checker.py | 10 ++++++---- test/utils/test/test_result.py | 5 +++-- 13 files changed, 53 insertions(+), 26 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index b2febc570..febb1c202 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -35,6 +35,7 @@ vars: PIP_COMPILE: pip-compile DOCKER: docker OCI_REFERENCE: ghcr.io/rdflib/rdflib + MYPY_VARIANT: '{{ env "MYPY_VARIANT" | default "mypy" }}' tasks: install:system-deps: desc: Install system dependencies @@ -130,10 +131,17 @@ tasks: cmds: - '{{.VENV_PYTHON}} -m isort {{if (mustFromJson (.CHECK | default "false"))}}--check --diff {{end}}{{.CLI_ARGS | default "."}}' mypy: + desc: Run mypy + cmds: + - task: "mypy:{{ .MYPY_VARIANT }}" + mypy:mypy: desc: Run mypy cmds: - "{{.VENV_PYTHON}} -m mypy --show-error-context --show-error-codes {{.CLI_ARGS}}" - + mypy:dmypy: + desc: Run dmypy + cmds: + - "{{.RUN_PREFIX}} dmypy run {{.CLI_ARGS}}" lint:fix: desc: Fix auto-fixable linting errors cmds: diff --git a/docs/conf.py b/docs/conf.py index 93d78d8a0..05a702883 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -302,6 +302,7 @@ def find_version(filename): ("py:class", "ParseFailAction"), ("py:class", "pyparsing.core.TokenConverter"), ("py:class", "pyparsing.results.ParseResults"), + ("py:class", "pyparsing.core.ParserElement"), # These are related to BerkeleyDB ("py:class", "db.DBEnv"), ] diff --git a/rdflib/events.py b/rdflib/events.py index d0290d5cd..84c9f07a0 100644 --- a/rdflib/events.py +++ b/rdflib/events.py @@ -1,3 +1,5 @@ +from __future__ import annotations + __doc__ = """ Dirt Simple Events @@ -23,6 +25,9 @@ """ + +from typing import Any, Dict, Optional + __all__ = ["Event", "Dispatcher"] @@ -53,9 +58,9 @@ class Dispatcher: subscribers. """ - _dispatch_map = None + _dispatch_map: Optional[Dict[Any, Any]] = None - def set_map(self, amap): + def set_map(self, amap: Dict[Any, Any]): self._dispatch_map = amap return self diff --git a/rdflib/plugins/parsers/notation3.py b/rdflib/plugins/parsers/notation3.py index 2a64be24f..290e7d04b 100755 --- a/rdflib/plugins/parsers/notation3.py +++ b/rdflib/plugins/parsers/notation3.py @@ -276,7 +276,7 @@ def _fixslash(s: str) -> str: N3_Empty = (SYMBOL, List_NS + "Empty") -runNamespaceValue = None +runNamespaceValue: Optional[str] = None def runNamespace() -> str: diff --git a/rdflib/plugins/sparql/parserutils.py b/rdflib/plugins/sparql/parserutils.py index b625f3646..2c5bc38bd 100644 --- a/rdflib/plugins/sparql/parserutils.py +++ b/rdflib/plugins/sparql/parserutils.py @@ -14,7 +14,7 @@ Union, ) -from pyparsing import ParseResults, TokenConverter, originalTextFor +from pyparsing import ParserElement, ParseResults, TokenConverter, originalTextFor from rdflib.term import BNode, Identifier, Variable @@ -241,7 +241,7 @@ class Comp(TokenConverter): Returns CompValue / Expr objects - depending on whether evalFn is set. """ - def __init__(self, name: str, expr): + def __init__(self, name: str, expr: ParserElement): self.expr = expr TokenConverter.__init__(self, expr) self.setName(name) diff --git a/rdflib/plugins/stores/memory.py b/rdflib/plugins/stores/memory.py index 13c15218a..68f0ece50 100644 --- a/rdflib/plugins/stores/memory.py +++ b/rdflib/plugins/stores/memory.py @@ -1,5 +1,7 @@ # # +from __future__ import annotations + from typing import ( TYPE_CHECKING, Any, @@ -34,7 +36,7 @@ __all__ = ["SimpleMemory", "Memory"] -ANY = None +ANY: None = None class SimpleMemory(Store): diff --git a/rdflib/store.py b/rdflib/store.py index e3c9f7ab2..a3f6b6959 100644 --- a/rdflib/store.py +++ b/rdflib/store.py @@ -65,7 +65,7 @@ VALID_STORE = 1 CORRUPTED_STORE = 0 NO_STORE = -1 -UNKNOWN = None +UNKNOWN: None = None Pickler = pickle.Pickler diff --git a/rdflib/tools/csv2rdf.py b/rdflib/tools/csv2rdf.py index fe740356a..b519a78fc 100644 --- a/rdflib/tools/csv2rdf.py +++ b/rdflib/tools/csv2rdf.py @@ -6,6 +6,7 @@ try: ``csv2rdf --help`` """ +from __future__ import annotations import codecs import configparser @@ -17,11 +18,12 @@ import sys import time import warnings +from typing import Any, Dict, List, Optional, Tuple from urllib.parse import quote import rdflib -from rdflib import RDF, RDFS -from rdflib.namespace import split_uri +from rdflib.namespace import RDF, RDFS, split_uri +from rdflib.term import URIRef __all__ = ["CSV2RDF"] @@ -88,7 +90,7 @@ """ # bah - ugly global -uris = {} +uris: Dict[Any, Tuple[URIRef, Optional[URIRef]]] = {} def toProperty(label): @@ -113,7 +115,7 @@ def toPropertyLabel(label): return label -def index(l_, i): +def index(l_: List[int], i: Tuple[int, ...]) -> Tuple[int, ...]: """return a set of indexes from a list >>> index([1,2,3],(0,2)) (1, 3) @@ -127,7 +129,7 @@ def csv_reader(csv_data, dialect=csv.excel, **kwargs): yield row -def prefixuri(x, prefix, class_=None): +def prefixuri(x, prefix, class_: Optional[URIRef] = None): if prefix: r = rdflib.URIRef(prefix + quote(x.encode("utf8").replace(" ", "_"), safe="")) else: @@ -143,7 +145,7 @@ class NodeMaker: def range(self): return rdflib.RDFS.Literal - def __call__(self, x): + def __call__(self, x: Any): return rdflib.Literal(x) diff --git a/test/jsonld/test_compaction.py b/test/jsonld/test_compaction.py index e76de5580..f6cdae14b 100644 --- a/test/jsonld/test_compaction.py +++ b/test/jsonld/test_compaction.py @@ -1,8 +1,10 @@ # -*- coding: UTF-8 -*- +from __future__ import annotations import itertools import json import re +from typing import Any, Dict, List, Tuple import pytest @@ -13,11 +15,11 @@ register("json-ld", Serializer, "rdflib.plugins.serializers.jsonld", "JsonLDSerializer") -cases = [] +cases: List[Tuple[str, Dict[str, Any]]] = [] -def case(*args): - cases.append(args) +def case(source: str, data: Dict[str, Any]): + cases.append((source, data)) case( diff --git a/test/test_graph/test_graph_context.py b/test/test_graph/test_graph_context.py index f6ef5c3e4..adb133826 100644 --- a/test/test_graph/test_graph_context.py +++ b/test/test_graph/test_graph_context.py @@ -1,8 +1,11 @@ +from __future__ import annotations + import os import shutil import sys import unittest from tempfile import mkdtemp, mkstemp +from typing import Optional import pytest @@ -13,7 +16,7 @@ class ContextTestCase(unittest.TestCase): store = "default" slow = True - tmppath = None + tmppath: Optional[str] = None def setUp(self): try: diff --git a/test/test_sparql/test_prefixed_name.py b/test/test_sparql/test_prefixed_name.py index 99d2fb108..9ac37b281 100644 --- a/test/test_sparql/test_prefixed_name.py +++ b/test/test_sparql/test_prefixed_name.py @@ -1,11 +1,12 @@ +from __future__ import annotations + import itertools import logging from contextlib import ExitStack -from typing import Type, Union +from typing import Optional, Type, Union import pyparsing import pytest -from pyparsing import Optional import rdflib from rdflib import Graph diff --git a/test/utils/sparql_checker.py b/test/utils/sparql_checker.py index 477c9d3c8..680742100 100644 --- a/test/utils/sparql_checker.py +++ b/test/utils/sparql_checker.py @@ -1,5 +1,7 @@ """This runs the nt tests for the W3C RDF Working Group's N-Quads test suite.""" +from __future__ import annotations + import enum import logging import pprint @@ -290,11 +292,11 @@ def check_syntax(monkeypatch: MonkeyPatch, entry: SPARQLEntry) -> None: if entry.type_info.negative: catcher = xstack.enter_context(pytest.raises(Exception)) if entry.type_info.query_type is QueryType.UPDATE: - tree = parseUpdate(query_text) - translateUpdate(tree) + parse_tree = parseUpdate(query_text) + translateUpdate(parse_tree) elif entry.type_info.query_type is QueryType.QUERY: - tree = parseQuery(query_text) - translateQuery(tree) + query_tree = parseQuery(query_text) + translateQuery(query_tree) if catcher is not None: assert catcher.value is not None logging.info("catcher.value = %s", catcher.value) diff --git a/test/utils/test/test_result.py b/test/utils/test/test_result.py index 1d9325791..d30e2d55e 100644 --- a/test/utils/test/test_result.py +++ b/test/utils/test/test_result.py @@ -1,9 +1,10 @@ +from __future__ import annotations + from contextlib import ExitStack from test.utils.result import BindingsCollectionType, assert_bindings_collections_equal -from typing import Type, Union +from typing import Optional, Type, Union import pytest -from pyparsing import Optional from rdflib.namespace import XSD from rdflib.term import BNode, Literal, URIRef, Variable