Skip to content

Python 3: Fix error with accPropServer - #9900

Merged
feerrenrut merged 3 commits into
threshold_py3_stagingfrom
fixErrorInSettingDialog
Jul 10, 2019
Merged

Python 3: Fix error with accPropServer#9900
feerrenrut merged 3 commits into
threshold_py3_stagingfrom
fixErrorInSettingDialog

Conversation

@feerrenrut

Copy link
Copy Markdown
Contributor

Link to issue number:

#9768

Summary of the issue:

The VARIANT out-param had not been initialised correct.
Comtypes was not initialising VARIANT.vt to VT_EMPTY, and attempting to call VariantClear (oleauto.h) before assigning it the value returned from getProp.

Description of how this pull request fixes the issue:

Instead, we implement a low-level (require a this param) getProp method, which is then provided pointers to the out-params, and can initialise them correctly.

Testing performed:

Run locally from source.

Known issues with pull request:

None

Change log entry:

None

The VARIANT out-param had not been initialised correct.
Comtypes was not initialising VARIANT.vt to VT_EMPTY, and attempting to call VariantClear (oleauto.h) before assigning it the value returned from getProp.
Instead, we implement a low-level (require a this param) getProp method, which is then provided pointers to the out-params, and can initialise them correctly.
@feerrenrut
feerrenrut requested a review from LeonarddeR July 8, 2019 18:14
@feerrenrut

Copy link
Copy Markdown
Contributor Author

I'll attach a try build link shortly.

@feerrenrut

Copy link
Copy Markdown
Contributor Author

Please use the following try build to test for issues.

@feerrenrut feerrenrut changed the title Fix error with accPropServer Python 3: Fix error with accPropServer Jul 8, 2019

@LeonarddeR LeonarddeR left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just some small things. Having said that, I was pretty sure that I had a similar low level implementation, though yet that implementation didn't work.

Comment thread source/gui/accPropServer.py Outdated
Comment thread source/gui/accPropServer.py Outdated
Comment thread source/gui/accPropServer.py Outdated
Comment thread source/gui/accPropServer.py
Comment thread source/gui/accPropServer.py Outdated
@Brian1Gaff

This comment has been minimized.

@feerrenrut

Copy link
Copy Markdown
Contributor Author

I was pretty sure that I had a similar low level implementation

I did't actually look at your implementation. The key things that took me time to realise:

  • understanding that the variant.vt value needs to be set to VT_EMPTY before assigning a value.
  • ensuring that all exceptions are caught and logged in the function so you know when there is an error.

- Encompass getProp in a try block, ensure all exceptions are caught and
logged.
- Tidy type hints
- Use clearer method to set pointer values
- Remove redefined S_OK
@feerrenrut
feerrenrut requested a review from LeonarddeR July 9, 2019 09:21
Comment thread source/gui/accPropServer.py Outdated
except Exception:
# Preset values for "no prop value", in case we return early.
pfGotProp.contents.value = self.DOES_NOT_HAVE_PROP
pvarValue.contents.vt = VT_EMPTY

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here you're setting contents.vt and below you're setting contents.value. Why is that?

If you prefer subscripting with [0], I can certainly live with that. Just not sure what's the preferred way of doing this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.vt must be set, to ensure that comtypes does not attempt to clear an uninitialised VARIANT , or more accurately, it's safe when it does clear it. When you assign a value, comtypes automatically converts the value being assigned, but first it clears the VARIANT. Out params don't seem to have a guarantee of being initialised. So .vt which, I assume stands for variant type, could be anything. It's explicitly unsafe to clear an uninitialised variant, see variantClear Docs for the following snippet:

Do not use VariantClear on unitialized variants; use VariantInit to initialize a new VARIANTARG or VARIANT.

Rather than setting .vt we could call VariantInit
I suspect this was causing the issue I was having when trying to override name a while back.

I don't really have a preference for getting to the pointer contents, I'll leave it as is.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm leaning towards using VariantInit rather than setting vt, but the server annotation sample does it like this.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This stackoverflow answer convinces me to use it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds reasonable.

pfGotProp.contents.value = self.HAS_PROP
pvarValue.contents.value = ret[0]
except Exception as e: # catch and log all exceptions so they are not swallowed by caller.
log.exception()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I still prefer returning something else than S_OK here. May be S_FALSE is a good one here, or comtypes.hresult.E_FAIL? Not sure how hresult codes work.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not so sure, I don't think we should be reporting an error unless it is the callers fault. If we would succeed with another value, then this essentially translates to a "look-up error", that outcome is handled by the pfGotProp outparam.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, fair enough.

@LeonarddeR

Copy link
Copy Markdown
Collaborator

@feerrenrut: related to this is the list of monkey patches we apply to comtypes.

From code inspection/investigation, it turns out that at least the patch to support byref in variants can be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants