Re: Trouble with list iteration / comprehension for wrapped COM objects

Mark Hammond via python-win32 <[email protected]> Fri, 18 Apr 2025 22:31:16 -0400
Newsgroups gmane.comp.python.windows
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--===============1603758368910056733==
Content-Type: multipart/alternative;
 boundary="------------RmPwzkZvNE0TrMJdFIUSc3yY"
Content-Language: en-US

This is a multi-part message in MIME format.
--------------RmPwzkZvNE0TrMJdFIUSc3yY
Content-Type: text/plain; charset=UTF-8; format=flowed
Content-Transfer-Encoding: 8bit

I'm not sure what's going wrong here. Does fetching the list of 
workspaces as a simple list work? That would be a workaround, and
feel free open an issue at https://github.com/mhammond/pywin32 since it 
shouldn't break that way.

Cheers

On 2025-04-18 8:33 p.m., dornech via python-win32 wrote:
> Hi there,
>
> I am working on an EXCEL wrapper to "phytonize" access to EXCEL.
>
> I create a wrapper class for all objects classes derived from abasic 
> wrapper class which mainly ensures that calls are snaked-case and 
> pyhtonized calls work. I. e. workbokkobject.SaveAs, 
> workbookobject.saveas and workbokkobject.save_as would all work. This 
> is done by overloaded __getattr__ and __setattr__ methods.
>
> The "real" EXCEL object is stored in the attribute "_xlWrapped".
>
> The overloaded __getattr__ also ensures that when retrieving f. e. a 
> workbook from the application wrapper, that the resulting EXCEL object 
> is wrapped as well. I. e. let xlapp be my wrapped EXCEL then 
> xlapp.active_workbook would return a reference to a wrapped Workbook 
> object which contains the reference to the "real" EXCEL workbook 
> object in the attribute _xlwrapped.
>
> I also overload __getitem__ to allow xlapp[1] as short for 
> xlapp.workbooks(1).
>
> Some of these classes I do extend for example to check existence of a 
> worksheet in a workbook.
>
> This as very brief introduction.
>
> Now I am struggeling with list comprehension and indexes.
>
>     # access un-wrapped EXCEL
>     print(xlapp._xlWrapped.Workbooks(1).Name)
>     print(xlapp._xlWrapped.Workbooks(2).Name)
>     for i, wb in enumerate(xlapp._xlWrapped.Workbooks):
>         print(i, wb.Name)
>
>     # access wrapped EXCEL
>     print(xlapp.Workbooks(1).Name)
>     print(xlapp.Workbooks(2).Name)
>     for i, wb in enumerate(xlapp.Workbooks):
>         print(i, wb.Name)
>
> This prints
>     WB1.xls
>     WB2.xls
>     0  WB1.xls
>     1  WB2.xls
>     WB1.xls
>     WB2.xls
>  and aborts with an windows/COM error:
>
>  ret = self._oleobj_.InvokeTypes(170, LCID, 2, (13, 0), ((12, 1),),Index
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> pywintypes.com_error: (-2147352567, 'Ausnahmefehler aufgetreten.', (0, 
> None, None, None, 0, -2147352565), None)
>
> Obviously when looping via the wrapper object the index is not 
> automatically adjusted.
> However, I must not increase the index by on in __getitem__ because 
> then the index would alway be increased.
>
> It seems, püywin32 has some special support for list comprehension and 
> index adjustment for COM objects?
> I haven't worked with an iterator before but is this the solution?
>
> Thanks in advance.
>
> Best
> Christoph
>
>
>
>
>
> _______________________________________________
> python-win32 mailing list
> [email protected]
> https://mail.python.org/mailman/listinfo/python-win32
--------------RmPwzkZvNE0TrMJdFIUSc3yY
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: 8bit

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p>I'm not sure what's going wrong here. Does fetching the list of
      workspaces as a simple list work? That would be a workaround, and
      <br>
      feel free open an issue at <a class="moz-txt-link-freetext" href="https://github.com/mhammond/pywin32">https://github.com/mhammond/pywin32</a>
      since it shouldn't break that way.</p>
    <p>Cheers</p>
    <div class="moz-cite-prefix">On 2025-04-18 8:33 p.m., dornech via
      python-win32 wrote:<br>
    </div>
    <blockquote type="cite"
      cite="mid:[email protected]">Hi there,
      <br>
      <br>
      I am working on an EXCEL wrapper to "phytonize" access to EXCEL.
      <br>
      <br>
      I create a wrapper class for all objects classes derived from
      abasic wrapper class which mainly ensures that calls are
      snaked-case and pyhtonized calls work. I. e.
      workbokkobject.SaveAs, workbookobject.saveas and
      workbokkobject.save_as would all work. This is done by overloaded
      __getattr__ and __setattr__ methods.
      <br>
      <br>
      The "real" EXCEL object is stored in the attribute "_xlWrapped".
      <br>
      <br>
      The overloaded __getattr__ also ensures that when retrieving f. e.
      a workbook from the application wrapper, that the resulting EXCEL
      object is wrapped as well. I. e. let xlapp be my wrapped EXCEL
      then xlapp.active_workbook would return a reference to a wrapped
      Workbook object which contains the reference to the "real" EXCEL
      workbook object in the attribute _xlwrapped.
      <br>
      <br>
      I also overload __getitem__ to allow xlapp[1] as short for
      xlapp.workbooks(1).
      <br>
      <br>
      Some of these classes I do extend for example to check existence
      of a worksheet in a workbook.
      <br>
      <br>
      This as very brief introduction.
      <br>
      <br>
      Now I am struggeling with list comprehension and indexes.
      <br>
      <br>
          # access un-wrapped EXCEL
      <br>
          print(xlapp._xlWrapped.Workbooks(1).Name)
      <br>
          print(xlapp._xlWrapped.Workbooks(2).Name)
      <br>
          for i, wb in enumerate(xlapp._xlWrapped.Workbooks):
      <br>
              print(i, wb.Name)
      <br>
      <br>
          # access wrapped EXCEL
      <br>
          print(xlapp.Workbooks(1).Name)
      <br>
          print(xlapp.Workbooks(2).Name)
      <br>
          for i, wb in enumerate(xlapp.Workbooks):
      <br>
              print(i, wb.Name)
      <br>
      <br>
      This prints
      <br>
          WB1.xls
      <br>
          WB2.xls
      <br>
          0  WB1.xls
      <br>
          1  WB2.xls
      <br>
          WB1.xls
      <br>
          WB2.xls
      <br>
       and aborts with an windows/COM error:
      <br>
      <br>
       ret = self._oleobj_.InvokeTypes(170, LCID, 2, (13, 0), ((12,
      1),),Index
      <br>
      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      <br>
      pywintypes.com_error: (-2147352567, 'Ausnahmefehler aufgetreten.',
      (0, None, None, None, 0, -2147352565), None)
      <br>
      <br>
      Obviously when looping via the wrapper object the index is not
      automatically adjusted.
      <br>
      However, I must not increase the index by on in __getitem__
      because then the index would alway be increased.
      <br>
      <br>
      It seems, püywin32 has some special support for list comprehension
      and index adjustment for COM objects?
      <br>
      I haven't worked with an iterator before but is this the solution?
      <br>
      <br>
      Thanks in advance.
      <br>
      <br>
      Best
      <br>
      Christoph
      <br>
      <br>
      <br>
      <br>
      <br>
      <br>
      _______________________________________________
      <br>
      python-win32 mailing list
      <br>
      <a class="moz-txt-link-abbreviated" href="mailto:[email protected]">[email protected]</a>
      <br>
      <a class="moz-txt-link-freetext" href="https://mail.python.org/mailman/listinfo/python-win32">https://mail.python.org/mailman/listinfo/python-win32</a>
      <br>
    </blockquote>
  </body>
</html>

--------------RmPwzkZvNE0TrMJdFIUSc3yY--

--===============1603758368910056733==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
python-win32 mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-win32

--===============1603758368910056733==--