diff --git a/.github/workflows/autotest.yml b/.github/workflows/autotest.yml index 0fb7ac20..8ffa00d2 100644 --- a/.github/workflows/autotest.yml +++ b/.github/workflows/autotest.yml @@ -62,7 +62,7 @@ jobs: architecture: ${{ matrix.architecture }} - name: install comtypes run: | - pip install --upgrade setuptools + pip install --upgrade build python -m pip install . pip uninstall comtypes -y python test_pip_install.py diff --git a/.gitignore b/.gitignore index 940abb2b..a7a9b271 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ comtypes/gen/ !comtypes/gen/__init__.py comtypes/tools/__pycache__/*.pyc comtypes.egg-info/* +custom location/* # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/pyproject.toml b/pyproject.toml index c9df6598..ba9e49d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,63 @@ +[project] +name = "comtypes" +description = "Pure Python COM package" +readme = "README.md" +requires-python = ">=3.9" +license = "MIT" +license-files = ["LICENSE.txt"] +authors = [ + { name = "Thomas Heller", email = "theller@python.net" }, +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Operating System :: Microsoft :: Windows", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Topic :: Software Development :: Libraries :: Python Modules", +] +dynamic = ["version"] + +[project.scripts] +clear_comtypes_cache = "comtypes.clear_cache:main" + +[project.urls] +Source = "https://github.com/enthought/comtypes" +Download = "https://github.com/enthought/comtypes/releases" +Issues = "https://github.com/enthought/comtypes/issues" + [build-system] -requires = ["setuptools>=61.2"] +requires = ["setuptools>=77.0.0"] build-backend = "setuptools.build_meta" +[tool.setuptools] +packages = [ + "comtypes", + "comtypes._post_coinit", + "comtypes.client", + "comtypes.server", + "comtypes.tools", + "comtypes.tools.codegenerator", + "comtypes.test", +] + +[tool.setuptools.dynamic] +version = { attr = "comtypes.__version__" } + +[tool.setuptools.package-data] +"comtypes.test" = [ + "TestComServer.idl", + "TestComServer.tlb", + "TestDispServer.idl", + "TestDispServer.tlb", + "mytypelib.idl", + "mylib.idl", + "mylib.tlb", + "urlhist.tlb", + "test_jscript.js", +] +"comtypes" = ["hints.pyi"] + [tool.ruff.lint] extend-select = ["I"] ignore = ["E402"] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index bb98b1c2..00000000 --- a/setup.cfg +++ /dev/null @@ -1,48 +0,0 @@ -[metadata] -name = comtypes -description = Pure Python COM package -author = Thomas Heller -author_email = theller@python.net -url = https://github.com/enthought/comtypes -download_url = https://github.com/enthought/comtypes/releases -version = attr:comtypes.__version__ -long_description = file:README.md -long_description_content_type = text/markdown -classifiers = - Development Status :: 5 - Production/Stable - Intended Audience :: Developers - License :: OSI Approved :: MIT License - Operating System :: Microsoft :: Windows - Programming Language :: Python - Programming Language :: Python :: 3 - Topic :: Software Development :: Libraries :: Python Modules - -[options] -python_requires = >=3.9 - -packages = - comtypes - comtypes._post_coinit - comtypes.client - comtypes.server - comtypes.tools - comtypes.tools.codegenerator - comtypes.test - -[options.package_data] -comtypes.test = - TestComServer.idl - TestComServer.tlb - TestDispServer.idl - TestDispServer.tlb - mytypelib.idl - mylib.idl - mylib.tlb - urlhist.tlb - test_jscript.js -comtypes = - hints.pyi - -[options.entry_points] -console_scripts = - clear_comtypes_cache = comtypes.clear_cache:main diff --git a/setup.py b/setup.py deleted file mode 100644 index 407cdfcb..00000000 --- a/setup.py +++ /dev/null @@ -1,117 +0,0 @@ -"""comtypes package install script""" - -import sys -import os -import subprocess - -from setuptools import Command, setup -from setuptools.command.install import install - - -class test(Command): - # Original version of this class posted - # by Berthold Hoellmann to distutils-sig@python.org - description = "run tests" - - user_options = [ - ('tests=', 't', "comma-separated list of packages that contain test modules"), - ( - 'use-resources=', - 'u', - "resources to use - resource names are defined by tests", - ), - ( - 'refcounts', - 'r', - "repeat tests to search for refcount leaks (requires " - "'sys.gettotalrefcount')", - ), - ] - - boolean_options = ["refcounts"] - - def initialize_options(self): - self.use_resources = "" - self.refcounts = False - self.tests = "comtypes.test" - self.failure = False - - def finalize_options(self): - if self.refcounts and not hasattr(sys, "gettotalrefcount"): - raise Exception("refcount option requires Python debug build") - self.tests = self.tests.split(",") - self.use_resources = self.use_resources.split(",") - - def run(self): - build = self.reinitialize_command('build') - build.run() - if build.build_lib is not None: - sys.path.insert(0, build.build_lib) - - # Register our ATL COM tester dll - import comtypes.test - - script_path = os.path.dirname(__file__) - source_dir = os.path.abspath(os.path.join(script_path, "source")) - comtypes.test.register_server(source_dir) - - comtypes.test.use_resources.extend(self.use_resources) - for name in self.tests: - package = __import__(name, globals(), locals(), ['*']) - sys.stdout.write( - "Testing package %s %s\n" % (name, (sys.version, sys.platform, os.name)) - ) - package_failure = comtypes.test.run_tests( - package, "test_*.py", self.verbose, self.refcounts - ) - self.failure = self.failure or package_failure - - -class post_install(install): - # both this static variable and method initialize_options() help to avoid - # weird setuptools error with "pip install comtypes", details are here: - # https://github.com/enthought/comtypes/issues/155 - # the working solution was found here: - # https://github.com/pypa/setuptools/blob/3b90be7bb6323eb44d0f28864509c1d47aa098de/setuptools/command/install.py - user_options = install.user_options + [ - ('old-and-unmanageable', None, "Try not to use this!"), - ( - 'single-version-externally-managed', - None, - "used by system package builders to create 'flat' eggs", - ), - ] - - def initialize_options(self): - install.initialize_options(self) - self.old_and_unmanageable = None - self.single_version_externally_managed = None - - def run(self): - install.run(self) - # Custom script we run at the end of installing - if not self.dry_run and not self.root: - print("Executing post install script...") - print(f'"{sys.executable}" -m comtypes.clear_cache -y') - try: - subprocess.check_call([ - sys.executable, - "-m", - "comtypes.clear_cache", - '-y', - ]) - except subprocess.CalledProcessError: - print("Failed to run post install script!") - - -if __name__ == '__main__': - dist = setup( - cmdclass={ - 'test': test, - 'install': post_install, - }, - ) - # Exit with a failure code if only running the tests and they failed - if dist.commands == ['test']: - command = dist.command_obj['test'] - sys.exit(command.failure) diff --git a/test_pip_install.py b/test_pip_install.py index 09e333e3..14a8474d 100644 --- a/test_pip_install.py +++ b/test_pip_install.py @@ -21,18 +21,18 @@ class TestPipInstall(unittest.TestCase): def setUp(self): """prepare the same package that is usually uploaded to PyPI""" - subprocess.check_call([sys.executable, 'setup.py', 'sdist', '--format=zip']) + subprocess.check_call([sys.executable, '-m', 'build', '--sdist']) - filename_for_upload = 'comtypes-%s.zip' % read_version() + filename_for_upload = 'comtypes-%s.tar.gz' % read_version() self.target_package = os.path.join(os.getcwd(), 'dist', filename_for_upload) self.pip_exe = os.path.join(os.path.dirname(sys.executable), 'Scripts', 'pip.exe') def test_pip_install(self): - """Test that "pip install comtypes-x.y.z.zip" works""" + """Test that "pip install comtypes-x.y.z.tar.gz" works""" subprocess.check_call([self.pip_exe, 'install', self.target_package]) def test_no_cache_dir_custom_location(self): - """Test that 'pip install comtypes-x.y.z.zip --no-cache-dir --target="...\custom location"' works""" + """Test that 'pip install comtypes-x.y.z.tar.gz --no-cache-dir --target="...\custom location"' works""" custom_dir = os.path.join(os.getcwd(), 'custom location') if os.path.exists(custom_dir): shutil.rmtree(custom_dir)