Skip to content

Commit

Permalink
Incompletely change git.index imports to test modattrs.py
Browse files Browse the repository at this point in the history
This also checks if the regression tests in test_imports.py work.

This replaces wildcard imports in git.index with explicit imports,
and adds git.index.__all__. But this temporarily omits from it the
public attributes of git.index that name its Python submodules and
are thus are present as an indirect effect of importing names
*from* them (since doing so also imports them).

This partial change, until it is completed in the next commit,
represents the kind of bug that modattrs.py seeks to safeguard
against, and verifies that a diff between old and current output of
modattrs.py clearly shows it. This diff is temporarily included as
ab.diff, which will be deleted in the next commit.

The key problem that diff reveals is the changed value of the util
attribute of the top-level git module. Due to the way wildcard
imports have been used within GitPython for its own modules,
expressions like `git.util` (where `git` is the top-level git
module) and imports like `from git import util` are actually
referring to git.index.util, rather than the util Python submodule
of the git module (conceptually git.util), which can only be
accessed via `from git.util import ...` or in `sys.modules`.
Although this is not an inherently good situation, in practice it
has to be maintained at least until the next major version, because
reasonable code that uses GitPython would be broken if the
situation were changed to be more intuitive.

But the more intuitive behavior automatically happens if wildcard
imports are replaced with explicit imports of the names they had
originally intended to import (in this case, in the top-level git
module, which has not yet been done but will be), or if __all__ is
added where helpful (in this case, in git.index, which this does).
Adding the names explicitly is sufficient to restore the old
behavior that is needed for backward compatibility, and has the
further advantage that the unintuitive behavior will be explicit
once all wildcard imports are replaced and __all__ is added to each
module where it would be helpful. The modattrs.py script serves to
ensure incompatible changes are not made; this commit checks it.

The tests in test_imports.py also cover this specific anticipated
incompatibility in git.util, but not all breakages that may arise
when refactoring imports and that diff-ing modattrs.py output would
help catch.
  • Loading branch information
EliahKagan committed Mar 18, 2024
1 parent 5b2771d commit fc86a23
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 8 deletions.
30 changes: 30 additions & 0 deletions ab.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
diff --git a/a b/b
index 81b3f984..7b8c8ede 100644
--- a/a
+++ b/b
@@ -83,14 +83,12 @@ git:
__path__: ['C:\\Users\\ek\\source\\repos\\GitPython\\git']
__spec__: ModuleSpec(name='git', loader=<_frozen_importlib_external.SourceFileLoader object at 0x...>, origin='C:\\Users\\ek\\source\\repos\\GitPython\\git\\__init__.py', submodule_search_locations=['C:\\Users\\ek\\source\\repos\\GitPython\\git'])
__version__: 'git'
- base: <module 'git.index.base' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\index\\base.py'>
cmd: <module 'git.cmd' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\cmd.py'>
compat: <module 'git.compat' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\compat.py'>
config: <module 'git.config' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\config.py'>
db: <module 'git.db' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\db.py'>
diff: <module 'git.diff' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\diff.py'>
exc: <module 'git.exc' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\exc.py'>
- fun: <module 'git.index.fun' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\index\\fun.py'>
head: <module 'git.refs.head' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\refs\\head.py'>
index: <module 'git.index' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\index\\__init__.py'>
log: <module 'git.refs.log' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\refs\\log.py'>
@@ -106,9 +104,8 @@ git:
symbolic: <module 'git.refs.symbolic' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\refs\\symbolic.py'>
tag: <module 'git.refs.tag' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\refs\\tag.py'>
to_hex_sha: <function to_hex_sha at 0x...>
- typ: <module 'git.index.typ' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\index\\typ.py'>
types: <module 'git.types' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\types.py'>
- util: <module 'git.index.util' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\index\\util.py'>
+ util: <module 'git.util' from 'C:\\Users\\ek\\source\\repos\\GitPython\\git\\util.py'>


git.cmd:
13 changes: 11 additions & 2 deletions git/index/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,14 @@

"""Initialize the index package."""

from .base import * # noqa: F401 F403
from .typ import * # noqa: F401 F403
__all__ = [
"BaseIndexEntry",
"BlobFilter",
"CheckoutError",
"IndexEntry",
"IndexFile",
"StageType",
]

from .base import CheckoutError, IndexFile
from .typ import BaseIndexEntry, BlobFilter, IndexEntry, StageType
5 changes: 2 additions & 3 deletions git/index/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
"""Module containing :class:`IndexFile`, an Index implementation facilitating all kinds
of index manipulations such as querying and merging."""

__all__ = ("IndexFile", "CheckoutError", "StageType")

import contextlib
import datetime
import glob
Expand Down Expand Up @@ -81,9 +83,6 @@
# ------------------------------------------------------------------------------------


__all__ = ("IndexFile", "CheckoutError", "StageType")


@contextlib.contextmanager
def _named_temporary_file_for_subprocess(directory: PathLike) -> Generator[str, None, None]:
"""Create a named temporary file git subprocesses can open, deleting it afterward.
Expand Down
5 changes: 2 additions & 3 deletions git/index/typ.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@

"""Additional types used by the index."""

__all__ = ("BlobFilter", "BaseIndexEntry", "IndexEntry", "StageType")

from binascii import b2a_hex
from pathlib import Path

from .util import pack, unpack
from git.objects import Blob


# typing ----------------------------------------------------------------------

from typing import NamedTuple, Sequence, TYPE_CHECKING, Tuple, Union, cast
Expand All @@ -23,8 +24,6 @@

# ---------------------------------------------------------------------------------

__all__ = ("BlobFilter", "BaseIndexEntry", "IndexEntry", "StageType")

# { Invariants
CE_NAMEMASK = 0x0FFF
CE_STAGEMASK = 0x3000
Expand Down

0 comments on commit fc86a23

Please sign in to comment.