alembic 1.11.0__py3-none-any.whl → 1.11.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. alembic/__init__.py +1 -1
  2. alembic/autogenerate/api.py +0 -2
  3. alembic/autogenerate/compare.py +24 -35
  4. alembic/autogenerate/render.py +24 -38
  5. alembic/command.py +0 -1
  6. alembic/config.py +20 -7
  7. alembic/context.pyi +2 -2
  8. alembic/ddl/base.py +3 -3
  9. alembic/ddl/impl.py +14 -9
  10. alembic/ddl/mssql.py +8 -9
  11. alembic/ddl/mysql.py +0 -1
  12. alembic/ddl/oracle.py +1 -1
  13. alembic/ddl/postgresql.py +35 -12
  14. alembic/ddl/sqlite.py +3 -5
  15. alembic/op.pyi +32 -20
  16. alembic/operations/base.py +34 -22
  17. alembic/operations/batch.py +10 -8
  18. alembic/operations/ops.py +60 -36
  19. alembic/operations/toimpl.py +18 -4
  20. alembic/runtime/environment.py +2 -3
  21. alembic/runtime/migration.py +3 -7
  22. alembic/script/base.py +3 -7
  23. alembic/script/revision.py +0 -4
  24. alembic/script/write_hooks.py +8 -7
  25. alembic/templates/async/script.py.mako +6 -4
  26. alembic/templates/generic/script.py.mako +6 -4
  27. alembic/templates/multidb/script.py.mako +6 -4
  28. alembic/testing/assertions.py +0 -3
  29. alembic/testing/env.py +0 -3
  30. alembic/testing/fixtures.py +0 -2
  31. alembic/testing/suite/_autogen_fixtures.py +0 -1
  32. alembic/util/langhelpers.py +0 -1
  33. alembic/util/pyfiles.py +0 -1
  34. alembic/util/sqla_compat.py +4 -5
  35. {alembic-1.11.0.dist-info → alembic-1.11.2.dist-info}/METADATA +1 -1
  36. {alembic-1.11.0.dist-info → alembic-1.11.2.dist-info}/RECORD +40 -40
  37. {alembic-1.11.0.dist-info → alembic-1.11.2.dist-info}/WHEEL +1 -1
  38. {alembic-1.11.0.dist-info → alembic-1.11.2.dist-info}/LICENSE +0 -0
  39. {alembic-1.11.0.dist-info → alembic-1.11.2.dist-info}/entry_points.txt +0 -0
  40. {alembic-1.11.0.dist-info → alembic-1.11.2.dist-info}/top_level.txt +0 -0
alembic/operations/ops.py CHANGED
@@ -53,6 +53,7 @@ if TYPE_CHECKING:
53
53
 
54
54
  from ..autogenerate.rewriter import Rewriter
55
55
  from ..runtime.migration import MigrationContext
56
+ from ..script.revision import _RevIdType
56
57
 
57
58
 
58
59
  class MigrateOperation:
@@ -132,8 +133,8 @@ class DropConstraintOp(MigrateOperation):
132
133
  self,
133
134
  constraint_name: Optional[sqla_compat._ConstraintNameDefined],
134
135
  table_name: str,
135
- *,
136
136
  type_: Optional[str] = None,
137
+ *,
137
138
  schema: Optional[str] = None,
138
139
  _reverse: Optional[AddConstraintOp] = None,
139
140
  ) -> None:
@@ -175,7 +176,6 @@ class DropConstraintOp(MigrateOperation):
175
176
  )
176
177
 
177
178
  def to_constraint(self) -> Constraint:
178
-
179
179
  if self._reverse is not None:
180
180
  constraint = self._reverse.to_constraint()
181
181
  constraint.name = self.constraint_name
@@ -196,8 +196,8 @@ class DropConstraintOp(MigrateOperation):
196
196
  operations: Operations,
197
197
  constraint_name: str,
198
198
  table_name: str,
199
- *,
200
199
  type_: Optional[str] = None,
200
+ *,
201
201
  schema: Optional[str] = None,
202
202
  ) -> None:
203
203
  r"""Drop a constraint of the given name, typically via DROP CONSTRAINT.
@@ -221,7 +221,6 @@ class DropConstraintOp(MigrateOperation):
221
221
  cls,
222
222
  operations: BatchOperations,
223
223
  constraint_name: str,
224
- *,
225
224
  type_: Optional[str] = None,
226
225
  ) -> None:
227
226
  """Issue a "drop constraint" instruction using the
@@ -397,7 +396,6 @@ class CreateUniqueConstraintOp(AddConstraintOp):
397
396
  def from_constraint(
398
397
  cls, constraint: Constraint
399
398
  ) -> CreateUniqueConstraintOp:
400
-
401
399
  constraint_table = sqla_compat._table_for_constraint(constraint)
402
400
 
403
401
  uq_constraint = cast("UniqueConstraint", constraint)
@@ -535,7 +533,6 @@ class CreateForeignKeyOp(AddConstraintOp):
535
533
 
536
534
  @classmethod
537
535
  def from_constraint(cls, constraint: Constraint) -> CreateForeignKeyOp:
538
-
539
536
  fk_constraint = cast("ForeignKeyConstraint", constraint)
540
537
  kw: dict = {}
541
538
  if fk_constraint.onupdate:
@@ -879,6 +876,7 @@ class CreateIndexOp(MigrateOperation):
879
876
  *,
880
877
  schema: Optional[str] = None,
881
878
  unique: bool = False,
879
+ if_not_exists: Optional[bool] = None,
882
880
  **kw: Any,
883
881
  ) -> None:
884
882
  self.index_name = index_name
@@ -886,6 +884,7 @@ class CreateIndexOp(MigrateOperation):
886
884
  self.columns = columns
887
885
  self.schema = schema
888
886
  self.unique = unique
887
+ self.if_not_exists = if_not_exists
889
888
  self.kw = kw
890
889
 
891
890
  def reverse(self) -> DropIndexOp:
@@ -931,6 +930,7 @@ class CreateIndexOp(MigrateOperation):
931
930
  *,
932
931
  schema: Optional[str] = None,
933
932
  unique: bool = False,
933
+ if_not_exists: Optional[bool] = None,
934
934
  **kw: Any,
935
935
  ) -> None:
936
936
  r"""Issue a "create index" instruction using the current
@@ -960,24 +960,34 @@ class CreateIndexOp(MigrateOperation):
960
960
  :class:`~sqlalchemy.sql.elements.quoted_name`.
961
961
  :param unique: If True, create a unique index.
962
962
 
963
- :param quote:
964
- Force quoting of this column's name on or off, corresponding
965
- to ``True`` or ``False``. When left at its default
966
- of ``None``, the column identifier will be quoted according to
967
- whether the name is case sensitive (identifiers with at least one
968
- upper case character are treated as case sensitive), or if it's a
969
- reserved word. This flag is only needed to force quoting of a
970
- reserved word which is not known by the SQLAlchemy dialect.
963
+ :param quote: Force quoting of this column's name on or off,
964
+ corresponding to ``True`` or ``False``. When left at its default
965
+ of ``None``, the column identifier will be quoted according to
966
+ whether the name is case sensitive (identifiers with at least one
967
+ upper case character are treated as case sensitive), or if it's a
968
+ reserved word. This flag is only needed to force quoting of a
969
+ reserved word which is not known by the SQLAlchemy dialect.
970
+
971
+ :param if_not_exists: If True, adds IF NOT EXISTS operator when
972
+ creating the new index.
973
+
974
+ .. versionadded:: 1.12.0
971
975
 
972
976
  :param \**kw: Additional keyword arguments not mentioned above are
973
- dialect specific, and passed in the form
974
- ``<dialectname>_<argname>``.
975
- See the documentation regarding an individual dialect at
976
- :ref:`dialect_toplevel` for detail on documented arguments.
977
+ dialect specific, and passed in the form
978
+ ``<dialectname>_<argname>``.
979
+ See the documentation regarding an individual dialect at
980
+ :ref:`dialect_toplevel` for detail on documented arguments.
977
981
 
978
982
  """
979
983
  op = cls(
980
- index_name, table_name, columns, schema=schema, unique=unique, **kw
984
+ index_name,
985
+ table_name,
986
+ columns,
987
+ schema=schema,
988
+ unique=unique,
989
+ if_not_exists=if_not_exists,
990
+ **kw,
981
991
  )
982
992
  return operations.invoke(op)
983
993
 
@@ -1016,15 +1026,17 @@ class DropIndexOp(MigrateOperation):
1016
1026
  def __init__(
1017
1027
  self,
1018
1028
  index_name: Union[quoted_name, str, conv],
1019
- *,
1020
1029
  table_name: Optional[str] = None,
1030
+ *,
1021
1031
  schema: Optional[str] = None,
1032
+ if_exists: Optional[bool] = None,
1022
1033
  _reverse: Optional[CreateIndexOp] = None,
1023
1034
  **kw: Any,
1024
1035
  ) -> None:
1025
1036
  self.index_name = index_name
1026
1037
  self.table_name = table_name
1027
1038
  self.schema = schema
1039
+ self.if_exists = if_exists
1028
1040
  self._reverse = _reverse
1029
1041
  self.kw = kw
1030
1042
 
@@ -1065,9 +1077,10 @@ class DropIndexOp(MigrateOperation):
1065
1077
  cls,
1066
1078
  operations: Operations,
1067
1079
  index_name: str,
1068
- *,
1069
1080
  table_name: Optional[str] = None,
1081
+ *,
1070
1082
  schema: Optional[str] = None,
1083
+ if_exists: Optional[bool] = None,
1071
1084
  **kw: Any,
1072
1085
  ) -> None:
1073
1086
  r"""Issue a "drop index" instruction using the current
@@ -1084,14 +1097,26 @@ class DropIndexOp(MigrateOperation):
1084
1097
  quoting of the schema outside of the default behavior, use
1085
1098
  the SQLAlchemy construct
1086
1099
  :class:`~sqlalchemy.sql.elements.quoted_name`.
1100
+
1101
+ :param if_exists: If True, adds IF EXISTS operator when
1102
+ dropping the index.
1103
+
1104
+ .. versionadded:: 1.12.0
1105
+
1087
1106
  :param \**kw: Additional keyword arguments not mentioned above are
1088
- dialect specific, and passed in the form
1089
- ``<dialectname>_<argname>``.
1090
- See the documentation regarding an individual dialect at
1091
- :ref:`dialect_toplevel` for detail on documented arguments.
1107
+ dialect specific, and passed in the form
1108
+ ``<dialectname>_<argname>``.
1109
+ See the documentation regarding an individual dialect at
1110
+ :ref:`dialect_toplevel` for detail on documented arguments.
1092
1111
 
1093
1112
  """
1094
- op = cls(index_name, table_name=table_name, schema=schema, **kw)
1113
+ op = cls(
1114
+ index_name,
1115
+ table_name=table_name,
1116
+ schema=schema,
1117
+ if_exists=if_exists,
1118
+ **kw,
1119
+ )
1095
1120
  return operations.invoke(op)
1096
1121
 
1097
1122
  @classmethod
@@ -1758,7 +1783,6 @@ class AlterColumnOp(AlterTableOp):
1758
1783
  return False
1759
1784
 
1760
1785
  def reverse(self) -> AlterColumnOp:
1761
-
1762
1786
  kw = self.kw.copy()
1763
1787
  kw["existing_type"] = self.existing_type
1764
1788
  kw["existing_nullable"] = self.existing_nullable
@@ -1994,7 +2018,7 @@ class AddColumnOp(AlterTableOp):
1994
2018
  def __init__(
1995
2019
  self,
1996
2020
  table_name: str,
1997
- column: Column,
2021
+ column: Column[Any],
1998
2022
  *,
1999
2023
  schema: Optional[str] = None,
2000
2024
  **kw: Any,
@@ -2010,7 +2034,7 @@ class AddColumnOp(AlterTableOp):
2010
2034
 
2011
2035
  def to_diff_tuple(
2012
2036
  self,
2013
- ) -> Tuple[str, Optional[str], str, Column]:
2037
+ ) -> Tuple[str, Optional[str], str, Column[Any]]:
2014
2038
  return ("add_column", self.schema, self.table_name, self.column)
2015
2039
 
2016
2040
  def to_column(self) -> Column:
@@ -2025,7 +2049,7 @@ class AddColumnOp(AlterTableOp):
2025
2049
  cls,
2026
2050
  schema: Optional[str],
2027
2051
  tname: str,
2028
- col: Column,
2052
+ col: Column[Any],
2029
2053
  ) -> AddColumnOp:
2030
2054
  return cls(tname, col, schema=schema)
2031
2055
 
@@ -2034,7 +2058,7 @@ class AddColumnOp(AlterTableOp):
2034
2058
  cls,
2035
2059
  operations: Operations,
2036
2060
  table_name: str,
2037
- column: Column,
2061
+ column: Column[Any],
2038
2062
  *,
2039
2063
  schema: Optional[str] = None,
2040
2064
  ) -> None:
@@ -2123,7 +2147,7 @@ class AddColumnOp(AlterTableOp):
2123
2147
  def batch_add_column(
2124
2148
  cls,
2125
2149
  operations: BatchOperations,
2126
- column: Column,
2150
+ column: Column[Any],
2127
2151
  *,
2128
2152
  insert_before: Optional[str] = None,
2129
2153
  insert_after: Optional[str] = None,
@@ -2173,7 +2197,7 @@ class DropColumnOp(AlterTableOp):
2173
2197
 
2174
2198
  def to_diff_tuple(
2175
2199
  self,
2176
- ) -> Tuple[str, Optional[str], str, Column]:
2200
+ ) -> Tuple[str, Optional[str], str, Column[Any]]:
2177
2201
  return (
2178
2202
  "remove_column",
2179
2203
  self.schema,
@@ -2197,7 +2221,7 @@ class DropColumnOp(AlterTableOp):
2197
2221
  cls,
2198
2222
  schema: Optional[str],
2199
2223
  tname: str,
2200
- col: Column,
2224
+ col: Column[Any],
2201
2225
  ) -> DropColumnOp:
2202
2226
  return cls(
2203
2227
  tname,
@@ -2668,9 +2692,9 @@ class MigrationScript(MigrateOperation):
2668
2692
  imports: Set[str] = set(),
2669
2693
  head: Optional[str] = None,
2670
2694
  splice: Optional[bool] = None,
2671
- branch_label: Optional[str] = None,
2695
+ branch_label: Optional[_RevIdType] = None,
2672
2696
  version_path: Optional[str] = None,
2673
- depends_on: Optional[Union[str, Sequence[str]]] = None,
2697
+ depends_on: Optional[_RevIdType] = None,
2674
2698
  ) -> None:
2675
2699
  self.rev_id = rev_id
2676
2700
  self.message = message
@@ -5,6 +5,7 @@ from sqlalchemy import schema as sa_schema
5
5
  from . import ops
6
6
  from .base import Operations
7
7
  from ..util.sqla_compat import _copy
8
+ from ..util.sqla_compat import sqla_2
8
9
 
9
10
  if TYPE_CHECKING:
10
11
  from sqlalchemy.sql.schema import Table
@@ -14,7 +15,6 @@ if TYPE_CHECKING:
14
15
  def alter_column(
15
16
  operations: "Operations", operation: "ops.AlterColumnOp"
16
17
  ) -> None:
17
-
18
18
  compiler = operations.impl.dialect.statement_compiler(
19
19
  operations.impl.dialect, None
20
20
  )
@@ -60,7 +60,7 @@ def alter_column(
60
60
  existing_nullable=existing_nullable,
61
61
  comment=comment,
62
62
  existing_comment=existing_comment,
63
- **operation.kw
63
+ **operation.kw,
64
64
  )
65
65
 
66
66
  if type_:
@@ -96,13 +96,27 @@ def create_index(
96
96
  operations: "Operations", operation: "ops.CreateIndexOp"
97
97
  ) -> None:
98
98
  idx = operation.to_index(operations.migration_context)
99
- operations.impl.create_index(idx)
99
+ kw = {}
100
+ if operation.if_not_exists is not None:
101
+ if not sqla_2:
102
+ raise NotImplementedError("SQLAlchemy 2.0+ required")
103
+
104
+ kw["if_not_exists"] = operation.if_not_exists
105
+ operations.impl.create_index(idx, **kw)
100
106
 
101
107
 
102
108
  @Operations.implementation_for(ops.DropIndexOp)
103
109
  def drop_index(operations: "Operations", operation: "ops.DropIndexOp") -> None:
110
+ kw = {}
111
+ if operation.if_exists is not None:
112
+ if not sqla_2:
113
+ raise NotImplementedError("SQLAlchemy 2.0+ required")
114
+
115
+ kw["if_exists"] = operation.if_exists
116
+
104
117
  operations.impl.drop_index(
105
- operation.to_index(operations.migration_context)
118
+ operation.to_index(operations.migration_context),
119
+ **kw,
106
120
  )
107
121
 
108
122
 
@@ -25,7 +25,6 @@ from .. import util
25
25
  from ..operations import Operations
26
26
 
27
27
  if TYPE_CHECKING:
28
-
29
28
  from sqlalchemy.engine import URL
30
29
  from sqlalchemy.engine.base import Connection
31
30
  from sqlalchemy.sql.elements import ClauseElement
@@ -84,8 +83,8 @@ OnVersionApplyFn = Callable[
84
83
  CompareServerDefault = Callable[
85
84
  [
86
85
  MigrationContext,
87
- Column,
88
- Column,
86
+ "Column[Any]",
87
+ "Column[Any]",
89
88
  Optional[str],
90
89
  Optional[FetchedValue],
91
90
  Optional[str],
@@ -522,7 +522,6 @@ class MigrationContext:
522
522
  if start_from_rev == "base":
523
523
  start_from_rev = None
524
524
  elif start_from_rev is not None and self.script:
525
-
526
525
  start_from_rev = [
527
526
  cast("Script", self.script.get_revision(sfr)).revision
528
527
  for sfr in util.to_list(start_from_rev)
@@ -614,7 +613,6 @@ class MigrationContext:
614
613
  assert self._migrations_fn is not None
615
614
  for step in self._migrations_fn(heads, self):
616
615
  with self.begin_transaction(_per_migration=True):
617
-
618
616
  if self.as_sql and not head_maintainer.heads:
619
617
  # for offline mode, include a CREATE TABLE from
620
618
  # the base
@@ -708,7 +706,7 @@ class MigrationContext:
708
706
  return None
709
707
 
710
708
  def _compare_type(
711
- self, inspector_column: Column, metadata_column: Column
709
+ self, inspector_column: Column[Any], metadata_column: Column
712
710
  ) -> bool:
713
711
  if self._user_compare_type is False:
714
712
  return False
@@ -728,12 +726,11 @@ class MigrationContext:
728
726
 
729
727
  def _compare_server_default(
730
728
  self,
731
- inspector_column: Column,
732
- metadata_column: Column,
729
+ inspector_column: Column[Any],
730
+ metadata_column: Column[Any],
733
731
  rendered_metadata_default: Optional[str],
734
732
  rendered_column_default: Optional[str],
735
733
  ) -> bool:
736
-
737
734
  if self._user_compare_server_default is False:
738
735
  return False
739
736
 
@@ -1000,7 +997,6 @@ class MigrationInfo:
1000
997
 
1001
998
 
1002
999
  class MigrationStep:
1003
-
1004
1000
  from_revisions_no_deps: Tuple[str, ...]
1005
1001
  to_revisions_no_deps: Tuple[str, ...]
1006
1002
  is_upgrade: bool
alembic/script/base.py CHANGED
@@ -26,23 +26,21 @@ from ..runtime import migration
26
26
  from ..util import not_none
27
27
 
28
28
  if TYPE_CHECKING:
29
+ from .revision import _RevIdType
30
+ from .revision import Revision
29
31
  from ..config import Config
30
32
  from ..config import MessagingOptions
31
33
  from ..runtime.migration import RevisionStep
32
34
  from ..runtime.migration import StampStep
33
- from ..script.revision import Revision
34
35
 
35
36
  try:
36
37
  from dateutil import tz
37
38
  except ImportError:
38
39
  tz = None # type: ignore[assignment]
39
40
 
40
- _RevIdType = Union[str, Sequence[str]]
41
-
42
41
  _sourceless_rev_file = re.compile(r"(?!\.\#|__init__)(.*\.py)(c|o)?$")
43
42
  _only_source_rev_file = re.compile(r"(?!\.\#|__init__)(.*\.py)$")
44
43
  _legacy_rev = re.compile(r"([a-f0-9]+)\.py$")
45
- _mod_def_re = re.compile(r"(upgrade|downgrade)_([a-z0-9]+)")
46
44
  _slug_re = re.compile(r"\w+")
47
45
  _default_file_template = "%(rev)s_%(slug)s"
48
46
  _split_on_space_comma = re.compile(r", *|(?: +)")
@@ -481,7 +479,6 @@ class ScriptDirectory:
481
479
  multiple_heads="Multiple heads are present; please specify a "
482
480
  "single target revision"
483
481
  ):
484
-
485
482
  heads_revs = self.get_revisions(heads)
486
483
 
487
484
  steps = []
@@ -504,7 +501,6 @@ class ScriptDirectory:
504
501
  dests = self.get_revisions(revision) or [None]
505
502
 
506
503
  for dest in dests:
507
-
508
504
  if dest is None:
509
505
  # dest is 'base'. Return a "delete branch" migration
510
506
  # for all applicable heads.
@@ -637,7 +633,7 @@ class ScriptDirectory:
637
633
  head: Optional[str] = None,
638
634
  refresh: bool = False,
639
635
  splice: Optional[bool] = False,
640
- branch_labels: Optional[str] = None,
636
+ branch_labels: Optional[_RevIdType] = None,
641
637
  version_path: Optional[str] = None,
642
638
  depends_on: Optional[_RevIdType] = None,
643
639
  **kw: Any,
@@ -336,7 +336,6 @@ class RevisionMap:
336
336
  and not parent._is_real_branch_point
337
337
  and not parent.is_merge_point
338
338
  ):
339
-
340
339
  parent.branch_labels.update(revision.branch_labels)
341
340
  if parent.down_revision:
342
341
  parent = map_[parent.down_revision]
@@ -813,7 +812,6 @@ class RevisionMap:
813
812
  omit_immediate_dependencies: bool = False,
814
813
  include_dependencies: bool = True,
815
814
  ) -> Iterator[Any]:
816
-
817
815
  if omit_immediate_dependencies:
818
816
 
819
817
  def fn(rev):
@@ -843,7 +841,6 @@ class RevisionMap:
843
841
  check: bool = False,
844
842
  include_dependencies: bool = True,
845
843
  ) -> Iterator[Revision]:
846
-
847
844
  if include_dependencies:
848
845
 
849
846
  def fn(rev):
@@ -945,7 +942,6 @@ class RevisionMap:
945
942
 
946
943
  current_candidate_idx = 0
947
944
  while current_heads:
948
-
949
945
  candidate = current_heads[current_candidate_idx]
950
946
 
951
947
  for check_head_index, ancestors in enumerate(ancestors_by_idx):
@@ -56,7 +56,7 @@ def _invoke(
56
56
  hook = _registry[name]
57
57
  except KeyError as ke:
58
58
  raise util.CommandError(
59
- "No formatter with name '%s' registered" % name
59
+ f"No formatter with name '{name}' registered"
60
60
  ) from ke
61
61
  else:
62
62
  return hook(revision, options)
@@ -82,10 +82,12 @@ def _run_hooks(path: str, hook_config: Mapping[str, str]) -> None:
82
82
  type_ = opts["type"]
83
83
  except KeyError as ke:
84
84
  raise util.CommandError(
85
- "Key %s.type is required for post write hook %r" % (name, name)
85
+ f"Key {name}.type is required for post write hook {name!r}"
86
86
  ) from ke
87
87
  else:
88
- with util.status("Running post write hook {name!r}", newline=True):
88
+ with util.status(
89
+ f"Running post write hook {name!r}", newline=True
90
+ ):
89
91
  _invoke(type_, path, opts)
90
92
 
91
93
 
@@ -114,13 +116,12 @@ def _parse_cmdline_options(cmdline_options_str: str, path: str) -> List[str]:
114
116
  def console_scripts(
115
117
  path: str, options: dict, ignore_output: bool = False
116
118
  ) -> None:
117
-
118
119
  try:
119
120
  entrypoint_name = options["entrypoint"]
120
121
  except KeyError as ke:
121
122
  raise util.CommandError(
122
- "Key %s.entrypoint is required for post write hook %r"
123
- % (options["_hook_name"], options["_hook_name"])
123
+ f"Key {options['_hook_name']}.entrypoint is required for post "
124
+ f"write hook {options['_hook_name']!r}"
124
125
  ) from ke
125
126
  for entry in compat.importlib_metadata_get("console_scripts"):
126
127
  if entry.name == entrypoint_name:
@@ -142,7 +143,7 @@ def console_scripts(
142
143
  [
143
144
  sys.executable,
144
145
  "-c",
145
- "import %s; %s.%s()" % (impl.module, impl.module, impl.attr),
146
+ f"import {impl.module}; {impl.module}.{impl.attr}()",
146
147
  ]
147
148
  + cmdline_options_list,
148
149
  cwd=cwd,
@@ -5,15 +5,17 @@ Revises: ${down_revision | comma,n}
5
5
  Create Date: ${create_date}
6
6
 
7
7
  """
8
+ from typing import Sequence, Union
9
+
8
10
  from alembic import op
9
11
  import sqlalchemy as sa
10
12
  ${imports if imports else ""}
11
13
 
12
14
  # revision identifiers, used by Alembic.
13
- revision = ${repr(up_revision)}
14
- down_revision = ${repr(down_revision)}
15
- branch_labels = ${repr(branch_labels)}
16
- depends_on = ${repr(depends_on)}
15
+ revision: str = ${repr(up_revision)}
16
+ down_revision: Union[str, None] = ${repr(down_revision)}
17
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
17
19
 
18
20
 
19
21
  def upgrade() -> None:
@@ -5,15 +5,17 @@ Revises: ${down_revision | comma,n}
5
5
  Create Date: ${create_date}
6
6
 
7
7
  """
8
+ from typing import Sequence, Union
9
+
8
10
  from alembic import op
9
11
  import sqlalchemy as sa
10
12
  ${imports if imports else ""}
11
13
 
12
14
  # revision identifiers, used by Alembic.
13
- revision = ${repr(up_revision)}
14
- down_revision = ${repr(down_revision)}
15
- branch_labels = ${repr(branch_labels)}
16
- depends_on = ${repr(depends_on)}
15
+ revision: str = ${repr(up_revision)}
16
+ down_revision: Union[str, None] = ${repr(down_revision)}
17
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
18
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
17
19
 
18
20
 
19
21
  def upgrade() -> None:
@@ -8,15 +8,17 @@ Revises: ${down_revision | comma,n}
8
8
  Create Date: ${create_date}
9
9
 
10
10
  """
11
+ from typing import Sequence, Union
12
+
11
13
  from alembic import op
12
14
  import sqlalchemy as sa
13
15
  ${imports if imports else ""}
14
16
 
15
17
  # revision identifiers, used by Alembic.
16
- revision = ${repr(up_revision)}
17
- down_revision = ${repr(down_revision)}
18
- branch_labels = ${repr(branch_labels)}
19
- depends_on = ${repr(depends_on)}
18
+ revision: str = ${repr(up_revision)}
19
+ down_revision: Union[str, None] = ${repr(down_revision)}
20
+ branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)}
21
+ depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)}
20
22
 
21
23
 
22
24
  def upgrade(engine_name: str) -> None:
@@ -64,7 +64,6 @@ def assert_raises_message_context_ok(
64
64
  def _assert_raises(
65
65
  except_cls, callable_, args, kwargs, msg=None, check_context=False
66
66
  ):
67
-
68
67
  with _expect_raises(except_cls, msg, check_context) as ec:
69
68
  callable_(*args, **kwargs)
70
69
  return ec.error
@@ -104,7 +103,6 @@ def expect_raises_message(except_cls, msg, check_context=True):
104
103
 
105
104
 
106
105
  def eq_ignore_whitespace(a, b, msg=None):
107
-
108
106
  a = re.sub(r"^\s+?|\n", "", a)
109
107
  a = re.sub(r" {2,}", " ", a)
110
108
  b = re.sub(r"^\s+?|\n", "", b)
@@ -120,7 +118,6 @@ def _get_dialect(name):
120
118
  if name is None or name == "default":
121
119
  return default.DefaultDialect()
122
120
  else:
123
-
124
121
  d = sqla_compat._create_url(name).get_dialect()()
125
122
 
126
123
  if name == "postgresql":
alembic/testing/env.py CHANGED
@@ -22,10 +22,8 @@ def _get_staging_directory():
22
22
 
23
23
 
24
24
  def staging_env(create=True, template="generic", sourceless=False):
25
-
26
25
  cfg = _testing_config()
27
26
  if create:
28
-
29
27
  path = os.path.join(_get_staging_directory(), "scripts")
30
28
  assert not os.path.exists(path), (
31
29
  "staging directory %s already exists; poor cleanup?" % path
@@ -284,7 +282,6 @@ def write_script(
284
282
 
285
283
 
286
284
  def make_sourceless(path, style):
287
-
288
285
  import py_compile
289
286
 
290
287
  py_compile.compile(path)
@@ -134,7 +134,6 @@ def op_fixture(
134
134
  literal_binds=False,
135
135
  native_boolean=None,
136
136
  ):
137
-
138
137
  opts = {}
139
138
  if naming_convention:
140
139
  opts["target_metadata"] = MetaData(naming_convention=naming_convention)
@@ -217,7 +216,6 @@ def op_fixture(
217
216
 
218
217
 
219
218
  class AlterColRoundTripFixture:
220
-
221
219
  # since these tests are about syntax, use more recent SQLAlchemy as some of
222
220
  # the type / server default compare logic might not work on older
223
221
  # SQLAlchemy versions as seems to be the case for SQLAlchemy 1.1 on Oracle
@@ -279,7 +279,6 @@ class AutogenFixtureTest(_ComparesFKs):
279
279
  return_ops=False,
280
280
  max_identifier_length=None,
281
281
  ):
282
-
283
282
  if max_identifier_length:
284
283
  dialect = self.bind.dialect
285
284
  existing_length = dialect.max_identifier_length
@@ -243,7 +243,6 @@ class Dispatcher:
243
243
  return decorate
244
244
 
245
245
  def dispatch(self, obj: Any, qualifier: str = "default") -> Any:
246
-
247
246
  if isinstance(obj, str):
248
247
  targets: Sequence = [obj]
249
248
  elif isinstance(obj, type):
alembic/util/pyfiles.py CHANGED
@@ -49,7 +49,6 @@ def coerce_resource_to_filename(fname: str) -> str:
49
49
 
50
50
  """
51
51
  if not os.path.isabs(fname) and ":" in fname:
52
-
53
52
  tokens = fname.split(":")
54
53
 
55
54
  # from https://importlib-resources.readthedocs.io/en/latest/migration.html#pkg-resources-resource-filename # noqa E501