types.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. # Copyright 2020 The Matrix.org Foundation C.I.C.
  2. #
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. #
  7. # http://www.apache.org/licenses/LICENSE-2.0
  8. #
  9. # Unless required by applicable law or agreed to in writing, software
  10. # distributed under the License is distributed on an "AS IS" BASIS,
  11. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. # See the License for the specific language governing permissions and
  13. # limitations under the License.
  14. from types import TracebackType
  15. from typing import Any, Iterator, List, Mapping, Optional, Sequence, Tuple, Type, Union
  16. from typing_extensions import Protocol
  17. """
  18. Some very basic protocol definitions for the DB-API2 classes specified in PEP-249
  19. """
  20. _Parameters = Union[Sequence[Any], Mapping[str, Any]]
  21. class Cursor(Protocol):
  22. def execute(self, sql: str, parameters: _Parameters = ...) -> Any:
  23. ...
  24. def executemany(self, sql: str, parameters: Sequence[_Parameters]) -> Any:
  25. ...
  26. def fetchone(self) -> Optional[Tuple]:
  27. ...
  28. def fetchmany(self, size: Optional[int] = ...) -> List[Tuple]:
  29. ...
  30. def fetchall(self) -> List[Tuple]:
  31. ...
  32. @property
  33. def description(
  34. self,
  35. ) -> Optional[
  36. Sequence[
  37. # Note that this is an approximate typing based on sqlite3 and other
  38. # drivers, and may not be entirely accurate.
  39. # FWIW, the DBAPI 2 spec is: https://peps.python.org/pep-0249/#description
  40. Tuple[
  41. str,
  42. Optional[Any],
  43. Optional[int],
  44. Optional[int],
  45. Optional[int],
  46. Optional[int],
  47. Optional[int],
  48. ]
  49. ]
  50. ]:
  51. ...
  52. @property
  53. def rowcount(self) -> int:
  54. return 0
  55. def __iter__(self) -> Iterator[Tuple]:
  56. ...
  57. def close(self) -> None:
  58. ...
  59. class Connection(Protocol):
  60. def cursor(self) -> Cursor:
  61. ...
  62. def close(self) -> None:
  63. ...
  64. def commit(self) -> None:
  65. ...
  66. def rollback(self) -> None:
  67. ...
  68. def __enter__(self) -> "Connection":
  69. ...
  70. def __exit__(
  71. self,
  72. exc_type: Optional[Type[BaseException]],
  73. exc_value: Optional[BaseException],
  74. traceback: Optional[TracebackType],
  75. ) -> Optional[bool]:
  76. ...
  77. class DBAPI2Module(Protocol):
  78. """The module-level attributes that we use from PEP 249.
  79. This is NOT a comprehensive stub for the entire DBAPI2."""
  80. __name__: str
  81. # Exceptions. See https://peps.python.org/pep-0249/#exceptions
  82. # For our specific drivers:
  83. # - Python's sqlite3 module doesn't contains the same descriptions as the
  84. # DBAPI2 spec, see https://docs.python.org/3/library/sqlite3.html#exceptions
  85. # - Psycopg2 maps every Postgres error code onto a unique exception class which
  86. # extends from this hierarchy. See
  87. # https://docs.python.org/3/library/sqlite3.html?highlight=sqlite3#exceptions
  88. # https://www.postgresql.org/docs/current/errcodes-appendix.html#ERRCODES-TABLE
  89. Warning: Type[Exception]
  90. Error: Type[Exception]
  91. # Errors are divided into `InterfaceError`s (something went wrong in the database
  92. # driver) and `DatabaseError`s (something went wrong in the database). These are
  93. # both subclasses of `Error`, but we can't currently express this in type
  94. # annotations due to https://github.com/python/mypy/issues/8397
  95. InterfaceError: Type[Exception]
  96. DatabaseError: Type[Exception]
  97. # Everything below is a subclass of `DatabaseError`.
  98. # Roughly: the database rejected a nonsensical value. Examples:
  99. # - An integer was too big for its data type.
  100. # - An invalid date time was provided.
  101. # - A string contained a null code point.
  102. DataError: Type[Exception]
  103. # Roughly: something went wrong in the database, but it's not within the application
  104. # programmer's control. Examples:
  105. # - We failed to establish a connection to the database.
  106. # - The connection to the database was lost.
  107. # - A deadlock was detected.
  108. # - A serialisation failure occurred.
  109. # - The database ran out of resources, such as storage, memory, connections, etc.
  110. # - The database encountered an error from the operating system.
  111. OperationalError: Type[Exception]
  112. # Roughly: we've given the database data which breaks a rule we asked it to enforce.
  113. # Examples:
  114. # - Stop, criminal scum! You violated the foreign key constraint
  115. # - Also check constraints, non-null constraints, etc.
  116. IntegrityError: Type[Exception]
  117. # Roughly: something went wrong within the database server itself.
  118. InternalError: Type[Exception]
  119. # Roughly: the application did something silly that needs to be fixed. Examples:
  120. # - We don't have permissions to do something.
  121. # - We tried to create a table with duplicate column names.
  122. # - We tried to use a reserved name.
  123. # - We referred to a column that doesn't exist.
  124. ProgrammingError: Type[Exception]
  125. # Roughly: we've tried to do something that this database doesn't support.
  126. NotSupportedError: Type[Exception]
  127. def connect(self, **parameters: object) -> Connection:
  128. ...
  129. __all__ = ["Cursor", "Connection", "DBAPI2Module"]