Skip to content

Commit 9e3cda3

Browse files
alexr-bqAlex Rehnby-Martinkarenc-bq
authored
Code quality pipeline (#3)
* Run static code analysis locally * Integrate tools and fix errors * Update workflow * Update workflow * Update python version in workflow * Fix linting errors from tests * Fix linting errors from tests * Fix isort order on tests * Change workflow order * Update .vscode/settings.json Co-authored-by: Karen <[email protected]> --------- Co-authored-by: Alex Rehnby-Martin <[email protected]> Co-authored-by: Karen <[email protected]>
1 parent 462ce54 commit 9e3cda3

File tree

11 files changed

+222
-109
lines changed

11 files changed

+222
-109
lines changed

.flake8

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[flake8]
2+
max-line-length = 130

.github/workflows/main.yml

+7-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
runs-on: ubuntu-latest
2424
strategy:
2525
matrix:
26-
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
26+
python-version: ["3.8", "3.9", "3.10", "3.11"]
2727
poetry-version: ["1.4.2"]
2828

2929
steps:
@@ -38,5 +38,11 @@ jobs:
3838
poetry-version: ${{ matrix.poetry-version }}
3939
- name: Install dependencies
4040
run: poetry install
41+
- name: Run mypy - static type checking
42+
run: poetry run mypy .
43+
- name: Run flake8 - linting
44+
run: poetry run flake8 .
45+
- name: Run isort - dependeny import sorting check
46+
run: poetry run isort --check-only .
4147
- name: Run unit tests
4248
run: poetry run python -m pytest

.vscode/settings.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"python.linting.mypyEnabled": false,
3+
"python.linting.enabled": true,
4+
"python.linting.flake8Enabled": true
5+
}

aws_wrapper/__init__.py

-1
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@
99
apilevel = "2.0"
1010
threadsafety = 2
1111
paramstyle = "pyformat"
12-

aws_wrapper/pep249.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
|__NotSupportedError
1515
1616
"""
17+
# mypy: ignore-errors
18+
19+
from typing import Any, Iterator, List, Optional, Sequence
1720

18-
from typing import Any, List, Iterator, Sequence
1921

2022
class Warning(Exception):
2123
__module__ = "pawswrapper"
@@ -68,16 +70,17 @@ class NotSupportedError(DatabaseError):
6870
class ConnectionTimeout(OperationalError):
6971
...
7072

73+
7174
class PipelineAborted(OperationalError):
7275
...
7376

77+
7478
class Connection:
7579

7680
__module__ = "pawswrapper"
7781

7882
@staticmethod
7983
def connect(
80-
cls,
8184
conninfo: str = "",
8285
**kwargs
8386
) -> Any:
@@ -168,5 +171,5 @@ def __iter__(self) -> Iterator[Any]:
168171
def setinputsizes(self, sizes: Any) -> None:
169172
...
170173

171-
def setoutputsize(self, size: Any, column: int = None) -> None:
174+
def setoutputsize(self, size: Any, column: Optional[int] = None) -> None:
172175
...

aws_wrapper/wrapper.py

+63-60
Original file line numberDiff line numberDiff line change
@@ -3,50 +3,52 @@
33
44
"""
55

6-
from ast import Num
7-
from typing import Any, Callable, Sequence, cast, Dict, Generator, Generic, Iterator
8-
from typing import List, NamedTuple, Optional, Type, TypeVar, Tuple, Union
9-
from typing import overload
6+
from typing import Any, Callable, Dict, Iterator, List, Optional, Union
7+
108
from .pep249 import Connection, Cursor, Error
119

10+
1211
class HostInfo:
1312
url: str
1413
port: int
1514

15+
1616
class Properties(Dict[str, str]):
1717
...
1818

19+
1920
class Plugin:
2021

21-
_num: int = 0;
22+
_num: int = 0
2223

2324
def __init__(self, num: int):
2425
self._num = num
2526

26-
def connect(self, hostInfo: HostInfo, props: Properties, initial: bool, executeFunc: Callable) -> Any:
27-
#print("Plugin {}: connect before".format(self._num))
28-
result = executeFunc();
29-
#print("Plugin {}: connect after".format(self._num))
27+
def connect(self, hostInfo: HostInfo, props: Properties,
28+
initial: bool, executeFunc: Callable) -> Any:
29+
# print("Plugin {}: connect before".format(self._num))
30+
result = executeFunc()
31+
# print("Plugin {}: connect after".format(self._num))
3032
return result
3133

3234
def execute(self, executeFunc: Callable) -> Any:
33-
#print("Plugin {}: execute before".format(self._num))
34-
result = executeFunc();
35-
#print("Plugin {}: execute after".format(self._num))
35+
# print("Plugin {}: execute before".format(self._num))
36+
result = executeFunc()
37+
# print("Plugin {}: execute after".format(self._num))
3638
return result
3739

3840
def subscribed(self, methodName: str) -> bool:
3941
return True
4042

43+
4144
class PluginManager:
4245

4346
_plugins: List[Plugin] = []
44-
_numOfPlugins = 0
45-
_functionCache: bool = True
46-
_executeFunc: Callable = None
47-
_connectFunc: Callable = None
47+
_executeFunc: Optional[Callable] = None
48+
_connectFunc: Optional[Callable] = None
4849

49-
def __init__(self, props: Properties = Properties(), numOfPlugins: int = 10, functionCache: bool = True):
50+
def __init__(self, props: Properties = Properties(),
51+
numOfPlugins: int = 10, functionCache: bool = True):
5052

5153
self._numOfPlugins = numOfPlugins
5254
self._functionCache = functionCache
@@ -59,7 +61,7 @@ def __init__(self, props: Properties = Properties(), numOfPlugins: int = 10, fun
5961

6062
@property
6163
def numOfPlugins(self) -> int:
62-
return self._numOfPlugins;
64+
return self._numOfPlugins
6365

6466
@property
6567
def executeFunc(self) -> Callable:
@@ -75,11 +77,13 @@ def executeFunc(self) -> Callable:
7577

7678
for i in range(numOfPlugins - 1, 0, -1):
7779
code = "plugins[{}].execute(lambda : {})".format(i - 1, code)
78-
80+
7981
code = "lambda x : {}".format(code)
80-
#print(code)
81-
self._executeFunc = eval(code, { "plugins": self._plugins })
82+
# print(code)
83+
84+
self._executeFunc = eval(code, {"plugins": self._plugins})
8285

86+
assert (self._executeFunc is not None)
8387
return self._executeFunc
8488

8589
@property
@@ -96,92 +100,92 @@ def connectFunc(self) -> Callable:
96100

97101
for i in range(numOfPlugins - 1, 0, -1):
98102
code = "plugins[{}].connect(hostInfo, props, initial, lambda : {})".format(i - 1, code)
99-
103+
100104
code = "lambda hostInfo, props, initial, x : {}".format(code)
101-
#print(code)
102-
self._connectFunc = eval(code, { "plugins": self._plugins })
105+
# print(code)
106+
self._connectFunc = eval(code, {"plugins": self._plugins})
103107

108+
assert (self._connectFunc is not None)
104109
return self._connectFunc
105110

106111

107112
class AwsWrapperConnection(Connection):
108113

109114
__module__ = "pawswrapper"
110-
111-
_targetConn: Connection = None
112-
_pluginManager: PluginManager = None
115+
116+
def __init__(self, pluginManager: PluginManager, targetConn: Connection):
117+
self._targetConn = targetConn
118+
self._pluginManager = pluginManager
113119

114120
@staticmethod
115121
def connect(
116122
conninfo: str = "",
117-
target: Union[str, callable] = None,
123+
target: Union[None, str, Callable] = None,
118124
**kwargs: Union[None, int, str]
119125
) -> "AwsWrapperConnection":
120126
# Check if target provided
121127
if not target:
122128
raise Error("Target driver is required")
123129

124130
if type(target) == str:
125-
target = eval(target);
131+
target = eval(target)
126132

127133
if not callable(target):
128134
raise Error("Target driver should be a target driver's connect() method/function")
129135

130136
numOfPlugins = kwargs.get("numOfPlugins")
131-
if numOfPlugins == None:
132-
numOfPlugins = 10
133-
else:
137+
if numOfPlugins is not None:
134138
kwargs.pop("numOfPlugins")
139+
if type(numOfPlugins) != int:
140+
numOfPlugins = 10
141+
135142
functionCache = kwargs.get("functionCache")
136-
if functionCache == None:
143+
if functionCache is None:
137144
functionCache = True
138145
else:
139146
kwargs.pop("functionCache")
147+
functionCache = bool(functionCache)
140148

141149
props: Properties = Properties()
142150
pluginManager: PluginManager = PluginManager(props=props, numOfPlugins=numOfPlugins, functionCache=functionCache)
143151
hostInfo: HostInfo = HostInfo()
144152

145-
146153
# Target driver is a connect function
147154
if pluginManager.numOfPlugins == 0:
148155
conn = target(conninfo, **kwargs)
149156
else:
150-
conn = pluginManager.connectFunc(hostInfo, props, True, lambda : target(conninfo, **kwargs))
151-
152-
return AwsWrapperConnection(pluginManager, conn);
157+
conn = pluginManager.connectFunc(hostInfo, props, True, lambda: target(conninfo, **kwargs))
153158

154-
def __init__(self, pluginManager: PluginManager, targetConn: Connection):
155-
self._targetConn = targetConn
156-
self._pluginManager = pluginManager
159+
return AwsWrapperConnection(pluginManager, conn)
157160

158161
def close(self) -> None:
159-
self._targetConn.close();
162+
if self._targetConn:
163+
self._targetConn.close()
160164

161165
def cursor(self, **kwargs) -> "AwsWrapperCursor":
162166
_cursor = self._targetConn.cursor(**kwargs)
163-
return AwsWrapperCursor(self, self._pluginManager, _cursor);
167+
return AwsWrapperCursor(self, self._pluginManager, _cursor)
164168

165169
def commit(self) -> None:
166-
self._targetConn.commit();
170+
self._targetConn.commit()
167171

168172
def rollback(self) -> None:
169-
self._targetConn.rollback();
173+
self._targetConn.rollback()
170174

171175
def tpc_begin(self, xid: Any) -> None:
172-
self._targetConn.tpc_begin(xid);
176+
self._targetConn.tpc_begin(xid)
173177

174178
def tpc_prepare(self) -> None:
175-
self._targetConn.tpc_prepare();
179+
self._targetConn.tpc_prepare()
176180

177181
def tpc_commit(self, xid: Any = None) -> None:
178-
self._targetConn.tpc_commit(xid);
182+
self._targetConn.tpc_commit(xid)
179183

180184
def tpc_rollback(self, xid: Any = None) -> None:
181-
self._targetConn.tpc_rollback(xid);
185+
self._targetConn.tpc_rollback(xid)
182186

183187
def tpc_recover(self) -> Any:
184-
return self._targetConn.tpc_recover();
188+
return self._targetConn.tpc_recover()
185189

186190
def __enter__(self: "AwsWrapperConnection") -> "AwsWrapperConnection":
187191
return self
@@ -191,7 +195,6 @@ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
191195
self._targetConn.close()
192196

193197

194-
195198
class AwsWrapperCursor(Cursor):
196199

197200
__module__ = "pawswrapper"
@@ -208,35 +211,36 @@ def __init__(self, conn: AwsWrapperConnection, pluginManager: PluginManager, tar
208211
# It's not part of PEP249
209212
@property
210213
def connection(self) -> AwsWrapperConnection:
211-
return self._conn;
214+
return self._conn
212215

213216
@property
214217
def description(self):
215-
return self._targetCursor.description;
218+
return self._targetCursor.description
216219

217220
@property
218221
def rowcount(self) -> int:
219-
return self._targetCursor.rowcount;
222+
return self._targetCursor.rowcount
220223

221224
@property
222225
def arraysize(self) -> int:
223-
return self._targetCursor.arraysize;
226+
return self._targetCursor.arraysize
224227

225228
def close(self) -> None:
226-
return self._targetCursor.close;
229+
self._targetCursor.close
227230

228231
def callproc(self, **kwargs):
229-
return self._targetCursor.callproc(**kwargs);
232+
return self._targetCursor.callproc(**kwargs)
230233

231234
def execute(
232235
self,
233236
query: str,
234237
**kwargs
235238
) -> "AwsWrapperCursor":
236239
if self._pluginManager.numOfPlugins == 0:
237-
return self._targetCursor.execute(query, **kwargs)
240+
self._targetCursor = self._targetCursor.execute(query, **kwargs)
241+
return self
238242

239-
result = self._pluginManager.executeFunc(lambda : self._targetCursor.execute(query, **kwargs))
243+
result = self._pluginManager.executeFunc(lambda: self._targetCursor.execute(query, **kwargs))
240244
return result
241245

242246
def executemany(
@@ -264,12 +268,11 @@ def __iter__(self) -> Iterator[Any]:
264268
def setinputsizes(self, sizes: Any) -> None:
265269
return self._targetCursor.setinputsizes(sizes)
266270

267-
def setoutputsize(self, size: Any, column: int = None) -> None:
271+
def setoutputsize(self, size: Any, column: Optional[int] = None) -> None:
268272
return self._targetCursor.setoutputsize(size, column)
269273

270274
def __enter__(self: "AwsWrapperCursor") -> "AwsWrapperCursor":
271275
return self
272276

273277
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
274278
self.close()
275-

0 commit comments

Comments
 (0)