-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Test-Path: Return $false when given an empty or $null -Path/-LiteralPath value #8080
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| CmdletProviderContext currentContext = CmdletProviderContext; | ||
|
|
||
| foreach (string path in _paths) | ||
| if (_paths != null && _paths.Length != 0) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We usually use short code path:
| if (_paths != null && _paths.Length != 0) | |
| if (_paths == null || _paths.Length == 0) | |
| { | |
| return false; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is in the ProcessRecord() method, so returning false is not an option. I suppose WriteObject(false); return; is the most appropriate short-cut method here. Thank you!
|
@SteveL-MSFT Is this a breaking change? |
|
@PowerShell/powershell-committee reviewed this, we believe the correct behavior is to accept null/nullcollection, but return non-terminating error at runtime (instead of exception or $false) |
|
@vexx32 Please continue and open new issue in PowerShell-Docs. |
$false will be output if it encounters a non-null but empty string.
|
Added non-terminating errors for the following cases, per PowerShell committee recommendation:
Docs issue: MicrosoftDocs/PowerShell-Docs#3165 |
|
@vexx32 Please add tests for new behaviors. |
src/Microsoft.PowerShell.Commands.Management/commands/management/PingPathCommand.cs
Show resolved
Hide resolved
|
|
||
| It 'Should write a non-terminating error when given a null path' { | ||
| { Test-Path -Path $null -ErrorAction Stop } | Should -Throw -ErrorId 'NullPathNotPermitted' | ||
| { Test-Path -Path $null -ErrorAction SilentlyContinue } | Should -Not -Throw |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems we should remove this. I am not sure that it tests "non-terminating"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's what I thought, too. Surprisingly, though, -ErrorAction SilentlyContinue will still trigger a | should -throw if and only if the error is terminating to start with (either throw or ThrowTerminatingError())
@indented-automation had to explain that one to me. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@adityapatwardhan @JamesWTruher @SteveL-MSFT Can we use the pattern to test non-terminating errors?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this change is explicitly to be a non-terminating error, this pattern seems fine. But should probably be followed up with -ErrorAction Stop to verify the non-terminating error is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure I follow? I don't see a need to double-check it with -ErrorAction Stop
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we need to add a comment to describe the pattern.
| } | ||
|
|
||
| It 'Should write a non-terminating error when given a null path' { | ||
| { Test-Path -Path $null -ErrorAction Stop } | Should -Throw -ErrorId 'NullPathNotPermitted' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we should tests here Test-Path $null, $null;.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done. Also had to modify some ErrorPosition tests as they were causing infinite loops when the cmldet simply wrote a non-terminating error.
Add comment to confusing but necessary test pattern
We'll get $false without |
|
We'll get a non-terminating error per the recommendation. In terms of output this will effectively be treated as Would explicitly outputting |
|
@vexx32 Could you please continue? Update: Sorry, seems my comments was addressed. |
|
@SteveL-MSFT @adityapatwardhan Could you please review the small PR? |
src/Microsoft.PowerShell.Commands.Management/commands/management/PingPathCommand.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.PowerShell.Commands.Management/commands/management/PingPathCommand.cs
Outdated
Show resolved
Hide resolved
|
MacOS CI failure appears to be temporary and no related to the PR as far as I can see. |
|
Restart MacOs CI. |
|
Is this change due to be released in PowerShell 7? I haven't seen it in the release notes of the previews released to date, just wanted to check that it's still on course to be included. |
|
@ZenoArrow The fix is in current 7.0 Preview5 and will be in 7.0 GA too. |
|
@iSazonov The behaviour seems to be fixed for empty path, but the behaviour is different from what I'd expect for $null values... Am I missing something? |
|
@ZenoArrow apologies! Looks like I neglected to update the PR description properly. The PS committee's decision was that we should maintain the error for $null values. I didn't agree, but that is that they decided and so that is how it ended up being implemented. If you disagree with their decision there (I'm right there with you really) I'd recommend opening an issue so that they can see that the behaviour isn't as desired and we can have them reconvene and reassess. 🙂 /Cc @SteveL-MSFT |
|
@vexx32 Thanks for the heads up. I can raise a new issue, but it'd effectively just be a duplicate of the issue raised by @KevinMarquette last year... Regarding returning the non-terminating error, I understand this to a degree, but what I can't understand is why Test-Path can't return more than just the error. Correct me if I'm wrong, but usually error stream output doesn't interfere with the standard output, so in my mind there's no reason not to return both (an error message to the error stream and a "False" value to the standard stream). |
|
It certainly could! But it's not strictly necessary. If you're using Test-Path as a conditional in most cases the non-respose will be treated as $false. For example: if (Test-Path $null) { "true!" } Else { "false!" } |
|
@vexx32 Good to know. In that case the current improvements to Test-Path should cover what I was hoping for. |

PR Summary
Fix #5717.
Fix #8076.
Test-Path is expected to be almost exclusively a True/False response cmdlet, and the cases where it may error or return an unexpected result are a few too many at present (see above issues). This PR allows
$null/ empty value(s) to be passed to Test-Path without throwing parameter binding exceptions. It also adds additional logic to Test-Path such that passing it$null,'', or' '(or any pure whitespace string) returns$falseinstead of throwing an error or returning$trueon a "path" that is nothing but whitespace.New behaviour:
Error conditions:
These are non-terminating errors.
A small handful of tests predicated on Test-Path failing in these cases have been updated to simply transform the error into terminating via -ErrorAction, as it appears that the important part of the test was not Test-Path itself, but throwing a terminating error in specific code strictures.
Tests for the additional behaviours have also been added.
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:to the beginning of the title and remove the prefix when the PR is ready.[feature]if the change is significant or affects feature tests