-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Modules containing colliding names causes side-effects that are visible in other modules #12036
Comments
It is expected behavior that latest module exports names in global and overloads previously defined names. |
@iSazonov Got it. Do you think I can rely on the shadowing that occurs when New-Module m {
Import-Module q
function m1 {
[pscustomobject]@{
Call = $MyInvocation.MyCommand.Name
CommandType = Get-Command Get-FileHash | % CommandType
Module = Get-Command Get-FileHash | % Module | % {[System.IO.FileInfo]::new($_.Path).Name}
}
}
function m2 {q1}
} | Import-Module
New-Module p {
Import-Module Microsoft.PowerShell.Utility
function p1 {
[pscustomobject]@{
Call = $MyInvocation.MyCommand.Name
CommandType = Get-Command Get-FileHash | % CommandType
Module = Get-Command Get-FileHash | % Module | % {[System.IO.FileInfo]::new($_.Path).Name}
}
}
} | Import-Module
m1
p1
m2
m1
p1
m1
p1 which outputs
Note that in this example the command to which each call site is resolved is the same for each call at that site. |
If you ask about workaround, yes, this is good because you use a module context to avoid name collisions. |
@rjmholt This repro is an abstraction of how this caused an issue. I've got a repo of 50 or so modules that I'm transitioning from Windows PowerShell. I'm relying on the 20k or so unit and integration tests from those modules to hopefully get this to happen smoothly. Under PowerShell 5.1 none of the modules had In my case I had an inadvertent name collision on The reliance for name resolution by modules on the global scope is, I think, a mistake that happened to not manifest in 5.1. My task currently is to determine how to ensure name resolution occurs reliably within each module without ever reaching the global scope. Hopefully I can find such a solution. My intuition is that this will probably be a one-time cleanup with some internal policy changes around importing of required modules. I think I prefer the new command resolution behavior, but I've still got a bit of work to do to determine whether I can get that to stabilize with our modules. |
Here is a summary of the policy I implemented to mitigate this issue. Policy
Reasoning(1) and (2) adequately shadow command names to ensure name resolution occurs within the module. (3) and (4) ensure that automated tests will fail for nearly all commands if they are not imported per (1). LimitationsIf a command that is already imported when PowerShell launches is not imported per (1), then that command is still vulnerable to this issue. |
@iSazonov I just reviewed this issue. I think the key point is this statement you made:
I think then, that the behavior I described in my OP is by design. If you agree, I'd like to close this issue. I think #12014 sufficiently covers the outstanding issue with surprising command name resolution. |
Ok, we can reopen in any time if needed. |
The way that PowerShell resolves commands with colliding names seems to have changed sometime between PowerShell 5.1 and 7. The new behavior is problematic because it introduces the possibility of the following happening:
Invoking a command in one module can have the side effect that changes the command to which a different name in an unrelated module resolves.
In other words, (at least by default in PowerShell 7, it seems) one can never be sure that code invoked in a different module will not inadvertently change the command to which a name in your module will resolve.
This seems like something I need to take into careful account when designing modules. Accordingly, I'm hoping to find answers to the following questions:
Other notes:
Steps to reproduce
Create the following well-defined module
q
in$Env:PSModulePath
:Invoke the following:
Expected behavior
Either this behavior (which is how PowerShell 5.1 behaves)
or this behavior
Actual behavior
Environment data
The text was updated successfully, but these errors were encountered: