changeset 31:3ca1a8774513

typing fixes. rewrite sequentialUri a bit Ignore-this: e03acba6e72acfd93d4670b80cab0646
author Drew Perttula <drewp@bigasterisk.com>
date Sat, 25 May 2019 02:36:17 +0000
parents a0f0fd316781
children c8cf9d85fa81
files Dockerfile.mypy rdfdb/autodepgraphapi.py rdfdb/currentstategraphapi.py rdfdb/currentstategraphapi_test.py rdfdb/grapheditapi.py rdfdb/graphfile.py rdfdb/patchsender.py rdfdb/service.py rdfdb/syncedgraph.py run_mypy.sh tasks.py
diffstat 11 files changed, 61 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Dockerfile.mypy	Sat May 25 02:36:17 2019 +0000
@@ -0,0 +1,7 @@
+FROM bang6:5000/base_x86
+
+WORKDIR /opt
+
+RUN pip3 install --index-url https://projects.bigasterisk.com/ --extra-index-url https://pypi.org/simple mypy
+RUN pip3 install --index-url https://projects.bigasterisk.com/ --extra-index-url https://pypi.org/simple rdflib cyclone mock treq rdflib-jsonld service_identity
+
--- a/rdfdb/autodepgraphapi.py	Sat May 25 00:30:43 2019 +0000
+++ b/rdfdb/autodepgraphapi.py	Sat May 25 02:36:17 2019 +0000
@@ -1,5 +1,6 @@
 import logging
-from rdflib import RDF, RDFS
+from typing import Callable, Dict, Set, Tuple
+from rdflib import RDF, RDFS, URIRef
 from rdfdb.currentstategraphapi import contextsForStatementNoWildcards
 log = logging.getLogger('autodepgraphapi')
 
@@ -20,7 +21,7 @@
 
     def __init__(self):
         self._watchers = _GraphWatchers()
-        self.currentFuncs = [] # stack of addHandler callers
+        self.currentFuncs: Callable[[], None] = [] # stack of addHandler callers
     
     def addHandler(self, func):
         """
@@ -143,16 +144,17 @@
     # I'm going to be repeating that logic a lot. Maybe just for the
     # subjects(RDF.type, t) call
 
+HandlerSet = Set[Callable[[], None]]
 
 class _GraphWatchers(object):
     """
     store the current handlers that care about graph changes
     """
     def __init__(self):
-        self._handlersSp = {} # (s,p): set(handlers)
-        self._handlersPo = {} # (p,o): set(handlers)
-        self._handlersSpo = {} # (s,p,o): set(handlers)
-        self._handlersS = {} # s: set(handlers)
+        self._handlersSp: Dict[Tuple[URIRef, URIRef], HandlerSet] = {} # (s,p): set(handlers)
+        self._handlersPo: Dict[Tuple[URIRef, URIRef], HandlerSet] = {} # (p,o): set(handlers)
+        self._handlersSpo: Dict[Tuple[URIRef, URIRef, URIRef], HandlerSet] = {} # (s,p,o): set(handlers)
+        self._handlersS: Dict[URIRef, HandlerSet] = {} # s: set(handlers)
 
     def addSubjPredWatcher(self, func, s, p):
         if func is None:
@@ -179,7 +181,7 @@
         this removes the handlers that it gives you
         """
         #self.dependencies()
-        ret = set()
+        ret: Set[Callable[[], None]] = set()
         affectedSubjPreds = set([(s, p) for s, p, o, c in patch.addQuads]+
                                 [(s, p) for s, p, o, c in patch.delQuads])
         for (s, p), funcs in self._handlersSp.items():
--- a/rdfdb/currentstategraphapi.py	Sat May 25 00:30:43 2019 +0000
+++ b/rdfdb/currentstategraphapi.py	Sat May 25 02:36:17 2019 +0000
@@ -1,5 +1,5 @@
 import logging, traceback, time, itertools
-from rdflib import ConjunctiveGraph
+from rdflib import ConjunctiveGraph, URIRef
 from rdfdb.rdflibpatch import contextsForStatement as rp_contextsForStatement
 log = logging.getLogger("currentstate")
 
@@ -17,6 +17,9 @@
     def __len__(self):
         return len(self.graph)
 
+    def contextsForStatement(self, stmt):
+        raise NotImplementedError
+
 
 class CurrentStateGraphApi(object):
     """
@@ -51,7 +54,8 @@
                     if tripleFilter == (None, None, None):
                         self2.logThisCopy(g, time.time() - t1)
                     
-                g.contextsForStatement = lambda t: contextsForStatementNoWildcards(g, t)
+                setattr(g, 'contextsForStatement',
+                        lambda t: contextsForStatementNoWildcards(g, t))
                 return g
 
             def logThisCopy(self, g, sec):
@@ -66,17 +70,19 @@
 
         return Mgr()
 
+    _reservedSequentials = None # Optional[Set[URIRef]]
+    
     def sequentialUri(self, prefix):
         """
         Prefix URIRef like http://example.com/r- will return
         http://example.com/r-1 if that uri is not a subject in the graph,
         or else http://example.com/r-2, etc
         """
+        if self._reservedSequentials is None:
+            self._reservedSequentials = set()
         for i in itertools.count(1):
-            newUri = prefix + str(i)
-            if not list(self._graph.triples((newUri, None, None))) and newUri not in getattr(self, '_reservedSequentials', []):
-                if not hasattr(self, '_reservedSequentials'):
-                    self._reservedSequentials = set()
+            newUri = URIRef(prefix + str(i))
+            if newUri not in self._reservedSequentials and not list(self._graph.triples((newUri, None, None))):
                 self._reservedSequentials.add(newUri)
                 return newUri
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/rdfdb/currentstategraphapi_test.py	Sat May 25 02:36:17 2019 +0000
@@ -0,0 +1,6 @@
+import unittest
+
+class TestSequentialUri(unittest.TestCase):
+    def test_returnsSequentialUris(self):
+        1/0
+        
--- a/rdfdb/grapheditapi.py	Sat May 25 00:30:43 2019 +0000
+++ b/rdfdb/grapheditapi.py	Sat May 25 02:36:17 2019 +0000
@@ -106,6 +106,7 @@
         class Obj(GraphEditApi):
             def patch(self, p):
                 appliedPatches.append(p)
+            _graph: ConjunctiveGraph
         obj = Obj()
         obj._graph = ConjunctiveGraph()
         stmt1 = (URIRef('s'), URIRef('p'), URIRef('o'), URIRef('g'))
--- a/rdfdb/graphfile.py	Sat May 25 00:30:43 2019 +0000
+++ b/rdfdb/graphfile.py	Sat May 25 02:36:17 2019 +0000
@@ -2,9 +2,10 @@
 from twisted.python.filepath import FilePath
 from twisted.internet import reactor
 from twisted.internet.inotify import humanReadableMask
-from rdflib import Graph, RDF
+from rdflib import Graph, RDF, URIRef
 from rdfdb.patch import Patch
 from rdfdb.rdflibpatch import inContext
+from typing import Dict
 
 log = logging.getLogger('graphfile')
 iolog = logging.getLogger('io')
@@ -20,7 +21,7 @@
         else:
             self._column += len(lines[0])
         return originalWrite(self, s)
-    TurtleSerializer.write = write
+    TurtleSerializer.write = write # type: ignore
     def predicateList(self, subject, newline=False):
         properties = self.buildPredicateHash(subject)
         propList = self.sortProperties(properties)
@@ -53,9 +54,9 @@
             self.write('\n')
         originalStatement(self, subject)
         return False         #  suppress blank line for 'minor' statements
-    TurtleSerializer.statement = statement
-    TurtleSerializer.predicateList = predicateList
-    TurtleSerializer.objectList = objectList
+    TurtleSerializer.statement = statement  # type: ignore
+    TurtleSerializer.predicateList = predicateList  # type: ignore
+    TurtleSerializer.objectList = objectList  # type: ignore
 
 patchN3SerializerToUseLessWhitespace()
 
@@ -80,7 +81,7 @@
 
         self.globalPrefixes = globalPrefixes
         self.ctxPrefixes = ctxPrefixes
-        self.readPrefixes = {}
+        self.readPrefixes: Dict[str, URIRef] = {}
         
         if not os.path.exists(path):
             # can't start notify until file exists
--- a/rdfdb/patchsender.py	Sat May 25 00:30:43 2019 +0000
+++ b/rdfdb/patchsender.py	Sat May 25 02:36:17 2019 +0000
@@ -1,7 +1,8 @@
-
 import logging, time
+from typing import List
 import cyclone.httpclient
 from twisted.internet import defer
+from rdfdb.patch import Patch
 log = logging.getLogger('syncedgraph')
 
 class PatchSender(object):
@@ -20,11 +21,11 @@
         """
         self.target = target
         self.myUpdateResource = myUpdateResource
-        self._patchesToSend = []
+        self._patchesToSend: List[Patch] = []
         self._currentSendPatchRequest = None
 
     def sendPatch(self, p):
-        sendResult = defer.Deferred()
+        sendResult: defer.Deferred[None] = defer.Deferred()
         self._patchesToSend.append((p, sendResult))
         self._continueSending()
         return sendResult
--- a/rdfdb/service.py	Sat May 25 00:30:43 2019 +0000
+++ b/rdfdb/service.py	Sat May 25 02:36:17 2019 +0000
@@ -5,7 +5,7 @@
 from twisted.internet.inotify import humanReadableMask, IN_CREATE
 import sys, optparse, logging, json, os
 import cyclone.web, cyclone.httpclient, cyclone.websocket
-from typing import Set
+from typing import Dict, List, Set
 
 from rdflib import ConjunctiveGraph, URIRef, Graph
 from rdfdb.graphfile import GraphFile
@@ -75,7 +75,7 @@
         self.patch, self.getSubgraph = patch, getSubgraph
         self.addlPrefixes = addlPrefixes
         
-        self.graphFiles = {} # context uri : GraphFile
+        self.graphFiles: Dict[URIRef, GraphFile] = {} # context uri : GraphFile
         
         self.notifier = INotify()
         self.notifier.startReading()
@@ -190,7 +190,7 @@
     """
     def __init__(self, dirUriMap, addlPrefixes):
       
-        self.clients = []
+        self.clients: List[Client] = []
         self.graph = ConjunctiveGraph()
 
         self.watchedFiles = WatchedFiles(dirUriMap,
--- a/rdfdb/syncedgraph.py	Sat May 25 00:30:43 2019 +0000
+++ b/rdfdb/syncedgraph.py	Sat May 25 02:36:17 2019 +0000
@@ -64,7 +64,7 @@
             receiverHost = socket.gethostname()
         
         self.rdfdbRoot = rdfdbRoot
-        self.initiallySynced = defer.Deferred()
+        self.initiallySynced: defer.Deferred[None] = defer.Deferred()
         self._graph = ConjunctiveGraph()
 
         self._receiver = PatchReceiver(self.rdfdbRoot, receiverHost, label, self._onPatch)
@@ -94,8 +94,8 @@
         # this should be locked so only one resync goes on at once
         return cyclone.httpclient.fetch(
             url=self.rdfdbRoot + "graph",
-            method="GET",
-            headers={'Accept':['x-trig']},
+            method=b"GET",
+            headers={b'Accept':[b'x-trig']},
             ).addCallback(self._resyncGraph)
 
     def _resyncGraph(self, response):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/run_mypy.sh	Sat May 25 02:36:17 2019 +0000
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+MYPYPATH=stubs mypy --check-untyped-defs rdfdb/*.py
--- a/tasks.py	Sat May 25 00:30:43 2019 +0000
+++ b/tasks.py	Sat May 25 02:36:17 2019 +0000
@@ -8,3 +8,9 @@
 def release(ctx):
     local_release(ctx)
 
+@task
+def mypy(ctx):
+    ctx.run('docker build -f Dockerfile.mypy -t rdfdb_mypy:latest .')
+    ctx.run('docker run --rm -it -v `pwd`:/opt rdfdb_mypy:latest'
+            ' /bin/sh /opt/run_mypy.sh',
+            pty=True)