Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Fix Propertyless Object not displaying correctly after ETS introspection#25871

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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
GregoireLD wants to merge13 commits intoPowerShell:master
base:master
Choose a base branch
Loading
fromGregoireLD:master

Conversation

@GregoireLD
Copy link

@GregoireLDGregoireLD commentedAug 16, 2025
edited
Loading

PR Summary

This fix the case where a Propertyless object is rendered undisplayable after being inspected using Get-Member or any similar introspection commands.

PR Context

Propertyless object are usually displayed using a fallback to their ToString() methods.
But the method currently used to evaluate the "Propertyless-ness" of an object relies on a flawed evaluation:
After inspecting the object, new properties are dynamically attached to the object, rendering it undisplayable, because no longer regarded as Propertyless.

This PR replace the current introspection-sensitiveHasNonRemotingProperties(so) withIsPropertyLessObject(so) not sensitive to passive introspection, and also taking care of excluding Remoting Properties as before.

The full rational and discussion prior to making this PR can be found in my issue report :
#25832

PR Checklist

mklement0 reacted with thumbs up emoji
@GregoireLD
Copy link
Author

I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.

@microsoft-github-policy-service agree

@GregoireLD
Copy link
Author

GregoireLD commentedAug 16, 2025
edited
Loading

I found that a Pester test existed specifically to check the ToString() fallback path, so I added a check to ensure the fallback now also still works after introspecting the object.

@iSazonoviSazonov added the CL-GeneralIndicates that a PR should be marked as a general cmdlet change in the Change Log labelAug 16, 2025
@microsoft-github-policy-servicemicrosoft-github-policy-servicebot added the Review - NeededThe PR is being reviewed labelAug 27, 2025
@GregoireLD
Copy link
Author

I got notified about the auto-“Review Needed”, so just in case, I wanted to confirm this is ready for reviewing.

Copy link
Contributor

CopilotAI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes a bug where propertyless objects (objects with only hidden properties) were not displaying correctly after being inspected withGet-Member or similar introspection commands. The fix replaces the introspection-sensitiveHasNonRemotingProperties() method with a newIsPropertyLessObject() method that properly handles objects after ETS introspection.

Key changes:

  • Introduced newIsPropertyLessObject() method that usesAssociationManager.ExpandAll() to evaluate properties without being affected by introspection side effects
  • Removed the deprecatedHasNonRemotingProperties() method and redundant property checks
  • AddedRemotingConstants.EventObject to the list of remoting properties to filter
  • Added comprehensive test coverage for the bug fix scenario

Reviewed Changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

FileDescription
src/System.Management.Automation/FormatAndOutput/common/FormatViewManager.csImplements newIsPropertyLessObject() method and removes old logic; adds EventObject to remoting property filter
src/Microsoft.PowerShell.Commands.Utility/commands/utility/FormatAndOutput/OutGridView/OutGridViewCommand.csUpdates to use newIsPropertyLessObject() method instead ofHasNonRemotingProperties()
test/powershell/engine/Formatting/BugFix.Tests.ps1Adds test case verifying propertyless objects display correctly afterGet-Member introspection

💡Add Copilot custom instructions for smarter, more guided reviews.Learn how to get started.

{
internalstaticboolIsPropertyLessObject(PSObjectso)
{
List<MshResolvedExpressionParameterAssociation>allProperties=AssociationManager.ExpandAll(so);

Choose a reason for hiding this comment

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

The new implementation callsAssociationManager.ExpandAll(so) which expands and collects all properties into a list upfront. The previousGetFirstPropertyOrDefault approach could short-circuit as soon as it found the first non-remoting property. For objects with many properties, this could cause a noticeable performance regression since all properties must now be expanded before any can be checked.

However, this approach does fix the correctness issue where ETS introspection was causing problems. The performance trade-off may be acceptable given that this is fixing a bug, but it's worth considering if there's a way to achieve both correctness and early-exit performance optimization.

Copilot uses AI. Check for mistakes.
Copy link
Collaborator

Choose a reason for hiding this comment

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

It is interesting suggestion. I'd prefer avoid using ExpandAll.
@GregoireLD Have you considered using a method from a closure/tear off class for the delegate implementing fast return?

Copy link
Author

Choose a reason for hiding this comment

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

@iSazonov No I must admit I have not. As a non-expert in C#, I tried to avoid introducing other unseen errors myself, I'm afraid using a closure would've potentially exposed me to the same kind of error we got because of theMemberNamePredicate. As such I preferred to lean on the safe side, and root my solution into what was done beforeGetFirstPropertyOrDefault got introduced here.
Yet, to avoid too much of a speed penalty, the way I look through the properties is that it will break from the list as soon as possible: Right at the start if there is no properties, or as soon as a non-remoting property is found.

So even with a massive object, and while I'm not sure how to optimise theExpandAll section, the looking through part can't, in the worst case scenario, read more than 6 properties at most (the maximum number of RemotingProperties there is, plus one).

Also, this code only gets used when handling objects where two specific conditions are met: there is no view attached to said object, and it's not a scalar either. Only then it will test if there is visible properties or not.

If you have a suggestion I can try and look into it.

As a sidetone, if this doesn't introduce a speed penalty, I would suggest to keep this PR, aimed at correcting the propertyless bug, while I work on a separate one looking into optimizing edge-cases uses of theExpandAll here.

Copy link
Author

Choose a reason for hiding this comment

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

@iSazonov After a quick benchmark, comparing the public PowerShell build and mine, my version usually gets similar speeds, or slightly better: I know this is anecdotal evidence, but based on my computer, outputting a "small" object 50000 times takes around 720 ms on the public build, and 660 ms on my version. For a "Big" (15 properties, including nested objects) object, 1050 ms on the public build, and 940 ms on my version.

When searching around though, I found PR#8785, the PR which introduced the change (and the bug) for performance reasons. The test included in this PR did put enough of a strain on my version to see a noticeable difference, similar to the speed we had prior to PR#8785 optimizations.

As is, this version would usually be similar ins speed to current version PowerShell, and in the worst case scenario, similar to the previous "pre PR#8785" version.

Thanks to your suggestion, I'm also exploring an alternative approach on a separate branch using aso.Properties.GetEnumerator() for a truly lazy property enumeration. And, so far, the speed gain is quite noticeable: instead of a 9x "pre PR#8785" penalty, the worst I got was a 3x penalty (again, only under the most straining tests). Yet, as this would be a new architectural pattern not matching either the current or original implementations, I think it might be preferable to address it in a separate PR.

What do you think ?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Current proposed code de-facto reverts#8785. I cannot accept this.
If it was a workaround in#8785 to get fast check of absent of properties, we should find better way than enumerate all properties.
In debugger I seeIsNotRemotingProperty() passpstypenames and as result we see the issue. Perhaps we should think in the direction - is it right to use _mshOwner.InstanceMembers and what we should skip.

Copy link
Author

Choose a reason for hiding this comment

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

@iSazonov Here, I merged my Lazy evaluation method in here so you can have a look at it. In most cases it was faster than current method, and the worst cases stays much faster than Pre#8785 speeds (instead of a 9x speed gain, we still gain a 2x or 3x compared to Pre#8785 speeds)

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think using enumerator force Engine to evaluate meta data for properties. Engine will cache the data and this give still a perf win. I think it make sense to keep#8785 achievements.
I have no full understanding that is right way to fix the issue but you could try to filter outpstypenames as simplest fix that I can see in the time.

Copy link
Author

Choose a reason for hiding this comment

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

I'm a bit worried that specifically filtering outpstypenames might lead into a similar issue down the line if some other properties were introduced later. While we do leave out some performance gains on the table (but we still benefits from some of#8785 optimizations), I think relying on a more "robust" or standardized mechanism like the GetEnumerator would make it more of a future-proof solution, if that makes sense to you

Copy link
Collaborator

Choose a reason for hiding this comment

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

The issue is an edge case. So it makes no sense to revert#8785 in some way and slow down hot path. If we could find simple fix the PR could be approved.

Copy link
Author

@GregoireLDGregoireLDNov 24, 2025
edited
Loading

Choose a reason for hiding this comment

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

I understand, one simpler fix I found would be to repurpose the currentIsNotRemotingProperty to also include and filter out thePSObject.PSTypeNames property. I will push a separate PR for you to compare the two.
EDIT: I created a separate PR (PR#26520) with said, much simpler, approach

GregoireLDand others added5 commitsNovember 20, 2025 12:44
…ViewManager.csGrammatical fixCo-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ViewManager.csCapitalization fixCo-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…matAndOutput/OutGridView/OutGridViewCommand.csCo-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Uses a GetEnumerator instead of ExpandAll to mitigate speed loss

Choose a reason for hiding this comment

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

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

Reviewers

@iSazonoviSazonoviSazonov left review comments

Copilot code reviewCopilotCopilot left review comments

+1 more reviewer

@saramichelle7576-websaramichelle7576-websaramichelle7576-web left review comments

Reviewers whose approvals may not affect merge requirements

At least 1 approving review is required to merge this pull request.

Assignees

No one assigned

Labels

CL-GeneralIndicates that a PR should be marked as a general cmdlet change in the Change LogReview - NeededThe PR is being reviewed

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

3 participants

@GregoireLD@iSazonov@saramichelle7576-web

[8]ページ先頭

©2009-2025 Movatter.jp