snek.psm1
function Import-PythonRuntime { param( [ValidateSet("v2.7", "v3.5", "v3.6", "v3.7")] $Version = "v3.7" ) $Architecture = 'x64' if ([IntPtr]::Size -eq 4) { $Architecture = 'x86' } $Runtime = [System.IO.Path]::Combine($PSScriptRoot, "binaries", $Architecture, $Version, "Python.Runtime.dll") [System.Reflection.Assembly]::LoadFrom($Runtime) | Out-Null } function Use-Python { param( [ScriptBlock]$Script, [ValidateSet("v2.7", "v3.5", "v3.6", "v3.7")] $Version = "v3.7" ) Import-PythonRuntime -Version $Version $runtime = $null try { $runtime = [Python.Runtime.Py]::Gil() $Script.Invoke() } Finally { $runtime.Dispose() } } function Import-PythonPackage { param( $Name ) # Wrap in an ArrayList so PowerShell doesn't try to unwind the dynamic because it will throw # an exception $ar = [System.Collections.ArrayList]::new() $ar.add([Python.Runtime.Py]::Import($Name)) | Out-Null $ar } function Invoke-Python { param( [Parameter(Mandatory)] $Code, [Parameter()] [type]$ReturnType ) if ($ReturnType) { if ($null -eq $Scope) { [Python.Runtime.PythonEngine]::Eval($Code) -as $ReturnType } else { $Scope.Eval($Code) -as $ReturnType } } else { if ($null -eq $Scope) { [Python.Runtime.PythonEngine]::Exec($Code) } else { $Scope.Exec($Code) } } } function Use-PythonScope { param( [Parameter(Mandatory)] [scriptblock]$ScriptBlock ) $Scope = $null try { $Scope = [Python.Runtime.Py]::CreateScope() $ScriptBlock.Invoke() } finally { $Scope.Dispose() } } function Set-PythonVariable { param( [Parameter(Mandatory)] $Name, [Parameter(Mandatory)] $Value ) if ($null -eq $Scope) { throw "Set-PythonVariable must be called within a Use-PythonScope" } $PyObject = [Python.Runtime.ConverterExtension]::ToPython($Value) $Scope.Set($Name, $PyObject) } function Install-PythonPackage { param( $Name, [ValidateSet("v2.7", "v3.5", "v3.6", "v3.7")] $Version = "v3.7" ) Invoke-Pip -Action "install" -Name $Name -Version $Version } function Uninstall-PythonPackage { param( $Name, [ValidateSet("v2.7", "v3.5", "v3.6", "v3.7")] $Version = "v3.7" ) Invoke-Pip -Action "uninstall" -Name $Name -Version $Version } function Invoke-Pip { param( $Action, $Name, [ValidateSet("v2.7", "v3.5", "v3.6", "v3.7")] $Version = "v3.7" ) Use-Python -Version $Version -Script { Invoke-Python -Code "import subprocess subprocess.check_call(['python', '-m', 'pip', '$Action', '$Name'])" } } |