Test-Path: Return $false when given an empty or $null -Path/-LiteralPath value#8080
Test-Path: Return $false when given an empty or $null -Path/-LiteralPath value#8080iSazonov merged 15 commits intoPowerShell:masterfrom
Conversation
There was a problem hiding this comment.
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.
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.
Seems we should remove this. I am not sure that it tests "non-terminating"
There was a problem hiding this comment.
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.
@adityapatwardhan @JamesWTruher @SteveL-MSFT Can we use the pattern to test non-terminating errors?
There was a problem hiding this comment.
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.
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.
I believe we need to add a comment to describe the pattern.
There was a problem hiding this comment.
I believe we should tests here Test-Path $null, $null;.
There was a problem hiding this comment.
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