Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

477 Move clear_comtypes_cache to be a callable module #478

Merged
merged 5 commits into from
Jun 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ Those `.py` files act like ”caches”.

If there are some problems with the developing code base, partial or non-executable modules might be created in `.../comtypes/gen/...`.
Importing them will cause some error.
If that happens, you should run `python -m clear_comtypes_cache` to clear those caches.
If that happens, you should run `python -m comtypes.clear_cache` to clear those caches.
The command will delete the entire `.../comtypes/gen` directory.
Importing `comtypes.gen.client` will restore the directory and `__init__.py` file.

Expand Down
57 changes: 0 additions & 57 deletions clear_comtypes_cache.py

This file was deleted.

53 changes: 53 additions & 0 deletions comtypes/clear_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import argparse
import contextlib
import os
import sys
from shutil import rmtree # TESTS ASSUME USE OF RMTREE


bennyrowland marked this conversation as resolved.
Show resolved Hide resolved
# if supporting Py>=3.11 only, this might be `contextlib.chdir`.
# https://docs.python.org/3/library/contextlib.html#contextlib.chdir
@contextlib.contextmanager
def chdir(path):
"""Context manager to change the current working directory."""
work_dir = os.getcwd()
os.chdir(path)
yield
os.chdir(work_dir)


def main():
parser = argparse.ArgumentParser(
prog="py -m comtypes.clear_cache", description="Removes comtypes cache folders."
)
parser.add_argument(
"-y", help="Pre-approve deleting all folders", action="store_true"
)
args = parser.parse_args()

if not args.y:
confirm = input("Remove comtypes cache directories? (y/n): ")
if confirm.lower() != "y":
print("Cache directories NOT removed")
return

# change cwd to avoid import from local folder during installation process
with chdir(os.path.dirname(sys.executable)):
try:
import comtypes.client
except ImportError:
print("Could not import comtypes", file=sys.stderr)
sys.exit(1)

# there are two possible locations for the cache folder (in the comtypes
# folder in site-packages if that is writable, otherwise in APPDATA)
# fortunately, by deleting the first location returned by _find_gen_dir()
# we make it un-writable, so calling it again gives us the APPDATA location
for _ in range(2):
dir_path = comtypes.client._find_gen_dir()
rmtree(dir_path)
print(f'Removed directory "{dir_path}"')


if __name__ == "__main__":
main()
25 changes: 25 additions & 0 deletions comtypes/test/test_clear_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""
Test for the ``comtypes.clear_cache`` module.
"""
import contextlib
import runpy
from unittest.mock import patch, call
from unittest import TestCase

from comtypes.client import _find_gen_dir


class ClearCacheTestCase(TestCase):
# we patch sys.stdout so unittest doesn't show the print statements

@patch("sys.argv", ["clear_cache.py", "-y"])
@patch("shutil.rmtree")
def test_clear_cache(self, mock_rmtree):
with contextlib.redirect_stdout(None):
runpy.run_module("comtypes.clear_cache", {}, "__main__")

# because we don't actually delete anything, _find_gen_dir() will
# give the same answer every time we call it
self.assertEqual(
mock_rmtree.call_args_list, [call(_find_gen_dir()) for _ in range(2)]
)
12 changes: 5 additions & 7 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,10 @@ def run(self):
install.run(self)
# Custom script we run at the end of installing
if not self.dry_run and not self.root:
filename = os.path.join(
self.install_scripts, "clear_comtypes_cache.py")
if not os.path.isfile(filename):
raise RuntimeError("Can't find '%s'" % (filename,))
print("Executing post install script...")
print('"' + sys.executable + '" "' + filename + '" -y')
print(f'"{sys.executable}" -m comtypes.clear_cache -y')
try:
subprocess.check_call([sys.executable, filename, '-y'])
subprocess.check_call([sys.executable, "-m", "comtypes.clear_cache", '-y'])
except subprocess.CalledProcessError:
print("Failed to run post install script!")

Expand Down Expand Up @@ -146,7 +142,9 @@ def run(self):
]},
classifiers=classifiers,

scripts=["clear_comtypes_cache.py"],
entry_points={
"console_scripts": ["clear_comtypes_cache=comtypes.clear_cache:main"]
},

cmdclass={
'test': test,
Expand Down