Skip to content

feat: adding missing docstrings for functions & classes #549

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 60 commits into from
Closed
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
11222db
feat: release 2.2a0 (#457)
larkee May 26, 2020
5551b58
feat: [WIP] The first stage of `nox` implementation (#468)
mf2199 Aug 25, 2020
bfde221
feat: refactor connect() function, cover it with unit tests (#462)
Aug 27, 2020
e017901
feat: Stage 2 of `nox` implementation - adding `docs` target (#473)
mf2199 Aug 29, 2020
144bdc2
fix: Fix black, isort compatibility (#469)
c24t Aug 31, 2020
7a1f6a6
feat: Stage 3-4 of `nox` implementation - adding auto-format targets …
mf2199 Aug 31, 2020
acd9209
feat: Stage 5 of `nox` implementation - adding coverage targets (#479)
mf2199 Aug 31, 2020
6028f88
feat: cursor must detect if the parent connection is closed (#463)
Sep 1, 2020
94ba284
feat: Stage 6 of `nox` implementation - enabling system tests (#480)
mf2199 Sep 8, 2020
59eb432
chore: Code refactoring to follow common Google API scheme - Stage I …
mf2199 Sep 14, 2020
048566c
chore: release 2.2a1 (#499)
c24t Sep 15, 2020
f5719f8
Merge branch 'master' of https://github.com/googleapis/python-spanner…
Sep 15, 2020
2c0c0a2
fix: Couple of tests are permanently broken while running locally
tina80lvl Sep 21, 2020
05bf7dc
fix: offset for current timezone
tina80lvl Sep 22, 2020
31185df
clean: whitespace
tina80lvl Sep 22, 2020
bd605a5
fix: localtime->gmtime
tina80lvl Sep 25, 2020
23f87ad
fix: gmtime->localtime
tina80lvl Sep 25, 2020
216a92b
refactor
tina80lvl Sep 30, 2020
3b34162
docs: utils.py
tina80lvl Sep 29, 2020
d5ba00c
docs: version.py`
tina80lvl Sep 29, 2020
ccfb6ce
refactor
tina80lvl Sep 30, 2020
9526cc2
Merge pull request #5 from q-logic/fix-472
mf2199 Sep 30, 2020
a921666
Merge remote-tracking branch 'upstream/master'
mf2199 Sep 30, 2020
60fd3fb
docs: parser.py
tina80lvl Oct 1, 2020
d86e8a1
refactor
tina80lvl Oct 1, 2020
325abb9
docs: parse_utils.py
tina80lvl Oct 1, 2020
539b3dd
docs: cursor.py
tina80lvl Oct 1, 2020
5ce0fa9
docs: connection.py
tina80lvl Oct 1, 2020
a9eb4a6
refactor
tina80lvl Oct 1, 2020
bbb3378
conflict
tina80lvl Oct 1, 2020
f364372
corrections
tina80lvl Oct 5, 2020
a703d5c
refactoring
tina80lvl Oct 5, 2020
f94dc9c
fixes
tina80lvl Oct 6, 2020
ec1aeca
conflicts
tina80lvl Oct 6, 2020
29801d9
cc
tina80lvl Oct 6, 2020
28a7faa
imperative
tina80lvl Oct 6, 2020
0d47d9a
merge origin
tina80lvl Oct 8, 2020
717cd4e
fixes
tina80lvl Oct 8, 2020
466e037
conflicts
tina80lvl Oct 8, 2020
8dabb7b
pull
tina80lvl Oct 12, 2020
6437b70
refactor
tina80lvl Oct 12, 2020
8e26153
fixes
tina80lvl Oct 12, 2020
f41acd5
review fixes
tina80lvl Oct 19, 2020
17eaefa
cleanup
tina80lvl Oct 21, 2020
a71ca06
review fix
tina80lvl Oct 21, 2020
a1ecbec
cc
tina80lvl Oct 22, 2020
b701555
draft test
tina80lvl Oct 27, 2020
50570db
resolving conflicts
tina80lvl Oct 29, 2020
a1ad37d
refactor
tina80lvl Oct 29, 2020
3c3572b
revert test
tina80lvl Oct 29, 2020
dc43995
missing parse_values added
tina80lvl Oct 29, 2020
b829809
review fixes
tina80lvl Nov 2, 2020
c6d924b
fixed suggections
tina80lvl Nov 8, 2020
0806ab8
Merge branch 'master' into docstr-1
mf2199 Nov 8, 2020
9e1be73
Merge branch 'master' into docstr-1
c24t Nov 12, 2020
9aa0c63
Rewrap a few docstrings
c24t Nov 12, 2020
467cdaa
merge
tina80lvl Nov 23, 2020
c4857a4
fixed conflicts
tina80lvl Nov 23, 2020
e04627c
merge fetch
tina80lvl Nov 23, 2020
9f286fb
delete google/cloud/spanner_dbapi
tina80lvl Dec 7, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions google/cloud/spanner_dbapi/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,11 +250,14 @@ def connect(
"""

client_info = ClientInfo(
user_agent=user_agent or DEFAULT_USER_AGENT, python_version=PY_VERSION,
user_agent=user_agent or DEFAULT_USER_AGENT,
python_version=PY_VERSION,
)

client = spanner.Client(
project=project, credentials=credentials, client_info=client_info,
project=project,
credentials=credentials,
client_info=client_info,
)

instance = client.instance(instance_id)
Expand Down
14 changes: 13 additions & 1 deletion google/cloud/spanner_dbapi/cursor.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,9 @@ def description(self):
- ``precision``
- ``scale``
- ``null_ok``

:rtype: tuple
:returns: A tuple of columns' information.
"""
if not (self._result_set and self._result_set.metadata):
return None
Expand All @@ -93,7 +96,11 @@ def description(self):

@property
def rowcount(self):
"""The number of rows produced by the last `.execute()`."""
"""The number of rows produced by the last ``.execute()``.

:rtype: int
:returns: The number of rows produced by the last ``.execute*()``.
"""
return self._row_count

def _raise_if_closed(self):
Expand Down Expand Up @@ -301,6 +308,11 @@ def __iter__(self):
return self._itr

def list_tables(self):
"""List the tables of the linked Database.

:rtype: list
:returns: The list of tables within the Database.
"""
return self.run_sql_in_snapshot(_helpers.SQL_LIST_TABLES)

def run_sql_in_snapshot(self, sql, params=None, param_types=None):
Expand Down
55 changes: 45 additions & 10 deletions google/cloud/spanner_dbapi/parse_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,11 +168,11 @@
def classify_stmt(query):
"""Determine SQL query type.

:type query: :class:`str`
:param query: SQL query.
:type query: str
:param query: A SQL query.

:rtype: :class:`str`
:returns: Query type name.
:rtype: str
:returns: The query type name.
"""
if RE_DDL.match(query):
return STMT_DDL
Expand Down Expand Up @@ -245,6 +245,17 @@ def parse_insert(insert_sql, params):
('INSERT INTO T (f1, f2) VALUES (UPPER(%s), %s)', ('c', 'd',))
],
}

:type insert_sql: str
:param insert_sql: A SQL insert request.

:type params: list
:param params: A list of parameters.

:rtype: dict
:returns: A dictionary that maps `sql_params_list` to the list of
parameters in cases a), b), d) or the dictionary with
information about the resulting table in case c).
""" # noqa
match = RE_INSERT.search(insert_sql)

Expand Down Expand Up @@ -341,6 +352,15 @@ def rows_for_insert_or_update(columns, params, pyformat_args=None):

We'll have to convert both params types into:
Params: [(1, 2, 3,), (4, 5, 6,), (7, 8, 9,)]

:type columns: list
:param columns: A list of the columns of the table.

:type params: list
:param params: A list of parameters.

:rtype: list
:returns: A properly restructured list of the parameters.
""" # noqa

if not pyformat_args:
Expand Down Expand Up @@ -438,6 +458,15 @@ def sql_pyformat_args_to_spanner(sql, params):
becomes:
SQL: 'SELECT * from t where f1=@a0, f2=@a1, f3=@a2'
Params: {'a0': 'a', 'a1': 23, 'a2': '888***'}

:type sql: str
:param sql: A SQL request.

:type params: list
:param params: A list of parameters.

:rtype: tuple(str, dict)
:returns: A tuple of the sanitized SQL and a dictionary of the named arguments.
"""
if not params:
return sanitize_literals_for_upload(sql), params
Expand Down Expand Up @@ -481,10 +510,10 @@ def cast_for_spanner(value):
"""Convert the param to its Cloud Spanner equivalent type.

:type value: Any
:param value: Value to convert to a Cloud Spanner type.
:param value: The value to convert to a Cloud Spanner type.

:rtype: Any
:returns: Value converted to a Cloud Spanner type.
:returns: The value converted to a Cloud Spanner type.
"""
if isinstance(value, decimal.Decimal):
return float(value)
Expand All @@ -494,10 +523,10 @@ def cast_for_spanner(value):
def get_param_types(params):
"""Determine Cloud Spanner types for the given parameters.

:type params: :class:`dict`
:type params: dict
:param params: Parameters requiring to find Cloud Spanner types.

:rtype: :class:`dict`
:rtype: dict
:returns: The types index for the given parameters.
"""
if params is None:
Expand All @@ -517,6 +546,12 @@ def ensure_where_clause(sql):
"""
Cloud Spanner requires a WHERE clause on UPDATE and DELETE statements.
Add a dummy WHERE clause if necessary.

:type sql: str
:param sql: A SQL statement.

:rtype: str
:returns: A SQL request with dummy WHERE clause if necessary.
"""
if any(
isinstance(token, sqlparse.sql.Where)
Expand All @@ -532,10 +567,10 @@ def escape_name(name):
' ', or is a Cloud Spanner's reserved keyword.

:type name: :class:`str`
:param name: Name to escape.
:param name: The name to escape.

:rtype: :class:`str`
:returns: Name escaped if it has to be escaped.
:returns: The name escaped if it has to be escaped.
"""
if "-" in name or " " in name or name.upper() in SPANNER_RESERVED_KEYWORDS:
return "`" + name + "`"
Expand Down
52 changes: 44 additions & 8 deletions google/cloud/spanner_dbapi/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,18 @@ def __len__(self):


class terminal(str):
"""
terminal represents the unit symbol that can be part of a SQL values clause.
"""
"""Represent the unit symbol that can be part of a SQL values clause."""

pass


class a_args(object):
"""Expression arguments.

:type argv: list
:param argv: A List of expression arguments.
"""

def __init__(self, argv):
self.argv = argv

Expand Down Expand Up @@ -102,9 +106,11 @@ def __getitem__(self, index):
return self.argv[index]

def homogenous(self):
"""
Return True if all the arguments are pyformat
args and have the same number of arguments.
"""Check arguments of the expression to be homogeneous.

:rtype: bool
:return: True if all the arguments of the expression are in pyformat
and each has the same length, False otherwise.
"""
if not self._is_equal_length():
return False
Expand All @@ -120,8 +126,10 @@ def homogenous(self):
return True

def _is_equal_length(self):
"""
Return False if all the arguments have the same length.
"""Return False if all the arguments have the same length.

:rtype: bool
:return: False if the sequences of the arguments have the same length.
"""
if len(self) == 0:
return True
Expand All @@ -135,6 +143,12 @@ def _is_equal_length(self):


class values(a_args):
"""A wrapper for values.

:rtype: str
:returns: A string of the values expression in a tree view.
"""

def __str__(self):
return "VALUES%s" % super().__str__()

Expand All @@ -147,6 +161,20 @@ def parse_values(stmt):


def expect(word, token):
"""Parse the given expression recursively.

:type word: str
:param word: A string expression.

:type token: str
:param token: An expression token.

:rtype: `Tuple(str, Any)`
:returns: A tuple containing the rest of the expression string and the
parse tree for the part of the expression that has already been
parsed.
:raises :class:`ProgrammingError`: If there is a parsing error.
"""
word = word.strip()
if token == VALUES:
if not word.startswith("VALUES"):
Expand Down Expand Up @@ -242,5 +270,13 @@ def expect(word, token):


def as_values(values_stmt):
"""Return the parsed values.

:type values_stmt: str
:param values_stmt: Raw values.

:rtype: Any
:returns: A tree of the already parsed expression.
"""
_, _values = parse_values(values_stmt)
return _values
39 changes: 30 additions & 9 deletions google/cloud/spanner_dbapi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@

class PeekIterator:
"""
PeekIterator peeks at the first element out of an iterator
for the sake of operations like auto-population of fields on reading
the first element.
Peek at the first element out of an iterator for the sake of operations
like auto-population of fields on reading the first element.
If next's result is an instance of list, it'll be converted into a tuple
to conform with DBAPI v2's sequence expectations.

:type source: list
:param source: A list of source for the Iterator.
"""

def __init__(self, source):
Expand Down Expand Up @@ -51,6 +53,15 @@ def __iter__(self):


def backtick_unicode(sql):
"""Check the SQL to be valid and split it by segments.

:type sql: str
:param sql: A SQL request.

:rtype: str
:returns: A SQL parsed by segments in unicode if initial
SQL is valid, initial string otherwise.
"""
matches = list(re_UNICODE_POINTS.finditer(sql))
if not matches:
return sql
Expand All @@ -71,11 +82,21 @@ def backtick_unicode(sql):


def sanitize_literals_for_upload(s):
"""
Convert literals in s, to be fit for consumption by Cloud Spanner.
1. Convert %% (escaped percent literals) to %. Percent signs must be escaped when
values like %s are used as SQL parameter placeholders but Spanner's query language
uses placeholders like @a0 and doesn't expect percent signs to be escaped.
2. Quote words containing non-ASCII, with backticks, for example föö to `föö`.
"""Convert literals in s, to be fit for consumption by Cloud Spanner.

* Convert %% (escaped percent literals) to %. Percent signs must be escaped
when values like %s are used as SQL parameter placeholders but Spanner's
query language uses placeholders like @a0 and doesn't expect percent
signs to be escaped.

* Quote words containing non-ASCII, with backticks, for example föö to
`föö`.

:type s: str
:param s: A string with literals to escaped for consumption by Cloud
Spanner.

:rtype: str
:returns: A sanitized string for uploading.
"""
return backtick_unicode(s.replace("%%", "%"))