8000 feat: adding missing docstrings for functions & classes (#188) · larkee/python-spanner@9788cf8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9788cf8

Browse files
tina80lvlc24tlarkee
authored
feat: adding missing docstrings for functions & classes (googleapis#188)
* feat: docs for parser.py * feat: docstrings * Fix whitespace, formatting * style: fix lint errors Co-authored-by: Chris Kleinknecht <libc@google.com> Co-authored-by: larkee <31196561+larkee@users.noreply.github.com> Co-authored-by: larkee <larkee@users.noreply.github.com>
1 parent ed7152a commit 9788cf8

File tree

4 files changed

+138
-33
lines changed

4 files changed

+138
-33
lines changed

google/cloud/spanner_dbapi/cursor.py

Lines changed: 21 additions & 2 deletions
< 10000 tr class="diff-line-row">
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ def description(self):
8585
- ``precision``
8686
- ``scale``
8787
- ``null_ok``
88+
89+
:rtype: tuple
90+
:returns: A tuple of columns' information.
8891
"""
8992
if not (self._result_set and self._result_set.metadata):
9093
return None
@@ -107,7 +110,11 @@ def description(self):
107110

108111
@property
109112
def rowcount(self):
110-
"""The number of rows produced by the last `.execute()`."""
113+
"""The number of rows produced by the last `.execute()`.
114+
115+
:rtype: int
116+
:returns: The number of rows produced by the last .execute*().
117+
"""
111118
return self._row_count
112119

113120
def _raise_if_closed(self):
@@ -127,7 +134,14 @@ def callproc(self, procname, args=None):
127134
self._raise_if_closed()
128135

129136
def close(self):
130-
"""Closes this Cursor, making it unusable from this point forward."""
137+
"""Prepare and execute a Spanner database operation.
138+
139+
:type sql: str
140+
:param sql: A SQL query statement.
141+
142+
:type args: list
143+
:param args: Additional parameters to supplement the SQL query.
144+
"""
131145
self._is_closed = True
132146

133147
def _do_execute_update(self, transaction, sql, params, param_types=None):
@@ -358,6 +372,11 @@ def __iter__(self):
358372
return self._itr
359373

360374
def list_tables(self):
375+
"""List the tables of the linked Database.
376+
377+
:rtype: list
378+
:returns: The list of tables within the Database.
379+
"""
361380
return self.run_sql_in_snapshot(_helpers.SQL_LIST_TABLES)
362381

363382
def run_sql_in_snapshot(self, sql, params=None, param_types=None):

google/cloud/spanner_dbapi/parse_utils.py

Lines changed: 41 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -176,11 +176,11 @@
176176
def classify_stmt(query):
177177
"""Determine SQL query type.
178178
179-
:type query: :class:`str`
180-
:param query: SQL query.
179+
:type query: str
180+
:param query: A SQL query.
181181
182-
:rtype: :class:`str`
183-
:returns: Query type name.
182+
:rtype: str
183+
:returns: The query type name.
184184
"""
185185
if RE_DDL.match(query):
186186
return STMT_DDL
@@ -253,6 +253,17 @@ def parse_insert(insert_sql, params):
253253
('INSERT INTO T (f1, f2) VALUES (UPPER(%s), %s)', ('c', 'd',))
254254
],
255255
}
256+
257+
:type insert_sql: str
258+
:param insert_sql: A SQL insert request.
259+
260+
:type params: list
261+
:param params: A list of parameters.
262+
263+
:rtype: dict
264+
:returns: A dictionary that maps `sql_params_list` to the list of
265+
parameters in cases a), b), d) or the dictionary with information
266+
about the resulting table in case c).
256267
""" # noqa
257268
match = RE_INSERT.search(insert_sql)
258269

@@ -348,8 +359,16 @@ def rows_for_insert_or_update(columns, params, pyformat_args=None):
348359
349360
We'll have to convert both params types into:
350361
Params: [(1, 2, 3,), (4, 5, 6,), (7, 8, 9,)]
351-
""" # noqa
352362
363+
:type columns: list
364+
:param columns: A list of the columns of the table.
365+
366+
:type params: list
367+
:param params: A list of parameters.
368+
369+
:rtype: list
370+
:returns: A properly restructured list of the parameters.
371+
""" # noqa
353372
if not pyformat_args:
354373
# This is the case where we have for example:
355374
# SQL: 'INSERT INTO t (f1, f2, f3)'
@@ -445,6 +464,16 @@ def sql_pyformat_args_to_spanner(sql, params):
445464
becomes:
446465
SQL: 'SELECT * from t where f1=@a0, f2=@a1, f3=@a2'
447466
Params: {'a0': 'a', 'a1': 23, 'a2': '888***'}
467+
468+
:type sql: str
469+
:param sql: A SQL request.
470+
471+
:type params: list
472+
:param params: A list of parameters.
473+
474+
:rtype: tuple(str, dict)
475+
:returns: A tuple of the sanitized SQL and a dictionary of the named
476+
arguments.
448477
"""
449478
if not params:
450479
return sanitize_literals_for_upload(sql), params
@@ -488,10 +517,10 @@ def cast_for_spanner(value):
488517
"""Convert the param to its Cloud Spanner equivalent type.
489518
490519
:type value: Any
491-
:param value: Value to convert to a Cloud Spanner type.
520+
:param value: The value to convert to a Cloud Spanner type.
492521
493522
:rtype: Any
494-
:returns: Value converted to a Cloud Spanner type.
523+
:returns: The value converted to a Cloud Spanner type.
495524
"""
496525
if isinstance(value, decimal.Decimal):
497526
return str(value)
@@ -501,10 +530,10 @@ def cast_for_spanner(value):
501530
def get_param_types(params):
502531
"""Determine Cloud Spanner types for the given parameters.
503532
504-
:type params: :class:`dict`
533+
:type params: dict
505534
:param params: Parameters requiring to find Cloud Spanner types.
506535
507-
:rtype: :class:`dict`
536+
:rtype: dict
508537
:returns: The types index for the given parameters.
509538
"""
510539
if params is None:
@@ -525,7 +554,7 @@ def ensure_where_clause(sql):
525554
Cloud Spanner requires a WHERE clause on UPDATE and DELETE statements.
526555
Add a dummy WHERE clause if non detected.
527556
528-
:type sql: `str`
557+
:type sql: str
529558
:param sql: SQL code to check.
530559
"""
531560
if any(isinstance(token, sqlparse.sql.Where) for token in sqlparse.parse(sql)[0]):
@@ -539,10 +568,10 @@ def escape_name(name):
539568
Apply backticks to the name that either contain '-' or
540569
' ', or is a Cloud Spanner's reserved keyword.
541570
542-
:type name: :class:`str`
571+
:type name: str
543572
:param name: Name to escape.
544573
545-
:rtype: :class:`str`
574+
:rtype: str
546575
:returns: Name escaped if it has to be escaped.
547576
"""
548577
if "-" in name or " " in name or name.upper() in SPANNER_RESERVED_KEYWORDS:

google/cloud/spanner_dbapi/parser.py

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,18 @@ def __len__(self):
6868

6969

7070
class terminal(str):
71-
"""
72-
terminal represents the unit symbol that can be part of a SQL values clause.
73-
"""
71+
"""Represent the unit symbol that can be part of a SQL values clause."""
7472

7573
pass
7674

7775

7876
class a_args(object):
77+
"""Expression arguments.
78+
79+
:type argv: list
80+
:param argv: A List of expression arguments.
81+
"""
82+
7983
def __init__(self, argv):
8084
self.argv = argv
8185

@@ -108,9 +112,11 @@ def __getitem__(self, index):
108112
return self.argv[index]
109113

110114
def homogenous(self):
111-
"""
112-
Return True if all the arguments are pyformat
113-
args and have the same number of arguments.
115+
"""Check arguments of the expression to be homogeneous.
116+
117+
:rtype: bool
118+
:return: True if all the arguments of the expression are in pyformat
119+
and each has the same length, False otherwise.
114120
"""
115121
if not self._is_equal_length():
116122
return False
@@ -126,8 +132,10 @@ def homogenous(self):
126132
return True
127133

128134
def _is_equal_length(self):
129-
"""
130-
Return False if all the arguments have the same length.
135+
"""Return False if all the arguments have the same length.
136+
137+
:rtype: bool
138+
:return: False if the sequences of the arguments have the same length.
131139
"""
132140
if len(self) == 0:
133141
return True
@@ -141,6 +149,12 @@ def _is_equal_length(self):
141149

142150

143151
class values(a_args):
152+
"""A wrapper for values.
153+
154+
:rtype: str
155+
:returns: A string of the values expression in a tree view.
156< F438 /code>+
"""
157+
144158
def __str__(self):
145159
return "VALUES%s" % super().__str__()
146160

@@ -153,6 +167,21 @@ def parse_values(stmt):
153167

154168

155169
def expect(word, token):
170+
"""Parse the given expression recursively.
171+
172+
:type word: str
173+
:param word: A string expression.
174+
175+
:type token: str
176+
:param token: An expression token.
177+
178+
:rtype: `Tuple(str, Any)`
179+
:returns: A tuple containing the rest of the expression string and the
180+
parse tree for the part of the expression that has already been
181+
parsed.
182+
183+
:raises :class:`ProgrammingError`: If there is a parsing error.
184+
"""
156185
word = word.strip()
157186
if token == VALUES:
158187
if not word.startswith("VALUES"):
@@ -242,5 +271,13 @@ def expect(word, token):
242271

243272

244273
def as_values(values_stmt):
274+
"""Return the parsed values.
275+
276+
:type values_stmt: str
277+
:param values_stmt: Raw values.
278+
279+
:rtype: Any
280+
:returns: A tree of the already parsed expression.
281+
"""
245282
_, _values = parse_values(values_stmt)
246283
return _values

google/cloud/spanner_dbapi/utils.py

Lines changed: 31 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,13 @@
1919

2020
class PeekIterator:
2121
"""
22-
PeekIterator peeks at the first element out of an iterator
23-
for the sake of operations like auto-population of fields on reading
24-
the first element.
25-
If next's result is an instance of list, it'll be converted into a tuple
26-
to conform with DBAPI v2's sequence expectations.
22+
Peek at the first element out of an iterator for the sake of operations
23+
like auto-population of fields on reading the first element.
24+
If next's result is an instance of list, it'll be converted into a tuple to
25+
conform with DBAPI v2's sequence expectations.
26+
27+
:type source: list
28+
:param source: A list of source for the Iterator.
2729
"""
2830

2931
def __init__(self, source):
@@ -97,6 +99,15 @@ def __iter__(self):
9799

98100

99101
def backtick_unicode(sql):
102+
"""Check the SQL to be valid and split it by segments.
103+
104+
:type sql: str
105+
:param sql: A SQL request.
106+
107+
:rtype: str
108+
:returns: A SQL parsed by segments in unicode if initial SQL is valid,
109+
initial string otherwise.
110+
"""
100111
matches = list(re_UNICODE_POINTS.finditer(sql))
101112
if not matches:
102113
return sql
@@ -117,11 +128,20 @@ def backtick_unicode(sql):
117128

118129

119130
def sanitize_literals_for_upload(s):
120-
"""
121-
Convert literals in s, to be fit for consumption by Cloud Spanner.
122-
1. Convert %% (escaped percent literals) to %. Percent signs must be escaped when
123-
values like %s are used as SQL parameter placeholders but Spanner's query language
124-
uses placeholders like @a0 and doesn't expect percent signs to be escaped.
125-
2. Quote words containing non-ASCII, with backticks, for example föö to `föö`.
131+
"""Convert literals in s, to be fit for consumption by Cloud Spanner.
132+
133+
* Convert %% (escaped percent literals) to %. Percent signs must be escaped
134+
when values like %s are used as SQL parameter placeholders but Spanner's
135+
query language uses placeholders like @a0 and doesn't expect percent
136+
signs to be escaped.
137+
* Quote words containing non-ASCII, with backticks, for example föö to
138+
`föö`.
139+
140+
:type s: str
141+
:param s: A string with literals to escaped for consumption by Cloud
142+
Spanner.
143+
144+
:rtype: str
145+
:returns: A sanitized string for uploading.
126146
"""
127147
return backtick_unicode(s.replace("%%", "%"))

0 commit comments

Comments
 (0)
0