From d3e14f6b87d4e914d56bded97d33be34cc1f997d Mon Sep 17 00:00:00 2001 From: Anthony Tuininga Date: Wed, 28 Sep 2022 09:08:54 -0600 Subject: [PATCH] Corrected and enhanced type checking issues (#52, #54, #60). --- doc/src/release_notes.rst | 6 +++++ src/oracledb/aq.py | 24 +++++++++--------- src/oracledb/connect_params.py | 4 +-- src/oracledb/connection.py | 8 +++--- src/oracledb/cursor.py | 8 +++--- src/oracledb/dbobject.py | 10 ++++---- src/oracledb/pool.py | 6 ++--- src/oracledb/pool_params.py | 2 +- src/oracledb/soda.py | 41 ++++++++++++++++--------------- src/oracledb/subscr.py | 35 +++++++++++++------------- utils/templates/connect_params.py | 4 +-- utils/templates/connection.py | 8 +++--- utils/templates/pool.py | 6 ++--- utils/templates/pool_params.py | 2 +- 14 files changed, 86 insertions(+), 78 deletions(-) diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index 56dae8d..abd700e 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -25,6 +25,12 @@ Thick Mode Changes Common Changes ++++++++++++++ +#) Fixed type checking errors + (`issue 52 `__). +#) Enhanced type checking + (`issue 54 `__), + (`issue 60 `__). + oracledb 1.1.0 (September 2022) ------------------------------- diff --git a/src/oracledb/aq.py b/src/oracledb/aq.py index 3971b87..b0e2bb9 100644 --- a/src/oracledb/aq.py +++ b/src/oracledb/aq.py @@ -32,7 +32,7 @@ import datetime from . import connection as connection_module -from typing import Type, Union +from typing import Union, List from . import errors, exceptions from .dbobject import DbObject, DbObjectType @@ -48,7 +48,7 @@ class Queue: queue._impl = impl return queue - def _verify_message(self, message: Type["MessageProperties"]) -> None: + def _verify_message(self, message: "MessageProperties") -> None: """ Internal method used for verifying a message. """ @@ -58,7 +58,7 @@ class Queue: errors._raise_err(errors.ERR_MESSAGE_HAS_NO_PAYLOAD) @property - def connection(self) -> Type["connection_module.Connection"]: + def connection(self) -> "connection_module.Connection": """ Returns the connection on which the queue was created. """ @@ -72,13 +72,13 @@ class Queue: message_impls = self._impl.deq_many(max_num_messages) return [MessageProperties._from_impl(impl) for impl in message_impls] - def deqMany(self, max_num_messages: int) -> list: + def deqMany(self, max_num_messages: int) -> List["MessageProperties"]: """ Deprecated: use deqmany() instead. """ return self.deqmany(max_num_messages) - def deqone(self) -> Union[Type["MessageProperties"], None]: + def deqone(self) -> Union["MessageProperties", None]: """ Dequeues at most one message from the queue and returns it. If no message is dequeued, None is returned. @@ -87,14 +87,14 @@ class Queue: if message_impl is not None: return MessageProperties._from_impl(message_impl) - def deqOne(self) -> Union[Type["MessageProperties"], None]: + def deqOne(self) -> Union["MessageProperties", None]: """ Deprecated: use deqone() instead. """ return self.deqone() @property - def deqoptions(self) -> Type["DeqOptions"]: + def deqoptions(self) -> "DeqOptions": """ Returns the options that will be used when dequeuing messages from the queue. @@ -102,7 +102,7 @@ class Queue: return self._deq_options @property - def deqOptions(self) -> Type["DeqOptions"]: + def deqOptions(self) -> "DeqOptions": """ Deprecated: use deqoptions instead. """ @@ -131,7 +131,7 @@ class Queue: """ return self.enqmany(messages) - def enqone(self, message: Type["MessageProperties"]) -> None: + def enqone(self, message: "MessageProperties") -> None: """ Enqueues a single message into the queue. The message must be a message property object which has had its payload attribute set to a value that @@ -140,14 +140,14 @@ class Queue: self._verify_message(message) self._impl.enq_one(message._impl) - def enqOne(self, message: Type["MessageProperties"]) -> None: + def enqOne(self, message: "MessageProperties") -> None: """ Deprecated: use enqone() instead. """ return self.enqone(message) @property - def enqoptions(self) -> Type["EnqOptions"]: + def enqoptions(self) -> "EnqOptions": """ Returns the options that will be used when enqueuing messages into the queue. @@ -155,7 +155,7 @@ class Queue: return self._enq_options @property - def enqOptions(self) -> Type["EnqOptions"]: + def enqOptions(self) -> "EnqOptions": """ Deprecated: use enqoptions() instead. """ diff --git a/src/oracledb/connect_params.py b/src/oracledb/connect_params.py index 347d617..0018079 100644 --- a/src/oracledb/connect_params.py +++ b/src/oracledb/connect_params.py @@ -34,7 +34,7 @@ #------------------------------------------------------------------------------ import functools -from typing import Type, Union, Callable +from typing import Union, Callable import oracledb @@ -575,7 +575,7 @@ class ConnectParams: """ return self._impl.wallet_location - def copy(self) -> Type["ConnectParams"]: + def copy(self) -> "ConnectParams": """ Creates a copy of the parameters and returns it. """ diff --git a/src/oracledb/connection.py b/src/oracledb/connection.py index 86e7f2d..8f13f35 100644 --- a/src/oracledb/connection.py +++ b/src/oracledb/connection.py @@ -64,7 +64,7 @@ class Connection: def __init__(self, dsn: str=None, *, - pool: Type["pool_module.ConnectionPool"]=None, + pool: "pool_module.ConnectionPool"=None, params: ConnectParams=None, **kwargs) -> None: """ @@ -603,7 +603,7 @@ class Connection: """ return self.tpc_prepare() - def queue(self, name: str, payload_type: [DbObjectType, str]=None, *, + def queue(self, name: str, payload_type: Union[DbObjectType, str]=None, *, payloadType: DbObjectType=None) -> Queue: """ Creates and returns a queue which is used to enqueue and dequeue @@ -1001,7 +1001,7 @@ def _connection_factory(f): """ @functools.wraps(f) def connect(dsn: str=None, *, - pool: Type["pool_module.ConnectionPool"]=None, + pool: "pool_module.ConnectionPool"=None, conn_class: Type[Connection]=Connection, params: ConnectParams=None, **kwargs) -> Connection: @@ -1014,7 +1014,7 @@ def _connection_factory(f): @_connection_factory def connect(dsn: str=None, *, - pool: Type["pool_module.ConnectionPool"]=None, + pool: "pool_module.ConnectionPool"=None, conn_class: Type[Connection]=Connection, params: ConnectParams=None, user: str=None, diff --git a/src/oracledb/cursor.py b/src/oracledb/cursor.py index 886615c..d172dfe 100644 --- a/src/oracledb/cursor.py +++ b/src/oracledb/cursor.py @@ -29,7 +29,7 @@ # fetching results from queries. #------------------------------------------------------------------------------ -from typing import Any, Type, Union, Callable +from typing import Any, Union, Callable from . import __name__ as MODULE_NAME from . import errors, exceptions @@ -42,7 +42,7 @@ from .dbobject import DbObjectType class Cursor: __module__ = MODULE_NAME - def __init__(self, connection: Type["connection_module.Connection"], + def __init__(self, connection: "connection_module.Connection", scrollable: bool = False) -> None: self._impl = None self.connection = connection @@ -309,7 +309,7 @@ class Cursor: def execute(self, statement: Union[str, None], parameters: Union[list, tuple, dict]=None, - **keyword_parameters: dict) -> Union[Type["Cursor"], None]: + **keyword_parameters: dict) -> Union["Cursor", None]: """ Execute a statement against the database. @@ -739,7 +739,7 @@ class Cursor: encoding_errors: str=None, bypass_decode: bool=False, *, - encodingErrors: str=None) -> Type["Var"]: + encodingErrors: str=None) -> "Var": """ Create a variable with the specified characteristics. This method was designed for use with PL/SQL in/out variables where the length or type diff --git a/src/oracledb/dbobject.py b/src/oracledb/dbobject.py index 3d6f5b2..03a7600 100644 --- a/src/oracledb/dbobject.py +++ b/src/oracledb/dbobject.py @@ -29,7 +29,7 @@ # object type metadata: DbObject, DbObjectType and DbObjectAttr. #------------------------------------------------------------------------------ -from typing import Sequence, Type, Union +from typing import Sequence, Union from . import __name__ as MODULE_NAME from .base_impl import DbType @@ -91,7 +91,7 @@ class DbObject: ix = self._impl.get_next_index(ix) return result - def copy(self) -> Type["DbObject"]: + def copy(self) -> "DbObject": """ Create a copy of the object and return it. """ @@ -181,7 +181,7 @@ class DbObject: self._impl.trim(num) @property - def type(self) -> Type["DbObjectType"]: + def type(self) -> "DbObjectType": """ Returns an ObjectType corresponding to the type of the object. """ @@ -211,7 +211,7 @@ class DbObjectAttr: return self._impl.name @property - def type(self) -> Union[Type["DbObjectType"], DbType]: + def type(self) -> Union["DbObjectType", DbType]: """ This read-only attribute returns the type of the attribute. This will be an Oracle Object Type if the variable binds Oracle objects; @@ -274,7 +274,7 @@ class DbObjectType: return self._impl.name @property - def element_type(self) -> Union[Type["DbObjectType"], DbType]: + def element_type(self) -> Union["DbObjectType", DbType]: """ This read-only attribute returns the type of elements found in collections of this type, if iscollection is True; otherwise, it diff --git a/src/oracledb/pool.py b/src/oracledb/pool.py index 5e7f48b..b034f09 100644 --- a/src/oracledb/pool.py +++ b/src/oracledb/pool.py @@ -120,7 +120,7 @@ class ConnectionPool: tag: str=None, matchanytag: bool=False, shardingkey: list=None, - supershardingkey: list=None) -> Type["connection_module.Connection"]: + supershardingkey: list=None) -> "connection_module.Connection": """ Acquire a connection from the pool and return it. @@ -177,7 +177,7 @@ class ConnectionPool: self._impl.close(force) self._impl = None - def drop(self, connection: Type["connection_module.Connection"]) -> None: + def drop(self, connection: "connection_module.Connection") -> None: """ Drop the connection from the pool, which is useful if the connection is no longer usable (such as when the database session is killed). @@ -322,7 +322,7 @@ class ConnectionPool: def ping_interval(self, value: int) -> None: self._impl.set_ping_interval(value) - def release(self, connection: Type["connection_module.Connection"], + def release(self, connection: "connection_module.Connection", tag: str=None) -> None: """ Release the connection back to the pool now, rather than whenever diff --git a/src/oracledb/pool_params.py b/src/oracledb/pool_params.py index b714aab..f3d17dc 100644 --- a/src/oracledb/pool_params.py +++ b/src/oracledb/pool_params.py @@ -468,7 +468,7 @@ class PoolParams(ConnectParams): """ return self._impl.wait_timeout - def copy(self) -> Type["PoolParams"]: + def copy(self) -> "PoolParams": """ Creates a copy of the parameters and returns it. """ diff --git a/src/oracledb/soda.py b/src/oracledb/soda.py index 906ebb3..b3ac9e6 100644 --- a/src/oracledb/soda.py +++ b/src/oracledb/soda.py @@ -29,7 +29,7 @@ # SodaDatabase, SodaCollection, SodaDocument, SodaDocCursor and SodaOperation. #------------------------------------------------------------------------------ -from typing import Type, Union +from typing import Union, List import json from . import connection @@ -58,7 +58,7 @@ class SodaDatabase: return json.dumps(content).encode() def createCollection(self, name: str, metadata: Union[str, dict]=None, - mapMode: bool=False) -> Type["SodaCollection"]: + mapMode: bool=False) -> "SodaCollection": """ Creates a SODA collection with the given name and returns a new SODA collection object. If you try to create a collection, and a collection @@ -85,7 +85,7 @@ class SodaDatabase: return SodaCollection._from_impl(self, collection_impl) def createDocument(self, content: object, key: str=None, - mediaType: str="application/json") -> Type["SodaDocument"]: + mediaType: str="application/json") -> "SodaDocument": """ Creates a SODA document usable for SODA write operations. You only need to use this method if your collection requires client-assigned keys or @@ -112,7 +112,8 @@ class SodaDatabase: doc_impl = self._impl.create_document(content_bytes, key, mediaType) return SodaDocument._from_impl(doc_impl) - def getCollectionNames(self, startName: str=None, limit: int=0) -> list: + def getCollectionNames(self, startName: str=None, + limit: int=0) -> List[str]: """ Returns a list of the names of collections in the database that match the criteria, in alphabetical order. @@ -126,7 +127,7 @@ class SodaDatabase: """ return self._impl.get_collection_names(startName, limit) - def openCollection(self, name: str) -> Type["SodaCollection"]: + def openCollection(self, name: str) -> "SodaCollection": """ Opens an existing collection with the given name and returns a new SODA collection object. If a collection with that name does not exist, None @@ -191,7 +192,7 @@ class SodaCollection: """ return self._impl.drop_index(name, force) - def find(self) -> Type["SodaOperation"]: + def find(self) -> "SodaOperation": """ This method is used to begin an operation that will act upon documents in the collection. It creates and returns a SodaOperation object which @@ -200,7 +201,7 @@ class SodaCollection: """ return SodaOperation(self) - def getDataGuide(self) -> Type["SodaDocument"]: + def getDataGuide(self) -> "SodaDocument": """ Returns a SODA document object containing property names, data types and lengths inferred from the JSON documents in the collection. It can @@ -253,7 +254,7 @@ class SodaCollection: self._impl.insert_one(doc_impl, hint=None, return_doc=False) def insertOneAndGet(self, doc: object, - hint: str=None) -> Type["SodaDocument"]: + hint: str=None) -> "SodaDocument": """ Similarly to insertOne() this method inserts a given document into the collection. The only difference is that it returns a SODA Document @@ -300,7 +301,7 @@ class SodaCollection: doc_impl = self._process_doc_arg(doc) self._impl.save(doc_impl, hint=None, return_doc=False) - def saveAndGet(self, doc: object, hint: str=None) -> Type["SodaDocument"]: + def saveAndGet(self, doc: object, hint: str=None) -> "SodaDocument": """ Saves a document into the collection. This method is equivalent to insertOneAndGet() except that if client-assigned keys are used, and the @@ -461,7 +462,7 @@ class SodaOperation: """ return self._collection._impl.get_count(self) - def fetchArraySize(self, value: int) -> Type["SodaOperation"]: + def fetchArraySize(self, value: int) -> "SodaOperation": """ This is a tuning method to specify the number of documents that are internally fetched in batches by calls to getCursor() and @@ -480,7 +481,7 @@ class SodaOperation: self._fetch_array_size = value return self - def filter(self, value: Union[dict, str]) -> Type["SodaOperation"]: + def filter(self, value: Union[dict, str]) -> "SodaOperation": """ Sets a filter specification for complex document queries and ordering of JSON documents. Filter specifications must be provided as a @@ -499,7 +500,7 @@ class SodaOperation: raise TypeError("expecting string or dictionary") return self - def getCursor(self) -> Type["SodaDocCursor"]: + def getCursor(self) -> "SodaDocCursor": """ Returns a SodaDocCursor object that can be used to iterate over the documents that match the criteria. @@ -513,7 +514,7 @@ class SodaOperation: """ return [d for d in self.getCursor()] - def getOne(self) -> Union[Type["SodaDocument"], None]: + def getOne(self) -> Union["SodaDocument", None]: """ Returns a single SodaDocument object that matches the criteria. Note that if multiple documents match the criteria only the first one is @@ -523,7 +524,7 @@ class SodaOperation: if doc_impl is not None: return SodaDocument._from_impl(doc_impl) - def hint(self, value: str) -> Type["SodaOperation"]: + def hint(self, value: str) -> "SodaOperation": """ Specifies a hint that will be provided to the SODA operation when it is performed. This is expected to be a string in the same format as SQL @@ -541,7 +542,7 @@ class SodaOperation: self._hint = value return self - def key(self, value: str) -> Type["SodaOperation"]: + def key(self, value: str) -> "SodaOperation": """ Specifies that the document with the specified key should be returned. This causes any previous calls made to this method and keys() to be @@ -556,7 +557,7 @@ class SodaOperation: self._keys = None return self - def keys(self, value: list) -> Type["SodaOperation"]: + def keys(self, value: list) -> "SodaOperation": """ Specifies that documents that match the keys found in the supplied sequence should be returned. This causes any previous calls made to @@ -573,7 +574,7 @@ class SodaOperation: self._key = None return self - def limit(self, value: int) -> Type["SodaOperation"]: + def limit(self, value: int) -> "SodaOperation": """ Specifies that only the specified number of documents should be returned. This method is only usable for read operations such as @@ -609,7 +610,7 @@ class SodaOperation: return self._collection._impl.replace_one(self, doc_impl, return_doc=False) - def replaceOneAndGet(self, doc: object) -> Type["SodaDocument"]: + def replaceOneAndGet(self, doc: object) -> "SodaDocument": """ Similarly to replaceOne(), this method replaces a single document in the collection with the specified document. The only difference is that @@ -621,7 +622,7 @@ class SodaOperation: return_doc=True) return SodaDocument._from_impl(return_doc_impl) - def skip(self, value: int) -> Type["SodaOperation"]: + def skip(self, value: int) -> "SodaOperation": """ Specifies the number of documents that match the other criteria that will be skipped. This method is only usable for read operations such as @@ -636,7 +637,7 @@ class SodaOperation: self._skip = value return self - def version(self, value: str) -> Type["SodaOperation"]: + def version(self, value: str) -> "SodaOperation": """ Specifies that documents with the specified version should be returned. Typically this is used with key() to implement optimistic locking, so diff --git a/src/oracledb/subscr.py b/src/oracledb/subscr.py index af562b5..ad1e7c8 100644 --- a/src/oracledb/subscr.py +++ b/src/oracledb/subscr.py @@ -30,7 +30,7 @@ # events are detected. #------------------------------------------------------------------------------ -from typing import Callable, Type, Union +from typing import Callable, Union, List from . import connection class Subscription: @@ -53,7 +53,7 @@ class Subscription: return self._impl.callback @property - def connection(self) -> Type["connection.Connection"]: + def connection(self) -> "connection.Connection": """ Returns the connection that was used to register the subscription when it was created. @@ -172,7 +172,7 @@ class Message: @property - def consumer_name(self) -> str: + def consumer_name(self) -> Union[str, None]: """ Returns the name of the consumer which generated the notification. It will be populated if the subscription was created with the namespace @@ -181,28 +181,29 @@ class Message: return self._consumer_name @property - def consumerName(self) -> str: + def consumerName(self) -> Union[str, None]: """ Deprecated. Use property consumer_name instead. """ return self.consumer_name @property - def dbname(self) -> str: + def dbname(self) -> Union[str, None]: """ Returns the name of the database that generated the notification. """ return self._db_name @property - def msgid(self) -> bytes: + def msgid(self) -> Union[bytes, None]: """ - Returns the message id of the AQ message that generated the notification. + Returns the message id of the AQ message that generated the + notification. """ return self._msgid @property - def queries(self) -> list: + def queries(self) -> List["MessageQuery"]: """ Returns a list of message query objects that give information about query result sets changed for this notification. This attribute will be @@ -212,7 +213,7 @@ class Message: return self._queries @property - def queue_name(self) -> str: + def queue_name(self) -> Union[str, None]: """ Returns the name of the queue which generated the notification. It will only be populated if the subscription was created with the namespace @@ -221,7 +222,7 @@ class Message: return self._queue_name @property - def queueName(self) -> str: + def queueName(self) -> Union[str, None]: """ Deprecated. Use property queue_name instead. """ @@ -247,7 +248,7 @@ class Message: return self._subscription @property - def tables(self) -> list: + def tables(self) -> List["MessageTable"]: """ Returns a list of message table objects that give information about the tables changed for this notification. This attribute will be an empty @@ -257,14 +258,14 @@ class Message: return self._tables @property - def txid(self) -> bytes: + def txid(self) -> Union[bytes, None]: """ Returns the id of the transaction that generated the notification. """ return self._txid @property - def type(self) -> str: + def type(self) -> int: """ Returns the type of message that has been sent. """ @@ -297,7 +298,7 @@ class MessageQuery: return self._operation @property - def tables(self) -> list: + def tables(self) -> List["MessageTable"]: """ Returns a list of message table objects that give information about the table changes that caused the query result set to change for this @@ -320,7 +321,7 @@ class MessageRow: return self._operation @property - def rowid(self) -> str: + def rowid(self) -> Union[str, None]: """ Returns the rowid of the row that was changed. """ @@ -335,7 +336,7 @@ class MessageTable: self._rows = [] @property - def name(self) -> str: + def name(self) -> Union[str, None]: """ Returns the name of the table that was changed. """ @@ -349,7 +350,7 @@ class MessageTable: return self._operation @property - def rows(self) -> list: + def rows(self) -> List["MessageRow"]: """ Returns a list of message row objects that give information about the rows changed on the table. This value is only filled in if the qos diff --git a/utils/templates/connect_params.py b/utils/templates/connect_params.py index efa5ddf..dd3e674 100644 --- a/utils/templates/connect_params.py +++ b/utils/templates/connect_params.py @@ -32,7 +32,7 @@ #------------------------------------------------------------------------------ import functools -from typing import Type, Union, Callable +from typing import Union, Callable import oracledb @@ -88,7 +88,7 @@ class ConnectParams: #{{ params_properties }} - def copy(self) -> Type["ConnectParams"]: + def copy(self) -> "ConnectParams": """ Creates a copy of the parameters and returns it. """ diff --git a/utils/templates/connection.py b/utils/templates/connection.py index 8a8cd97..955514b 100644 --- a/utils/templates/connection.py +++ b/utils/templates/connection.py @@ -62,7 +62,7 @@ class Connection: def __init__(self, dsn: str=None, *, - pool: Type["pool_module.ConnectionPool"]=None, + pool: "pool_module.ConnectionPool"=None, params: ConnectParams=None, **kwargs) -> None: """ @@ -601,7 +601,7 @@ class Connection: """ return self.tpc_prepare() - def queue(self, name: str, payload_type: [DbObjectType, str]=None, *, + def queue(self, name: str, payload_type: Union[DbObjectType, str]=None, *, payloadType: DbObjectType=None) -> Queue: """ Creates and returns a queue which is used to enqueue and dequeue @@ -999,7 +999,7 @@ def _connection_factory(f): """ @functools.wraps(f) def connect(dsn: str=None, *, - pool: Type["pool_module.ConnectionPool"]=None, + pool: "pool_module.ConnectionPool"=None, conn_class: Type[Connection]=Connection, params: ConnectParams=None, **kwargs) -> Connection: @@ -1012,7 +1012,7 @@ def _connection_factory(f): @_connection_factory def connect(dsn: str=None, *, - pool: Type["pool_module.ConnectionPool"]=None, + pool: "pool_module.ConnectionPool"=None, conn_class: Type[Connection]=Connection, params: ConnectParams=None, #{{ args_with_defaults }} diff --git a/utils/templates/pool.py b/utils/templates/pool.py index 5e7a531..92b2310 100644 --- a/utils/templates/pool.py +++ b/utils/templates/pool.py @@ -118,7 +118,7 @@ class ConnectionPool: tag: str=None, matchanytag: bool=False, shardingkey: list=None, - supershardingkey: list=None) -> Type["connection_module.Connection"]: + supershardingkey: list=None) -> "connection_module.Connection": """ Acquire a connection from the pool and return it. @@ -175,7 +175,7 @@ class ConnectionPool: self._impl.close(force) self._impl = None - def drop(self, connection: Type["connection_module.Connection"]) -> None: + def drop(self, connection: "connection_module.Connection") -> None: """ Drop the connection from the pool, which is useful if the connection is no longer usable (such as when the database session is killed). @@ -320,7 +320,7 @@ class ConnectionPool: def ping_interval(self, value: int) -> None: self._impl.set_ping_interval(value) - def release(self, connection: Type["connection_module.Connection"], + def release(self, connection: "connection_module.Connection", tag: str=None) -> None: """ Release the connection back to the pool now, rather than whenever diff --git a/utils/templates/pool_params.py b/utils/templates/pool_params.py index 68a6da9..752c060 100644 --- a/utils/templates/pool_params.py +++ b/utils/templates/pool_params.py @@ -66,7 +66,7 @@ class PoolParams(ConnectParams): #{{ params_properties }} - def copy(self) -> Type["PoolParams"]: + def copy(self) -> "PoolParams": """ Creates a copy of the parameters and returns it. """