B _B@sddlZddlZddlZddlZddlmZddZddZddZdd d Zde_ Gd d d e Z Gddde Z Gddde Z Gddde ZGddde ZdS)N) iteritemscCs&t|tjr|S|dk r"|dSdS)z6Helper function to coerce a string to a bytes() objectNzutf-8) isinstancesix binary_typeencode)valr4/tmp/pip-unpacked-wheel-d4p3hk07/pyomo/common/env.py _as_bytess   r cCs$t|tjr|S|dk r |SdS)z8Helper function to coerce a string to a unicode() objectN)rr text_typedecode)rrrr _as_unicodes  r cCs(yt|}dStk r"dSXdS)z6Load a CDLL library, returning bool indicating successTFN)ctypesCDLLOSError)namedllrrr _attempt_ctypes_cdll$s  rcCstj|sdStjdkr&tdt_tjt|f}y| |}Wn*tj k rnd}tj dt_YnX|r|t |fS|dfSdS)aLoad a DLL with a timeout On some platforms and some DLLs (notably Windows GitHub Actions with Python 3.5, 3.6, and 3.7 and the msvcr90.dll) we have observed behavior where the ctypes.CDLL() call hangs indefinitely. This uses multiprocessing to attempt the import in a subprocess (with a timeout) and then only calls the import in the main process if the subprocess succeeded. Performance note: CtypesEnviron only ever attempts to load a DLL once (the DLL reference is then held in a class attribute), and this interface only spawns the subprocess if ctypes.util.find_library actually locates the target library. This will have a measurable impact on Windows (where the DLLs exist), but not on other platforms. )FNNrF) rutilZ find_library _load_dllpoolmultiprocessingZPoolZ apply_asyncrget TimeoutError terminater)rtimeoutZjobresultrrr r-s     rc@s8eZdZdZddZddZddZdd Zd d Zd S) _RestorableEnvironInterfacez8Interface to track environment changes and restore statecCs||s t||_i|_x.tttjD]\}}|||kr(|||<q(W|j}|dk rxx|D]}|tjkr`||=q`WdS)N) availableAssertionErrorr_original_statelistrosenviron get_env_dict)selfrkeyrZorigEnvrrr __init__Xs      z$_RestorableEnvironInterface.__init__cCsBx6t|jD](\}}|s,||dk r4||=q |||<q Wi|_dS)N)rr!)r&r'rrrr restoreks   z#_RestorableEnvironInterface.restorecCs(t|tjr|j|S|j|SdS)N)rrr rwgetenvgetenv)r&r'rrr __getitem__ts  z'_RestorableEnvironInterface.__getitem__cCs||jkr|||j|<t|tjrTt|tjr@|j||q|j|t|n.t|tjrt|jt||n|j||dS)N)r!rrr r wputenv_sr putenv_s)r&r'rrrr __setitem__zs    z'_RestorableEnvironInterface.__setitem__cCsF||jkr|||j|<t|tjr4|j|dn|j|ddS)N)r!rrr rr-r.)r&r'rrr __delitem__s   z'_RestorableEnvironInterface.__delitem__N) __name__ __module__ __qualname____doc__r(r)r,r/r2rrrr rUs  rc@sDeZdZdZdZddZddZddZd d Zd d Z d dZ dS) _OSEnvironz:Helper class to proxy a "DLL-like" interface to os.environz os.environcCsdS)NTr)r&rrr rsz_OSEnviron.availablecCs ttjS)N)dictr#r$)r&rrr r%sz_OSEnviron.get_env_dictcCsRtjrttj|dSytj|dStk rLttjt|dSXdS)N) rPY2r r#r$renvironbAttributeErrorr )r&r'rrr r+s z_OSEnviron.getenvcCsttj|dS)N)r r#r$r)r&r'rrr r*sz_OSEnviron.wgetenvcCs:|s|tjkrtj|=dStjr,|tj|<n |tj|<dS)N)r#r$rr9r:)r&r'rrrr r.s  z_OSEnviron.putenv_scCs:|s|tjkrtj|=dStjr,|tj|<n |tj|<dS)N)r#r$rr9)r&r'rrrr r-s  z_OSEnviron.wputenv_sN) r3r4r5r6_libnamerr%r+r*r.r-rrrr r7s  r7c@s(eZdZdZddZddZddZdS) _MsvcrtDLLzrr<rZ _putenv_sr.rc_char_pargtypesc_intrestypeZ _wputenv_sr- c_wchar_pr+Z_wgetenvr*)r&rrr rs$           z_MsvcrtDLL.availablecCs|s dSy$ttj|jd}|js.d}Wntk rHd}YnX|dkry$ttj|jd}|jstdSWntk rdSXi}d}xZ|D]R}|sP|t |7}t |dkrtd|dkrtd| dd\}}|||<qW|S) NZ _wenvironZ_environrz=Error processing MSVCRT _environ: 0-length string encounteredizMError processing MSVCRT _environ: exceeded max environment block size (32767)=r) rrPOINTERrCin_dllrcontents ValueErrorr?lensplit)r&Zenvpanssizeliner'rrrr r%s@         z_MsvcrtDLL.get_env_dictN)r3r4r5r6r(rr%rrrr r=sr=c@s8eZdZdZddZddZddZdd Zd d Zd S) _Win32DLLz;Helper class to manage the interface with the Win32 runtimecCs&||_|dkrd|_nd|_d|_dS)NF)r<r>r)r&rrrr r(s z_Win32DLL.__init__cCs|jdk r|jSt|j\|_|_|js.|jS|jj|_tjtjg|j_tj |j_ |jj |_ tj tj g|j _tj |j _ |jj|_tjtjtjg|j_tj|j_ |jj|_tj tj tjg|j_tj|j_ |jj|_g|j_ttj|j_ |jj|_ttjg|j_tj |j_ |jS)N)r>rr<rZSetEnvironmentVariableAr.rr?r@c_boolrBZSetEnvironmentVariableWr-rCZGetEnvironmentVariableA _getenv_dllc_ulongZGetEnvironmentVariableW _wgetenv_dllZGetEnvironmentStringsW_envstrrEc_wcharZFreeEnvironmentStringsW _free_envstr)r&rrr rs0            z_Win32DLL.availablecCs<||dd}|sdStd|}|||||jp:dS)Nr)rPrcreate_string_buffervalue)r&r'rLbufrrr r+Ds z_Win32DLL.getenvcCs<||dd}|sdStd|}|||||jp:dS)Nr)rRrcreate_unicode_bufferrX)r&r'rLrYrrr r*Ls z_Win32DLL.wgetenvcCsi}|}ddh}d}x|||krd}xT|||kr~|||7}|t||7}t||dkrltd|dkr,tdq,W|dd \}}|||<|t||7}qW|||S) NrZrVrr0zMError processing Win32 GetEnvironmentStringsW: 0-length character encounteredizZError processing Win32 GetEnvironmentStringsW: exceeded max environment block size (32767)rDr)rSrIrHrJrU)r&rKZ_str_buf_nulli_strr'rrrr r%Ts(    z_Win32DLL.get_env_dictN) r3r4r5r6r(rr+r*r%rrrr rNs %rNc @seZdZdZedeeejdddedededed ed ed ed ed edg Z ddZ ddZ ddZ ddZ ddZddZddZddZdS) CtypesEnvirona(A context manager for managing environment variables This class provides a simplified interface for consistently setting and restoring environment variables, with special handling to ensure consistency with the C Runtime Library environment on Windows platforms. `os.environ` reflects the current python environment variables, and will be passed to subprocesses. However, it does not reflect the C Runtime Library (MSVCRT) environment on Windows platforms. This can be problemmatic as DLLs loaded through the CTYPES interface will see the MSVCRT environment and not os.environ. This class provides a way to manage environment variables and pass changes to both os.environ and the MSVCRT runtime. This class implements a context manager API, so that clients can temporarily change - and then subsequently restore - the environment. .. testcode:: :hide: import os from pyomo.common.env import TemporaryEnv orig_env_val = os.environ.get('TEMP_ENV_VAR', None) .. doctest:: >>> os.environ['TEMP_ENV_VAR'] = 'original value' >>> print(os.environ['TEMP_ENV_VAR']) original value >>> with CtypesEnviron(TEMP_ENV_VAR='temporary value'): ... print(os.envion['TEMP_ENV_VAR']) temporary value >>> print(os.environ['TEMP_ENV_VAR']) original value .. testcode:: :hide: if orig_env_val is None: del os.environ['TEMP_ENV_VAR'] else: os.environ['TEMP_ENV_VAR'] = orig_env_val kernel32Z find_msvcrtcCsdS)Nrrrrr r1zCtypesEnviron.z!api-ms-win-crt-environment-l1-1-0msvcrtZmsvcr120Zmsvcr110Zmsvcr100Zmsvcr90Zmsvcr80Zmsvcr71Zmsvcr70cKsbttg|_|jdd|jDtjdk r@tjdt_xt|D]\}}|||<qJWdS)Ncss|]}|rt|VqdS)N)rr).0rrrr sz)CtypesEnviron.__init__..) rr7 interfacesextendDLLsrrrr)r&kwdskvrrr r(s    zCtypesEnviron.__init__cCs|S)Nr)r&rrr __enter__szCtypesEnviron.__enter__cCs |dS)N)r))r&exc_type exc_value exc_tracebackrrr __exit__szCtypesEnviron.__exit__cCs xt|jD] }|q WdS)aFRestore the environment to the original state This restores all environment variables modified through this object to the state they were in before this instance made any changes. Note that any changes made directly to os.environ outside this instance will not be detected / undone. N)reversedrer))r&librrr r)szCtypesEnviron.restorecCs tj|S)z=Return the current environment variable value from os.environ)r#r$)r&r'rrr r,szCtypesEnviron.__getitem__cCs |tjkS)z'Return True if the key is in os.environ)r#r$)r&r'rrr __contains__szCtypesEnviron.__contains__cCsx|jD] }|||<qWdS)z=Set an environment variable in all known runtime environmentsN)re)r&r'rrqrrr r/s zCtypesEnviron.__setitem__cCsx|jD] }||=qWdS)zBRemove an environment variable from all known runtime environmentsN)re)r&r'rqrrr r2s zCtypesEnviron.__delitem__N)r3r4r5r6rNr=getattrrrrgr(rkror)r,rrr/r2rrrr r_us(0  r_)r)rrr#rrr r rrrobjectrr7r=rNr_rrrr  s    %=6La