|
169 | 169 | IndexEntry, |
170 | 170 | IndexFile, |
171 | 171 | StageType, |
| 172 | + # NOTE: This tells type checkers what util resolves to. We delete it, and it is |
| 173 | + # really resolved by __getattr__, which warns. See below on what to use instead. |
172 | 174 | util, |
173 | 175 | ) |
174 | 176 | from git.util import ( # @NoMove |
|
183 | 185 | raise ImportError("%s: %s" % (_exc.__class__.__name__, _exc)) from _exc |
184 | 186 |
|
185 | 187 |
|
186 | | -# NOTE: The expression `git.util` evaluates to git.index.util and `from git import util` |
187 | | -# imports git.index.util, NOT git.util. It may not be feasible to change this until the |
188 | | -# next major version, to avoid breaking code inadvertently relying on it. |
189 | | -# |
190 | | -# - If git.index.util *is* what you want, use or import from that, to avoid confusion. |
191 | | -# |
192 | | -# - To use the "real" git.util module, write `from git.util import ...`, or if necessary |
193 | | -# access it as `sys.modules["git.util"]`. |
194 | | -# |
195 | | -# (This differs from other indirect-submodule imports that are unambiguously non-public |
196 | | -# and subject to immediate removal. Here, the public git.util module, though different, |
197 | | -# makes less discoverable that the expression `git.util` refers to a non-public |
198 | | -# attribute of the git module.) |
199 | | -# |
200 | | -# This had come about by a wildcard import. Now that all intended imports are explicit, |
201 | | -# the intuitive but potentially incompatible binding occurs due to the usual rules for |
202 | | -# Python submodule bindings. So for now we delete that and let __getattr__ handle it. |
203 | | -# |
204 | | -del util |
205 | | - |
206 | | - |
207 | 188 | def _warned_import(message: str, fullname: str) -> "ModuleType": |
208 | 189 | import importlib |
209 | 190 |
|
@@ -242,7 +223,36 @@ def _getattr(name: str) -> Any: |
242 | 223 | raise AttributeError(f"module {__name__!r} has no attribute {name!r}") |
243 | 224 |
|
244 | 225 |
|
245 | | -if not TYPE_CHECKING: # Preserve static checking for undefined/misspelled attributes. |
| 226 | +if not TYPE_CHECKING: |
| 227 | + # NOTE: The expression `git.util` gives git.index.util and `from git import util` |
| 228 | + # imports git.index.util, NOT git.util. It may not be feasible to change this until |
| 229 | + # the next major version, to avoid breaking code inadvertently relying on it. |
| 230 | + # |
| 231 | + # - If git.index.util *is* what you want, use (or import from) that, to avoid |
| 232 | + # confusion. |
| 233 | + # |
| 234 | + # - To use the "real" git.util module, write `from git.util import ...`, or if |
| 235 | + # necessary access it as `sys.modules["git.util"]`. |
| 236 | + # |
| 237 | + # Note also that `import git.util` technically imports the "real" git.util... but |
| 238 | + # the *expression* `git.util` after doing so is still git.index.util! |
| 239 | + # |
| 240 | + # (This situation differs from that of other indirect-submodule imports that are |
| 241 | + # unambiguously non-public and subject to immediate removal. Here, the public |
| 242 | + # git.util module, though different, makes less discoverable that the expression |
| 243 | + # `git.util` refers to a non-public attribute of the git module.) |
| 244 | + # |
| 245 | + # This had originally come about by a wildcard import. Now that all intended imports |
| 246 | + # are explicit, the intuitive but potentially incompatible binding occurs due to the |
| 247 | + # usual rules for Python submodule bindings. So for now we replace that binding with |
| 248 | + # git.index.util, delete that, and let __getattr__ handle it and issue a warning. |
| 249 | + # |
| 250 | + # For the same runtime behavior, it would be enough to forgo importing util, and |
| 251 | + # delete util as created naturally; __getattr__ would behave the same. But type |
| 252 | + # checkers would not know what util refers to when accessed as an attribute of git. |
| 253 | + del util |
| 254 | + |
| 255 | + # This is "hidden" to preserve static checking for undefined/misspelled attributes. |
246 | 256 | __getattr__ = _getattr |
247 | 257 |
|
248 | 258 | # { Initialize git executable path |
|
0 commit comments