Skip to content
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
10 changes: 10 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ jobs:
python -m win32.scripts.pywin32_postinstall -install -destination "$UserSite"
pywin32_postinstall -remove -destination "$UserSite"

# Compilation and registration of the PyCOMTest server dll
- name: Set up MSVC
uses: microsoft/setup-msbuild@v2
- name: Build and register the PyCOMTest server dll
run: |
cd com/TestSources/PyCOMTest
msbuild .\PyCOMTest.sln -property:Configuration=Release
cd x64/Release
regsvr32 .\PyCOMTest.dll

- name: Run tests
# Run the tests directly from the source dir so support files (eg, .wav files etc)
# can be found - they aren't installed into the Python tree.
Expand Down
18 changes: 10 additions & 8 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,23 @@ arm64libs/
pywin32.egg-info/
PyWin32.kpf

# Visual Studio project files
*.sln
*.suo
*.vc*proj*
*.user

# COM test bits
com/TestSources/Build
com/TestSources/PyCOMTest/PyCOMTest.h
com/TestSources/PyCOMTest/PyCOMTest.sln
com/TestSources/PyCOMTest/PyCOMTest.suo
com/TestSources/PyCOMTest/PyCOMTest.tlb
com/TestSources/PyCOMTest/PyCOMTest.vc*proj*
com/TestSources/PyCOMTest/PyCOMTest_i.c
com/TestSources/PyCOMTest/.vs/
com/TestSources/PyCOMTest/PyCOMTest/
com/TestSources/PyCOMTest/x64/
!com/TestSources/PyCOMTest/PyCOMTest.sln
!com/TestSources/PyCOMTest/PyCOMTest.vcxproj

# SWIG generated files.
com/win32comext/adsi/src/*.cpp
Expand All @@ -50,12 +58,6 @@ win32/src/win32service_messages.h
win32/src/win32evtlog_messages.h
isapi/src/pyISAPI_messages.h

# Visual Studio project files
*.sln
*.suo
*.vcproj
*.user

# Eclipse + PyDev
.project
.pydevproject
Expand Down
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ https://mhammond.github.io/pywin32_installers.html .

Coming in build 311, as yet unreleased
--------------------------------------
* Fixed a regression that broke special __dunder__ methods with CoClass. (#1870, #2493, @Avasam, @geppi)

Build 310, released 2025/03/16
------------------------------
Expand Down
4 changes: 2 additions & 2 deletions com/TestSources/PyCOMTest/PyCOMTest.idl
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ typedef enum // Missing EnumTestAttributes2
uuid(6bcdcb60-5605-11d0-ae5f-cadd4c000000),
version(1.1),
// an extended character in the help string should stress things...
helpstring("Python COM Test Harness 1.0 Type Library, � pywin32 contributors")
helpstring("Python COM Test Harness 1.0 Type Library, � pywin32 contributors")
]
library PyCOMTestLib
{
Expand Down Expand Up @@ -70,7 +70,7 @@ library PyCOMTestLib
const long LongTest2 = 0x7FFFFFFFL;
const unsigned char UCharTest = 255;
const char CharTest = -1;
const LPWSTR StringTest = L"Hello Wo�ld";
const LPWSTR StringTest = L"Hello Wo�ld";
};

enum TestAttributes3{ // Note missing the enum name.
Expand Down
31 changes: 31 additions & 0 deletions com/TestSources/PyCOMTest/PyCOMTest.sln
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35027.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "PyCOMTest", "PyCOMTest.vcxproj", "{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}.Debug|x64.ActiveCfg = Debug|x64
{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}.Debug|x64.Build.0 = Debug|x64
{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}.Debug|x86.ActiveCfg = Debug|Win32
{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}.Debug|x86.Build.0 = Debug|Win32
{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}.Release|x64.ActiveCfg = Release|x64
{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}.Release|x64.Build.0 = Release|x64
{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}.Release|x86.ActiveCfg = Release|Win32
{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {E15B431A-88C2-47F5-B809-AAC25279BD21}
EndGlobalSection
EndGlobal
164 changes: 164 additions & 0 deletions com/TestSources/PyCOMTest/PyCOMTest.vcxproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{8EB3046C-6CE8-4537-9B58-6EDD46E6D632}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0.22000.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>NotSet</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>true</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;PYCOMTEST_EXPORTS;/nologo /MDd /W3 /Gm /GX /ZI /Od /D _DEBUG /D WIN32 /D _WINDOWS /D _USRDLL /D _UNICODE /D _WINDLL /D _AFXDLL /D _MBCS /Yupreconn.h /FD /c;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>Connect.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;PYCOMTEST_EXPORTS;/nologo /MDd /W3 /Gm /GX /ZI /Od /D _DEBUG /D WIN32 /D _WINDOWS /D _USRDLL /D _UNICODE /D _WINDLL /D _AFXDLL /D _MBCS /Yupreconn.h /FD /c;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<ModuleDefinitionFile>Connect.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;PYCOMTEST_EXPORTS;/nologo /MD /W3 /GX /O2 /D NDEBUG /D WIN32 /D _WINDOWS /D _USRDLL /D _UNICODE /D _WINDLL /D _AFXDLL /D _MBCS /Yupreconn.h /FD /c;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<ModuleDefinitionFile>Connect.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;PYCOMTEST_EXPORTS;/nologo /MD /W3 /GX /O2 /D NDEBUG /D WIN32 /D _WINDOWS /D _USRDLL /D _UNICODE /D _WINDLL /D _AFXDLL /D _MBCS /Yupreconn.h /FD /c;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<WarningLevel>Level3</WarningLevel>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>false</OptimizeReferences>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ModuleDefinitionFile>Connect.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="Connect.cpp" />
<ClCompile Include="DSCArrayTest.cpp" />
<ClCompile Include="preconn.cpp" />
<ClCompile Include="PyCOMImpl.cpp" />
<ClCompile Include="SimpleCounter.cpp" />
</ItemGroup>
<ItemGroup>
<Midl Include="PyCOMTest.idl">
<HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).h</HeaderFileName>
<TypeLibraryName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(Filename).tlb</TypeLibraryName>
<HeaderFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).h</HeaderFileName>
<TypeLibraryName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).tlb</TypeLibraryName>
</Midl>
</ItemGroup>
<ItemGroup>
<None Include="ArrayTest.rgs" />
<None Include="Connect.def" />
<None Include="PyCOMTest.rgs" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="connres.h" />
<ClInclude Include="DSCArrayTest.h" />
<ClInclude Include="preconn.h" />
<ClInclude Include="PyCOMImpl.h" />
<ClInclude Include="SimpleCounter.h" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="Connect.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
51 changes: 19 additions & 32 deletions com/win32com/client/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -628,18 +628,7 @@ class CoClassBaseClass:
def __init__(self, oobj=None):
if oobj is None:
oobj = pythoncom.new(self.CLSID)
dispobj = self.__dict__["_dispobj_"] = self.default_interface(oobj)
# See comments below re the special methods.
for maybe in [
"__call__",
"__str__",
"__int__",
"__iter__",
"__len__",
"__bool__",
]:
if hasattr(dispobj, maybe):
setattr(self, maybe, getattr(self, "__maybe" + maybe))
self.__dict__["_dispobj_"] = self.default_interface(oobj)

def __repr__(self):
return f"<win32com.gen_py.{__doc__}.{self.__class__.__name__}>"
Expand All @@ -663,31 +652,29 @@ def __setattr__(self, attr, value):
pass
self.__dict__[attr] = value

# Special methods don't use __getattr__ etc, so explicitly delegate here.
# Note however, that not all are safe to let bubble up - things like
# `bool(ob)` will break if the object defines __int__ but then raises an
# attribute error - eg, see #1753.
# It depends on what the wrapped COM object actually defines whether these
# will exist on the underlying object, so __init__ explicitly checks if they
# do and if so, wires them up.
# Special methods don't use __getattr__ etc, so explicitly delegate here.
# Some wrapped objects might not have them, but that's OK - the attribute
# error can just bubble up.
# This was initially implemented to address #1699 which did cause a problem
# with bool() in #1753 because the code initially implemented __nonzero__
# instead of __bool__, which was pointed out in the conclusion of #1870.
def __call__(self, *args, **kwargs):
return self.__dict__["_dispobj_"](*args, **kwargs)

def __maybe__call__(self, *args, **kwargs):
return self.__dict__["_dispobj_"].__call__(*args, **kwargs)
def __str__(self, *args):
return str(self.__dict__["_dispobj_"])

def __maybe__str__(self, *args):
return self.__dict__["_dispobj_"].__str__(*args)
def __int__(self, *args):
return int(self.__dict__["_dispobj_"])

def __maybe__int__(self, *args):
return self.__dict__["_dispobj_"].__int__(*args)
def __iter__(self):
return iter(self.__dict__["_dispobj_"])

def __maybe__iter__(self):
return self.__dict__["_dispobj_"].__iter__()
def __len__(self):
return len(self.__dict__["_dispobj_"])

def __maybe__len__(self):
return self.__dict__["_dispobj_"].__len__()

def __maybe__bool__(self):
return self.__dict__["_dispobj_"].__bool__()
def __bool__(self):
return bool(self.__dict__["_dispobj_"])


# A very simple VARIANT class. Only to be used with poorly-implemented COM
Expand Down
2 changes: 1 addition & 1 deletion com/win32com/test/testArrays.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def _normalize_array(a):

class ArrayTest(util.TestCase):
def setUp(self):
self.arr = gencache.EnsureDispatch("PyCOMTest.ArrayTest")
self.arr = gencache.EnsureDispatch("PyCOMTest.ArrayTest", bForDemand=False)

def tearDown(self):
self.arr = None
Expand Down
4 changes: 3 additions & 1 deletion com/win32com/test/testPyComTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@
from win32com.client import gencache

try:
gencache.EnsureModule("{6BCDCB60-5605-11D0-AE5F-CADD4C000000}", 0, 1, 1)
gencache.EnsureModule(
"{6BCDCB60-5605-11D0-AE5F-CADD4C000000}", 0, 1, 1, bForDemand=False
)
except pythoncom.com_error:
print("The PyCOMTest module can not be located or generated.")
print(importMsg)
Expand Down
5 changes: 3 additions & 2 deletions com/win32com/test/testall.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,11 @@ def testit(self):

custom_test_cases = [
# Level 1 tests.
[],
# Level 2 tests.
[
PyCOMTest,
],
# Level 2 tests.
[
PippoTest,
],
# Level 3 tests
Expand Down