B u `]@s~ddlZddlZddlZddlZddlZddlZddlZddlm Z ddl m Z d/ddZ ddZ ejeje Zd ejdgd fd d Zd ejdgd fd d Zd ejgd fddZdddddZdddddZddZddZd0ddZd1ddZGdddeZGd d!d!eZGd"d#d#eZeeeZeeeZ e d$d%d&d2d'd(Z!e d)d%d&d*d+Z"e d,d%d&d-d.Z#dS)3N) deprecated)configcCsZt}x|r|j}|d8}q W|jj}|rH|ddkrH|ddkrH|Stjt|S)zReturns the file name for the module that calls this function. This function is more reliable than __file__ on platforms like Windows and in situations where the program has called os.chdir(). rr<>) inspect currentframef_backf_code co_filenameospathabspathgetfile) stack_offsetZ callerFrameZ frameNamer:/tmp/pip-unpacked-wheel-n62dbgi3/pyomo/common/fileutils.py this_files  rcCstjtddS)zJReturns the directory containing the module that calls this function. )r)r rdirnamerrrrr this_file_dir+srTc Cstjtj|}g}|r*|t|s>tj||krht|tj r^| | tj n | |dg}|rt|tj r||n | |xl|D]d} | sqxX|D]P} xJt tj| || D].} || sq|dk rt| |sqtj| SWqWqWdS)aYLocate a path, given a set of search parameters Parameters ---------- name : str The name to locate. The name may contain references to a user's home directory (``~user``), environment variables (``${HOME}/bin``), and shell wildcards (``?`` and ``*``); all of which will be expanded. validate : function A function to call to validate the path (used by find_file and find_dir to discriminate files and directories) cwd : bool Start by looking in the current working directory [default: True] mode : mask If not None, only return entries that can be accessed for reading/writing/executing. Valid values are the inclusive OR of {os.R_OK, os.W_OK, os.X_OK} [default: ``os.R_OK``] ext : str or iterable of str If not None, also look for name+ext [default: None] pathlist : str or iterable of str A list of strings containing paths to search, each string contains a single path. If pathlist is a string, then it is first split using os.pathsep to generate the pathlist [default: ``[]``]. allow_pathlist_deep_references : bool If allow_pathlist_deep_references is True and the name appears to be a relative path, allow deep reference matches relative to directories in the pathlist (e.g., if name is ``foo/my.exe`` and ``/usr/bin`` is in the pathlist, then :py:func:`find_file` could return ``/usr/bin/foo/my.exe``). If allow_pathlist_deep_references is False and the name appears to be a relative path, then only matches relative to the current directory are allowed (assuming cwd==True). [default: True] Notes ----- find_path uses glob, so the path and/or name may contain wildcards. The first matching entry is returned. N)r r expanduser expandvarsappendgetcwdbasename isinstancesix string_typesextendsplitpathsepglobjoinaccessr) namevalidatecwdmodeextpathlistallow_pathlist_deep_references locationsZextlistrZ_exttestrrr find_path4s04       r0c Cst|tjj|||||dS)aLocate a file, given a set of search parameters Parameters ---------- filename : str The file name to locate. The file name may contain references to a user's home directory (``~user``), environment variables (``${HOME}/bin``), and shell wildcards (``?`` and ``*``); all of which will be expanded. cwd : bool Start by looking in the current working directory [default: True] mode : mask If not None, only return files that can be accessed for reading/writing/executing. Valid values are the inclusive OR of {os.R_OK, os.W_OK, os.X_OK} [default: ``os.R_OK``] ext : str or iterable of str If not None, also look for filename+ext [default: None] pathlist : str or iterable of str A list of strings containing paths to search, each string contains a single path. If pathlist is a string, then it is first split using os.pathsep to generate the pathlist [default: ``[]``]. allow_pathlist_deep_references : bool If allow_pathlist_deep_references is True and the filename appears to be a relative path, allow deep reference matches relative to directories in the pathlist (e.g., if filename is ``foo/my.exe`` and ``/usr/bin`` is in the pathlist, then :py:func:`find_file` could return ``/usr/bin/foo/my.exe``). If allow_pathlist_deep_references is False and the filename appears to be a relative path, then only matches relative to the current directory are allowed (assuming cwd==True). [default: True] Notes ----- find_file uses glob, so the path and/or file name may contain wildcards. The first matching file is returned. )r)r*r+r,r-)r0r risfile)filenamer)r*r+r,r-rrr find_files.r3cCst|tjj||||dS)aLocate a directory, given a set of search parameters Parameters ---------- dirname : str The directory name to locate. The name may contain references to a user's home directory (``~user``), environment variables (``${HOME}/bin``), and shell wildcards (``?`` and ``*``); all of which will be expanded. cwd : bool Start by looking in the current working directory [default: True] mode : mask If not None, only return directories that can be accessed for reading/writing/executing. Valid values are the inclusive OR of {os.R_OK, os.W_OK, os.X_OK} [default: ``os.R_OK``] pathlist : str or iterable of str A list of strings containing paths to search, each string contains a single path. If pathlist is a string, then it is first split using os.pathsep to generate the pathlist [default: ``[]``]. allow_pathlist_deep_references : bool If allow_pathlist_deep_references is True and the dirname appears to be a relative path, allow deep reference matches relative to directories in the pathlist (e.g., if dirname is ``foo/bar`` and ``/usr/bin`` is in the pathlist, then :py:func:`find_dir` could return ``/usr/bin/foo/bar``). If allow_pathlist_deep_references is False and the dirname appears to be a relative path, then only matches relative to the current directory are allowed (assuming cwd==True). [default: True] Notes ----- find_dir uses glob, so the path and/or directory name may contain wildcards. The first matching directory is returned. )r)r*r,r-)r0r risdir)rr)r*r,r-rrrfind_dirs+r5z.exe)linuxwindowscygwindarwin)z.soz.so.*)z.dllz.pyd)z.dllz.soz.so.*)z.dylibz.soz.so.*cCs,t}xdD]}||d}qW|S)Nz.-_r)platformsystemlowerr")r;crrr_systems  r>cCstjddptjtjS)NPATHr)r environgetdefpathr"r#rrrr_pathsrCcCs8|dkrRtjtjdg}|tjddtj |rt| tjtjdn"t |t j rl|tj }nt|}|r|tttd}t||||d}|dkr|dstd||||d}|dk r|S|drtdkr|dd}tjtj|\}}|d r(tj|Stj|SdS) aFind a dynamic library using find_file to search typical locations. Finds a specified library (file) by searching a specified set of paths. This routine will look for the specified file name, as well as looking for the filename followed by architecture-specific extensions (e.g., `.dll`, `.so`, or `.dynlib`). Note that as this uses :py:func:find_file(), the filename and search paths may contain wildcards. If the explicit path search fails to locate a library, then this returns the result from passing the basename (with 'lib' and extension removed) to ctypes.util.find_library() Parameters ---------- libname : str The library name to search for cwd : bool Start by looking in the current working directory [default: True] include_PATH : bool Include the executable search PATH at the end of the list of directories to search. [default: True] pathlist : str or list of str List of paths to search for the file. If None, then pathlist will default to the local Pyomo configuration library directory (and the local Pyomo binary directory if include_PATH is set) and the contents of LD_LIBRARY_PATH. If a string, then the string is split using os.pathsep. [default: None] Notes ----- find_library() uses :py:func:`find_file` with ``allow_pathlist_deep_references=True``, so libnames containing relative paths will be matched relative to all paths in pathlist. NlibZLD_LIBRARY_PATHrbin)r)r+r,r7)z.soz.dllz.dylib)r rr%rPYOMO_CONFIG_DIRr!r@rAr"r#rrrr listrC_libExtr>r3 startswithsplitextrr<ctypesutil find_library)Zlibnamer) include_PATHr,r+rDZ libname_baserrrrNs,*    rNcCsx|dkrtjtjdg}n"t|tjr6|tj }nt |}|rN| t t td}t|||tjtjB|ddS)aFind an executable using find_file to search typical locations. Finds a specified executable by searching a specified set of paths. This routine will look for the specified file name, as well as looking for the filename followed by architecture-specific extensions (e.g., ``.exe``). Note that as this uses :py:func:`find_file()`, the filename and search paths may contain wildcards. Parameters ---------- exename : str The executable file name to search for cwd : bool Start by looking in the current working directory [default: True] include_PATH : bool Include the executable search PATH at the end of the list of directories to search. [default: True] pathlist : str or list of str List of paths to search for the file. If None, then pathlist will default to the local Pyomo configuration binary directory. If a string, then the string is split using os.pathsep. [Default: None] Notes ----- find_executable() uses :py:func:`find_file` with ``allow_pathlist_deep_references=False``, so search strings containing relative paths will only be matched relative to the current working directory. This prevents confusion in the case where a user called ``find_executable("./foo")`` and forgot to copy ``foo`` into the local directory, but this function picked up another ``foo`` in the user's PATH that they did not want to use. NrEF)r)r+r*r,r-)r rr%rrGrrr r"r#rHr!rC_exeExtrAr>r3R_OKX_OK)exenamer)rOr,r+rrrfind_executableRs(  rTc@sdeZdZddZddZddZeddd d d Zd d ZddZ ddZ ddZ e Z ddZ dS) _PathDatacCs"||_||_d|_d|_d|_dS)N)_mngr_registered_namerC_path_override_status)selfmanagerr'rrr__init__s z_PathData.__init__cCsR|jdkrL|jr|j}n|j}|jj||jjd}|r:|n|j|_t||_|jS)zReturn the full, normalized path to the registered path entry. If the object is not found (or was marked "disabled"), ``path()`` returns None. N)r,)rYrXrWrV_findr,rCbool)rZtargettmprrrrs  z_PathData.pathcCs2||_||js.tdd|j|fdS)Nz pyomo.commonzXexplicitly setting the path for '%s' to an invalid object or nonexistent location ('%s'))rXrehashrYlogging getLoggerwarningrW)rZvaluerrrset_paths  z_PathData.set_pathzBget_path() is deprecated; use pyomo.common.Executable(name).path()z5.6.2)versioncCs|S)N)r)rZrrrget_pathsz_PathData.get_pathcCsd|_d|_dS)aDisable this path entry This method "disables" this path entry by marking it as "not found". Disabled entries return False for `available()` and None for `path()`. The disabled status will persist until the next call to `rehash()`. FN)rYrC)rZrrrdisables z_PathData.disablecCs|jdkr||jS)zReturns True if the registered path is available. Entries are available if the object was found found in the search locations and has not been explicitly disabled. N)rYr)rZrrr availables z_PathData.availablecCsd|_|dS)zRequery the location of this path entry This method derives its name from the csh command of the same name, which rebuilds the hash table of executables reachable through the PATH. N)rYr)rZrrrrasz_PathData.rehashcCs|S)zAlias for ``available()``.)rj)rZrrr __nonzero__sz_PathData.__nonzero__cCs|}|sdS|S)Nr)r)rZansrrr__str__sz_PathData.__str__N)__name__ __module__ __qualname__r\rrfrrhrirjrark__bool__rmrrrrrUs    rUc@s&eZdZeddZejddZdS)_ExecutableDatacCs|S)N)r)rZrrr executablesz_ExecutableData.executablecCs||dS)N)rf)rZrerrrrssN)rnrorppropertyrssetterrrrrrrs rrc@s(eZdZdZddZddZddZdS) PathManageraThe PathManager defines a registry class for path locations The :py:class:`PathManager` defines a class very similar to the :py:class:`CachedFactory` class; however it does not register type constructors. Instead, it registers instances of :py:class:`_PathData` (or :py:class:`_ExecutableData`). These contain the resolved path to the directory object under which the :py:class:`_PathData` object was registered. We do not use the PyUtilib ``register_executable`` and ``registered_executable`` functions so that we can automatically include Pyomo-specific locations in the search path (namely the ``PYOMO_CONFIG_DIR``). Users will generally interact with this class through global instances of this class (``pyomo.common.Executable`` and ``pyomo.common.Library``). Users are not required or expected to register file names with the :py:class:`PathManager`; they will be automatically registered upon first use. Generally, users interact through the ``path()`` and ``available()`` methods: .. doctest:: :hide: >>> import pyomo.common >>> import os >>> from stat import S_IXUSR, S_IXGRP, S_IXOTH >>> _testfile = os.path.join( ... pyomo.common.config.PYOMO_CONFIG_DIR, 'bin', 'demo_exec_file') >>> _del_testfile = not os.path.exists(_testfile) >>> if _del_testfile: ... open(_testfile,'w').close() ... _mode = os.stat(_testfile).st_mode ... os.chmod(_testfile, _mode | S_IXUSR | S_IXGRP | S_IXOTH) .. doctest:: >>> from pyomo.common import Executable >>> if Executable('demo_exec_file').available(): ... loc = Executable('demo_exec_file').path() ... print(os.path.isfile(loc)) True >>> print(os.access(loc, os.X_OK)) True For convenience, :py:meth:`available()` and :py:meth:`path()` are available by casting the :py:class:`_PathData` object requrned from ``Executable`` or ``Library`` to either a ``bool`` or ``str``: .. doctest:: >>> if Executable('demo_exec_file'): ... cmd = "%s --help" % Executable('demo_exec_file') The :py:class:`PathManager` caches the location / existence of the target directory entry. If something in the environment changes (e.g., the PATH) or the file is created or removed after the first time a client queried the location or availability, the PathManager will return incorrect information. You can cause the :py:class:`PathManager` to refresh its cache by calling ``rehash()`` on either the :py:class:`_PathData` (for the single file) or the :py:class:`PathManager` to refresh the cache for all files: .. doctest:: >>> # refresh the cache for a single file >>> Executable('demo_exec_file').rehash() >>> # or all registered files >>> Executable.rehash() The ``Executable`` singleton looks for executables in the system ``PATH`` and in the list of directories specified by the ``pathlist`` attribute. ``Executable.pathlist`` defaults to a list containing the ``os.path.join(pyomo.common.config.PYOMO_CONFIG_DIR, 'bin')``. The ``Library`` singleton looks for executables in the system ``LD_LIBRARY_PATH``, ``PATH`` and in the list of directories specified by the ``pathlist`` attribute. ``Library.pathlist`` defaults to a list containing the ``os.path.join(pyomo.common.config.PYOMO_CONFIG_DIR, 'lib')``. Users may also override the normal file resolution by explicitly setting the location using :py:meth:`set_path`: .. doctest:: >>> Executable('demo_exec_file').set_path(os.path.join( ... pyomo.common.config.PYOMO_CONFIG_DIR, 'bin', 'demo_exec_file')) Explicitly setting the path is an absolute operation and will set the location whether or not that location points to an actual file. Additionally, the explicit location will persist through calls to ``rehash()``. If you wish to remove the explicit executable location, call ``set_path(None)``: .. doctest:: >>> Executable('demo_exec_file').set_path(None) The ``Executable`` singleton uses :py:class:`_ExecutableData`, an extended form of the :py:class:`_PathData` class, which provides the ``executable`` property as an alais for :py:meth:`path()` and :py:meth:`set_path()`: .. doctest:: >>> loc = Executable('demo_exec_file').executable >>> print(os.path.isfile(loc)) >>> Executable('demo_exec_file').executable = os.path.join( ... pyomo.common.config.PYOMO_CONFIG_DIR, 'bin', 'demo_exec_file') >>> Executable('demo_exec_file').executable = None .. doctest:: :hide: >>> if _del_testfile: ... os.remove(_testfile) cCsi|_||_||_d|_dS)N)_pathTor] _dataClassr,)rZfinderZ dataClassrrrr\bszPathManager.__init__cCs&||jkr||||j|<|j|S)N)rwrx)rZrrrr__call__hs zPathManager.__call__cCs"xt|jD] }|qWdS)zRequery the location of all registered executables This method derives its name from the csh command of the same name, which rebuilds the hash table of executables reachable through the PATH. N)r itervaluesrwra)rZrCrrrramszPathManager.rehashN)rnrorp__doc__r\rzrarrrrrvsxrvzhpyomo.common.register_executable(name) has been deprecated; explicit registration is no longer necessaryz5.6.2)rgcCs t|S)N) Executablera)r'r(rrrregister_executablesr~a2pyomo.common.registered_executable(name) has been deprecated; use pyomo.common.Executable(name).path() to get the path or pyomo.common.Executable(name).available() to get a bool indicating file availability. Equivalent results can be obtained by casting Executable(name) to string or bool.cCs t|}|dkrdS|SdS)N)r}r)r'rlrrrregistered_executables rz\pyomo.common.unregister_executable(name) has been deprecated; use Executable(name).disable()cCst|dS)N)r}ri)r'rrrunregister_executablesr)r)TTN)TTN)N)$Z ctypes.utilrLr$rrbr r:r deprecationrrrrrrrZPYOMO_ROOT_DIRrQr0r3r5rPrIr>rCrNrTobjectrUrrrvr}Libraryr~rrrrrr sV   S  5 1 J 5X